replaced unittest assertions pytest assertions (#26530)

This commit is contained in:
Aarif
2021-02-19 12:25:51 +05:00
committed by GitHub
parent a8b9733654
commit cce5c9ef1a
81 changed files with 3006 additions and 3700 deletions

View File

@@ -42,7 +42,7 @@ class TestLazyMod(unittest.TestCase): # lint-amnesty, pylint: disable=missing-c
assert module_name not in sys.modules
colorsys = LazyModule(module_name)
hsv = colorsys.rgb_to_hsv(.3, .4, .2)
self.assertEqual(hsv[0], 0.25)
assert hsv[0] == 0.25
def test_dotted(self):
# wsgiref is a module with submodules that is not already imported.
@@ -54,4 +54,4 @@ class TestLazyMod(unittest.TestCase): # lint-amnesty, pylint: disable=missing-c
del sys.modules[module_name]
assert module_name not in sys.modules
wsgiref_util = LazyModule(module_name)
self.assertEqual(wsgiref_util.guess_scheme({}), "http")
assert wsgiref_util.guess_scheme({}) == 'http'

View File

@@ -26,19 +26,19 @@ class TestSafeExec(unittest.TestCase): # lint-amnesty, pylint: disable=missing-
def test_set_values(self):
g = {}
safe_exec("a = 17", g)
self.assertEqual(g['a'], 17)
assert g['a'] == 17
def test_division(self):
g = {}
# Future division: 1/2 is 0.5.
safe_exec("a = 1/2", g)
self.assertEqual(g['a'], 0.5)
assert g['a'] == 0.5
def test_assumed_imports(self):
g = {}
# Math is always available.
safe_exec("a = int(math.pi)", g)
self.assertEqual(g['a'], 3)
assert g['a'] == 3
def test_random_seeding(self):
g = {}
@@ -47,11 +47,11 @@ class TestSafeExec(unittest.TestCase): # lint-amnesty, pylint: disable=missing-
# Without a seed, the results are unpredictable
safe_exec("rnums = [random.randint(0, 999) for _ in xrange(100)]", g)
self.assertNotEqual(g['rnums'], rnums)
assert g['rnums'] != rnums
# With a seed, the results are predictable
safe_exec("rnums = [random.randint(0, 999) for _ in xrange(100)]", g, random_seed=17)
self.assertEqual(g['rnums'], rnums)
assert g['rnums'] == rnums
def test_random_is_still_importable(self):
g = {}
@@ -63,7 +63,7 @@ class TestSafeExec(unittest.TestCase): # lint-amnesty, pylint: disable=missing-
"import random\n"
"rnums = [random.randint(0, 999) for _ in xrange(100)]\n",
g, random_seed=17)
self.assertEqual(g['rnums'], rnums)
assert g['rnums'] == rnums
def test_python_lib(self):
pylib = os.path.dirname(__file__) + "/test_files/pylib"
@@ -75,9 +75,9 @@ class TestSafeExec(unittest.TestCase): # lint-amnesty, pylint: disable=missing-
def test_raising_exceptions(self):
g = {}
with self.assertRaises(SafeExecException) as cm:
with pytest.raises(SafeExecException) as cm:
safe_exec("1/0", g)
self.assertIn("ZeroDivisionError", text_type(cm.exception))
assert 'ZeroDivisionError' in text_type(cm.exception)
class TestSafeOrNot(unittest.TestCase): # lint-amnesty, pylint: disable=missing-class-docstring
@@ -87,7 +87,7 @@ class TestSafeOrNot(unittest.TestCase): # lint-amnesty, pylint: disable=missing
pytest.skip()
g = {}
with self.assertRaises(SafeExecException) as cm:
with pytest.raises(SafeExecException) as cm:
safe_exec("import os; files = os.listdir('/')", g)
assert "OSError" in text_type(cm.exception)
assert "Permission denied" in text_type(cm.exception)
@@ -95,7 +95,7 @@ class TestSafeOrNot(unittest.TestCase): # lint-amnesty, pylint: disable=missing
def test_can_do_something_forbidden_if_run_unsafely(self):
g = {}
safe_exec("import os; files = os.listdir('/')", g, unsafely=True)
self.assertEqual(g['files'], os.listdir('/'))
assert g['files'] == os.listdir('/')
class TestLimitConfiguration(unittest.TestCase):
@@ -199,16 +199,16 @@ class TestSafeExecCaching(unittest.TestCase):
# Cache miss
safe_exec("a = int(math.pi)", g, cache=DictCache(cache))
self.assertEqual(g['a'], 3)
assert g['a'] == 3
# A result has been cached
self.assertEqual(list(cache.values())[0], (None, {'a': 3}))
assert list(cache.values())[0] == (None, {'a': 3})
# Fiddle with the cache, then try it again.
cache[list(cache.keys())[0]] = (None, {'a': 17})
g = {}
safe_exec("a = int(math.pi)", g, cache=DictCache(cache))
self.assertEqual(g['a'], 17)
assert g['a'] == 17
def test_cache_large_code_chunk(self):
# Caching used to die on memcache with more than 250 bytes of code.
@@ -218,7 +218,7 @@ class TestSafeExecCaching(unittest.TestCase):
g = {}
cache = {}
safe_exec(code, g, cache=DictCache(cache))
self.assertEqual(g['a'], 12345)
assert g['a'] == 12345
def test_cache_exceptions(self):
# Used to be that running code that raised an exception didn't cache
@@ -226,28 +226,28 @@ class TestSafeExecCaching(unittest.TestCase):
code = "1/0"
g = {}
cache = {}
with self.assertRaises(SafeExecException):
with pytest.raises(SafeExecException):
safe_exec(code, g, cache=DictCache(cache))
# The exception should be in the cache now.
self.assertEqual(len(cache), 1)
assert len(cache) == 1
cache_exc_msg, cache_globals = list(cache.values())[0] # lint-amnesty, pylint: disable=unused-variable
self.assertIn("ZeroDivisionError", cache_exc_msg)
assert 'ZeroDivisionError' in cache_exc_msg
# Change the value stored in the cache, the result should change.
cache[list(cache.keys())[0]] = ("Hey there!", {})
with self.assertRaises(SafeExecException):
with pytest.raises(SafeExecException):
safe_exec(code, g, cache=DictCache(cache))
self.assertEqual(len(cache), 1)
assert len(cache) == 1
cache_exc_msg, cache_globals = list(cache.values())[0]
self.assertEqual("Hey there!", cache_exc_msg)
assert 'Hey there!' == cache_exc_msg
# Change it again, now no exception!
cache[list(cache.keys())[0]] = (None, {'a': 17})
safe_exec(code, g, cache=DictCache(cache))
self.assertEqual(g['a'], 17)
assert g['a'] == 17
def test_unicode_submission(self):
# Check that using non-ASCII unicode does not raise an encoding error.
@@ -288,8 +288,8 @@ class TestUpdateHash(unittest.TestCase):
del d2[i]
# Check that our dicts are equal, but with different key order.
self.assertEqual(d1, d2)
self.assertNotEqual(list(d1.keys()), list(d2.keys()))
assert d1 == d2
assert list(d1.keys()) != list(d2.keys())
return d1, d2
@@ -298,19 +298,19 @@ class TestUpdateHash(unittest.TestCase):
h10 = self.hash_obj(10)
hs1 = self.hash_obj("1")
self.assertNotEqual(h1, h10)
self.assertNotEqual(h1, hs1)
assert h1 != h10
assert h1 != hs1
def test_list_ordering(self):
h1 = self.hash_obj({'a': [1, 2, 3]})
h2 = self.hash_obj({'a': [3, 2, 1]})
self.assertNotEqual(h1, h2)
assert h1 != h2
def test_dict_ordering(self):
d1, d2 = self.equal_but_different_dicts()
h1 = self.hash_obj(d1)
h2 = self.hash_obj(d2)
self.assertEqual(h1, h2)
assert h1 == h2
def test_deep_ordering(self):
d1, d2 = self.equal_but_different_dicts()
@@ -318,7 +318,7 @@ class TestUpdateHash(unittest.TestCase):
o2 = {'a': [1, 2, [d2], 3, 4]}
h1 = self.hash_obj(o1)
h2 = self.hash_obj(o2)
self.assertEqual(h1, h2)
assert h1 == h2
class TestRealProblems(unittest.TestCase): # lint-amnesty, pylint: disable=missing-class-docstring
@@ -386,4 +386,4 @@ class TestRealProblems(unittest.TestCase): # lint-amnesty, pylint: disable=miss
""")
g = {}
safe_exec(code, g)
self.assertIn("aVAP", g)
assert 'aVAP' in g

View File

@@ -58,12 +58,12 @@ class CapaAnswerPoolTest(unittest.TestCase):
# [('choice_3', u'wrong-3'), ('choice_5', u'correct-2'), ('choice_1', u'wrong-2'), ('choice_4', u'wrong-4')]
self.assertRegex(the_html, r"<div>.*\[.*'wrong-3'.*'correct-2'.*'wrong-2'.*'wrong-4'.*\].*</div>")
self.assertRegex(the_html, r"<div>\{.*'1_solution_2'.*\}</div>")
self.assertEqual(the_html, problem.get_html(), 'should be able to call get_html() twice')
assert the_html == problem.get_html(), 'should be able to call get_html() twice'
# Check about masking
response = list(problem.responders.values())[0]
self.assertFalse(response.has_mask())
self.assertTrue(response.has_answerpool())
self.assertEqual(response.unmask_order(), ['choice_3', 'choice_5', 'choice_1', 'choice_4'])
assert not response.has_mask()
assert response.has_answerpool()
assert response.unmask_order() == ['choice_3', 'choice_5', 'choice_1', 'choice_4']
def test_answer_pool_4_choices_1_multiplechoiceresponse_seed2(self):
problem = new_loncapa_problem(self.common_question_xml, seed=9)
@@ -73,9 +73,9 @@ class CapaAnswerPoolTest(unittest.TestCase):
self.assertRegex(the_html, r"<div>\{.*'1_solution_1'.*\}</div>")
# Check about masking
response = list(problem.responders.values())[0]
self.assertFalse(response.has_mask())
self.assertTrue(hasattr(response, 'has_answerpool'))
self.assertEqual(response.unmask_order(), ['choice_0', 'choice_4', 'choice_3', 'choice_2'])
assert not response.has_mask()
assert hasattr(response, 'has_answerpool')
assert response.unmask_order() == ['choice_0', 'choice_4', 'choice_3', 'choice_2']
def test_no_answer_pool_4_choices_1_multiplechoiceresponse(self):
xml_str = textwrap.dedent("""
@@ -117,11 +117,11 @@ class CapaAnswerPoolTest(unittest.TestCase):
the_html = problem.get_html()
self.assertRegex(the_html, r"<div>.*\[.*'wrong-1'.*'wrong-2'.*'correct-1'.*'wrong-3'.*'wrong-4'.*'correct-2'.*\].*</div>") # lint-amnesty, pylint: disable=line-too-long
self.assertRegex(the_html, r"<div>\{.*'1_solution_1'.*'1_solution_2'.*\}</div>")
self.assertEqual(the_html, problem.get_html(), 'should be able to call get_html() twice')
assert the_html == problem.get_html(), 'should be able to call get_html() twice'
# Check about masking
response = list(problem.responders.values())[0]
self.assertFalse(response.has_mask())
self.assertFalse(response.has_answerpool())
assert not response.has_mask()
assert not response.has_answerpool()
def test_0_answer_pool_4_choices_1_multiplechoiceresponse(self):
xml_str = textwrap.dedent("""
@@ -164,8 +164,8 @@ class CapaAnswerPoolTest(unittest.TestCase):
self.assertRegex(the_html, r"<div>.*\[.*'wrong-1'.*'wrong-2'.*'correct-1'.*'wrong-3'.*'wrong-4'.*'correct-2'.*\].*</div>") # lint-amnesty, pylint: disable=line-too-long
self.assertRegex(the_html, r"<div>\{.*'1_solution_1'.*'1_solution_2'.*\}</div>")
response = list(problem.responders.values())[0]
self.assertFalse(response.has_mask())
self.assertFalse(response.has_answerpool())
assert not response.has_mask()
assert not response.has_answerpool()
def test_invalid_answer_pool_value(self):
xml_str = textwrap.dedent("""
@@ -282,8 +282,8 @@ class CapaAnswerPoolTest(unittest.TestCase):
self.assertRegex(the_html, r"<div>.*\[.*'correct-2'.*'wrong-1'.*'wrong-2'.*.*'wrong-3'.*'wrong-4'.*\].*</div>")
self.assertRegex(the_html, r"<div>\{.*'1_solution_2'.*\}</div>")
response = list(problem.responders.values())[0]
self.assertFalse(response.has_mask())
self.assertEqual(response.unmask_order(), ['choice_5', 'choice_0', 'choice_1', 'choice_3', 'choice_4'])
assert not response.has_mask()
assert response.unmask_order() == ['choice_5', 'choice_0', 'choice_1', 'choice_3', 'choice_4']
def test_answer_pool_2_multiplechoiceresponses_seed1(self):
xml_str = textwrap.dedent("""
@@ -543,8 +543,8 @@ class CapaAnswerPoolTest(unittest.TestCase):
self.assertRegex(the_html, str1)
# attributes *not* present
response = list(problem.responders.values())[0]
self.assertFalse(response.has_mask())
self.assertFalse(response.has_answerpool())
assert not response.has_mask()
assert not response.has_answerpool()
def test_answer_pool_and_no_answer_pool(self):
xml_str = textwrap.dedent("""

View File

@@ -5,7 +5,7 @@ Test capa problem.
import textwrap
import unittest
import pytest
import ddt
import six
from lxml import etree
@@ -48,17 +48,9 @@ class CAPAProblemTest(unittest.TestCase):
</problem>
""".format(question=question)
problem = new_loncapa_problem(xml)
self.assertEqual(
problem.problem_data,
{
'1_2_1':
{
'label': question,
'descriptions': {'description_1_1_1': 'Only the paranoid survive.'}
}
}
)
self.assertEqual(len(problem.tree.xpath('//label')), 0)
assert problem.problem_data ==\
{'1_2_1': {'label': question, 'descriptions': {'description_1_1_1': 'Only the paranoid survive.'}}}
assert len(problem.tree.xpath('//label')) == 0
@ddt.unpack
@ddt.data(
@@ -85,20 +77,8 @@ class CAPAProblemTest(unittest.TestCase):
</problem>
""".format(question, label_attr)
problem = new_loncapa_problem(xml)
self.assertEqual(
problem.problem_data,
{
'1_2_1':
{
'label': question,
'descriptions': {}
}
}
)
self.assertEqual(
len(problem.tree.xpath("//*[normalize-space(text())='{}']".format(question))),
0
)
assert problem.problem_data == {'1_2_1': {'label': question, 'descriptions': {}}}
assert len(problem.tree.xpath("//*[normalize-space(text())='{}']".format(question))) == 0
@ddt.unpack
@ddt.data(
@@ -137,26 +117,10 @@ class CAPAProblemTest(unittest.TestCase):
</problem>
""".format(question1, question2)
problem = new_loncapa_problem(xml)
self.assertEqual(
problem.problem_data,
{
'1_2_1':
{
'label': question1,
'descriptions': {}
},
'1_3_1':
{
'label': question2,
'descriptions': {}
}
}
)
assert problem.problem_data ==\
{'1_2_1': {'label': question1, 'descriptions': {}}, '1_3_1': {'label': question2, 'descriptions': {}}}
for question in (question1, question2):
self.assertEqual(
len(problem.tree.xpath('//label[text()="{}"]'.format(question))),
0
)
assert len(problem.tree.xpath('//label[text()="{}"]'.format(question))) == 0
def test_multiple_descriptions(self):
"""
@@ -176,19 +140,9 @@ class CAPAProblemTest(unittest.TestCase):
</problem>
""".format(desc1, desc2)
problem = new_loncapa_problem(xml)
self.assertEqual(
problem.problem_data,
{
'1_2_1':
{
'label': '___ requires sacrifices.',
'descriptions': {
'description_1_1_1': desc1,
'description_1_1_2': desc2
}
}
}
)
assert problem.problem_data ==\
{'1_2_1': {'label': '___ requires sacrifices.',
'descriptions': {'description_1_1_1': desc1, 'description_1_1_2': desc2}}}
def test_additional_answer_is_skipped_from_resulting_html(self):
"""Tests that additional_answer element is not present in transformed HTML"""
@@ -204,8 +158,8 @@ class CAPAProblemTest(unittest.TestCase):
</problem>
"""
problem = new_loncapa_problem(xml)
self.assertEqual(len(problem.extracted_tree.xpath('//additional_answer')), 0)
self.assertNotIn('additional_answer', problem.get_html())
assert len(problem.extracted_tree.xpath('//additional_answer')) == 0
assert 'additional_answer' not in problem.get_html()
def test_non_accessible_inputtype(self):
"""
@@ -223,18 +177,9 @@ class CAPAProblemTest(unittest.TestCase):
</problem>
""".format(question, question)
problem = new_loncapa_problem(xml)
self.assertEqual(
problem.problem_data,
{
'1_2_1':
{
'label': question,
'descriptions': {}
}
}
)
assert problem.problem_data == {'1_2_1': {'label': question, 'descriptions': {}}}
# <p> tag with question text should not be deleted
self.assertEqual(problem.tree.xpath("string(p[text()='{}'])".format(question)), question)
assert problem.tree.xpath("string(p[text()='{}'])".format(question)) == question
def test_label_is_empty_if_no_label_attribute(self):
"""
@@ -252,16 +197,7 @@ class CAPAProblemTest(unittest.TestCase):
</problem>
""".format(question)
problem = new_loncapa_problem(xml)
self.assertEqual(
problem.problem_data,
{
'1_2_1':
{
'label': '',
'descriptions': {}
}
}
)
assert problem.problem_data == {'1_2_1': {'label': '', 'descriptions': {}}}
def test_multiple_questions_problem(self):
"""
@@ -294,22 +230,12 @@ class CAPAProblemTest(unittest.TestCase):
</problem>
"""
problem = new_loncapa_problem(xml)
self.assertEqual(
problem.problem_data,
{
'1_2_1':
{
'label': 'Select the correct synonym of paranoid?',
'descriptions': {'description_1_1_1': 'Only the paranoid survive.'}
},
'1_3_1':
{
'label': 'What Apple device competed with the portable CD player?',
'descriptions': {'description_1_2_1': 'Device looks like an egg plant.'}
}
}
)
self.assertEqual(len(problem.tree.xpath('//label')), 0)
assert problem.problem_data ==\
{'1_2_1': {'label': 'Select the correct synonym of paranoid?',
'descriptions': {'description_1_1_1': 'Only the paranoid survive.'}},
'1_3_1': {'label': 'What Apple device competed with the portable CD player?',
'descriptions': {'description_1_2_1': 'Device looks like an egg plant.'}}}
assert len(problem.tree.xpath('//label')) == 0
def test_question_title_not_removed_got_children(self):
"""
@@ -334,20 +260,8 @@ class CAPAProblemTest(unittest.TestCase):
</problem>
""".format(question)
problem = new_loncapa_problem(xml)
self.assertEqual(
problem.problem_data,
{
'1_2_1':
{
'label': '',
'descriptions': {}
}
}
)
self.assertEqual(
len(problem.tree.xpath('//p/img')),
1
)
assert problem.problem_data == {'1_2_1': {'label': '', 'descriptions': {}}}
assert len(problem.tree.xpath('//p/img')) == 1
@ddt.unpack
@ddt.data(
@@ -371,23 +285,9 @@ class CAPAProblemTest(unittest.TestCase):
""".format(group_label, input1_label, input2_label)
problem = new_loncapa_problem(xml)
self.assertEqual(
problem.problem_data,
{
'1_2_1':
{
'group_label': group_label,
'label': input1_label,
'descriptions': {}
},
'1_2_2':
{
'group_label': group_label,
'label': input2_label,
'descriptions': {}
}
}
)
assert problem.problem_data ==\
{'1_2_1': {'group_label': group_label, 'label': input1_label, 'descriptions': {}},
'1_2_2': {'group_label': group_label, 'label': input2_label, 'descriptions': {}}}
def test_single_inputtypes(self):
"""
@@ -411,11 +311,11 @@ class CAPAProblemTest(unittest.TestCase):
# verify that only no multi input group div is present
multi_inputs_group = problem_html.xpath('//div[@class="multi-inputs-group"]')
self.assertEqual(len(multi_inputs_group), 0)
assert len(multi_inputs_group) == 0
# verify that question is rendered only once
question = problem_html.xpath("//*[normalize-space(text())='{}']".format(question))
self.assertEqual(len(question), 1)
assert len(question) == 1
def assert_question_tag(self, question1, question2, tag, label_attr=False):
"""
@@ -449,22 +349,9 @@ class CAPAProblemTest(unittest.TestCase):
question2_label_attr=question2_label_attr,
)
problem = new_loncapa_problem(xml)
self.assertEqual(
problem.problem_data,
{
'1_2_1':
{
'label': question1,
'descriptions': {}
},
'1_3_1':
{
'label': question2,
'descriptions': {}
}
}
)
self.assertEqual(len(problem.tree.xpath('//{}'.format(tag))), 0)
assert problem.problem_data ==\
{'1_2_1': {'label': question1, 'descriptions': {}}, '1_3_1': {'label': question2, 'descriptions': {}}}
assert len(problem.tree.xpath('//{}'.format(tag))) == 0
@ddt.unpack
@ddt.data(
@@ -505,10 +392,10 @@ class CAPAProblemTest(unittest.TestCase):
</optionresponse>
</problem>
"""
with self.assertRaises(LoncapaProblemError):
with pytest.raises(LoncapaProblemError):
new_loncapa_problem(xml.format(correctness=True))
problem = new_loncapa_problem(xml.format(correctness=False))
self.assertIsNotNone(problem)
assert problem is not None
@ddt.ddt
@@ -524,7 +411,7 @@ class CAPAMultiInputProblemTest(unittest.TestCase):
def assert_problem_data(self, problem_data):
"""Verify problem data is in expected state"""
for problem_value in six.viewvalues(problem_data):
self.assertIsInstance(problem_value['label'], Markup)
assert isinstance(problem_value['label'], Markup)
def assert_problem_html(self, problem_html, group_label, *input_labels):
"""
@@ -541,24 +428,24 @@ class CAPAMultiInputProblemTest(unittest.TestCase):
multi_inputs_group = html.xpath(
'//div[@class="wrapper-problem-response"]/div[@class="multi-inputs-group"]'
)
self.assertEqual(len(multi_inputs_group), 1)
assert len(multi_inputs_group) == 1
if group_label is None:
# if multi inputs group label is not present then there shouldn't be `aria-labelledby` attribute
self.assertEqual(multi_inputs_group[0].attrib.get('aria-labelledby'), None)
assert multi_inputs_group[0].attrib.get('aria-labelledby') is None
else:
# verify that multi input group label <p> tag exists and its
# id matches with correct multi input group aria-labelledby
multi_inputs_group_label_id = multi_inputs_group[0].attrib.get('aria-labelledby')
multi_inputs_group_label = html.xpath('//p[@id="{}"]'.format(multi_inputs_group_label_id))
self.assertEqual(len(multi_inputs_group_label), 1)
self.assertEqual(multi_inputs_group_label[0].text, group_label)
assert len(multi_inputs_group_label) == 1
assert multi_inputs_group_label[0].text == group_label
# verify that label for each input comes only once
for input_label in input_labels:
# normalize-space is used to remove whitespace around the text
input_label_element = multi_inputs_group[0].xpath('//*[normalize-space(text())="{}"]'.format(input_label))
self.assertEqual(len(input_label_element), 1)
assert len(input_label_element) == 1
@ddt.unpack
@ddt.data(
@@ -646,13 +533,13 @@ class CAPAMultiInputProblemTest(unittest.TestCase):
description_ids = multi_inputs_group.attrib.get('aria-describedby', '').split()
# Verify that number of descriptions matches description_ids
self.assertEqual(len(description_ids), len(descriptions))
assert len(description_ids) == len(descriptions)
# For each description, check its order and text is correct
for index, description_id in enumerate(description_ids):
description_element = multi_inputs_group.xpath('//p[@id="{}"]'.format(description_id))
self.assertEqual(len(description_element), 1)
self.assertEqual(description_element[0].text, descriptions[index])
assert len(description_element) == 1
assert description_element[0].text == descriptions[index]
@ddt.ddt
@@ -678,7 +565,7 @@ class CAPAProblemReportHelpersTest(unittest.TestCase):
}
}
with patch.object(problem, 'problem_data', mock_problem_data):
self.assertEqual(problem.find_question_label(answer_id), stripped_label)
assert problem.find_question_label(answer_id) == stripped_label
@ddt.data(None, dict(), [None])
def test_find_answer_test_not_implemented(self, current_answer):
@@ -718,7 +605,7 @@ class CAPAProblemReportHelpersTest(unittest.TestCase):
</problem>
"""
)
self.assertEqual(problem.find_answer_text(answer_id, choice_id), answer_text)
assert problem.find_answer_text(answer_id, choice_id) == answer_text
@ddt.data(
# Test for ChoiceResponse
@@ -756,7 +643,7 @@ class CAPAProblemReportHelpersTest(unittest.TestCase):
</problem>
"""
)
self.assertEqual(problem.find_correct_answer_text(answer_id), answer_text)
assert problem.find_correct_answer_text(answer_id) == answer_text
def test_find_answer_text_textinput(self):
problem = new_loncapa_problem(
@@ -768,7 +655,7 @@ class CAPAProblemReportHelpersTest(unittest.TestCase):
</problem>
"""
)
self.assertEqual(problem.find_answer_text('1_2_1', 'hide'), 'hide')
assert problem.find_answer_text('1_2_1', 'hide') == 'hide'
def test_get_question_answer(self):
problem = new_loncapa_problem(
@@ -789,4 +676,4 @@ class CAPAProblemReportHelpersTest(unittest.TestCase):
# Ensure that the answer is a string so that the dict returned from this
# function can eventualy be serialized to json without issues.
self.assertIsInstance(problem.get_question_answers()['1_solution_1'], six.text_type)
assert isinstance(problem.get_question_answers()['1_solution_1'], six.text_type)

View File

@@ -5,7 +5,7 @@ Tests to verify that CorrectMap behaves correctly
import datetime
import unittest
import pytest
from capa.correctmap import CorrectMap
@@ -54,48 +54,48 @@ class CorrectMapTest(unittest.TestCase):
)
# Assert that each input has the expected properties
self.assertTrue(self.cmap.is_correct('1_2_1'))
self.assertFalse(self.cmap.is_correct('2_2_1'))
self.assertTrue(self.cmap.is_correct('3_2_1'))
assert self.cmap.is_correct('1_2_1')
assert not self.cmap.is_correct('2_2_1')
assert self.cmap.is_correct('3_2_1')
self.assertTrue(self.cmap.is_partially_correct('3_2_1'))
self.assertFalse(self.cmap.is_partially_correct('2_2_1'))
assert self.cmap.is_partially_correct('3_2_1')
assert not self.cmap.is_partially_correct('2_2_1')
# Intentionally testing an item that's not in cmap.
self.assertFalse(self.cmap.is_partially_correct('9_2_1'))
assert not self.cmap.is_partially_correct('9_2_1')
self.assertEqual(self.cmap.get_correctness('1_2_1'), 'correct')
self.assertEqual(self.cmap.get_correctness('2_2_1'), 'incorrect')
self.assertEqual(self.cmap.get_correctness('3_2_1'), 'partially-correct')
assert self.cmap.get_correctness('1_2_1') == 'correct'
assert self.cmap.get_correctness('2_2_1') == 'incorrect'
assert self.cmap.get_correctness('3_2_1') == 'partially-correct'
self.assertEqual(self.cmap.get_npoints('1_2_1'), 5)
self.assertEqual(self.cmap.get_npoints('2_2_1'), 0)
self.assertEqual(self.cmap.get_npoints('3_2_1'), 3)
assert self.cmap.get_npoints('1_2_1') == 5
assert self.cmap.get_npoints('2_2_1') == 0
assert self.cmap.get_npoints('3_2_1') == 3
self.assertEqual(self.cmap.get_msg('1_2_1'), 'Test message')
self.assertEqual(self.cmap.get_msg('2_2_1'), None)
assert self.cmap.get_msg('1_2_1') == 'Test message'
assert self.cmap.get_msg('2_2_1') is None
self.assertEqual(self.cmap.get_hint('1_2_1'), 'Test hint')
self.assertEqual(self.cmap.get_hint('2_2_1'), None)
assert self.cmap.get_hint('1_2_1') == 'Test hint'
assert self.cmap.get_hint('2_2_1') is None
self.assertEqual(self.cmap.get_hintmode('1_2_1'), 'always')
self.assertEqual(self.cmap.get_hintmode('2_2_1'), None)
assert self.cmap.get_hintmode('1_2_1') == 'always'
assert self.cmap.get_hintmode('2_2_1') is None
self.assertTrue(self.cmap.is_queued('1_2_1'))
self.assertFalse(self.cmap.is_queued('2_2_1'))
assert self.cmap.is_queued('1_2_1')
assert not self.cmap.is_queued('2_2_1')
self.assertEqual(self.cmap.get_queuetime_str('1_2_1'), '20130228100026')
self.assertEqual(self.cmap.get_queuetime_str('2_2_1'), None)
assert self.cmap.get_queuetime_str('1_2_1') == '20130228100026'
assert self.cmap.get_queuetime_str('2_2_1') is None
self.assertTrue(self.cmap.is_right_queuekey('1_2_1', 'secretstring'))
self.assertFalse(self.cmap.is_right_queuekey('1_2_1', 'invalidstr'))
self.assertFalse(self.cmap.is_right_queuekey('1_2_1', ''))
self.assertFalse(self.cmap.is_right_queuekey('1_2_1', None))
assert self.cmap.is_right_queuekey('1_2_1', 'secretstring')
assert not self.cmap.is_right_queuekey('1_2_1', 'invalidstr')
assert not self.cmap.is_right_queuekey('1_2_1', '')
assert not self.cmap.is_right_queuekey('1_2_1', None)
self.assertFalse(self.cmap.is_right_queuekey('2_2_1', 'secretstring'))
self.assertFalse(self.cmap.is_right_queuekey('2_2_1', 'invalidstr'))
self.assertFalse(self.cmap.is_right_queuekey('2_2_1', ''))
self.assertFalse(self.cmap.is_right_queuekey('2_2_1', None))
assert not self.cmap.is_right_queuekey('2_2_1', 'secretstring')
assert not self.cmap.is_right_queuekey('2_2_1', 'invalidstr')
assert not self.cmap.is_right_queuekey('2_2_1', '')
assert not self.cmap.is_right_queuekey('2_2_1', None)
def test_get_npoints(self):
# Set the correctmap properties for 4 inputs
@@ -153,28 +153,28 @@ class CorrectMapTest(unittest.TestCase):
# If no points assigned and correct --> 1 point
# If no points assigned and partially correct --> 1 point
# If no points assigned and incorrect --> 0 points
self.assertEqual(self.cmap.get_npoints('1_2_1'), 5.3)
self.assertEqual(self.cmap.get_npoints('2_2_1'), 1)
self.assertEqual(self.cmap.get_npoints('3_2_1'), 5)
self.assertEqual(self.cmap.get_npoints('4_2_1'), 0)
self.assertEqual(self.cmap.get_npoints('5_2_1'), 0)
self.assertEqual(self.cmap.get_npoints('6_2_1'), 2.5)
self.assertEqual(self.cmap.get_npoints('7_2_1'), 1)
assert self.cmap.get_npoints('1_2_1') == 5.3
assert self.cmap.get_npoints('2_2_1') == 1
assert self.cmap.get_npoints('3_2_1') == 5
assert self.cmap.get_npoints('4_2_1') == 0
assert self.cmap.get_npoints('5_2_1') == 0
assert self.cmap.get_npoints('6_2_1') == 2.5
assert self.cmap.get_npoints('7_2_1') == 1
def test_set_overall_message(self):
# Default is an empty string string
self.assertEqual(self.cmap.get_overall_message(), "")
assert self.cmap.get_overall_message() == ''
# Set a message that applies to the whole question
self.cmap.set_overall_message("Test message")
# Retrieve the message
self.assertEqual(self.cmap.get_overall_message(), "Test message")
assert self.cmap.get_overall_message() == 'Test message'
# Setting the message to None --> empty string
self.cmap.set_overall_message(None)
self.assertEqual(self.cmap.get_overall_message(), "")
assert self.cmap.get_overall_message() == ''
def test_update_from_correctmap(self):
# Initialize a CorrectMap with some properties
@@ -199,15 +199,9 @@ class CorrectMapTest(unittest.TestCase):
other_cmap.update(self.cmap)
# Assert that it has all the same properties
self.assertEqual(
other_cmap.get_overall_message(),
self.cmap.get_overall_message()
)
assert other_cmap.get_overall_message() == self.cmap.get_overall_message()
self.assertEqual(
other_cmap.get_dict(),
self.cmap.get_dict()
)
assert other_cmap.get_dict() == self.cmap.get_dict()
def test_update_from_invalid(self):
# Should get an exception if we try to update() a CorrectMap
@@ -215,7 +209,7 @@ class CorrectMapTest(unittest.TestCase):
invalid_list = [None, "string", 5, datetime.datetime.today()]
for invalid in invalid_list:
with self.assertRaises(Exception):
with pytest.raises(Exception):
self.cmap.update(invalid)
def test_set_none_state(self):
@@ -226,4 +220,4 @@ class CorrectMapTest(unittest.TestCase):
invalid_list = [None, "", False, 0]
for invalid in invalid_list:
self.cmap.set_dict(invalid)
self.assertEqual(self.cmap.get_dict(), {})
assert self.cmap.get_dict() == {}

View File

@@ -30,7 +30,7 @@ class HelperTest(unittest.TestCase):
'''
def check(self, d):
xml = etree.XML(test_capa_system().render_template('blah', d))
self.assertEqual(d, extract_context(xml))
assert d == extract_context(xml)
def test_extract_context(self):
self.check({})
@@ -51,12 +51,12 @@ class SolutionRenderTest(unittest.TestCase):
renderer = lookup_tag('solution')(test_capa_system(), element)
self.assertEqual(renderer.id, 'solution_12')
assert renderer.id == 'solution_12'
# Our test_capa_system "renders" templates to a div with the repr of the context.
xml = renderer.get_html()
context = extract_context(xml)
self.assertEqual(context, {'id': 'solution_12'})
assert context == {'id': 'solution_12'}
class MathRenderTest(unittest.TestCase):
@@ -70,7 +70,7 @@ class MathRenderTest(unittest.TestCase):
renderer = lookup_tag('math')(test_capa_system(), element)
self.assertEqual(renderer.mathstr, mathjax_out)
assert renderer.mathstr == mathjax_out
def test_parsing(self):
self.check_parse('$abc$', '[mathjaxinline]abc[/mathjaxinline]')

View File

@@ -5,7 +5,7 @@ Tests of extended hints
import unittest
import pytest
from ddt import data, ddt, unpack
from capa.tests.helpers import load_fixture, new_loncapa_problem
@@ -89,7 +89,7 @@ class TextInputHintsTest(HintTest):
@unpack
def test_text_input_hints(self, problem_id, choice, expected_string):
hint = self.get_hint(problem_id, choice)
self.assertEqual(hint, expected_string)
assert hint == expected_string
@ddt
@@ -121,7 +121,7 @@ class TextInputExtendedHintsCaseInsensitive(HintTest):
@unpack
def test_text_input_hints(self, problem_id, choice, expected_string):
hint = self.get_hint(problem_id, choice)
self.assertEqual(hint, expected_string)
assert hint == expected_string
@ddt
@@ -149,7 +149,7 @@ class TextInputExtendedHintsCaseSensitive(HintTest):
@unpack
def test_text_input_hints(self, problem_id, choice, expected_string):
message_text = self.get_hint(problem_id, choice)
self.assertEqual(message_text, expected_string)
assert message_text == expected_string
@ddt
@@ -173,8 +173,8 @@ class TextInputExtendedHintsCompatible(HintTest):
@unpack
def test_text_input_hints(self, problem_id, choice, correct, expected_string):
message_text = self.get_hint(problem_id, choice)
self.assertEqual(message_text, expected_string)
self.assertEqual(self.correctness(problem_id, choice), correct)
assert message_text == expected_string
assert self.correctness(problem_id, choice) == correct
@ddt
@@ -209,8 +209,8 @@ class TextInputExtendedHintsRegex(HintTest):
@unpack
def test_text_input_hints(self, problem_id, choice, correct, expected_string):
message_text = self.get_hint(problem_id, choice)
self.assertEqual(message_text, expected_string)
self.assertEqual(self.correctness(problem_id, choice), correct)
assert message_text == expected_string
assert self.correctness(problem_id, choice) == correct
@ddt
@@ -250,7 +250,7 @@ class NumericInputHintsTest(HintTest):
@unpack
def test_numeric_input_hints(self, problem_id, choice, expected_string):
hint = self.get_hint(problem_id, choice)
self.assertEqual(hint, expected_string)
assert hint == expected_string
@ddt
@@ -329,7 +329,7 @@ class CheckboxHintsTest(HintTest):
def test_checkbox_hints(self, problem_id, choice, expected_string):
self.maxDiff = None # pylint: disable=invalid-name
hint = self.get_hint(problem_id, choice)
self.assertEqual(hint, expected_string)
assert hint == expected_string
class CheckboxHintsTestTracking(HintTest):
@@ -449,7 +449,7 @@ class MultpleChoiceHintsTest(HintTest):
@unpack
def test_multiplechoice_hints(self, problem_id, choice, expected_string):
hint = self.get_hint(problem_id, choice)
self.assertEqual(hint, expected_string)
assert hint == expected_string
@ddt
@@ -483,7 +483,7 @@ class MultpleChoiceHintsWithHtmlTest(HintTest):
@unpack
def test_multiplechoice_hints(self, problem_id, choice, expected_string):
hint = self.get_hint(problem_id, choice)
self.assertEqual(hint, expected_string)
assert hint == expected_string
@ddt
@@ -530,7 +530,7 @@ class DropdownHintsTest(HintTest):
@unpack
def test_dropdown_hints(self, problem_id, choice, expected_string):
hint = self.get_hint(problem_id, choice)
self.assertEqual(hint, expected_string)
assert hint == expected_string
class ErrorConditionsTest(HintTest):
@@ -539,5 +539,5 @@ class ErrorConditionsTest(HintTest):
"""
def test_error_conditions_illegal_element(self):
xml_with_errors = load_fixture('extended_hints_with_errors.xml')
with self.assertRaises(Exception):
with pytest.raises(Exception):
new_loncapa_problem(xml_with_errors) # this problem is improperly constructed

View File

@@ -65,8 +65,8 @@ class CapaHtmlRenderTest(unittest.TestCase):
# Expect that the include file was embedded in the problem
test_element = rendered_html.find("test")
self.assertEqual(test_element.tag, "test")
self.assertEqual(test_element.text, "Test include")
assert test_element.tag == 'test'
assert test_element.text == 'Test include'
def test_process_outtext(self):
# Generate some XML with <startouttext /> and <endouttext />
@@ -85,7 +85,7 @@ class CapaHtmlRenderTest(unittest.TestCase):
# Expect that the <startouttext /> and <endouttext />
# were converted to <span></span> tags
span_element = rendered_html.find('span')
self.assertEqual(span_element.text, 'Test text')
assert span_element.text == 'Test text'
def test_anonymous_student_id(self):
# make sure anonymous_student_id is rendered properly as a context variable
@@ -103,7 +103,7 @@ class CapaHtmlRenderTest(unittest.TestCase):
# Expect that the anonymous_student_id was converted to "student"
span_element = rendered_html.find('span')
self.assertEqual(span_element.text, 'Welcome student')
assert span_element.text == 'Welcome student'
def test_render_script(self):
# Generate some XML with a <script> tag
@@ -121,7 +121,7 @@ class CapaHtmlRenderTest(unittest.TestCase):
# Expect that the script element has been removed from the rendered HTML
script_element = rendered_html.find('script')
self.assertEqual(None, script_element)
assert script_element is None
def test_render_javascript(self):
# Generate some XML with a <script> tag
@@ -138,10 +138,7 @@ class CapaHtmlRenderTest(unittest.TestCase):
rendered_html = etree.XML(problem.get_html())
# expect the javascript is still present in the rendered html
self.assertIn(
"<script type=\"text/javascript\">function(){}</script>",
etree.tostring(rendered_html).decode('utf-8')
)
assert '<script type="text/javascript">function(){}</script>' in etree.tostring(rendered_html).decode('utf-8')
def test_render_response_xml(self):
# Generate some XML for a string response
@@ -162,23 +159,23 @@ class CapaHtmlRenderTest(unittest.TestCase):
problem = new_loncapa_problem(xml_str, capa_system=the_system)
rendered_html = etree.XML(problem.get_html())
# Expect problem has been turned into a <div>
self.assertEqual(rendered_html.tag, "div")
assert rendered_html.tag == 'div'
# Expect that the response has been turned into a <div> with correct attributes
response_element = rendered_html.find('div')
self.assertEqual(response_element.tag, "div")
self.assertEqual(response_element.attrib["aria-label"], "Question 1")
assert response_element.tag == 'div'
assert response_element.attrib['aria-label'] == 'Question 1'
# Expect that the response div.wrapper-problem-response
# that contains a <div> for the textline
textline_element = response_element.find('div')
self.assertEqual(textline_element.text, 'Input Template Render')
assert textline_element.text == 'Input Template Render'
# Expect a child <div> for the solution
# with the rendered template
solution_element = rendered_html.xpath('//div[@class="input-template-render"]')[0]
self.assertEqual(solution_element.text, 'Input Template Render')
assert solution_element.text == 'Input Template Render'
# Expect that the template renderer was called with the correct
# arguments, once for the textline input and once for
@@ -208,10 +205,7 @@ class CapaHtmlRenderTest(unittest.TestCase):
mock.call('solutionspan.html', expected_solution_context)
]
self.assertEqual(
the_system.render_template.call_args_list,
expected_calls
)
assert the_system.render_template.call_args_list == expected_calls
def test_correct_aria_label(self):
xml = """
@@ -233,8 +227,8 @@ class CapaHtmlRenderTest(unittest.TestCase):
problem = new_loncapa_problem(xml)
rendered_html = etree.XML(problem.get_html())
response_elements = rendered_html.findall('div')
self.assertEqual(response_elements[0].attrib['aria-label'], 'Question 1')
self.assertEqual(response_elements[1].attrib['aria-label'], 'Question 2')
assert response_elements[0].attrib['aria-label'] == 'Question 1'
assert response_elements[1].attrib['aria-label'] == 'Question 2'
def test_render_response_with_overall_msg(self):
# CustomResponse script that sets an overall_message
@@ -261,16 +255,16 @@ class CapaHtmlRenderTest(unittest.TestCase):
# Expect that there is a <div> within the response <div>
# with css class response_message
msg_div_element = rendered_html.find(".//div[@class='response_message']")
self.assertEqual(msg_div_element.tag, "div")
self.assertEqual(msg_div_element.get('class'), "response_message")
assert msg_div_element.tag == 'div'
assert msg_div_element.get('class') == 'response_message'
# Expect that the <div> contains our message (as part of the XML tree)
msg_p_elements = msg_div_element.findall('p')
self.assertEqual(msg_p_elements[0].tag, "p")
self.assertEqual(msg_p_elements[0].text, "Test message 1")
assert msg_p_elements[0].tag == 'p'
assert msg_p_elements[0].text == 'Test message 1'
self.assertEqual(msg_p_elements[1].tag, "p")
self.assertEqual(msg_p_elements[1].text, "Test message 2")
assert msg_p_elements[1].tag == 'p'
assert msg_p_elements[1].text == 'Test message 2'
def test_substitute_python_vars(self):
# Generate some XML with Python variables defined in a script
@@ -288,7 +282,7 @@ class CapaHtmlRenderTest(unittest.TestCase):
# Expect that the variable $test has been replaced with its value
span_element = rendered_html.find('span')
self.assertEqual(span_element.get('attr'), "TEST")
assert span_element.get('attr') == 'TEST'
def test_xml_comments_and_other_odd_things(self):
# Comments and processing instructions should be skipped.

View File

@@ -91,7 +91,7 @@ class TemplateTestCase(unittest.TestCase):
message = ("XML does not have %d match(es) for xpath '%s'\nXML: %s\nContext: %s"
% (exact_num, str(xpath), etree.tostring(xml_root), str(context_dict)))
self.assertEqual(len(xml_root.xpath(xpath)), exact_num, msg=message)
assert len(xml_root.xpath(xpath)) == exact_num, message
def assert_no_xpath(self, xml_root, xpath, context_dict):
"""
@@ -117,12 +117,11 @@ class TemplateTestCase(unittest.TestCase):
If no elements are found, the assertion fails.
"""
element_list = xml_root.xpath(xpath)
self.assertGreater(len(element_list), 0, "Could not find element at '%s'\n%s" %
(str(xpath), etree.tostring(xml_root)))
assert len(element_list) > 0, ("Could not find element at '%s'\n%s" % (str(xpath), etree.tostring(xml_root)))
if exact:
self.assertEqual(text, element_list[0].text.strip())
assert text == element_list[0].text.strip()
else:
self.assertIn(text, element_list[0].text.strip())
assert text in element_list[0].text.strip()
def assert_description(self, describedby_xpaths):
"""
@@ -137,17 +136,17 @@ class TemplateTestCase(unittest.TestCase):
descriptions = OrderedDict(
(tag.get('id'), stringify_children(tag)) for tag in xml.xpath('//p[@class="question-description"]')
)
self.assertEqual(self.DESCRIPTIONS, descriptions)
assert self.DESCRIPTIONS == descriptions
# for each xpath verify that description_ids are set correctly
for describedby_xpath in describedby_xpaths:
describedbys = xml.xpath(describedby_xpath)
# aria-describedby attributes must have ids
self.assertTrue(describedbys)
assert describedbys
for describedby in describedbys:
self.assertEqual(describedby, self.DESCRIPTION_IDS)
assert describedby == self.DESCRIPTION_IDS
def assert_describedby_attribute(self, describedby_xpaths):
"""
@@ -162,7 +161,7 @@ class TemplateTestCase(unittest.TestCase):
# for each xpath verify that description_ids are set correctly
for describedby_xpath in describedby_xpaths:
describedbys = xml.xpath(describedby_xpath)
self.assertFalse(describedbys)
assert not describedbys
def assert_status(self, status_div=False, status_class=False):
"""
@@ -234,8 +233,8 @@ class TemplateTestCase(unittest.TestCase):
self.assert_has_xpath(xml, "//*[@aria-label='%s']" % label['expected'], self.context)
else:
element_list = xml.xpath(xpath)
self.assertEqual(len(element_list), 1)
self.assertEqual(stringify_children(element_list[0]), label['actual'])
assert len(element_list) == 1
assert stringify_children(element_list[0]) == label['actual']
class ChoiceGroupTemplateTest(TemplateTestCase):

View File

@@ -24,6 +24,7 @@ import unittest
import xml.sax.saxutils as saxutils
from collections import OrderedDict
import pytest
import six
from lxml import etree
from lxml.html import fromstring
@@ -88,7 +89,7 @@ class OptionInputTest(unittest.TestCase):
'describedby_html': DESCRIBEDBY.format(status_id='sky_input')
}
self.assertEqual(context, expected)
assert context == expected
def test_option_parsing(self):
f = inputtypes.OptionInput.parse_options
@@ -98,7 +99,7 @@ class OptionInputTest(unittest.TestCase):
Take list of options, confirm that output is in the silly doubled format
"""
expected = [(o, o) for o in options]
self.assertEqual(f(input), expected)
assert f(input) == expected
check("('a','b')", ['a', 'b'])
check("('a', 'b')", ['a', 'b'])
@@ -159,7 +160,7 @@ class ChoiceGroupTest(unittest.TestCase):
'describedby_html': DESCRIBEDBY.format(status_id='sky_input')
}
self.assertEqual(context, expected)
assert context == expected
def test_choicegroup(self):
self.check_group('choicegroup', 'radio', '')
@@ -251,7 +252,7 @@ class JSInputTest(unittest.TestCase):
}
full_expected_context.update(expected_context)
self.assertEqual(full_expected_context, context)
assert full_expected_context == context
class TextLineTest(unittest.TestCase):
@@ -288,7 +289,7 @@ class TextLineTest(unittest.TestCase):
'response_data': RESPONSE_DATA,
'describedby_html': DESCRIBEDBY.format(status_id=prob_id)
}
self.assertEqual(context, expected)
assert context == expected
def test_math_rendering(self):
size = "42"
@@ -327,7 +328,7 @@ class TextLineTest(unittest.TestCase):
'response_data': RESPONSE_DATA,
'describedby_html': DESCRIBEDBY.format(status_id=prob_id)
}
self.assertEqual(context, expected)
assert context == expected
def test_trailing_text_rendering(self):
size = "42"
@@ -372,7 +373,7 @@ class TextLineTest(unittest.TestCase):
'response_data': RESPONSE_DATA,
'describedby_html': TRAILING_TEXT_DESCRIBEDBY.format(trailing_text_id=prob_id, status_id=prob_id)
}
self.assertEqual(context, expected)
assert context == expected
class FileSubmissionTest(unittest.TestCase):
@@ -416,7 +417,7 @@ class FileSubmissionTest(unittest.TestCase):
'describedby_html': DESCRIBEDBY.format(status_id=prob_id)
}
self.assertEqual(context, expected)
assert context == expected
class CodeInputTest(unittest.TestCase):
@@ -472,7 +473,7 @@ class CodeInputTest(unittest.TestCase):
'describedby_html': DESCRIBEDBY.format(status_id=prob_id)
}
self.assertEqual(context, expected)
assert context == expected
class MatlabTest(unittest.TestCase):
@@ -534,7 +535,7 @@ class MatlabTest(unittest.TestCase):
'describedby_html': HTML('aria-describedby="status_prob_1_2"')
}
self.assertEqual(context, expected)
assert context == expected
def test_rendering_with_state(self):
state = {
@@ -569,7 +570,7 @@ class MatlabTest(unittest.TestCase):
'describedby_html': DESCRIBEDBY.format(status_id=prob_id)
}
self.assertEqual(context, expected)
assert context == expected
def test_rendering_when_completed(self):
for status in ['correct', 'incorrect']:
@@ -603,7 +604,7 @@ class MatlabTest(unittest.TestCase):
'describedby_html': DESCRIBEDBY.format(status_id=prob_id)
}
self.assertEqual(context, expected)
assert context == expected
@patch('capa.inputtypes.time.time', return_value=10)
def test_rendering_while_queued(self, time): # lint-amnesty, pylint: disable=unused-argument
@@ -637,7 +638,7 @@ class MatlabTest(unittest.TestCase):
'describedby_html': DESCRIBEDBY.format(status_id=prob_id)
}
self.assertEqual(context, expected)
assert context == expected
def test_plot_data(self):
data = {'submission': 'x = 1234;'}
@@ -645,19 +646,19 @@ class MatlabTest(unittest.TestCase):
test_capa_system().xqueue['interface'].send_to_queue.assert_called_with(header=ANY, body=ANY)
self.assertTrue(response['success'])
self.assertIsNotNone(self.the_input.input_state['queuekey'])
self.assertEqual(self.the_input.input_state['queuestate'], 'queued')
assert response['success']
assert self.the_input.input_state['queuekey'] is not None
assert self.the_input.input_state['queuestate'] == 'queued'
def test_plot_data_failure(self):
data = {'submission': 'x = 1234;'}
error_message = 'Error message!'
test_capa_system().xqueue['interface'].send_to_queue.return_value = (1, error_message)
response = self.the_input.handle_ajax("plot", data)
self.assertFalse(response['success'])
self.assertEqual(response['message'], error_message)
self.assertNotIn('queuekey', self.the_input.input_state)
self.assertNotIn('queuestate', self.the_input.input_state)
assert not response['success']
assert response['message'] == error_message
assert 'queuekey' not in self.the_input.input_state
assert 'queuestate' not in self.the_input.input_state
@patch('capa.inputtypes.time.time', return_value=10)
def test_ungraded_response_success(self, time): # lint-amnesty, pylint: disable=unused-argument
@@ -674,9 +675,9 @@ class MatlabTest(unittest.TestCase):
queue_msg = json.dumps({'msg': inner_msg})
the_input.ungraded_response(queue_msg, queuekey)
self.assertIsNone(input_state['queuekey'])
self.assertIsNone(input_state['queuestate'])
self.assertEqual(input_state['queue_msg'], inner_msg)
assert input_state['queuekey'] is None
assert input_state['queuestate'] is None
assert input_state['queue_msg'] == inner_msg
@patch('capa.inputtypes.time.time', return_value=10)
def test_ungraded_response_key_mismatch(self, time): # lint-amnesty, pylint: disable=unused-argument
@@ -693,9 +694,9 @@ class MatlabTest(unittest.TestCase):
queue_msg = json.dumps({'msg': inner_msg})
the_input.ungraded_response(queue_msg, 'abc')
self.assertEqual(input_state['queuekey'], queuekey)
self.assertEqual(input_state['queuestate'], 'queued')
self.assertNotIn('queue_msg', input_state)
assert input_state['queuekey'] == queuekey
assert input_state['queuestate'] == 'queued'
assert 'queue_msg' not in input_state
@patch('capa.inputtypes.time.time', return_value=20)
def test_matlab_response_timeout_not_exceeded(self, time): # lint-amnesty, pylint: disable=unused-argument
@@ -704,7 +705,7 @@ class MatlabTest(unittest.TestCase):
elt = etree.fromstring(self.xml)
the_input = self.input_class(test_capa_system(), elt, state)
self.assertEqual(the_input.status, 'queued')
assert the_input.status == 'queued'
@patch('capa.inputtypes.time.time', return_value=45)
def test_matlab_response_timeout_exceeded(self, time): # lint-amnesty, pylint: disable=unused-argument
@@ -713,8 +714,8 @@ class MatlabTest(unittest.TestCase):
elt = etree.fromstring(self.xml)
the_input = self.input_class(test_capa_system(), elt, state)
self.assertEqual(the_input.status, 'unsubmitted')
self.assertEqual(the_input.msg, 'No response from Xqueue within {} seconds. Aborted.'.format(XQUEUE_TIMEOUT))
assert the_input.status == 'unsubmitted'
assert the_input.msg == 'No response from Xqueue within {} seconds. Aborted.'.format(XQUEUE_TIMEOUT)
@patch('capa.inputtypes.time.time', return_value=20)
def test_matlab_response_migration_of_queuetime(self, time): # lint-amnesty, pylint: disable=unused-argument
@@ -725,7 +726,7 @@ class MatlabTest(unittest.TestCase):
elt = etree.fromstring(self.xml)
the_input = self.input_class(test_capa_system(), elt, state)
self.assertEqual(the_input.status, 'unsubmitted')
assert the_input.status == 'unsubmitted'
def test_matlab_api_key(self):
"""
@@ -741,8 +742,8 @@ class MatlabTest(unittest.TestCase):
body = system.xqueue['interface'].send_to_queue.call_args[1]['body']
payload = json.loads(body)
self.assertEqual('test_api_key', payload['token'])
self.assertEqual('2', payload['endpoint_version'])
assert 'test_api_key' == payload['token']
assert '2' == payload['endpoint_version']
def test_get_html(self):
# usual output
@@ -791,17 +792,17 @@ class MatlabTest(unittest.TestCase):
audio_index = element_tags.index('audio')
six.assertCountEqual(self, element_keys[audio_index], ['autobuffer', 'controls', 'autoplay', 'src'])
self.assertEqual(elements[audio_index].get('src'), 'data:audio/wav;base64=')
self.assertEqual(elements[audio_index].text, 'Audio is not supported on this browser.')
assert elements[audio_index].get('src') == 'data:audio/wav;base64='
assert elements[audio_index].text == 'Audio is not supported on this browser.'
href_index = element_keys.index(['href'])
self.assertEqual(elements[href_index].get('href'), 'https://endpoint.mss-mathworks.com/media/filename.wav')
assert elements[href_index].get('href') == 'https://endpoint.mss-mathworks.com/media/filename.wav'
id_index = element_keys.index(['id'])
self.assertEqual(elements[id_index].get('id'), 'mwAudioPlaceHolder')
assert elements[id_index].get('id') == 'mwAudioPlaceHolder'
output_string = etree.tostring(output).decode('utf-8')
# check that exception is raised during parsing for html.
self.the_input.capa_system.render_template = lambda *args: "<aaa"
with self.assertRaises(etree.XMLSyntaxError):
with pytest.raises(etree.XMLSyntaxError):
self.the_input.get_html()
self.the_input.capa_system.render_template = old_render_template
@@ -886,7 +887,7 @@ class MatlabTest(unittest.TestCase):
'response_data': {},
'describedby_html': 'aria-describedby="status_{id}"'.format(id=prob_id)
}
self.assertEqual(context, expected)
assert context == expected
self.the_input.capa_system.render_template = DemoSystem().render_template
self.the_input.get_html() # Should not raise an exception
@@ -903,7 +904,7 @@ class MatlabTest(unittest.TestCase):
}
elt = etree.fromstring(self.xml)
the_input = self.input_class(test_capa_system(), elt, state)
self.assertEqual(the_input.queue_msg, queue_msg)
assert the_input.queue_msg == queue_msg
def test_matlab_queue_message_not_allowed_tag(self):
"""
@@ -918,7 +919,7 @@ class MatlabTest(unittest.TestCase):
elt = etree.fromstring(self.xml)
the_input = self.input_class(test_capa_system(), elt, state)
expected = "&lt;script&gt;Test message&lt;/script&gt;"
self.assertEqual(the_input.queue_msg, expected)
assert the_input.queue_msg == expected
def test_matlab_sanitize_msg(self):
"""
@@ -927,7 +928,7 @@ class MatlabTest(unittest.TestCase):
not_allowed_tag = 'script'
self.the_input.msg = "<{0}>Test message</{0}>".format(not_allowed_tag)
expected = "&lt;script&gt;Test message&lt;/script&gt;"
self.assertEqual(self.the_input._get_render_context()['msg'], expected) # pylint: disable=protected-access
assert self.the_input._get_render_context()['msg'] == expected # pylint: disable=protected-access
def html_tree_equal(received, expected):
@@ -996,7 +997,7 @@ class SchematicTest(unittest.TestCase):
'describedby_html': DESCRIBEDBY.format(status_id=prob_id)
}
self.assertEqual(context, expected)
assert context == expected
class ImageInputTest(unittest.TestCase):
@@ -1041,7 +1042,7 @@ class ImageInputTest(unittest.TestCase):
'describedby_html': DESCRIBEDBY.format(status_id=prob_id)
}
self.assertEqual(context, expected)
assert context == expected
def test_with_value(self):
# Check that compensating for the dot size works properly.
@@ -1096,7 +1097,7 @@ class CrystallographyTest(unittest.TestCase):
'describedby_html': DESCRIBEDBY.format(status_id=prob_id)
}
self.assertEqual(context, expected)
assert context == expected
class VseprTest(unittest.TestCase):
@@ -1143,7 +1144,7 @@ class VseprTest(unittest.TestCase):
'describedby_html': DESCRIBEDBY.format(status_id=prob_id)
}
self.assertEqual(context, expected)
assert context == expected
class ChemicalEquationTest(unittest.TestCase):
@@ -1180,7 +1181,7 @@ class ChemicalEquationTest(unittest.TestCase):
'response_data': RESPONSE_DATA,
'describedby_html': DESCRIBEDBY.format(status_id=prob_id)
}
self.assertEqual(context, expected)
assert context == expected
def test_chemcalc_ajax_sucess(self):
"""
@@ -1189,24 +1190,24 @@ class ChemicalEquationTest(unittest.TestCase):
data = {'formula': "H"}
response = self.the_input.handle_ajax("preview_chemcalc", data)
self.assertIn('preview', response)
self.assertNotEqual(response['preview'], '')
self.assertEqual(response['error'], "")
assert 'preview' in response
assert response['preview'] != ''
assert response['error'] == ''
def test_ajax_bad_method(self):
"""
With a bad dispatch, we shouldn't receive anything
"""
response = self.the_input.handle_ajax("obviously_not_real", {})
self.assertEqual(response, {})
assert response == {}
def test_ajax_no_formula(self):
"""
When we ask for a formula rendering, there should be an error if no formula
"""
response = self.the_input.handle_ajax("preview_chemcalc", {})
self.assertIn('error', response)
self.assertEqual(response['error'], "No formula specified.")
assert 'error' in response
assert response['error'] == 'No formula specified.'
def test_ajax_parse_err(self):
"""
@@ -1220,8 +1221,8 @@ class ChemicalEquationTest(unittest.TestCase):
{'formula': 'H2O + invalid chemistry'}
)
self.assertIn('error', response)
self.assertIn("Couldn't parse formula", response['error'])
assert 'error' in response
assert "Couldn't parse formula" in response['error']
@patch('capa.inputtypes.log')
def test_ajax_other_err(self, mock_log):
@@ -1237,8 +1238,8 @@ class ChemicalEquationTest(unittest.TestCase):
mock_log.warning.assert_called_once_with(
"Error while previewing chemical formula", exc_info=True
)
self.assertIn('error', response)
self.assertEqual(response['error'], "Error while rendering preview")
assert 'error' in response
assert response['error'] == 'Error while rendering preview'
class FormulaEquationTest(unittest.TestCase):
@@ -1277,7 +1278,7 @@ class FormulaEquationTest(unittest.TestCase):
'response_data': RESPONSE_DATA,
'describedby_html': DESCRIBEDBY.format(status_id=prob_id)
}
self.assertEqual(context, expected)
assert context == expected
def test_trailing_text_rendering(self):
"""
@@ -1324,7 +1325,7 @@ class FormulaEquationTest(unittest.TestCase):
'describedby_html': TRAILING_TEXT_DESCRIBEDBY.format(trailing_text_id=prob_id, status_id=prob_id)
}
self.assertEqual(context, expected)
assert context == expected
def test_formcalc_ajax_sucess(self):
"""
@@ -1333,17 +1334,17 @@ class FormulaEquationTest(unittest.TestCase):
data = {'formula': "x^2+1/2", 'request_start': 0}
response = self.the_input.handle_ajax("preview_formcalc", data)
self.assertIn('preview', response)
self.assertNotEqual(response['preview'], '')
self.assertEqual(response['error'], "")
self.assertEqual(response['request_start'], data['request_start'])
assert 'preview' in response
assert response['preview'] != ''
assert response['error'] == ''
assert response['request_start'] == data['request_start']
def test_ajax_bad_method(self):
"""
With a bad dispatch, we shouldn't receive anything
"""
response = self.the_input.handle_ajax("obviously_not_real", {})
self.assertEqual(response, {})
assert response == {}
def test_ajax_no_formula(self):
"""
@@ -1353,8 +1354,8 @@ class FormulaEquationTest(unittest.TestCase):
"preview_formcalc",
{'request_start': 1, }
)
self.assertIn('error', response)
self.assertEqual(response['error'], "No formula specified.")
assert 'error' in response
assert response['error'] == 'No formula specified.'
def test_ajax_parse_err(self):
"""
@@ -1368,8 +1369,8 @@ class FormulaEquationTest(unittest.TestCase):
{'formula': 'x^2+1/2', 'request_start': 1, }
)
self.assertIn('error', response)
self.assertEqual(response['error'], "Sorry, couldn't parse formula")
assert 'error' in response
assert response['error'] == "Sorry, couldn't parse formula"
@patch('capa.inputtypes.log')
def test_ajax_other_err(self, mock_log):
@@ -1385,8 +1386,8 @@ class FormulaEquationTest(unittest.TestCase):
mock_log.warning.assert_called_once_with(
"Error while previewing formula", exc_info=True
)
self.assertIn('error', response)
self.assertEqual(response['error'], "Error while rendering preview")
assert 'error' in response
assert response['error'] == 'Error while rendering preview'
class DragAndDropTest(unittest.TestCase):
@@ -1457,10 +1458,10 @@ class DragAndDropTest(unittest.TestCase):
# as we are dumping 'draggables' dicts while dumping user_input, string
# comparison will fail, as order of keys is random.
self.assertEqual(json.loads(context['drag_and_drop_json']), user_input)
assert json.loads(context['drag_and_drop_json']) == user_input
context.pop('drag_and_drop_json')
expected.pop('drag_and_drop_json')
self.assertEqual(context, expected)
assert context == expected
class AnnotationInputTest(unittest.TestCase):
@@ -1591,7 +1592,7 @@ class TestChoiceText(unittest.TestCase):
expected.update(state)
the_input = lookup_tag(tag)(test_capa_system(), element, state)
context = the_input._get_render_context() # pylint: disable=protected-access
self.assertEqual(context, expected)
assert context == expected
def test_radiotextgroup(self):
"""
@@ -1611,7 +1612,7 @@ class TestChoiceText(unittest.TestCase):
"""
Test to ensure that an unrecognized inputtype tag causes an error
"""
with self.assertRaises(Exception):
with pytest.raises(Exception):
self.check_group('invalid', 'choice', 'checkbox')
def test_invalid_input_tag(self):
@@ -1632,8 +1633,8 @@ class TestStatus(unittest.TestCase):
Test stringifing Status objects
"""
statobj = inputtypes.Status('test')
self.assertEqual(str(statobj), 'test')
self.assertEqual(six.text_type(statobj), u'test')
assert str(statobj) == 'test'
assert six.text_type(statobj) == u'test'
def test_classes(self):
"""
@@ -1648,7 +1649,7 @@ class TestStatus(unittest.TestCase):
]
for status, classname in css_classes:
statobj = inputtypes.Status(status)
self.assertEqual(statobj.classname, classname)
assert statobj.classname == classname
def test_display_names(self):
"""
@@ -1665,7 +1666,7 @@ class TestStatus(unittest.TestCase):
]
for status, display_name in names:
statobj = inputtypes.Status(status)
self.assertEqual(statobj.display_name, display_name)
assert statobj.display_name == display_name
def test_translated_names(self):
"""
@@ -1674,10 +1675,10 @@ class TestStatus(unittest.TestCase):
func = lambda t: t.upper()
# status is in the mapping
statobj = inputtypes.Status('queued', func)
self.assertEqual(statobj.display_name, u'PROCESSING')
assert statobj.display_name == u'PROCESSING'
# status is not in the mapping
statobj = inputtypes.Status('test', func)
self.assertEqual(statobj.display_name, u'test')
self.assertEqual(str(statobj), 'test')
self.assertEqual(statobj.classname, 'test')
assert statobj.display_name == u'test'
assert str(statobj) == 'test'
assert statobj.classname == 'test'

View File

@@ -12,6 +12,7 @@ import unittest
import zipfile
from datetime import datetime
import pytest
import calc
import mock
import pyparsing
@@ -66,23 +67,23 @@ class ResponseTest(unittest.TestCase):
input_dict = {'1_2_1': submission}
correct_map = problem.grade_answers(input_dict)
if msg is None:
self.assertEqual(correct_map.get_correctness('1_2_1'), expected_correctness)
assert correct_map.get_correctness('1_2_1') == expected_correctness
else:
self.assertEqual(correct_map.get_correctness('1_2_1'), expected_correctness, msg)
assert correct_map.get_correctness('1_2_1') == expected_correctness, msg
def assert_answer_format(self, problem):
answers = problem.get_question_answers()
self.assertIsNotNone(answers['1_2_1'])
assert answers['1_2_1'] is not None
# pylint: disable=missing-function-docstring
def assert_multiple_grade(self, problem, correct_answers, incorrect_answers):
for input_str in correct_answers:
result = problem.grade_answers({'1_2_1': input_str}).get_correctness('1_2_1')
self.assertEqual(result, 'correct')
assert result == 'correct'
for input_str in incorrect_answers:
result = problem.grade_answers({'1_2_1': input_str}).get_correctness('1_2_1')
self.assertEqual(result, 'incorrect')
assert result == 'incorrect'
def assert_multiple_partial(self, problem, correct_answers, incorrect_answers, partial_answers):
"""
@@ -91,15 +92,15 @@ class ResponseTest(unittest.TestCase):
"""
for input_str in correct_answers:
result = problem.grade_answers({'1_2_1': input_str}).get_correctness('1_2_1')
self.assertEqual(result, 'correct')
assert result == 'correct'
for input_str in incorrect_answers:
result = problem.grade_answers({'1_2_1': input_str}).get_correctness('1_2_1')
self.assertEqual(result, 'incorrect')
assert result == 'incorrect'
for input_str in partial_answers:
result = problem.grade_answers({'1_2_1': input_str}).get_correctness('1_2_1')
self.assertEqual(result, 'partially-correct')
assert result == 'partially-correct'
def _get_random_number_code(self):
"""Returns code to be used to generate a random result."""
@@ -143,13 +144,13 @@ class MultiChoiceResponseTest(ResponseTest): # pylint: disable=missing-class-do
# Multiple Choice problems only allow one partial credit scheme.
# Change this test if that changes.
problem = self.build_problem(choices=[False, True, 'partial'], credit_type='points,points')
with self.assertRaises(LoncapaProblemError):
with pytest.raises(LoncapaProblemError):
input_dict = {'1_2_1': 'choice_1'}
problem.grade_answers(input_dict)
# 'bongo' is not a valid grading scheme.
problem = self.build_problem(choices=[False, True, 'partial'], credit_type='bongo')
with self.assertRaises(LoncapaProblemError):
with pytest.raises(LoncapaProblemError):
input_dict = {'1_2_1': 'choice_1'}
problem.grade_answers(input_dict)
@@ -163,13 +164,13 @@ class MultiChoiceResponseTest(ResponseTest): # pylint: disable=missing-class-do
# Ensure that we get the expected number of points
# Using assertAlmostEqual to avoid floating point issues
correct_map = problem.grade_answers({'1_2_1': 'choice_0'})
self.assertAlmostEqual(correct_map.get_npoints('1_2_1'), 1)
assert round(correct_map.get_npoints('1_2_1') - 1, 7) >= 0
correct_map = problem.grade_answers({'1_2_1': 'choice_1'})
self.assertAlmostEqual(correct_map.get_npoints('1_2_1'), 0.6)
assert round(correct_map.get_npoints('1_2_1') - 0.6, 7) >= 0
correct_map = problem.grade_answers({'1_2_1': 'choice_2'})
self.assertAlmostEqual(correct_map.get_npoints('1_2_1'), 0)
assert round(correct_map.get_npoints('1_2_1') - 0, 7) >= 0
def test_contextualized_choices(self):
script = textwrap.dedent("""
@@ -350,7 +351,7 @@ class SymbolicResponseTest(ResponseTest): # pylint: disable=missing-class-docst
# Should not allow multiple inputs, since we specify
# only one "expect" value
with self.assertRaises(Exception):
with pytest.raises(Exception):
self.build_problem(math_display=True, expect="2*x+3*y", num_inputs=3)
def _assert_symbolic_grade(
@@ -375,9 +376,7 @@ class SymbolicResponseTest(ResponseTest): # pylint: disable=missing-class-docst
correct_map = problem.grade_answers(input_dict)
self.assertEqual(
correct_map.get_correctness('1_2_1'), expected_correctness
)
assert correct_map.get_correctness('1_2_1') == expected_correctness
class OptionResponseTest(ResponseTest): # pylint: disable=missing-class-docstring
@@ -423,8 +422,8 @@ class OptionResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
input_dict = {'1_2_1': '1000'}
correct_map = problem.grade_answers(input_dict)
self.assertEqual(correct_map.get_correctness('1_2_1'), 'correct')
self.assertEqual(correct_map.get_property('1_2_1', 'answervariable'), '$a')
assert correct_map.get_correctness('1_2_1') == 'correct'
assert correct_map.get_property('1_2_1', 'answervariable') == '$a'
class FormulaResponseTest(ResponseTest):
@@ -480,14 +479,12 @@ class FormulaResponseTest(ResponseTest):
# Expect to receive a hint if we add an extra y
input_dict = {'1_2_1': "x + 2*y + y"}
correct_map = problem.grade_answers(input_dict)
self.assertEqual(correct_map.get_hint('1_2_1'),
'Check the coefficient of y')
assert correct_map.get_hint('1_2_1') == 'Check the coefficient of y'
# Expect to receive a hint if we leave out x
input_dict = {'1_2_1': "2*y"}
correct_map = problem.grade_answers(input_dict)
self.assertEqual(correct_map.get_hint('1_2_1'),
'Try including the variable x')
assert correct_map.get_hint('1_2_1') == 'Try including the variable x'
def test_script(self):
"""
@@ -574,8 +571,8 @@ class FormulaResponseTest(ResponseTest):
tolerance="1%",
answer="x"
)
self.assertTrue(list(problem.responders.values())[0].validate_answer('14*x'))
self.assertFalse(list(problem.responders.values())[0].validate_answer('3*y+2*x'))
assert list(problem.responders.values())[0].validate_answer('14*x')
assert not list(problem.responders.values())[0].validate_answer('3*y+2*x')
class StringResponseTest(ResponseTest): # pylint: disable=missing-class-docstring
@@ -799,10 +796,10 @@ class StringResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
def test_exception(self):
problem = self.build_problem(answer="a2", case_sensitive=False, regexp=True, additional_answers=['?\\d?'])
with self.assertRaises(Exception) as cm:
with pytest.raises(Exception) as cm:
self.assert_grade(problem, "a3", "correct")
exception_message = text_type(cm.exception)
self.assertIn("nothing to repeat", exception_message)
assert 'nothing to repeat' in exception_message
def test_hints(self):
@@ -818,24 +815,22 @@ class StringResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
# We should get a hint for Wisconsin
input_dict = {'1_2_1': 'Wisconsin'}
correct_map = problem.grade_answers(input_dict)
self.assertEqual(correct_map.get_hint('1_2_1'),
"The state capital of Wisconsin is Madison")
assert correct_map.get_hint('1_2_1') == 'The state capital of Wisconsin is Madison'
# We should get a hint for Minnesota
input_dict = {'1_2_1': 'Minnesota'}
correct_map = problem.grade_answers(input_dict)
self.assertEqual(correct_map.get_hint('1_2_1'),
"The state capital of Minnesota is St. Paul")
assert correct_map.get_hint('1_2_1') == 'The state capital of Minnesota is St. Paul'
# We should NOT get a hint for Michigan (the correct answer)
input_dict = {'1_2_1': 'Michigan'}
correct_map = problem.grade_answers(input_dict)
self.assertEqual(correct_map.get_hint('1_2_1'), "")
assert correct_map.get_hint('1_2_1') == ''
# We should NOT get a hint for any other string
input_dict = {'1_2_1': 'California'}
correct_map = problem.grade_answers(input_dict)
self.assertEqual(correct_map.get_hint('1_2_1'), "")
assert correct_map.get_hint('1_2_1') == ''
def test_hints_regexp_and_answer_regexp(self):
different_student_answers = [
@@ -867,38 +862,36 @@ class StringResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
# We should get a hint for Wisconsin
input_dict = {'1_2_1': 'Wisconsin'}
correct_map = problem.grade_answers(input_dict)
self.assertEqual(correct_map.get_hint('1_2_1'),
"The state capital of Wisconsin is Madison")
assert correct_map.get_hint('1_2_1') == 'The state capital of Wisconsin is Madison'
# We should get a hint for Minnesota
input_dict = {'1_2_1': 'Minnesota'}
correct_map = problem.grade_answers(input_dict)
self.assertEqual(correct_map.get_hint('1_2_1'),
"The state capital of Minnesota is St. Paul")
assert correct_map.get_hint('1_2_1') == 'The state capital of Minnesota is St. Paul'
# We should NOT get a hint for Michigan (the correct answer)
input_dict = {'1_2_1': 'Michigan'}
correct_map = problem.grade_answers(input_dict)
self.assertEqual(correct_map.get_hint('1_2_1'), "")
assert correct_map.get_hint('1_2_1') == ''
# We should NOT get a hint for any other string
input_dict = {'1_2_1': 'California'}
correct_map = problem.grade_answers(input_dict)
self.assertEqual(correct_map.get_hint('1_2_1'), "")
assert correct_map.get_hint('1_2_1') == ''
# We should get the same hint for each answer
for answer in different_student_answers:
input_dict = {'1_2_1': answer}
correct_map = problem.grade_answers(input_dict)
self.assertEqual(correct_map.get_hint('1_2_1'), "First letter of correct answer is M.")
assert correct_map.get_hint('1_2_1') == 'First letter of correct answer is M.'
input_dict = {'1_2_1': '59'}
correct_map = problem.grade_answers(input_dict)
self.assertEqual(correct_map.get_hint('1_2_1'), "Should not end with 9.")
assert correct_map.get_hint('1_2_1') == 'Should not end with 9.'
input_dict = {'1_2_1': '57'}
correct_map = problem.grade_answers(input_dict)
self.assertEqual(correct_map.get_hint('1_2_1'), "")
assert correct_map.get_hint('1_2_1') == ''
def test_computed_hints(self):
problem = self.build_problem(
@@ -914,7 +907,7 @@ class StringResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
input_dict = {'1_2_1': 'Hello'}
correct_map = problem.grade_answers(input_dict)
self.assertEqual(correct_map.get_hint('1_2_1'), "Hello??")
assert correct_map.get_hint('1_2_1') == 'Hello??'
def test_hint_function_randomization(self):
# The hint function should get the seed from the problem.
@@ -930,7 +923,7 @@ class StringResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
)
correct_map = problem.grade_answers({'1_2_1': '2'})
hint = correct_map.get_hint('1_2_1')
self.assertEqual(hint, self._get_random_number_result(problem.seed))
assert hint == self._get_random_number_result(problem.seed)
def test_empty_answer_graded_as_incorrect(self):
"""
@@ -971,7 +964,7 @@ class CodeResponseTest(ResponseTest): # pylint: disable=missing-class-docstring
cmap.update(CorrectMap(answer_id=answer_id, queuestate=None))
self.problem.correct_map.update(cmap)
self.assertEqual(self.problem.is_queued(), False)
assert self.problem.is_queued() is False
# Now we queue the LCP
cmap = CorrectMap()
@@ -980,7 +973,7 @@ class CodeResponseTest(ResponseTest): # pylint: disable=missing-class-docstring
cmap.update(CorrectMap(answer_id=answer_ids[i], queuestate=queuestate))
self.problem.correct_map.update(cmap)
self.assertEqual(self.problem.is_queued(), True)
assert self.problem.is_queued() is True
def test_update_score(self):
'''
@@ -1009,10 +1002,12 @@ class CodeResponseTest(ResponseTest): # pylint: disable=missing-class-docstring
self.problem.correct_map.update(old_cmap) # Deep copy
self.problem.update_score(xserver_msgs[correctness], queuekey=0)
self.assertEqual(self.problem.correct_map.get_dict(), old_cmap.get_dict()) # Deep comparison
assert self.problem.correct_map.get_dict() == old_cmap.get_dict()
# Deep comparison
for answer_id in answer_ids:
self.assertTrue(self.problem.correct_map.is_queued(answer_id)) # Should be still queued, since message undelivered # lint-amnesty, pylint: disable=line-too-long
assert self.problem.correct_map.is_queued(answer_id)
# Should be still queued, since message undelivered # lint-amnesty, pylint: disable=line-too-long
# Correct queuekey, state should be updated
for correctness in ['correct', 'incorrect']:
@@ -1026,13 +1021,15 @@ class CodeResponseTest(ResponseTest): # pylint: disable=missing-class-docstring
new_cmap.set(answer_id=answer_id, npoints=npoints, correctness=correctness, msg=grader_msg, queuestate=None) # lint-amnesty, pylint: disable=line-too-long
self.problem.update_score(xserver_msgs[correctness], queuekey=1000 + i)
self.assertEqual(self.problem.correct_map.get_dict(), new_cmap.get_dict())
assert self.problem.correct_map.get_dict() == new_cmap.get_dict()
for j, test_id in enumerate(answer_ids):
if j == i:
self.assertFalse(self.problem.correct_map.is_queued(test_id)) # Should be dequeued, message delivered # lint-amnesty, pylint: disable=line-too-long
assert not self.problem.correct_map.is_queued(test_id)
# Should be dequeued, message delivered # lint-amnesty, pylint: disable=line-too-long
else:
self.assertTrue(self.problem.correct_map.is_queued(test_id)) # Should be queued, message undelivered # lint-amnesty, pylint: disable=line-too-long
assert self.problem.correct_map.is_queued(test_id)
# Should be queued, message undelivered # lint-amnesty, pylint: disable=line-too-long
def test_recentmost_queuetime(self):
'''
@@ -1046,7 +1043,7 @@ class CodeResponseTest(ResponseTest): # pylint: disable=missing-class-docstring
cmap.update(CorrectMap(answer_id=answer_id, queuestate=None))
self.problem.correct_map.update(cmap)
self.assertEqual(self.problem.get_recentmost_queuetime(), None)
assert self.problem.get_recentmost_queuetime() is None
# CodeResponse requires internal CorrectMap state. Build it now in the queued state
cmap = CorrectMap()
@@ -1062,7 +1059,7 @@ class CodeResponseTest(ResponseTest): # pylint: disable=missing-class-docstring
datetime.strftime(latest_timestamp, dateformat), dateformat
).replace(tzinfo=UTC)
self.assertEqual(self.problem.get_recentmost_queuetime(), latest_timestamp)
assert self.problem.get_recentmost_queuetime() == latest_timestamp
def test_convert_files_to_filenames(self):
'''
@@ -1074,9 +1071,9 @@ class CodeResponseTest(ResponseTest): # pylint: disable=missing-class-docstring
'1_3_1': ['answer1', 'answer2', 'answer3'],
'1_4_1': [fp, fp]}
answers_converted = convert_files_to_filenames(answers_with_file)
self.assertEqual(answers_converted['1_2_1'], 'String-based answer')
self.assertEqual(answers_converted['1_3_1'], ['answer1', 'answer2', 'answer3'])
self.assertEqual(answers_converted['1_4_1'], [fp.name, fp.name])
assert answers_converted['1_2_1'] == 'String-based answer'
assert answers_converted['1_3_1'] == ['answer1', 'answer2', 'answer3']
assert answers_converted['1_4_1'] == [fp.name, fp.name]
def test_parse_score_msg_of_responder(self):
"""
@@ -1116,7 +1113,7 @@ class CodeResponseTest(ResponseTest): # pylint: disable=missing-class-docstring
self.problem.correct_map = CorrectMap()
self.problem.correct_map.update(old_cmap)
output = self.problem.update_score(xserver_msgs['correct'], queuekey=1000 + i)
self.assertEqual(output[answer_id]['msg'], grader_msg)
assert output[answer_id]['msg'] == grader_msg
for grader_msg in invalid_grader_msgs:
correct_score_msg = json.dumps({'correct': True, 'score': 1, 'msg': grader_msg})
@@ -1128,7 +1125,7 @@ class CodeResponseTest(ResponseTest): # pylint: disable=missing-class-docstring
self.problem.correct_map.update(old_cmap)
output = self.problem.update_score(xserver_msgs['correct'], queuekey=1000 + i)
self.assertEqual(output[answer_id]['msg'], u'Invalid grader reply. Please contact the course staff.')
assert output[answer_id]['msg'] == u'Invalid grader reply. Please contact the course staff.'
class ChoiceResponseTest(ResponseTest): # pylint: disable=missing-class-docstring
@@ -1169,7 +1166,7 @@ class ChoiceResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
choices=[False, False, True, True],
credit_type='edc,halves,bongo'
)
with self.assertRaises(LoncapaProblemError):
with pytest.raises(LoncapaProblemError):
input_dict = {'1_2_1': 'choice_1'}
problem.grade_answers(input_dict)
@@ -1179,7 +1176,7 @@ class ChoiceResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
choices=[False, False, True, True],
credit_type='bongo'
)
with self.assertRaises(LoncapaProblemError):
with pytest.raises(LoncapaProblemError):
input_dict = {'1_2_1': 'choice_1'}
problem.grade_answers(input_dict)
@@ -1245,7 +1242,7 @@ class ChoiceResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
)
correct_map = problem.grade_answers({'1_2_1': 'choice_2'})
self.assertAlmostEqual(correct_map.get_npoints('1_2_1'), 0.75)
assert round(correct_map.get_npoints('1_2_1') - 0.75, 7) >= 0
# Second: Halves grading style
problem = self.build_problem(
@@ -1255,7 +1252,7 @@ class ChoiceResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
)
correct_map = problem.grade_answers({'1_2_1': 'choice_2'})
self.assertAlmostEqual(correct_map.get_npoints('1_2_1'), 0.5)
assert round(correct_map.get_npoints('1_2_1') - 0.5, 7) >= 0
# Third: Halves grading style with more options
problem = self.build_problem(
@@ -1265,7 +1262,7 @@ class ChoiceResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
)
correct_map = problem.grade_answers({'1_2_1': 'choice_2,choice4'})
self.assertAlmostEqual(correct_map.get_npoints('1_2_1'), 0.25)
assert round(correct_map.get_npoints('1_2_1') - 0.25, 7) >= 0
def test_grade_with_no_checkbox_selected(self):
"""
@@ -1276,7 +1273,7 @@ class ChoiceResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
)
correct_map = problem.grade_answers({})
self.assertEqual(correct_map.get_correctness('1_2_1'), 'incorrect')
assert correct_map.get_correctness('1_2_1') == 'incorrect'
def test_contextualized_choices(self):
script = textwrap.dedent("""
@@ -1337,14 +1334,14 @@ class NumericalResponseTest(ResponseTest): # pylint: disable=missing-class-docs
# Assert primary answer is graded correctly.
correct_map = problem.grade_answers({'1_2_1': primary_answer})
self.assertEqual(correct_map.get_correctness('1_2_1'), 'correct')
self.assertIn(primary_correcthint, correct_map.get_msg('1_2_1'))
assert correct_map.get_correctness('1_2_1') == 'correct'
assert primary_correcthint in correct_map.get_msg('1_2_1')
# Assert additional answers are graded correct
for answer, correcthint in additional_answers.items():
correct_map = problem.grade_answers({'1_2_1': answer})
self.assertEqual(correct_map.get_correctness('1_2_1'), 'correct')
self.assertIn(correcthint, correct_map.get_msg('1_2_1'))
assert correct_map.get_correctness('1_2_1') == 'correct'
assert correcthint in correct_map.get_msg('1_2_1')
def test_additional_answer_get_score(self):
"""
@@ -1355,15 +1352,15 @@ class NumericalResponseTest(ResponseTest): # pylint: disable=missing-class-docs
# Check primary answer.
new_cmap = responder.get_score({'1_2_1': '100'})
self.assertEqual(new_cmap.get_correctness('1_2_1'), 'correct')
assert new_cmap.get_correctness('1_2_1') == 'correct'
# Check additional answer.
new_cmap = responder.get_score({'1_2_1': '1'})
self.assertEqual(new_cmap.get_correctness('1_2_1'), 'correct')
assert new_cmap.get_correctness('1_2_1') == 'correct'
# Check any wrong answer.
new_cmap = responder.get_score({'1_2_1': '2'})
self.assertEqual(new_cmap.get_correctness('1_2_1'), 'incorrect')
assert new_cmap.get_correctness('1_2_1') == 'incorrect'
def test_grade_range_tolerance_partial_credit(self):
problem_setup = [
@@ -1404,13 +1401,13 @@ class NumericalResponseTest(ResponseTest): # pylint: disable=missing-class-docs
# no complex number in range tolerance staff answer
problem = self.build_problem(answer='[1j, 5]')
input_dict = {'1_2_1': '3'}
with self.assertRaises(StudentInputError):
with pytest.raises(StudentInputError):
problem.grade_answers(input_dict)
# no complex numbers in student ansers to range tolerance problems
problem = self.build_problem(answer='(1, 5)')
input_dict = {'1_2_1': '1*J'}
with self.assertRaises(StudentInputError):
with pytest.raises(StudentInputError):
problem.grade_answers(input_dict)
# test isnan student input: no exception,
@@ -1419,16 +1416,16 @@ class NumericalResponseTest(ResponseTest): # pylint: disable=missing-class-docs
input_dict = {'1_2_1': ''}
correct_map = problem.grade_answers(input_dict)
correctness = correct_map.get_correctness('1_2_1')
self.assertEqual(correctness, 'incorrect')
assert correctness == 'incorrect'
# test invalid range tolerance answer
with self.assertRaises(StudentInputError):
with pytest.raises(StudentInputError):
problem = self.build_problem(answer='(1 5)')
# test empty boundaries
problem = self.build_problem(answer='(1, ]')
input_dict = {'1_2_1': '3'}
with self.assertRaises(StudentInputError):
with pytest.raises(StudentInputError):
problem.grade_answers(input_dict)
def test_grade_exact(self):
@@ -1489,7 +1486,7 @@ class NumericalResponseTest(ResponseTest): # pylint: disable=missing-class-docs
# 'bongo' is not a valid grading scheme.
problem = self.build_problem(answer=4, tolerance=0.1, credit_type='bongo')
input_dict = {'1_2_1': '4'}
with self.assertRaises(LoncapaProblemError):
with pytest.raises(LoncapaProblemError):
problem.grade_answers(input_dict)
def test_grade_decimal_tolerance(self):
@@ -1556,7 +1553,7 @@ class NumericalResponseTest(ResponseTest): # pylint: disable=missing-class-docs
"""See if division by zero is handled correctly."""
problem = self.build_problem(answer="1") # Answer doesn't matter
input_dict = {'1_2_1': '1/0'}
with self.assertRaises(StudentInputError):
with pytest.raises(StudentInputError):
problem.grade_answers(input_dict)
def test_staff_inputs_expressions(self):
@@ -1662,15 +1659,15 @@ class NumericalResponseTest(ResponseTest): # pylint: disable=missing-class-docs
"""Tests the answer compare function."""
problem = self.build_problem(answer="42")
responder = list(problem.responders.values())[0]
self.assertTrue(responder.compare_answer('48', '8*6'))
self.assertFalse(responder.compare_answer('48', '9*5'))
assert responder.compare_answer('48', '8*6')
assert not responder.compare_answer('48', '9*5')
def test_validate_answer(self):
"""Tests the answer validation function."""
problem = self.build_problem(answer="42")
responder = list(problem.responders.values())[0]
self.assertTrue(responder.validate_answer('23.5'))
self.assertFalse(responder.validate_answer('fish'))
assert responder.validate_answer('23.5')
assert not responder.validate_answer('fish')
class CustomResponseTest(ResponseTest): # pylint: disable=missing-class-docstring
@@ -1704,11 +1701,11 @@ class CustomResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
# Check that the message for the particular input was received
input_msg = correctmap.get_msg('1_2_1')
self.assertEqual(input_msg, "Test Message")
assert input_msg == 'Test Message'
# Check that the overall message (for the whole response) was received
overall_msg = correctmap.get_overall_message()
self.assertEqual(overall_msg, "Overall message")
assert overall_msg == 'Overall message'
def test_inline_randomization(self):
# Make sure the seed from the problem gets fed into the script execution.
@@ -1719,7 +1716,7 @@ class CustomResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
correctmap = problem.grade_answers(input_dict)
input_msg = correctmap.get_msg('1_2_1')
self.assertEqual(input_msg, self._get_random_number_result(problem.seed))
assert input_msg == self._get_random_number_result(problem.seed)
def test_function_code_single_input(self):
# For function code, we pass in these arguments:
@@ -1754,9 +1751,9 @@ class CustomResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
msg = correct_map.get_msg('1_2_1')
npoints = correct_map.get_npoints('1_2_1')
self.assertEqual(correctness, 'correct')
self.assertEqual(msg, "Message text")
self.assertEqual(npoints, 1)
assert correctness == 'correct'
assert msg == 'Message text'
assert npoints == 1
# Partially Credit answer
input_dict = {'1_2_1': '21'}
@@ -1766,9 +1763,9 @@ class CustomResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
msg = correct_map.get_msg('1_2_1')
npoints = correct_map.get_npoints('1_2_1')
self.assertEqual(correctness, 'partially-correct')
self.assertEqual(msg, "Message text")
self.assertTrue(0 <= npoints <= 1)
assert correctness == 'partially-correct'
assert msg == 'Message text'
assert 0 <= npoints <= 1
# Incorrect answer
input_dict = {'1_2_1': '0'}
@@ -1778,9 +1775,9 @@ class CustomResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
msg = correct_map.get_msg('1_2_1')
npoints = correct_map.get_npoints('1_2_1')
self.assertEqual(correctness, 'incorrect')
self.assertEqual(msg, "Message text")
self.assertEqual(npoints, 0)
assert correctness == 'incorrect'
assert msg == 'Message text'
assert npoints == 0
def test_function_code_single_input_decimal_score(self):
# For function code, we pass in these arguments:
@@ -1817,20 +1814,20 @@ class CustomResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
# Correct answer
input_dict = {'1_2_1': '42'}
correct_map = problem.grade_answers(input_dict)
self.assertEqual(correct_map.get_npoints('1_2_1'), 0.9)
self.assertEqual(correct_map.get_correctness('1_2_1'), 'correct')
assert correct_map.get_npoints('1_2_1') == 0.9
assert correct_map.get_correctness('1_2_1') == 'correct'
# Incorrect answer
input_dict = {'1_2_1': '43'}
correct_map = problem.grade_answers(input_dict)
self.assertEqual(correct_map.get_npoints('1_2_1'), 0.1)
self.assertEqual(correct_map.get_correctness('1_2_1'), 'incorrect')
assert correct_map.get_npoints('1_2_1') == 0.1
assert correct_map.get_correctness('1_2_1') == 'incorrect'
# Partially Correct answer
input_dict = {'1_2_1': '21'}
correct_map = problem.grade_answers(input_dict)
self.assertEqual(correct_map.get_npoints('1_2_1'), 0.5)
self.assertEqual(correct_map.get_correctness('1_2_1'), 'partially-correct')
assert correct_map.get_npoints('1_2_1') == 0.5
assert correct_map.get_correctness('1_2_1') == 'partially-correct'
def test_script_context(self):
# Ensure that python script variables can be used in the "expect" and "answer" fields,
@@ -1853,11 +1850,11 @@ class CustomResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
correctmap = problem.grade_answers(input_dict)
# CustomResponse also adds 'expect' to the problem context; check that directly first:
self.assertEqual(problem.context['expect'], '42')
assert problem.context['expect'] == '42'
# Also make sure the problem was graded correctly:
correctness = correctmap.get_correctness('1_2_1')
self.assertEqual(correctness, 'correct')
assert correctness == 'correct'
def test_function_code_multiple_input_no_msg(self):
@@ -1885,32 +1882,32 @@ class CustomResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
correct_map = problem.grade_answers(input_dict)
correctness = correct_map.get_correctness('1_2_1')
self.assertEqual(correctness, 'correct')
assert correctness == 'correct'
correctness = correct_map.get_correctness('1_2_2')
self.assertEqual(correctness, 'correct')
assert correctness == 'correct'
# One answer incorrect -- expect both inputs marked partially correct
input_dict = {'1_2_1': '0', '1_2_2': '42'}
correct_map = problem.grade_answers(input_dict)
correctness = correct_map.get_correctness('1_2_1')
self.assertEqual(correctness, 'partially-correct')
self.assertTrue(0 <= correct_map.get_npoints('1_2_1') <= 1)
assert correctness == 'partially-correct'
assert 0 <= correct_map.get_npoints('1_2_1') <= 1
correctness = correct_map.get_correctness('1_2_2')
self.assertEqual(correctness, 'partially-correct')
self.assertTrue(0 <= correct_map.get_npoints('1_2_2') <= 1)
assert correctness == 'partially-correct'
assert 0 <= correct_map.get_npoints('1_2_2') <= 1
# Both answers incorrect -- expect both inputs marked incorrect
input_dict = {'1_2_1': '0', '1_2_2': '0'}
correct_map = problem.grade_answers(input_dict)
correctness = correct_map.get_correctness('1_2_1')
self.assertEqual(correctness, 'incorrect')
assert correctness == 'incorrect'
correctness = correct_map.get_correctness('1_2_2')
self.assertEqual(correctness, 'incorrect')
assert correctness == 'incorrect'
def test_function_code_multiple_inputs(self):
@@ -1950,25 +1947,25 @@ class CustomResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
correct_map = problem.grade_answers(input_dict)
# Expect that we receive the overall message (for the whole response)
self.assertEqual(correct_map.get_overall_message(), "Overall message")
assert correct_map.get_overall_message() == 'Overall message'
# Expect that the inputs were graded individually
self.assertEqual(correct_map.get_correctness('1_2_1'), 'incorrect')
self.assertEqual(correct_map.get_correctness('1_2_2'), 'correct')
self.assertEqual(correct_map.get_correctness('1_2_3'), 'correct')
self.assertEqual(correct_map.get_correctness('1_2_4'), 'partially-correct')
assert correct_map.get_correctness('1_2_1') == 'incorrect'
assert correct_map.get_correctness('1_2_2') == 'correct'
assert correct_map.get_correctness('1_2_3') == 'correct'
assert correct_map.get_correctness('1_2_4') == 'partially-correct'
# Expect that the inputs were given correct npoints
self.assertEqual(correct_map.get_npoints('1_2_1'), 0)
self.assertEqual(correct_map.get_npoints('1_2_2'), 1)
self.assertEqual(correct_map.get_npoints('1_2_3'), 1)
self.assertTrue(0 <= correct_map.get_npoints('1_2_4') <= 1)
assert correct_map.get_npoints('1_2_1') == 0
assert correct_map.get_npoints('1_2_2') == 1
assert correct_map.get_npoints('1_2_3') == 1
assert 0 <= correct_map.get_npoints('1_2_4') <= 1
# Expect that we received messages for each individual input
self.assertEqual(correct_map.get_msg('1_2_1'), 'Feedback 1')
self.assertEqual(correct_map.get_msg('1_2_2'), 'Feedback 2')
self.assertEqual(correct_map.get_msg('1_2_3'), 'Feedback 3')
self.assertEqual(correct_map.get_msg('1_2_4'), 'Feedback 4')
assert correct_map.get_msg('1_2_1') == 'Feedback 1'
assert correct_map.get_msg('1_2_2') == 'Feedback 2'
assert correct_map.get_msg('1_2_3') == 'Feedback 3'
assert correct_map.get_msg('1_2_4') == 'Feedback 4'
def test_function_code_multiple_inputs_decimal_score(self):
@@ -2008,16 +2005,16 @@ class CustomResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
correct_map = problem.grade_answers(input_dict)
# Expect that the inputs were graded individually
self.assertEqual(correct_map.get_correctness('1_2_1'), 'incorrect')
self.assertEqual(correct_map.get_correctness('1_2_2'), 'correct')
self.assertEqual(correct_map.get_correctness('1_2_3'), 'correct')
self.assertEqual(correct_map.get_correctness('1_2_4'), 'partially-correct')
assert correct_map.get_correctness('1_2_1') == 'incorrect'
assert correct_map.get_correctness('1_2_2') == 'correct'
assert correct_map.get_correctness('1_2_3') == 'correct'
assert correct_map.get_correctness('1_2_4') == 'partially-correct'
# Expect that the inputs were given correct npoints
self.assertEqual(correct_map.get_npoints('1_2_1'), 0.1)
self.assertEqual(correct_map.get_npoints('1_2_2'), 0.9)
self.assertEqual(correct_map.get_npoints('1_2_3'), 0.9)
self.assertEqual(correct_map.get_npoints('1_2_4'), 0.7)
assert correct_map.get_npoints('1_2_1') == 0.1
assert correct_map.get_npoints('1_2_2') == 0.9
assert correct_map.get_npoints('1_2_3') == 0.9
assert correct_map.get_npoints('1_2_4') == 0.7
def test_function_code_with_extra_args(self):
script = textwrap.dedent("""\
@@ -2048,8 +2045,8 @@ class CustomResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
correctness = correct_map.get_correctness('1_2_1')
msg = correct_map.get_msg('1_2_1')
self.assertEqual(correctness, 'correct')
self.assertEqual(msg, "Message text")
assert correctness == 'correct'
assert msg == 'Message text'
# Partially Correct answer
input_dict = {'1_2_1': '21'}
@@ -2058,8 +2055,8 @@ class CustomResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
correctness = correct_map.get_correctness('1_2_1')
msg = correct_map.get_msg('1_2_1')
self.assertEqual(correctness, 'partially-correct')
self.assertEqual(msg, "Message text")
assert correctness == 'partially-correct'
assert msg == 'Message text'
# Incorrect answer
input_dict = {'1_2_1': '0'}
@@ -2068,8 +2065,8 @@ class CustomResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
correctness = correct_map.get_correctness('1_2_1')
msg = correct_map.get_msg('1_2_1')
self.assertEqual(correctness, 'incorrect')
self.assertEqual(msg, "Message text")
assert correctness == 'incorrect'
assert msg == 'Message text'
def test_function_code_with_attempt_number(self):
script = textwrap.dedent("""\
@@ -2098,8 +2095,8 @@ class CustomResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
correctness = correct_map.get_correctness('1_2_1')
msg = correct_map.get_msg('1_2_1')
self.assertEqual(correctness, 'correct')
self.assertEqual(msg, "This is attempt number 1")
assert correctness == 'correct'
assert msg == 'This is attempt number 1'
# second attempt
problem.context['attempt'] = 2
@@ -2108,8 +2105,8 @@ class CustomResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
correctness = correct_map.get_correctness('1_2_1')
msg = correct_map.get_msg('1_2_1')
self.assertEqual(correctness, 'correct')
self.assertEqual(msg, "This is attempt number 2")
assert correctness == 'correct'
assert msg == 'This is attempt number 2'
def test_multiple_inputs_return_one_status(self):
# When given multiple inputs, the 'answer_given' argument
@@ -2143,30 +2140,30 @@ class CustomResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
correct_map = problem.grade_answers(input_dict)
# Everything marked incorrect
self.assertEqual(correct_map.get_correctness('1_2_1'), 'incorrect')
self.assertEqual(correct_map.get_correctness('1_2_2'), 'incorrect')
self.assertEqual(correct_map.get_correctness('1_2_3'), 'incorrect')
assert correct_map.get_correctness('1_2_1') == 'incorrect'
assert correct_map.get_correctness('1_2_2') == 'incorrect'
assert correct_map.get_correctness('1_2_3') == 'incorrect'
# Grade the inputs (one input partially correct)
input_dict = {'1_2_1': '-1', '1_2_2': '2', '1_2_3': '3'}
correct_map = problem.grade_answers(input_dict)
# Everything marked partially correct
self.assertEqual(correct_map.get_correctness('1_2_1'), 'partially-correct')
self.assertEqual(correct_map.get_correctness('1_2_2'), 'partially-correct')
self.assertEqual(correct_map.get_correctness('1_2_3'), 'partially-correct')
assert correct_map.get_correctness('1_2_1') == 'partially-correct'
assert correct_map.get_correctness('1_2_2') == 'partially-correct'
assert correct_map.get_correctness('1_2_3') == 'partially-correct'
# Grade the inputs (everything correct)
input_dict = {'1_2_1': '1', '1_2_2': '2', '1_2_3': '3'}
correct_map = problem.grade_answers(input_dict)
# Everything marked incorrect
self.assertEqual(correct_map.get_correctness('1_2_1'), 'correct')
self.assertEqual(correct_map.get_correctness('1_2_2'), 'correct')
self.assertEqual(correct_map.get_correctness('1_2_3'), 'correct')
assert correct_map.get_correctness('1_2_1') == 'correct'
assert correct_map.get_correctness('1_2_2') == 'correct'
assert correct_map.get_correctness('1_2_3') == 'correct'
# Message is interpreted as an "overall message"
self.assertEqual(correct_map.get_overall_message(), 'Message text')
assert correct_map.get_overall_message() == 'Message text'
def test_script_exception_function(self):
@@ -2179,7 +2176,7 @@ class CustomResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
problem = self.build_problem(script=script, cfn="check_func")
# Expect that an exception gets raised when we check the answer
with self.assertRaises(ResponseError):
with pytest.raises(ResponseError):
problem.grade_answers({'1_2_1': '42'})
def test_script_exception_inline(self):
@@ -2189,7 +2186,7 @@ class CustomResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
problem = self.build_problem(answer=script)
# Expect that an exception gets raised when we check the answer
with self.assertRaises(ResponseError):
with pytest.raises(ResponseError):
problem.grade_answers({'1_2_1': '42'})
def test_invalid_dict_exception(self):
@@ -2203,7 +2200,7 @@ class CustomResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
problem = self.build_problem(script=script, cfn="check_func")
# Expect that an exception gets raised when we check the answer
with self.assertRaises(ResponseError):
with pytest.raises(ResponseError):
problem.grade_answers({'1_2_1': '42'})
def test_setup_randomization(self):
@@ -2212,7 +2209,7 @@ class CustomResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
num = {code}
""".format(code=self._get_random_number_code()))
problem = self.build_problem(script=script)
self.assertEqual(problem.context['num'], self._get_random_number_result(problem.seed))
assert problem.context['num'] == self._get_random_number_result(problem.seed)
def test_check_function_randomization(self):
# The check function should get random-seeded from the problem.
@@ -2225,7 +2222,7 @@ class CustomResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
input_dict = {'1_2_1': '42'}
correct_map = problem.grade_answers(input_dict)
msg = correct_map.get_msg('1_2_1')
self.assertEqual(msg, self._get_random_number_result(problem.seed))
assert msg == self._get_random_number_result(problem.seed)
def test_random_isnt_none(self):
# Bug LMS-500 says random.seed(10) fails with:
@@ -2243,7 +2240,7 @@ class CustomResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
num = random.randint(0, 1e9)
""")
problem = self.build_problem(script=script)
self.assertEqual(problem.context['num'], num)
assert problem.context['num'] == num
def test_module_imports_inline(self):
'''
@@ -2322,7 +2319,7 @@ class CustomResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
capa_system = test_capa_system()
capa_system.get_python_lib_zip = lambda: zipstring.getvalue() # lint-amnesty, pylint: disable=unnecessary-lambda
problem = self.build_problem(script=script, capa_system=capa_system)
self.assertEqual(problem.context['num'], 17)
assert problem.context['num'] == 17
def test_function_code_multiple_inputs_order(self):
# Ensure that order must be correct according to sub-problem position
@@ -2378,18 +2375,18 @@ class CustomResponseTest(ResponseTest): # pylint: disable=missing-class-docstri
correct_map = problem.grade_answers(input_dict)
self.assertNotEqual(list(problem.student_answers.keys()), correct_order)
assert list(problem.student_answers.keys()) != correct_order
# euqal to correct order after sorting at get_score
self.assertListEqual(list(problem.responders.values())[0].context['idset'], correct_order)
self.assertEqual(correct_map.get_correctness('1_2_1'), 'correct')
self.assertEqual(correct_map.get_correctness('1_2_9'), 'correct')
self.assertEqual(correct_map.get_correctness('1_2_11'), 'incorrect')
assert correct_map.get_correctness('1_2_1') == 'correct'
assert correct_map.get_correctness('1_2_9') == 'correct'
assert correct_map.get_correctness('1_2_11') == 'incorrect'
self.assertEqual(correct_map.get_msg('1_2_1'), '1')
self.assertEqual(correct_map.get_msg('1_2_9'), '9')
self.assertEqual(correct_map.get_msg('1_2_11'), '11')
assert correct_map.get_msg('1_2_1') == '1'
assert correct_map.get_msg('1_2_9') == '9'
assert correct_map.get_msg('1_2_11') == '11'
class SchematicResponseTest(ResponseTest):
@@ -2420,7 +2417,7 @@ class SchematicResponseTest(ResponseTest):
# Expect that the problem is graded as true
# (That is, our script verifies that the context
# is what we expect)
self.assertEqual(correct_map.get_correctness('1_2_1'), 'correct')
assert correct_map.get_correctness('1_2_1') == 'correct'
def test_check_function_randomization(self):
# The check function should get a random seed from the problem.
@@ -2431,7 +2428,7 @@ class SchematicResponseTest(ResponseTest):
input_dict = {'1_2_1': json.dumps(submission_dict)}
correct_map = problem.grade_answers(input_dict)
self.assertEqual(correct_map.get_correctness('1_2_1'), 'correct')
assert correct_map.get_correctness('1_2_1') == 'correct'
def test_script_exception(self):
# Construct a script that will raise an exception
@@ -2439,7 +2436,7 @@ class SchematicResponseTest(ResponseTest):
problem = self.build_problem(answer=script)
# Expect that an exception gets raised when we check the answer
with self.assertRaises(ResponseError):
with pytest.raises(ResponseError):
submission_dict = {'test': 'test'}
input_dict = {'1_2_1': json.dumps(submission_dict)}
problem.grade_answers(input_dict)
@@ -2476,10 +2473,9 @@ class AnnotationResponseTest(ResponseTest): # lint-amnesty, pylint: disable=mis
actual_correctness = correct_map.get_correctness(answer_id)
actual_points = correct_map.get_npoints(answer_id)
self.assertEqual(expected_correctness, actual_correctness,
msg="%s should be marked %s" % (answer_id, expected_correctness))
self.assertEqual(expected_points, actual_points,
msg="%s should have %d points" % (answer_id, expected_points))
assert expected_correctness == actual_correctness,\
('%s should be marked %s' % (answer_id, expected_correctness))
assert expected_points == actual_points, ('%s should have %d points' % (answer_id, expected_points))
class ChoiceTextResponseTest(ResponseTest):
@@ -2654,7 +2650,7 @@ class ChoiceTextResponseTest(ResponseTest):
"""
Test that build problem raises errors for invalid options
"""
with self.assertRaises(Exception):
with pytest.raises(Exception):
self.build_problem(type="invalidtextgroup")
def test_unchecked_input_not_validated(self):

View File

@@ -35,9 +35,9 @@ class CapaShuffleTest(unittest.TestCase):
self.assertRegex(the_html, r"<div>.*\[.*'Banana'.*'Apple'.*'Chocolate'.*'Donut'.*\].*</div>")
# Check that choice name masking is enabled and that unmasking works
response = list(problem.responders.values())[0]
self.assertFalse(response.has_mask())
self.assertEqual(response.unmask_order(), ['choice_1', 'choice_0', 'choice_2', 'choice_3'])
self.assertEqual(the_html, problem.get_html(), 'should be able to call get_html() twice')
assert not response.has_mask()
assert response.unmask_order() == ['choice_1', 'choice_0', 'choice_2', 'choice_3']
assert the_html == problem.get_html(), 'should be able to call get_html() twice'
def test_shuffle_custom_names(self):
xml_str = textwrap.dedent("""
@@ -56,9 +56,9 @@ class CapaShuffleTest(unittest.TestCase):
# B A C D
# Check that the custom name= names come through
response = list(problem.responders.values())[0]
self.assertFalse(response.has_mask())
self.assertTrue(response.has_shuffle())
self.assertEqual(response.unmask_order(), ['choice_0', 'choice_aaa', 'choice_1', 'choice_ddd'])
assert not response.has_mask()
assert response.has_shuffle()
assert response.unmask_order() == ['choice_0', 'choice_aaa', 'choice_1', 'choice_ddd']
def test_shuffle_different_seed(self):
xml_str = textwrap.dedent("""
@@ -91,9 +91,9 @@ class CapaShuffleTest(unittest.TestCase):
the_html = problem.get_html()
self.assertRegex(the_html, r"<div>.*\[.*'Apple'.*\].*</div>")
response = list(problem.responders.values())[0]
self.assertFalse(response.has_mask())
self.assertTrue(response.has_shuffle())
self.assertEqual(response.unmask_order(), ['choice_0'])
assert not response.has_mask()
assert response.has_shuffle()
assert response.unmask_order() == ['choice_0']
def test_shuffle_6_choices(self):
xml_str = textwrap.dedent("""
@@ -132,8 +132,8 @@ class CapaShuffleTest(unittest.TestCase):
the_html = problem.get_html()
self.assertRegex(the_html, r"<div>.*\[.*'Apple'.*'Banana'.*'Chocolate'.*'Donut'.*\].*</div>")
response = list(problem.responders.values())[0]
self.assertFalse(response.has_mask())
self.assertFalse(response.has_shuffle())
assert not response.has_mask()
assert not response.has_shuffle()
def test_shuffle_fixed_head_end(self):
xml_str = textwrap.dedent("""
@@ -275,18 +275,18 @@ class CapaShuffleTest(unittest.TestCase):
""")
problem = new_loncapa_problem(xml_str, seed=0)
orig_html = problem.get_html()
self.assertEqual(orig_html, problem.get_html(), 'should be able to call get_html() twice')
assert orig_html == problem.get_html(), 'should be able to call get_html() twice'
html = orig_html.replace('\n', ' ') # avoid headaches with .* matching
print(html)
self.assertRegex(html, r"<div>.*\[.*'Banana'.*'Apple'.*'Chocolate'.*'Donut'.*\].*</div>.*" +
r"<div>.*\[.*'C'.*'A'.*'D'.*'B'.*\].*</div>")
# Look at the responses in their authored order
responses = sorted(list(problem.responders.values()), key=lambda resp: int(resp.id[resp.id.rindex('_') + 1:]))
self.assertFalse(responses[0].has_mask())
self.assertTrue(responses[0].has_shuffle())
self.assertTrue(responses[1].has_shuffle())
self.assertEqual(responses[0].unmask_order(), ['choice_1', 'choice_0', 'choice_2', 'choice_3'])
self.assertEqual(responses[1].unmask_order(), ['choice_2', 'choice_0', 'choice_3', 'choice_1'])
assert not responses[0].has_mask()
assert responses[0].has_shuffle()
assert responses[1].has_shuffle()
assert responses[0].unmask_order() == ['choice_1', 'choice_0', 'choice_2', 'choice_3']
assert responses[1].unmask_order() == ['choice_2', 'choice_0', 'choice_3', 'choice_1']
def test_shuffle_not_with_answerpool(self):
"""Raise error if shuffle and answer-pool are both used."""

View File

@@ -91,7 +91,7 @@ class CapaTargetedFeedbackTest(unittest.TestCase):
self.assertRegex(without_new_lines, r"<div>.*'wrong-1'.*'wrong-2'.*'correct-1'.*'wrong-3'.*</div>")
self.assertNotRegex(without_new_lines, r"feedback1|feedback2|feedback3|feedbackC")
self.assertEqual(the_html, problem.get_html(), "Should be able to call get_html() twice")
assert the_html == problem.get_html(), 'Should be able to call get_html() twice'
def test_targeted_feedback_student_answer1(self):
problem = new_loncapa_problem(load_fixture('targeted_feedback.xml'))
@@ -105,7 +105,7 @@ class CapaTargetedFeedbackTest(unittest.TestCase):
self.assertNotRegex(without_new_lines, r"feedback1|feedback2|feedbackC")
# Check that calling it multiple times yields the same thing
the_html2 = problem.get_html()
self.assertEqual(the_html, the_html2)
assert the_html == the_html2
def test_targeted_feedback_student_answer2(self):
problem = new_loncapa_problem(load_fixture('targeted_feedback.xml'))
@@ -304,7 +304,7 @@ class CapaTargetedFeedbackTest(unittest.TestCase):
self.assertNotRegex(without_new_lines, r"feedback2|feedback3")
# Check that calling it multiple times yields the same thing
the_html2 = problem.get_html()
self.assertEqual(the_html, the_html2)
assert the_html == the_html2
def test_targeted_feedback_no_show_solution_explanation(self):
xml_str = textwrap.dedent("""

View File

@@ -30,94 +30,94 @@ class UtilTest(unittest.TestCase):
def test_compare_with_tolerance(self): # lint-amnesty, pylint: disable=too-many-statements
# Test default tolerance '0.001%' (it is relative)
result = compare_with_tolerance(100.0, 100.0)
self.assertTrue(result)
assert result
result = compare_with_tolerance(100.001, 100.0)
self.assertTrue(result)
assert result
result = compare_with_tolerance(101.0, 100.0)
self.assertFalse(result)
assert not result
# Test absolute percentage tolerance
result = compare_with_tolerance(109.9, 100.0, '10%', False)
self.assertTrue(result)
assert result
result = compare_with_tolerance(110.1, 100.0, '10%', False)
self.assertFalse(result)
assert not result
# Test relative percentage tolerance
result = compare_with_tolerance(111.0, 100.0, '10%', True)
self.assertTrue(result)
assert result
result = compare_with_tolerance(112.0, 100.0, '10%', True)
self.assertFalse(result)
assert not result
# Test absolute tolerance (string)
result = compare_with_tolerance(109.9, 100.0, '10.0', False)
self.assertTrue(result)
assert result
result = compare_with_tolerance(110.1, 100.0, '10.0', False)
self.assertFalse(result)
assert not result
# Test relative tolerance (string)
result = compare_with_tolerance(111.0, 100.0, '0.1', True)
self.assertTrue(result)
assert result
result = compare_with_tolerance(112.0, 100.0, '0.1', True)
self.assertFalse(result)
assert not result
# Test absolute tolerance (float)
result = compare_with_tolerance(109.9, 100.0, 10.0, False)
self.assertTrue(result)
assert result
result = compare_with_tolerance(110.1, 100.0, 10.0, False)
self.assertFalse(result)
assert not result
# Test relative tolerance (float)
result = compare_with_tolerance(111.0, 100.0, 0.1, True)
self.assertTrue(result)
assert result
result = compare_with_tolerance(112.0, 100.0, 0.1, True)
self.assertFalse(result)
assert not result
##### Infinite values #####
infinity = float('Inf')
# Test relative tolerance (float)
result = compare_with_tolerance(infinity, 100.0, 1.0, True)
self.assertFalse(result)
assert not result
result = compare_with_tolerance(100.0, infinity, 1.0, True)
self.assertFalse(result)
assert not result
result = compare_with_tolerance(infinity, infinity, 1.0, True)
self.assertTrue(result)
assert result
# Test absolute tolerance (float)
result = compare_with_tolerance(infinity, 100.0, 1.0, False)
self.assertFalse(result)
assert not result
result = compare_with_tolerance(100.0, infinity, 1.0, False)
self.assertFalse(result)
assert not result
result = compare_with_tolerance(infinity, infinity, 1.0, False)
self.assertTrue(result)
assert result
# Test relative tolerance (string)
result = compare_with_tolerance(infinity, 100.0, '1.0', True)
self.assertFalse(result)
assert not result
result = compare_with_tolerance(100.0, infinity, '1.0', True)
self.assertFalse(result)
assert not result
result = compare_with_tolerance(infinity, infinity, '1.0', True)
self.assertTrue(result)
assert result
# Test absolute tolerance (string)
result = compare_with_tolerance(infinity, 100.0, '1.0', False)
self.assertFalse(result)
assert not result
result = compare_with_tolerance(100.0, infinity, '1.0', False)
self.assertFalse(result)
assert not result
result = compare_with_tolerance(infinity, infinity, '1.0', False)
self.assertTrue(result)
assert result
# Test absolute tolerance for smaller values
result = compare_with_tolerance(100.01, 100.0, 0.01, False)
self.assertTrue(result)
assert result
result = compare_with_tolerance(100.001, 100.0, 0.001, False)
self.assertTrue(result)
assert result
result = compare_with_tolerance(100.01, 100.0, '0.01%', False)
self.assertTrue(result)
assert result
result = compare_with_tolerance(100.002, 100.0, 0.001, False)
self.assertFalse(result)
assert not result
result = compare_with_tolerance(0.4, 0.44, 0.01, False)
self.assertFalse(result)
assert not result
result = compare_with_tolerance(100.01, 100.0, 0.010, False)
self.assertTrue(result)
assert result
# Test complex_number instructor_complex
result = compare_with_tolerance(0.4, complex(0.44, 0), 0.01, False)
self.assertFalse(result)
assert not result
result = compare_with_tolerance(100.01, complex(100.0, 0), 0.010, False)
self.assertTrue(result)
assert result
result = compare_with_tolerance(110.1, complex(100.0, 0), '10.0', False)
self.assertFalse(result)
assert not result
result = compare_with_tolerance(111.0, complex(100.0, 0), '10%', True)
self.assertTrue(result)
assert result
def test_sanitize_html(self):
"""
@@ -126,28 +126,26 @@ class UtilTest(unittest.TestCase):
allowed_tags = ['div', 'p', 'audio', 'pre', 'span']
for tag in allowed_tags:
queue_msg = "<{0}>Test message</{0}>".format(tag)
self.assertEqual(sanitize_html(queue_msg), queue_msg)
assert sanitize_html(queue_msg) == queue_msg
not_allowed_tag = 'script'
queue_msg = "<{0}>Test message</{0}>".format(not_allowed_tag)
expected = "&lt;script&gt;Test message&lt;/script&gt;"
self.assertEqual(sanitize_html(queue_msg), expected)
assert sanitize_html(queue_msg) == expected
def test_get_inner_html_from_xpath(self):
"""
Test for getting inner html as string from xpath node.
"""
xpath_node = etree.XML('<hint style="smtng">aa<a href="#">bb</a>cc</hint>')
self.assertEqual(get_inner_html_from_xpath(xpath_node), 'aa<a href="#">bb</a>cc')
assert get_inner_html_from_xpath(xpath_node) == 'aa<a href="#">bb</a>cc'
def test_remove_markup(self):
"""
Test for markup removal with bleach.
"""
self.assertEqual(
remove_markup("The <mark>Truth</mark> is <em>Out There</em> & you need to <strong>find</strong> it"),
"The Truth is Out There &amp; you need to find it"
)
assert remove_markup('The <mark>Truth</mark> is <em>Out There</em> & you need to <strong>find</strong> it') ==\
'The Truth is Out There &amp; you need to find it'
@ddt.data(
'When the root level failš the whole hierarchy wont work anymore.',
@@ -159,7 +157,7 @@ class UtilTest(unittest.TestCase):
text = '$answer0'
context = {key: context_value}
contextual_text = contextualize_text(text, context)
self.assertEqual(context_value, contextual_text)
assert context_value == contextual_text
def test_contextualize_text_with_non_ascii_context(self):
"""Verify that variable substitution works as intended with non-ascii characters."""
@@ -168,4 +166,4 @@ class UtilTest(unittest.TestCase):
context = {'a': u'あなたあなたあなた', 'b': u'あなたhi'}
expected_text = '$あなたあなたあなたあなた あなたhi'
contextual_text = contextualize_text(text, context)
self.assertEqual(expected_text, contextual_text)
assert expected_text == contextual_text

View File

@@ -12,34 +12,34 @@ class Test_PositionsCompare(unittest.TestCase):
""" describe"""
def test_nested_list_and_list1(self):
self.assertEqual(PositionsCompare([[1, 2], 40]), PositionsCompare([1, 3]))
assert PositionsCompare([[1, 2], 40]) == PositionsCompare([1, 3])
def test_nested_list_and_list2(self):
self.assertNotEqual(PositionsCompare([1, 12]), PositionsCompare([1, 1]))
assert PositionsCompare([1, 12]) != PositionsCompare([1, 1])
def test_list_and_list1(self):
self.assertNotEqual(PositionsCompare([[1, 2], 12]), PositionsCompare([1, 15]))
assert PositionsCompare([[1, 2], 12]) != PositionsCompare([1, 15])
def test_list_and_list2(self):
self.assertEqual(PositionsCompare([1, 11]), PositionsCompare([1, 1]))
assert PositionsCompare([1, 11]) == PositionsCompare([1, 1])
def test_numerical_list_and_string_list(self):
self.assertNotEqual(PositionsCompare([1, 2]), PositionsCompare(["1"]))
assert PositionsCompare([1, 2]) != PositionsCompare(['1'])
def test_string_and_string_list1(self):
self.assertEqual(PositionsCompare("1"), PositionsCompare(["1"]))
assert PositionsCompare('1') == PositionsCompare(['1'])
def test_string_and_string_list2(self):
self.assertEqual(PositionsCompare("abc"), PositionsCompare("abc"))
assert PositionsCompare('abc') == PositionsCompare('abc')
def test_string_and_string_list3(self):
self.assertNotEqual(PositionsCompare("abd"), PositionsCompare("abe"))
assert PositionsCompare('abd') != PositionsCompare('abe')
def test_float_and_string(self):
self.assertNotEqual(PositionsCompare([3.5, 5.7]), PositionsCompare(["1"]))
assert PositionsCompare([3.5, 5.7]) != PositionsCompare(['1'])
def test_floats_and_ints(self):
self.assertEqual(PositionsCompare([3.5, 4.5]), PositionsCompare([5, 7]))
assert PositionsCompare([3.5, 4.5]) == PositionsCompare([5, 7])
class Test_DragAndDrop_Grade(unittest.TestCase): # lint-amnesty, pylint: disable=missing-class-docstring
@@ -64,7 +64,7 @@ class Test_DragAndDrop_Grade(unittest.TestCase): # lint-amnesty, pylint: disabl
'rule': 'anyof'
}
]
self.assertTrue(draganddrop.grade(user_input, correct_answer))
assert draganddrop.grade(user_input, correct_answer)
def test_targets_are_draggable_2(self):
user_input = json.dumps([
@@ -107,7 +107,7 @@ class Test_DragAndDrop_Grade(unittest.TestCase): # lint-amnesty, pylint: disabl
'rule': 'unordered_equal'
}
]
self.assertTrue(draganddrop.grade(user_input, correct_answer))
assert draganddrop.grade(user_input, correct_answer)
def test_targets_are_draggable_2_manual_parsing(self):
user_input = json.dumps([
@@ -150,7 +150,7 @@ class Test_DragAndDrop_Grade(unittest.TestCase): # lint-amnesty, pylint: disabl
'rule': 'unordered_equal'
}
]
self.assertTrue(draganddrop.grade(user_input, correct_answer))
assert draganddrop.grade(user_input, correct_answer)
def test_targets_are_draggable_3_nested(self):
user_input = json.dumps([
@@ -209,7 +209,7 @@ class Test_DragAndDrop_Grade(unittest.TestCase): # lint-amnesty, pylint: disabl
'rule': 'unordered_equal'
}
]
self.assertTrue(draganddrop.grade(user_input, correct_answer))
assert draganddrop.grade(user_input, correct_answer)
def test_targets_are_draggable_4_real_example(self):
user_input = json.dumps([
@@ -283,83 +283,83 @@ class Test_DragAndDrop_Grade(unittest.TestCase): # lint-amnesty, pylint: disabl
},
]
self.assertTrue(draganddrop.grade(user_input, correct_answer))
assert draganddrop.grade(user_input, correct_answer)
def test_targets_true(self):
user_input = '[{"1": "t1"}, \
{"name_with_icon": "t2"}]'
correct_answer = {'1': 't1', 'name_with_icon': 't2'}
self.assertTrue(draganddrop.grade(user_input, correct_answer))
assert draganddrop.grade(user_input, correct_answer)
def test_expect_no_actions_wrong(self):
user_input = '[{"1": "t1"}, \
{"name_with_icon": "t2"}]'
correct_answer = []
self.assertFalse(draganddrop.grade(user_input, correct_answer))
assert not draganddrop.grade(user_input, correct_answer)
def test_expect_no_actions_right(self):
user_input = '[]'
correct_answer = []
self.assertTrue(draganddrop.grade(user_input, correct_answer))
assert draganddrop.grade(user_input, correct_answer)
def test_targets_false(self):
user_input = '[{"1": "t1"}, \
{"name_with_icon": "t2"}]'
correct_answer = {'1': 't3', 'name_with_icon': 't2'}
self.assertFalse(draganddrop.grade(user_input, correct_answer))
assert not draganddrop.grade(user_input, correct_answer)
def test_multiple_images_per_target_true(self):
user_input = '[{"1": "t1"}, {"name_with_icon": "t2"}, \
{"2": "t1"}]'
correct_answer = {'1': 't1', 'name_with_icon': 't2', '2': 't1'}
self.assertTrue(draganddrop.grade(user_input, correct_answer))
assert draganddrop.grade(user_input, correct_answer)
def test_multiple_images_per_target_false(self):
user_input = '[{"1": "t1"}, {"name_with_icon": "t2"}, \
{"2": "t1"}]'
correct_answer = {'1': 't2', 'name_with_icon': 't2', '2': 't1'}
self.assertFalse(draganddrop.grade(user_input, correct_answer))
assert not draganddrop.grade(user_input, correct_answer)
def test_targets_and_positions(self):
user_input = '[{"1": [10,10]}, \
{"name_with_icon": [[10,10],4]}]'
correct_answer = {'1': [10, 10], 'name_with_icon': [[10, 10], 4]}
self.assertTrue(draganddrop.grade(user_input, correct_answer))
assert draganddrop.grade(user_input, correct_answer)
def test_position_and_targets(self):
user_input = '[{"1": "t1"}, {"name_with_icon": "t2"}]'
correct_answer = {'1': 't1', 'name_with_icon': 't2'}
self.assertTrue(draganddrop.grade(user_input, correct_answer))
assert draganddrop.grade(user_input, correct_answer)
def test_positions_exact(self):
user_input = '[{"1": [10, 10]}, {"name_with_icon": [20, 20]}]'
correct_answer = {'1': [10, 10], 'name_with_icon': [20, 20]}
self.assertTrue(draganddrop.grade(user_input, correct_answer))
assert draganddrop.grade(user_input, correct_answer)
def test_positions_false(self):
user_input = '[{"1": [10, 10]}, {"name_with_icon": [20, 20]}]'
correct_answer = {'1': [25, 25], 'name_with_icon': [20, 20]}
self.assertFalse(draganddrop.grade(user_input, correct_answer))
assert not draganddrop.grade(user_input, correct_answer)
def test_positions_true_in_radius(self):
user_input = '[{"1": [10, 10]}, {"name_with_icon": [20, 20]}]'
correct_answer = {'1': [14, 14], 'name_with_icon': [20, 20]}
self.assertTrue(draganddrop.grade(user_input, correct_answer))
assert draganddrop.grade(user_input, correct_answer)
def test_positions_true_in_manual_radius(self):
user_input = '[{"1": [10, 10]}, {"name_with_icon": [20, 20]}]'
correct_answer = {'1': [[40, 10], 30], 'name_with_icon': [20, 20]}
self.assertTrue(draganddrop.grade(user_input, correct_answer))
assert draganddrop.grade(user_input, correct_answer)
def test_positions_false_in_manual_radius(self):
user_input = '[{"1": [10, 10]}, {"name_with_icon": [20, 20]}]'
correct_answer = {'1': [[40, 10], 29], 'name_with_icon': [20, 20]}
self.assertFalse(draganddrop.grade(user_input, correct_answer))
assert not draganddrop.grade(user_input, correct_answer)
def test_correct_answer_not_has_key_from_user_answer(self):
user_input = '[{"1": "t1"}, {"name_with_icon": "t2"}]'
correct_answer = {'3': 't3', 'name_with_icon': 't2'}
self.assertFalse(draganddrop.grade(user_input, correct_answer))
assert not draganddrop.grade(user_input, correct_answer)
def test_anywhere(self):
"""Draggables can be places anywhere on base image.
@@ -369,7 +369,7 @@ class Test_DragAndDrop_Grade(unittest.TestCase): # lint-amnesty, pylint: disabl
{"grass":[322.5,199.449951171875]}]'
correct_answer = {'grass': [[300, 200], 200], 'ant': [[500, 0], 200]}
self.assertTrue(draganddrop.grade(user_input, correct_answer))
assert draganddrop.grade(user_input, correct_answer)
def test_lcao_correct(self):
"""Describe carbon molecule in LCAO-MO"""
@@ -408,7 +408,7 @@ class Test_DragAndDrop_Grade(unittest.TestCase): # lint-amnesty, pylint: disabl
'rule': 'anyof'
}]
self.assertTrue(draganddrop.grade(user_input, correct_answer))
assert draganddrop.grade(user_input, correct_answer)
def test_lcao_extra_element_incorrect(self):
"""Describe carbon molecule in LCAO-MO"""
@@ -447,7 +447,7 @@ class Test_DragAndDrop_Grade(unittest.TestCase): # lint-amnesty, pylint: disabl
'rule': 'anyof'
}]
self.assertFalse(draganddrop.grade(user_input, correct_answer))
assert not draganddrop.grade(user_input, correct_answer)
def test_reuse_draggable_no_mupliples(self):
"""Test reusable draggables (no mupltiple draggables per target)"""
@@ -471,7 +471,7 @@ class Test_DragAndDrop_Grade(unittest.TestCase): # lint-amnesty, pylint: disabl
'rule': 'anyof'
}
]
self.assertTrue(draganddrop.grade(user_input, correct_answer))
assert draganddrop.grade(user_input, correct_answer)
def test_reuse_draggable_with_mupliples(self):
"""Test reusable draggables with mupltiple draggables per target"""
@@ -495,7 +495,7 @@ class Test_DragAndDrop_Grade(unittest.TestCase): # lint-amnesty, pylint: disabl
'rule': 'anyof'
}
]
self.assertTrue(draganddrop.grade(user_input, correct_answer))
assert draganddrop.grade(user_input, correct_answer)
def test_reuse_many_draggable_with_mupliples(self):
"""Test reusable draggables with mupltiple draggables per target"""
@@ -525,7 +525,7 @@ class Test_DragAndDrop_Grade(unittest.TestCase): # lint-amnesty, pylint: disabl
'rule': 'anyof'
}
]
self.assertTrue(draganddrop.grade(user_input, correct_answer))
assert draganddrop.grade(user_input, correct_answer)
def test_reuse_many_draggable_with_mupliples_wrong(self):
"""Test reusable draggables with mupltiple draggables per target"""
@@ -556,7 +556,7 @@ class Test_DragAndDrop_Grade(unittest.TestCase): # lint-amnesty, pylint: disabl
'targets': ['target6'],
'rule': 'anyof'
}]
self.assertFalse(draganddrop.grade(user_input, correct_answer))
assert not draganddrop.grade(user_input, correct_answer)
def test_label_10_targets_with_a_b_c_false(self):
"""Test reusable draggables (no mupltiple draggables per target)"""
@@ -581,7 +581,7 @@ class Test_DragAndDrop_Grade(unittest.TestCase): # lint-amnesty, pylint: disabl
'rule': 'unordered_equal'
}
]
self.assertFalse(draganddrop.grade(user_input, correct_answer))
assert not draganddrop.grade(user_input, correct_answer)
def test_label_10_targets_with_a_b_c_(self):
"""Test reusable draggables (no mupltiple draggables per target)"""
@@ -606,7 +606,7 @@ class Test_DragAndDrop_Grade(unittest.TestCase): # lint-amnesty, pylint: disabl
'rule': 'unordered_equal'
}
]
self.assertTrue(draganddrop.grade(user_input, correct_answer))
assert draganddrop.grade(user_input, correct_answer)
def test_label_10_targets_with_a_b_c_multiple(self):
"""Test reusable draggables (mupltiple draggables per target)"""
@@ -631,7 +631,7 @@ class Test_DragAndDrop_Grade(unittest.TestCase): # lint-amnesty, pylint: disabl
'rule': 'anyof+number'
}
]
self.assertTrue(draganddrop.grade(user_input, correct_answer))
assert draganddrop.grade(user_input, correct_answer)
def test_label_10_targets_with_a_b_c_multiple_false(self):
"""Test reusable draggables (mupltiple draggables per target)"""
@@ -656,7 +656,7 @@ class Test_DragAndDrop_Grade(unittest.TestCase): # lint-amnesty, pylint: disabl
'rule': 'anyof+number'
}
]
self.assertFalse(draganddrop.grade(user_input, correct_answer))
assert not draganddrop.grade(user_input, correct_answer)
def test_label_10_targets_with_a_b_c_reused(self):
"""Test a b c in 10 labels reused"""
@@ -681,7 +681,7 @@ class Test_DragAndDrop_Grade(unittest.TestCase): # lint-amnesty, pylint: disabl
'rule': 'unordered_equal+number'
}
]
self.assertTrue(draganddrop.grade(user_input, correct_answer))
assert draganddrop.grade(user_input, correct_answer)
def test_label_10_targets_with_a_b_c_reused_false(self):
"""Test a b c in 10 labels reused false"""
@@ -706,7 +706,7 @@ class Test_DragAndDrop_Grade(unittest.TestCase): # lint-amnesty, pylint: disabl
'rule': 'unordered_equal+number'
}
]
self.assertFalse(draganddrop.grade(user_input, correct_answer))
assert not draganddrop.grade(user_input, correct_answer)
def test_mixed_reuse_and_not_reuse(self):
"""Test reusable draggables """
@@ -725,7 +725,7 @@ class Test_DragAndDrop_Grade(unittest.TestCase): # lint-amnesty, pylint: disabl
'rule': 'exact'
}
]
self.assertTrue(draganddrop.grade(user_input, correct_answer))
assert draganddrop.grade(user_input, correct_answer)
def test_mixed_reuse_and_not_reuse_number(self):
"""Test reusable draggables with number """
@@ -743,7 +743,7 @@ class Test_DragAndDrop_Grade(unittest.TestCase): # lint-amnesty, pylint: disabl
'rule': 'exact'
}
]
self.assertTrue(draganddrop.grade(user_input, correct_answer))
assert draganddrop.grade(user_input, correct_answer)
def test_mixed_reuse_and_not_reuse_number_false(self):
"""Test reusable draggables with numbers, but wrong"""
@@ -761,7 +761,7 @@ class Test_DragAndDrop_Grade(unittest.TestCase): # lint-amnesty, pylint: disabl
'rule': 'exact'
}
]
self.assertFalse(draganddrop.grade(user_input, correct_answer))
assert not draganddrop.grade(user_input, correct_answer)
def test_alternative_correct_answer(self):
user_input = '[{"name_with_icon":"t1"},\
@@ -772,7 +772,7 @@ class Test_DragAndDrop_Grade(unittest.TestCase): # lint-amnesty, pylint: disabl
{'draggables': ['name_with_icon'], 'targets': ['t1', 't1', 't1'],
'rule': 'exact'}
]
self.assertTrue(draganddrop.grade(user_input, correct_answer))
assert draganddrop.grade(user_input, correct_answer)
class Test_DragAndDrop_Populate(unittest.TestCase): # lint-amnesty, pylint: disable=missing-class-docstring
@@ -787,61 +787,45 @@ class Test_DragAndDrop_Populate(unittest.TestCase): # lint-amnesty, pylint: dis
user_groups = [['1'], ['name_with_icon']]
user_positions = [{'user': [[10, 10]]}, {'user': [[20, 20]]}]
self.assertEqual(correct_groups, dnd.correct_groups)
self.assertEqual(correct_positions, dnd.correct_positions)
self.assertEqual(user_groups, dnd.user_groups)
self.assertEqual(user_positions, dnd.user_positions)
assert correct_groups == dnd.correct_groups
assert correct_positions == dnd.correct_positions
assert user_groups == dnd.user_groups
assert user_positions == dnd.user_positions
class Test_DraAndDrop_Compare_Positions(unittest.TestCase): # lint-amnesty, pylint: disable=missing-class-docstring
def test_1(self):
dnd = draganddrop.DragAndDrop({'1': 't1'}, '[{"1": "t1"}]')
self.assertTrue(dnd.compare_positions(correct=[[1, 1], [2, 3]],
user=[[2, 3], [1, 1]],
flag='anyof'))
assert dnd.compare_positions(correct=[[1, 1], [2, 3]], user=[[2, 3], [1, 1]], flag='anyof')
def test_2a(self):
dnd = draganddrop.DragAndDrop({'1': 't1'}, '[{"1": "t1"}]')
self.assertTrue(dnd.compare_positions(correct=[[1, 1], [2, 3]],
user=[[2, 3], [1, 1]],
flag='exact'))
assert dnd.compare_positions(correct=[[1, 1], [2, 3]], user=[[2, 3], [1, 1]], flag='exact')
def test_2b(self):
dnd = draganddrop.DragAndDrop({'1': 't1'}, '[{"1": "t1"}]')
self.assertFalse(dnd.compare_positions(correct=[[1, 1], [2, 3]],
user=[[2, 13], [1, 1]],
flag='exact'))
assert not dnd.compare_positions(correct=[[1, 1], [2, 3]], user=[[2, 13], [1, 1]], flag='exact')
def test_3(self):
dnd = draganddrop.DragAndDrop({'1': 't1'}, '[{"1": "t1"}]')
self.assertFalse(dnd.compare_positions(correct=["a", "b"],
user=["a", "b", "c"],
flag='anyof'))
assert not dnd.compare_positions(correct=['a', 'b'], user=['a', 'b', 'c'], flag='anyof')
def test_4(self):
dnd = draganddrop.DragAndDrop({'1': 't1'}, '[{"1": "t1"}]')
self.assertTrue(dnd.compare_positions(correct=["a", "b", "c"],
user=["a", "b"],
flag='anyof'))
assert dnd.compare_positions(correct=['a', 'b', 'c'], user=['a', 'b'], flag='anyof')
def test_5(self):
dnd = draganddrop.DragAndDrop({'1': 't1'}, '[{"1": "t1"}]')
self.assertFalse(dnd.compare_positions(correct=["a", "b", "c"],
user=["a", "c", "b"],
flag='exact'))
assert not dnd.compare_positions(correct=['a', 'b', 'c'], user=['a', 'c', 'b'], flag='exact')
def test_6(self):
dnd = draganddrop.DragAndDrop({'1': 't1'}, '[{"1": "t1"}]')
self.assertTrue(dnd.compare_positions(correct=["a", "b", "c"],
user=["a", "c", "b"],
flag='anyof'))
assert dnd.compare_positions(correct=['a', 'b', 'c'], user=['a', 'c', 'b'], flag='anyof')
def test_7(self):
dnd = draganddrop.DragAndDrop({'1': 't1'}, '[{"1": "t1"}]')
self.assertFalse(dnd.compare_positions(correct=["a", "b", "b"],
user=["a", "c", "b"],
flag='anyof'))
assert not dnd.compare_positions(correct=['a', 'b', 'b'], user=['a', 'c', 'b'], flag='anyof')
def suite(): # lint-amnesty, pylint: disable=missing-function-docstring

View File

@@ -43,7 +43,7 @@ class FormulaTest(unittest.TestCase): # lint-amnesty, pylint: disable=missing-c
test = etree.tostring(xml)
# success?
self.assertEqual(test.decode('utf-8'), expected)
assert test.decode('utf-8') == expected
def test_fix_simple_superscripts(self):
expr = '''
@@ -67,7 +67,7 @@ class FormulaTest(unittest.TestCase): # lint-amnesty, pylint: disable=missing-c
test = etree.tostring(xml)
# success?
self.assertEqual(test.decode('utf-8'), expected)
assert test.decode('utf-8') == expected
def test_fix_complex_superscripts(self):
expr = '''
@@ -92,7 +92,7 @@ class FormulaTest(unittest.TestCase): # lint-amnesty, pylint: disable=missing-c
test = etree.tostring(xml)
# success?
self.assertEqual(test.decode('utf-8'), expected)
assert test.decode('utf-8') == expected
def test_fix_msubsup(self):
expr = '''
@@ -114,4 +114,4 @@ class FormulaTest(unittest.TestCase): # lint-amnesty, pylint: disable=missing-c
test = etree.tostring(xml)
# success?
self.assertEqual(test.decode('utf-8'), expected)
assert test.decode('utf-8') == expected

View File

@@ -32,7 +32,7 @@ class SymmathCheckTest(TestCase): # lint-amnesty, pylint: disable=missing-class
# Expect that the exact same symbolic string is marked correct
result = symmath_check(expected_str, expected_str, dynamath=[dynamath])
self.assertTrue('ok' in result and result['ok'])
assert (('ok' in result) and result['ok'])
def test_symmath_check_equivalent_symbols(self):
expected_str = "x+2*y"
@@ -52,7 +52,7 @@ class SymmathCheckTest(TestCase): # lint-amnesty, pylint: disable=missing-class
# Expect that equivalent symbolic strings are marked correct
result = symmath_check(expected_str, input_str, dynamath=[dynamath])
self.assertTrue('ok' in result and result['ok'])
assert (('ok' in result) and result['ok'])
def test_symmath_check_different_symbols(self):
expected_str = "0"
@@ -70,8 +70,8 @@ class SymmathCheckTest(TestCase): # lint-amnesty, pylint: disable=missing-class
# Expect that an incorrect response is marked incorrect
result = symmath_check(expected_str, input_str, dynamath=[dynamath])
self.assertTrue('ok' in result and not result['ok'])
self.assertNotIn('fail', result['msg'])
assert (('ok' in result) and (not result['ok']))
assert 'fail' not in result['msg']
def _symmath_check_numbers(self, number_list): # lint-amnesty, pylint: disable=missing-function-docstring
@@ -81,11 +81,9 @@ class SymmathCheckTest(TestCase): # lint-amnesty, pylint: disable=missing-class
expect = n
ans = n
result = symmath_check(str(expect), str(ans))
self.assertTrue('ok' in result and result['ok'],
"%f should == %f" % (expect, ans))
assert (('ok' in result) and result['ok']), ('%f should == %f' % (expect, ans))
# Change expect so that it != ans
expect += 0.1
result = symmath_check(str(expect), str(ans))
self.assertTrue('ok' in result and not result['ok'],
"%f should != %f" % (expect, ans))
assert (('ok' in result) and (not result['ok'])), ('%f should != %f' % (expect, ans))

View File

@@ -4,6 +4,7 @@ Test for asset XML generation / parsing.
import unittest
import pytest
from contracts import ContractNotRespected
from lxml import etree
@@ -59,7 +60,7 @@ class TestAssetXml(unittest.TestCase):
continue
orig_value = getattr(asset_md, attr)
new_value = getattr(new_asset_md, attr)
self.assertEqual(orig_value, new_value)
assert orig_value == new_value
def test_export_with_None_value(self):
"""
@@ -87,7 +88,7 @@ class TestAssetXml(unittest.TestCase):
Ensure full asset sections with the wrong tag are detected.
"""
root = etree.Element("glassets")
with self.assertRaises(ContractNotRespected):
with pytest.raises(ContractNotRespected):
AssetMetadata.add_all_assets_as_xml(root, self.course_assets)
def test_wrong_node_type_single(self):
@@ -97,5 +98,5 @@ class TestAssetXml(unittest.TestCase):
asset_md = self.course_assets[0]
root = etree.Element("assets")
asset = etree.SubElement(root, "smashset")
with self.assertRaises(ContractNotRespected):
with pytest.raises(ContractNotRespected):
asset_md.to_xml(asset)

View File

@@ -4,6 +4,7 @@ Simple test to ensure that modulestore base classes remain abstract
from unittest import TestCase
import pytest
from xmodule.modulestore import ModuleStoreRead, ModuleStoreWrite
@@ -14,5 +15,6 @@ class AbstractionTest(TestCase):
"""
def test_cant_instantiate_abstract_class(self):
self.assertRaises(TypeError, ModuleStoreRead) # Cannot be instantiated due to explicit abstraction
self.assertRaises(TypeError, ModuleStoreWrite)
pytest.raises(TypeError, ModuleStoreRead)
# Cannot be instantiated due to explicit abstraction
pytest.raises(TypeError, ModuleStoreWrite)

View File

@@ -45,11 +45,11 @@ class TestAsidesXmlStore(TestCase):
Check whether block has the expected aside w/ its fields and then recurse to the block's children
"""
asides = block.runtime.get_asides(block)
self.assertEqual(len(asides), 1, "Found {} asides but expected only test_aside".format(asides))
self.assertIsInstance(asides[0], AsideTestType)
assert len(asides) == 1, 'Found {} asides but expected only test_aside'.format(asides)
assert isinstance(asides[0], AsideTestType)
category = block.scope_ids.block_type
self.assertEqual(asides[0].data_field, "{} aside data".format(category))
self.assertEqual(asides[0].content, "{} Aside".format(category.capitalize()))
assert asides[0].data_field == '{} aside data'.format(category)
assert asides[0].content == '{} Aside'.format(category.capitalize())
for child in block.get_children():
check_block(child)

View File

@@ -6,7 +6,7 @@ too.
import unittest
from datetime import datetime, timedelta
import pytest
import ddt
import pytz
import six
@@ -83,16 +83,14 @@ class TestSortedAssetList(unittest.TestCase):
def test_exception_on_bad_sort(self):
asset_key = self.course_key.make_asset_key('asset', 'pic1.jpg')
with self.assertRaises(IncorrectlySortedList):
with pytest.raises(IncorrectlySortedList):
__ = self.sorted_asset_list_by_last_edit.find(asset_key)
def test_find(self):
asset_key = self.course_key.make_asset_key('asset', 'asset.txt')
self.assertEqual(self.sorted_asset_list_by_filename.find(asset_key), 0)
assert self.sorted_asset_list_by_filename.find(asset_key) == 0
asset_key_last = self.course_key.make_asset_key('asset', 'weather_patterns.bmp')
self.assertEqual(
self.sorted_asset_list_by_filename.find(asset_key_last), len(AssetStoreTestData.all_asset_data) - 1
)
assert self.sorted_asset_list_by_filename.find(asset_key_last) == (len(AssetStoreTestData.all_asset_data) - 1)
@attr('mongo')
@@ -126,7 +124,7 @@ class TestMongoAssetMetadataStorage(TestCase):
if type(mdata1) != type(mdata2): # lint-amnesty, pylint: disable=unidiomatic-typecheck
self.fail(self._formatMessage(msg, u"{} is not same type as {}".format(mdata1, mdata2)))
for attr in mdata1.ATTRS_ALLOWED_TO_UPDATE: # lint-amnesty, pylint: disable=redefined-outer-name
self.assertEqual(getattr(mdata1, attr), getattr(mdata2, attr), msg)
assert getattr(mdata1, attr) == getattr(mdata2, attr), msg
def _compare_datetimes(self, datetime1, datetime2, msg=None):
"""
@@ -188,9 +186,9 @@ class TestMongoAssetMetadataStorage(TestCase):
store.save_asset_metadata(new_asset_md, ModuleStoreEnum.UserID.test)
# Find the asset's metadata and confirm it's the same.
found_asset_md = store.find_asset_metadata(new_asset_loc)
self.assertIsNotNone(found_asset_md)
self.assertEqual(new_asset_md, found_asset_md)
self.assertEqual(len(store.get_all_asset_metadata(course.id, 'asset')), 1)
assert found_asset_md is not None
assert new_asset_md == found_asset_md
assert len(store.get_all_asset_metadata(course.id, 'asset')) == 1
@ddt.data(*MODULESTORE_SETUPS)
def test_delete(self, storebuilder):
@@ -201,13 +199,13 @@ class TestMongoAssetMetadataStorage(TestCase):
course = CourseFactory.create(modulestore=store)
new_asset_loc = course.id.make_asset_key('asset', 'burnside.jpg')
# Attempt to delete an asset that doesn't exist.
self.assertEqual(store.delete_asset_metadata(new_asset_loc, ModuleStoreEnum.UserID.test), 0)
self.assertEqual(len(store.get_all_asset_metadata(course.id, 'asset')), 0)
assert store.delete_asset_metadata(new_asset_loc, ModuleStoreEnum.UserID.test) == 0
assert len(store.get_all_asset_metadata(course.id, 'asset')) == 0
new_asset_md = self._make_asset_metadata(new_asset_loc)
store.save_asset_metadata(new_asset_md, ModuleStoreEnum.UserID.test)
self.assertEqual(store.delete_asset_metadata(new_asset_loc, ModuleStoreEnum.UserID.test), 1)
self.assertEqual(len(store.get_all_asset_metadata(course.id, 'asset')), 0)
assert store.delete_asset_metadata(new_asset_loc, ModuleStoreEnum.UserID.test) == 1
assert len(store.get_all_asset_metadata(course.id, 'asset')) == 0
@ddt.data(*MODULESTORE_SETUPS)
def test_find_non_existing_assets(self, storebuilder):
@@ -219,7 +217,7 @@ class TestMongoAssetMetadataStorage(TestCase):
new_asset_loc = course.id.make_asset_key('asset', 'burnside.jpg')
# Find existing asset metadata.
asset_md = store.find_asset_metadata(new_asset_loc)
self.assertIsNone(asset_md)
assert asset_md is None
@ddt.data(*MODULESTORE_SETUPS)
def test_get_all_non_existing_assets(self, storebuilder):
@@ -230,7 +228,7 @@ class TestMongoAssetMetadataStorage(TestCase):
course = CourseFactory.create(modulestore=store)
# Find existing asset metadata.
asset_md = store.get_all_asset_metadata(course.id, 'asset')
self.assertEqual(asset_md, [])
assert asset_md == []
@ddt.data(*MODULESTORE_SETUPS)
def test_find_assets_in_non_existent_course(self, storebuilder):
@@ -244,9 +242,9 @@ class TestMongoAssetMetadataStorage(TestCase):
))
new_asset_loc = fake_course_id.make_asset_key('asset', 'burnside.jpg')
# Find asset metadata from non-existent course.
with self.assertRaises(ItemNotFoundError):
with pytest.raises(ItemNotFoundError):
store.find_asset_metadata(new_asset_loc)
with self.assertRaises(ItemNotFoundError):
with pytest.raises(ItemNotFoundError):
store.get_all_asset_metadata(fake_course_id, 'asset')
@ddt.data(*MODULESTORE_SETUPS)
@@ -260,11 +258,11 @@ class TestMongoAssetMetadataStorage(TestCase):
new_asset_md = self._make_asset_metadata(new_asset_loc)
# Add asset metadata.
store.save_asset_metadata(new_asset_md, ModuleStoreEnum.UserID.test)
self.assertEqual(len(store.get_all_asset_metadata(course.id, 'asset')), 1)
assert len(store.get_all_asset_metadata(course.id, 'asset')) == 1
# Add *the same* asset metadata.
store.save_asset_metadata(new_asset_md, ModuleStoreEnum.UserID.test)
# Still one here?
self.assertEqual(len(store.get_all_asset_metadata(course.id, 'asset')), 1)
assert len(store.get_all_asset_metadata(course.id, 'asset')) == 1
@ddt.data(*MODULESTORE_SETUPS)
def test_different_asset_types(self, storebuilder):
@@ -277,8 +275,8 @@ class TestMongoAssetMetadataStorage(TestCase):
new_asset_md = self._make_asset_metadata(new_asset_loc)
# Add asset metadata.
store.save_asset_metadata(new_asset_md, ModuleStoreEnum.UserID.test)
self.assertEqual(len(store.get_all_asset_metadata(course.id, 'vrml')), 1)
self.assertEqual(len(store.get_all_asset_metadata(course.id, 'asset')), 0)
assert len(store.get_all_asset_metadata(course.id, 'vrml')) == 1
assert len(store.get_all_asset_metadata(course.id, 'asset')) == 0
@ddt.data(*MODULESTORE_SETUPS)
def test_asset_types_with_other_field_names(self, storebuilder):
@@ -291,10 +289,10 @@ class TestMongoAssetMetadataStorage(TestCase):
new_asset_md = self._make_asset_metadata(new_asset_loc)
# Add asset metadata.
store.save_asset_metadata(new_asset_md, ModuleStoreEnum.UserID.test)
self.assertEqual(len(store.get_all_asset_metadata(course.id, 'course_id')), 1)
self.assertEqual(len(store.get_all_asset_metadata(course.id, 'asset')), 0)
assert len(store.get_all_asset_metadata(course.id, 'course_id')) == 1
assert len(store.get_all_asset_metadata(course.id, 'asset')) == 0
all_assets = store.get_all_asset_metadata(course.id, 'course_id')
self.assertEqual(all_assets[0].asset_id.path, new_asset_loc.path)
assert all_assets[0].asset_id.path == new_asset_loc.path
@ddt.data(*MODULESTORE_SETUPS)
def test_lock_unlock_assets(self, storebuilder):
@@ -312,13 +310,13 @@ class TestMongoAssetMetadataStorage(TestCase):
store.set_asset_metadata_attr(new_asset_loc, "locked", not locked_state, ModuleStoreEnum.UserID.test)
# Find the same course and check its locked status.
updated_asset_md = store.find_asset_metadata(new_asset_loc)
self.assertIsNotNone(updated_asset_md)
self.assertEqual(updated_asset_md.locked, not locked_state)
assert updated_asset_md is not None
assert updated_asset_md.locked == (not locked_state)
# Now flip it back.
store.set_asset_metadata_attr(new_asset_loc, "locked", locked_state, ModuleStoreEnum.UserID.test)
reupdated_asset_md = store.find_asset_metadata(new_asset_loc)
self.assertIsNotNone(reupdated_asset_md)
self.assertEqual(reupdated_asset_md.locked, locked_state)
assert reupdated_asset_md is not None
assert reupdated_asset_md.locked == locked_state
ALLOWED_ATTRS = (
('pathname', '/new/path'),
@@ -359,9 +357,9 @@ class TestMongoAssetMetadataStorage(TestCase):
store.set_asset_metadata_attr(new_asset_loc, attribute, value, ModuleStoreEnum.UserID.test)
# Find the same course asset and check its changed attribute.
updated_asset_md = store.find_asset_metadata(new_asset_loc)
self.assertIsNotNone(updated_asset_md)
self.assertIsNotNone(getattr(updated_asset_md, attribute, None))
self.assertEqual(getattr(updated_asset_md, attribute, None), value)
assert updated_asset_md is not None
assert getattr(updated_asset_md, attribute, None) is not None
assert getattr(updated_asset_md, attribute, None) == value
@ddt.data(*MODULESTORE_SETUPS)
def test_set_disallowed_attrs(self, storebuilder):
@@ -379,10 +377,10 @@ class TestMongoAssetMetadataStorage(TestCase):
store.set_asset_metadata_attr(new_asset_loc, attribute, value, ModuleStoreEnum.UserID.test)
# Find the same course and check its changed attribute.
updated_asset_md = store.find_asset_metadata(new_asset_loc)
self.assertIsNotNone(updated_asset_md)
self.assertIsNotNone(getattr(updated_asset_md, attribute, None))
assert updated_asset_md is not None
assert getattr(updated_asset_md, attribute, None) is not None
# Make sure that the attribute is unchanged from its original value.
self.assertEqual(getattr(updated_asset_md, attribute, None), original_attr_val)
assert getattr(updated_asset_md, attribute, None) == original_attr_val
@ddt.data(*MODULESTORE_SETUPS)
def test_set_unknown_attrs(self, storebuilder):
@@ -399,10 +397,10 @@ class TestMongoAssetMetadataStorage(TestCase):
store.set_asset_metadata_attr(new_asset_loc, attribute, value, ModuleStoreEnum.UserID.test)
# Find the same course and check its changed attribute.
updated_asset_md = store.find_asset_metadata(new_asset_loc)
self.assertIsNotNone(updated_asset_md)
assert updated_asset_md is not None
# Make sure the unknown field was *not* added.
with self.assertRaises(AttributeError):
self.assertEqual(getattr(updated_asset_md, attribute), value)
with pytest.raises(AttributeError):
assert getattr(updated_asset_md, attribute) == value
@ddt.data(*MODULESTORE_SETUPS)
def test_save_one_different_asset(self, storebuilder):
@@ -416,9 +414,9 @@ class TestMongoAssetMetadataStorage(TestCase):
self._make_asset_metadata(asset_key)
)
store.save_asset_metadata(new_asset_thumbnail, ModuleStoreEnum.UserID.test)
self.assertEqual(len(store.get_all_asset_metadata(course.id, 'different')), 1)
self.assertEqual(store.delete_asset_metadata(asset_key, ModuleStoreEnum.UserID.test), 1)
self.assertEqual(len(store.get_all_asset_metadata(course.id, 'different')), 0)
assert len(store.get_all_asset_metadata(course.id, 'different')) == 1
assert store.delete_asset_metadata(asset_key, ModuleStoreEnum.UserID.test) == 1
assert len(store.get_all_asset_metadata(course.id, 'different')) == 0
@ddt.data(*MODULESTORE_SETUPS)
def test_find_different(self, storebuilder):
@@ -433,17 +431,17 @@ class TestMongoAssetMetadataStorage(TestCase):
)
store.save_asset_metadata(new_asset_thumbnail, ModuleStoreEnum.UserID.test)
self.assertIsNotNone(store.find_asset_metadata(asset_key))
assert store.find_asset_metadata(asset_key) is not None
unknown_asset_key = course.id.make_asset_key('different', 'nosuchfile.jpg')
self.assertIsNone(store.find_asset_metadata(unknown_asset_key))
assert store.find_asset_metadata(unknown_asset_key) is None
def _check_asset_values(self, assets, orig):
"""
Check asset type/path values.
"""
for idx, asset in enumerate(orig):
self.assertEqual(assets[idx].asset_id.asset_type, asset[0])
self.assertEqual(assets[idx].asset_id.path, asset[1])
assert assets[idx].asset_id.asset_type == asset[0]
assert assets[idx].asset_id.path == asset[1]
@ddt.data(*MODULESTORE_SETUPS)
def test_get_multiple_types(self, storebuilder):
@@ -468,17 +466,17 @@ class TestMongoAssetMetadataStorage(TestCase):
('asset', self.regular_assets),
):
assets = store.get_all_asset_metadata(course.id, asset_type)
self.assertEqual(len(assets), len(asset_list))
assert len(assets) == len(asset_list)
self._check_asset_values(assets, asset_list)
self.assertEqual(len(store.get_all_asset_metadata(course.id, 'not_here')), 0)
self.assertEqual(len(store.get_all_asset_metadata(course.id, None)), 4)
assert len(store.get_all_asset_metadata(course.id, 'not_here')) == 0
assert len(store.get_all_asset_metadata(course.id, None)) == 4
assets = store.get_all_asset_metadata(
course.id, None, start=0, maxresults=-1,
sort=('displayname', ModuleStoreEnum.SortOrder.ascending)
)
self.assertEqual(len(assets), len(self.alls))
assert len(assets) == len(self.alls)
self._check_asset_values(assets, self.alls)
@ddt.data(*MODULESTORE_SETUPS)
@@ -507,17 +505,17 @@ class TestMongoAssetMetadataStorage(TestCase):
('asset', self.regular_assets),
):
assets = store.get_all_asset_metadata(course.id, asset_type)
self.assertEqual(len(assets), len(asset_list))
assert len(assets) == len(asset_list)
self._check_asset_values(assets, asset_list)
self.assertEqual(len(store.get_all_asset_metadata(course.id, 'not_here')), 0)
self.assertEqual(len(store.get_all_asset_metadata(course.id, None)), 4)
assert len(store.get_all_asset_metadata(course.id, 'not_here')) == 0
assert len(store.get_all_asset_metadata(course.id, None)) == 4
assets = store.get_all_asset_metadata(
course.id, None, start=0, maxresults=-1,
sort=('displayname', ModuleStoreEnum.SortOrder.ascending)
)
self.assertEqual(len(assets), len(self.alls))
assert len(assets) == len(self.alls)
self._check_asset_values(assets, self.alls)
@ddt.data(*MODULESTORE_SETUPS)
@@ -549,17 +547,17 @@ class TestMongoAssetMetadataStorage(TestCase):
('vrml', self.vrmls),
):
assets = store.get_all_asset_metadata(course1.id, asset_type)
self.assertEqual(len(assets), len(asset_list))
assert len(assets) == len(asset_list)
self._check_asset_values(assets, asset_list)
self.assertEqual(len(store.get_all_asset_metadata(course1.id, 'asset')), 0)
self.assertEqual(len(store.get_all_asset_metadata(course1.id, None)), 3)
assert len(store.get_all_asset_metadata(course1.id, 'asset')) == 0
assert len(store.get_all_asset_metadata(course1.id, None)) == 3
assets = store.get_all_asset_metadata(
course1.id, None, start=0, maxresults=-1,
sort=('displayname', ModuleStoreEnum.SortOrder.ascending)
)
self.assertEqual(len(assets), len(self.differents + self.vrmls))
assert len(assets) == len((self.differents + self.vrmls))
self._check_asset_values(assets, self.differents + self.vrmls)
@ddt.data(*MODULESTORE_SETUPS)
@@ -575,7 +573,7 @@ class TestMongoAssetMetadataStorage(TestCase):
)
store.save_asset_metadata(new_asset_thumbnail, ModuleStoreEnum.UserID.test)
self.assertEqual(len(store.get_all_asset_metadata(course.id, 'different')), 1)
assert len(store.get_all_asset_metadata(course.id, 'different')) == 1
@ddt.data(*MODULESTORE_SETUPS)
def test_get_all_assets_with_paging(self, storebuilder):
@@ -617,38 +615,38 @@ class TestMongoAssetMetadataStorage(TestCase):
)
num_expected_results = sort_test[2][i]
expected_filename = sort_test[1][2 * i]
self.assertEqual(len(asset_page), num_expected_results)
self.assertEqual(asset_page[0].asset_id.path, expected_filename)
assert len(asset_page) == num_expected_results
assert asset_page[0].asset_id.path == expected_filename
if num_expected_results == 2:
expected_filename = sort_test[1][(2 * i) + 1]
self.assertEqual(asset_page[1].asset_id.path, expected_filename)
assert asset_page[1].asset_id.path == expected_filename
# Now fetch everything.
asset_page = store.get_all_asset_metadata(
course2.id, 'asset', start=0, sort=('displayname', ModuleStoreEnum.SortOrder.ascending)
)
self.assertEqual(len(asset_page), 5)
self.assertEqual(asset_page[0].asset_id.path, 'code.tgz')
self.assertEqual(asset_page[1].asset_id.path, 'demo.swf')
self.assertEqual(asset_page[2].asset_id.path, 'dog.png')
self.assertEqual(asset_page[3].asset_id.path, 'roman_history.pdf')
self.assertEqual(asset_page[4].asset_id.path, 'weather_patterns.bmp')
assert len(asset_page) == 5
assert asset_page[0].asset_id.path == 'code.tgz'
assert asset_page[1].asset_id.path == 'demo.swf'
assert asset_page[2].asset_id.path == 'dog.png'
assert asset_page[3].asset_id.path == 'roman_history.pdf'
assert asset_page[4].asset_id.path == 'weather_patterns.bmp'
# Some odd conditions.
asset_page = store.get_all_asset_metadata(
course2.id, 'asset', start=100, sort=('uploadDate', ModuleStoreEnum.SortOrder.ascending)
)
self.assertEqual(len(asset_page), 0)
assert len(asset_page) == 0
asset_page = store.get_all_asset_metadata(
course2.id, 'asset', start=3, maxresults=0,
sort=('displayname', ModuleStoreEnum.SortOrder.ascending)
)
self.assertEqual(len(asset_page), 0)
assert len(asset_page) == 0
asset_page = store.get_all_asset_metadata(
course2.id, 'asset', start=3, maxresults=-12345,
sort=('displayname', ModuleStoreEnum.SortOrder.descending)
)
self.assertEqual(len(asset_page), 2)
assert len(asset_page) == 2
@ddt.data('XML_MODULESTORE_BUILDER', 'MIXED_MODULESTORE_BUILDER')
def test_xml_not_yet_implemented(self, storebuilderName):
@@ -659,8 +657,8 @@ class TestMongoAssetMetadataStorage(TestCase):
with storebuilder.build(contentstore=None) as (__, store):
course_key = store.make_course_key("org", "course", "run")
asset_key = course_key.make_asset_key('asset', 'foo.jpg')
self.assertEqual(store.find_asset_metadata(asset_key), None)
self.assertEqual(store.get_all_asset_metadata(course_key, 'asset'), [])
assert store.find_asset_metadata(asset_key) is None
assert store.get_all_asset_metadata(course_key, 'asset') == []
@ddt.data(*MODULESTORE_SETUPS)
def test_copy_all_assets_same_modulestore(self, storebuilder):
@@ -671,16 +669,16 @@ class TestMongoAssetMetadataStorage(TestCase):
course1 = CourseFactory.create(modulestore=store)
course2 = CourseFactory.create(modulestore=store)
self.setup_assets(course1.id, None, store)
self.assertEqual(len(store.get_all_asset_metadata(course1.id, 'asset')), 2)
self.assertEqual(len(store.get_all_asset_metadata(course2.id, 'asset')), 0)
assert len(store.get_all_asset_metadata(course1.id, 'asset')) == 2
assert len(store.get_all_asset_metadata(course2.id, 'asset')) == 0
store.copy_all_asset_metadata(course1.id, course2.id, ModuleStoreEnum.UserID.test * 101)
self.assertEqual(len(store.get_all_asset_metadata(course1.id, 'asset')), 2)
assert len(store.get_all_asset_metadata(course1.id, 'asset')) == 2
all_assets = store.get_all_asset_metadata(
course2.id, 'asset', sort=('displayname', ModuleStoreEnum.SortOrder.ascending)
)
self.assertEqual(len(all_assets), 2)
self.assertEqual(all_assets[0].asset_id.path, 'pic1.jpg')
self.assertEqual(all_assets[1].asset_id.path, 'shout.ogg')
assert len(all_assets) == 2
assert all_assets[0].asset_id.path == 'pic1.jpg'
assert all_assets[1].asset_id.path == 'shout.ogg'
@ddt.data(*MODULESTORE_SETUPS)
def test_copy_all_assets_from_course_with_no_assets(self, storebuilder):
@@ -691,12 +689,12 @@ class TestMongoAssetMetadataStorage(TestCase):
course1 = CourseFactory.create(modulestore=store)
course2 = CourseFactory.create(modulestore=store)
store.copy_all_asset_metadata(course1.id, course2.id, ModuleStoreEnum.UserID.test * 101)
self.assertEqual(len(store.get_all_asset_metadata(course1.id, 'asset')), 0)
self.assertEqual(len(store.get_all_asset_metadata(course2.id, 'asset')), 0)
assert len(store.get_all_asset_metadata(course1.id, 'asset')) == 0
assert len(store.get_all_asset_metadata(course2.id, 'asset')) == 0
all_assets = store.get_all_asset_metadata(
course2.id, 'asset', sort=('displayname', ModuleStoreEnum.SortOrder.ascending)
)
self.assertEqual(len(all_assets), 0)
assert len(all_assets) == 0
@ddt.data(
('mongo', 'split'),
@@ -714,12 +712,12 @@ class TestMongoAssetMetadataStorage(TestCase):
with mixed_store.default_store(to_store):
course2 = CourseFactory.create(modulestore=mixed_store)
self.setup_assets(course1.id, None, mixed_store)
self.assertEqual(len(mixed_store.get_all_asset_metadata(course1.id, 'asset')), 2)
self.assertEqual(len(mixed_store.get_all_asset_metadata(course2.id, 'asset')), 0)
assert len(mixed_store.get_all_asset_metadata(course1.id, 'asset')) == 2
assert len(mixed_store.get_all_asset_metadata(course2.id, 'asset')) == 0
mixed_store.copy_all_asset_metadata(course1.id, course2.id, ModuleStoreEnum.UserID.test * 102)
all_assets = mixed_store.get_all_asset_metadata(
course2.id, 'asset', sort=('displayname', ModuleStoreEnum.SortOrder.ascending)
)
self.assertEqual(len(all_assets), 2)
self.assertEqual(all_assets[0].asset_id.path, 'pic1.jpg')
self.assertEqual(all_assets[1].asset_id.path, 'shout.ogg')
assert len(all_assets) == 2
assert all_assets[0].asset_id.path == 'pic1.jpg'
assert all_assets[1].asset_id.path == 'shout.ogg'

View File

@@ -10,6 +10,7 @@ import unittest
from tempfile import mkdtemp
from uuid import uuid4
import pytest
import ddt
import path
from opaque_keys.edx.keys import AssetKey
@@ -101,7 +102,7 @@ class TestContentstore(unittest.TestCase):
asset_key = self.course1_key.make_asset_key('asset', self.course1_files[0])
self.contentstore.delete(asset_key)
with self.assertRaises(NotFoundError):
with pytest.raises(NotFoundError):
self.contentstore.find(asset_key)
# ensure deleting a non-existent file is a noop
@@ -114,17 +115,15 @@ class TestContentstore(unittest.TestCase):
"""
self.set_up_assets(deprecated)
asset_key = self.course1_key.make_asset_key('asset', self.course1_files[0])
self.assertIsNotNone(self.contentstore.find(asset_key), "Could not find {}".format(asset_key))
assert self.contentstore.find(asset_key) is not None, 'Could not find {}'.format(asset_key)
self.assertIsNotNone(self.contentstore.find(asset_key, as_stream=True), "Could not find {}".format(asset_key))
assert self.contentstore.find(asset_key, as_stream=True) is not None, 'Could not find {}'.format(asset_key)
unknown_asset = self.course1_key.make_asset_key('asset', 'no_such_file.gif')
with self.assertRaises(NotFoundError):
with pytest.raises(NotFoundError):
self.contentstore.find(unknown_asset)
self.assertIsNone(
self.contentstore.find(unknown_asset, throw_on_not_found=False),
"Found unknown asset {}".format(unknown_asset)
)
assert self.contentstore.find(unknown_asset, throw_on_not_found=False) is None,\
f'Found unknown asset {unknown_asset}'
@ddt.data(True, False)
def test_export_for_course(self, deprecated):
@@ -140,11 +139,11 @@ class TestContentstore(unittest.TestCase):
)
for filename in self.course1_files:
filepath = path.Path(root_dir / filename)
self.assertTrue(filepath.isfile(), "{} is not a file".format(filepath))
assert filepath.isfile(), '{} is not a file'.format(filepath)
for filename in self.course2_files:
if filename not in self.course1_files:
filepath = path.Path(root_dir / filename)
self.assertFalse(filepath.isfile(), "{} is unexpected exported a file".format(filepath))
assert not filepath.isfile(), '{} is unexpected exported a file'.format(filepath)
finally:
shutil.rmtree(root_dir)
@@ -155,18 +154,18 @@ class TestContentstore(unittest.TestCase):
"""
self.set_up_assets(deprecated)
course1_assets, count = self.contentstore.get_all_content_for_course(self.course1_key)
self.assertEqual(count, len(self.course1_files), course1_assets)
assert count == len(self.course1_files), course1_assets
for asset in course1_assets:
parsed = AssetKey.from_string(asset['filename'])
self.assertIn(parsed.block_id, self.course1_files)
assert parsed.block_id in self.course1_files
course1_assets, __ = self.contentstore.get_all_content_for_course(self.course1_key, 1, 1)
self.assertEqual(len(course1_assets), 1, course1_assets)
assert len(course1_assets) == 1, course1_assets
fake_course = CourseLocator('test', 'fake', 'non')
course_assets, count = self.contentstore.get_all_content_for_course(fake_course)
self.assertEqual(count, 0)
self.assertEqual(course_assets, [])
assert count == 0
assert course_assets == []
@ddt.data(True, False)
def test_attrs(self, deprecated):
@@ -178,7 +177,7 @@ class TestContentstore(unittest.TestCase):
asset_key = self.course1_key.make_asset_key('asset', filename)
prelocked = self.contentstore.get_attr(asset_key, 'locked', False)
self.contentstore.set_attr(asset_key, 'locked', not prelocked)
self.assertEqual(self.contentstore.get_attr(asset_key, 'locked', False), not prelocked)
assert self.contentstore.get_attr(asset_key, 'locked', False) == (not prelocked)
@ddt.data(True, False)
def test_copy_assets(self, deprecated):
@@ -194,10 +193,10 @@ class TestContentstore(unittest.TestCase):
source = self.contentstore.find(asset_key)
copied = self.contentstore.find(dest_key)
for propname in ['name', 'content_type', 'length', 'locked']:
self.assertEqual(getattr(source, propname), getattr(copied, propname))
assert getattr(source, propname) == getattr(copied, propname)
__, count = self.contentstore.get_all_content_for_course(dest_course)
self.assertEqual(count, len(self.course1_files))
assert count == len(self.course1_files)
@ddt.data(True, False)
def test_copy_assets_with_duplicates(self, deprecated):
@@ -209,7 +208,7 @@ class TestContentstore(unittest.TestCase):
self.contentstore.copy_all_course_assets(self.course1_key, dest_course)
__, count = self.contentstore.get_all_content_for_course(dest_course)
self.assertEqual(count, 5)
assert count == 5
@ddt.data(True, False)
def test_delete_assets(self, deprecated):
@@ -219,7 +218,7 @@ class TestContentstore(unittest.TestCase):
self.set_up_assets(deprecated)
self.contentstore.delete_all_course_assets(self.course1_key)
__, count = self.contentstore.get_all_content_for_course(self.course1_key)
self.assertEqual(count, 0)
assert count == 0
# ensure it didn't remove any from other course
__, count = self.contentstore.get_all_content_for_course(self.course2_key)
self.assertEqual(count, len(self.course2_files))
assert count == len(self.course2_files)

View File

@@ -188,12 +188,12 @@ class CrossStoreXMLRoundtrip(CourseComparisonTest, PartitionTestCase):
source_course = source_store.get_course(source_course_key, depth=None, lazy=False) # lint-amnesty, pylint: disable=no-member
self.assertEqual(source_course.url_name, 'course')
assert source_course.url_name == 'course'
export_dir_path = path(self.export_dir)
policy_dir = export_dir_path / 'exported_source_course' / 'policies' / source_course_key.run
policy_path = policy_dir / 'policy.json'
self.assertTrue(os.path.exists(policy_path))
assert os.path.exists(policy_path)
import_course_from_xml(
dest_store,
@@ -208,4 +208,4 @@ class CrossStoreXMLRoundtrip(CourseComparisonTest, PartitionTestCase):
dest_course = dest_store.get_course(dest_course_key, depth=None, lazy=False) # lint-amnesty, pylint: disable=no-member
self.assertEqual(dest_course.url_name, 'course')
assert dest_course.url_name == 'course'

View File

@@ -64,4 +64,4 @@ class TestInheritanceMixin(unittest.TestCase):
confirm if the submission deadline has passed or not.
"""
self.add_submission_deadline_information(due_date, graceperiod, self_paced)
self.assertEqual(is_past_deadline, self.xblock.has_deadline_passed())
assert is_past_deadline == self.xblock.has_deadline_passed()

View File

@@ -5,7 +5,7 @@ Basic unit tests related to content libraries.
Higher-level tests are in `cms/djangoapps/contentstore`.
"""
import pytest
import ddt
import six
from bson.objectid import ObjectId
@@ -45,7 +45,7 @@ class TestLibraries(MixedSplitTestCase):
"""
org, lib_code = ('DuplicateX', "DUP")
LibraryFactory.create(org=org, library=lib_code, modulestore=self.store)
with self.assertRaises(DuplicateCourseError):
with pytest.raises(DuplicateCourseError):
LibraryFactory.create(org=org, library=lib_code, modulestore=self.store)
@ddt.data(
@@ -57,9 +57,9 @@ class TestLibraries(MixedSplitTestCase):
Test __unicode__() and __str__() methods of libraries
"""
library = LibraryFactory.create(metadata={"display_name": name}, modulestore=self.store)
self.assertIn(name, six.text_type(library))
assert name in six.text_type(library)
if not isinstance(name, six.text_type):
self.assertIn(name, str(library))
assert name in str(library)
def test_display_with_default_methods(self):
"""
@@ -69,8 +69,8 @@ class TestLibraries(MixedSplitTestCase):
org = 'TestOrgX'
lib_code = 'LC101'
library = LibraryFactory.create(org=org, library=lib_code, modulestore=self.store)
self.assertEqual(library.display_org_with_default, org)
self.assertEqual(library.display_number_with_default, lib_code)
assert library.display_org_with_default == org
assert library.display_number_with_default == lib_code
def test_block_with_children(self):
"""
@@ -94,7 +94,7 @@ class TestLibraries(MixedSplitTestCase):
metadata={"data": "Hello world", },
modulestore=self.store,
)
self.assertEqual(child_block.parent.replace(version_guid=None, branch=None), vert_block.location)
assert child_block.parent.replace(version_guid=None, branch=None) == vert_block.location
def test_update_item(self):
"""
@@ -116,10 +116,10 @@ class TestLibraries(MixedSplitTestCase):
self.store.update_item(block, self.user_id)
# Reload block from the modulestore
block = self.store.get_item(block_key)
self.assertEqual(block.data, "NEW")
self.assertEqual(block.location, block_key)
assert block.data == 'NEW'
assert block.location == block_key
new_version = self.store.get_item(block_key, remove_version=False, remove_branch=False).location.version_guid
self.assertNotEqual(old_version, new_version)
assert old_version != new_version
def test_delete_item(self):
"""
@@ -135,15 +135,15 @@ class TestLibraries(MixedSplitTestCase):
modulestore=self.store,
)
library = self.store.get_library(lib_key)
self.assertEqual(len(library.children), 1)
assert len(library.children) == 1
self.store.delete_item(block.location, self.user_id)
library = self.store.get_library(lib_key)
self.assertEqual(len(library.children), 0)
assert len(library.children) == 0
def test_get_library_non_existent(self):
""" Test get_library() with non-existent key """
result = self.store.get_library(LibraryLocator("non", "existent"))
self.assertEqual(result, None)
assert result is None
def test_get_library_keys(self):
""" Test get_library_keys() """
@@ -159,9 +159,9 @@ class TestLibraries(MixedSplitTestCase):
lib_list = self.store.get_libraries()
self.assertEqual(len(lib_list), len(libraries))
assert len(lib_list) == len(libraries)
for lib in lib_list:
self.assertIn(lib.location.library_key, lib_dict)
assert lib.location.library_key in lib_dict
def test_strip(self):
"""
@@ -172,10 +172,10 @@ class TestLibraries(MixedSplitTestCase):
lib_key = LibraryFactory.create(modulestore=self.store).location.library_key
# Re-load the library from the modulestore, explicitly including version information:
lib = self.store.get_library(lib_key)
self.assertEqual(lib.location.version_guid, None)
self.assertEqual(lib.location.branch, None)
self.assertEqual(lib.location.library_key.version_guid, None)
self.assertEqual(lib.location.library_key.branch, None)
assert lib.location.version_guid is None
assert lib.location.branch is None
assert lib.location.library_key.version_guid is None
assert lib.location.library_key.branch is None
def test_get_lib_version(self):
"""
@@ -186,7 +186,7 @@ class TestLibraries(MixedSplitTestCase):
# Re-load the library from the modulestore, explicitly including version information:
lib = self.store.get_library(lib_key, remove_version=False, remove_branch=False)
version = lib.location.library_key.version_guid
self.assertIsInstance(version, ObjectId)
assert isinstance(version, ObjectId)
def test_xblock_in_lib_have_published_version_returns_false(self):
library = LibraryFactory.create(modulestore=self.store)
@@ -197,4 +197,4 @@ class TestLibraries(MixedSplitTestCase):
publish_item=False,
modulestore=self.store,
)
self.assertFalse(self.store.has_published_version(block))
assert not self.store.has_published_version(block)

View File

@@ -166,7 +166,7 @@ class CommonMixedModuleStoreSetup(CourseComparisonTest):
if isinstance(self.course.id, CourseLocator):
self.course_locations[self.MONGO_COURSEID] = self.course.location
else:
self.assertEqual(self.course.id, course_key)
assert self.course.id == course_key
# create chapter
chapter = self.store.create_child(self.user_id, self.course.location, 'chapter',
@@ -283,7 +283,7 @@ class CommonMixedModuleStoreSetup(CourseComparisonTest):
).make_usage_key('vertical', 'fake')
self._create_course(test_course_key)
self.assertEqual(default, self.store.get_modulestore_type(self.course.id))
assert default == self.store.get_modulestore_type(self.course.id)
class AsideFoo(XBlockAside):
@@ -328,13 +328,9 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
Make sure we get back the store type we expect for given mappings
"""
self.initdb(default_ms)
self.assertEqual(self.store.get_modulestore_type(
self._course_key_from_string(self.MONGO_COURSEID)), default_ms
)
assert self.store.get_modulestore_type(self._course_key_from_string(self.MONGO_COURSEID)) == default_ms
# try an unknown mapping, it should be the 'default' store
self.assertEqual(self.store.get_modulestore_type(
CourseKey.from_string('foo/bar/2012_Fall')), default_ms
)
assert self.store.get_modulestore_type(CourseKey.from_string('foo/bar/2012_Fall')) == default_ms
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_get_modulestore_cache(self, default_ms):
@@ -346,9 +342,9 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self.store.mappings = {}
course_key = self.course_locations[self.MONGO_COURSEID].course_key
with check_exact_number_of_calls(self.store.default_modulestore, 'has_course', 1):
self.assertEqual(self.store.default_modulestore, self.store._get_modulestore_for_courselike(course_key)) # pylint: disable=protected-access
self.assertIn(course_key, self.store.mappings)
self.assertEqual(self.store.default_modulestore, self.store._get_modulestore_for_courselike(course_key)) # pylint: disable=protected-access
assert self.store.default_modulestore == self.store._get_modulestore_for_courselike(course_key) # pylint: disable=protected-access, line-too-long
assert course_key in self.store.mappings
assert self.store.default_modulestore == self.store._get_modulestore_for_courselike(course_key) # pylint: disable=protected-access, line-too-long
@ddt.data(*itertools.product(
(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split),
@@ -364,7 +360,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self.store.create_course('org_x', 'course_y', 'run_z', self.user_id)
if reset_mixed_mappings:
self.store.mappings = {}
with self.assertRaises(DuplicateCourseError):
with pytest.raises(DuplicateCourseError):
self.store.create_course('org_x', 'course_y', 'run_z', self.user_id)
@ddt.data(ModuleStoreEnum.Type.split, ModuleStoreEnum.Type.mongo)
@@ -376,7 +372,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
with self.store.default_store(default_store):
self.store.create_course('org_x', 'course_y', 'run_z', self.user_id)
with self.assertRaises(DuplicateCourseError):
with pytest.raises(DuplicateCourseError):
self.store.create_course('ORG_X', 'COURSE_Y', 'RUN_Z', self.user_id)
# Draft:
@@ -390,14 +386,14 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self._create_block_hierarchy()
with check_mongo_calls(max_find.pop(0), max_send):
self.assertTrue(self.store.has_item(self.problem_x1a_1)) # lint-amnesty, pylint: disable=no-member
assert self.store.has_item(self.problem_x1a_1) # lint-amnesty, pylint: disable=no-member
# try negative cases
with check_mongo_calls(max_find.pop(0), max_send):
self.assertFalse(self.store.has_item(self.fake_location))
assert not self.store.has_item(self.fake_location)
# verify that an error is raised when the revision is not valid
with self.assertRaises(UnsupportedRevisionError):
with pytest.raises(UnsupportedRevisionError):
self.store.has_item(self.fake_location, revision=ModuleStoreEnum.RevisionOption.draft_preferred)
# draft queries:
@@ -413,15 +409,15 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self._create_block_hierarchy()
with check_mongo_calls(max_find.pop(0), max_send):
self.assertIsNotNone(self.store.get_item(self.problem_x1a_1)) # lint-amnesty, pylint: disable=no-member
assert self.store.get_item(self.problem_x1a_1) is not None # lint-amnesty, pylint: disable=no-member
# try negative cases
with check_mongo_calls(max_find.pop(0), max_send):
with self.assertRaises(ItemNotFoundError):
with pytest.raises(ItemNotFoundError):
self.store.get_item(self.fake_location)
# verify that an error is raised when the revision is not valid
with self.assertRaises(UnsupportedRevisionError):
with pytest.raises(UnsupportedRevisionError):
self.store.get_item(self.fake_location, revision=ModuleStoreEnum.RevisionOption.draft_preferred)
# Draft:
@@ -437,10 +433,10 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
course_locn = self.course_locations[self.MONGO_COURSEID]
with check_mongo_calls(max_find, max_send):
modules = self.store.get_items(course_locn.course_key, qualifiers={'category': 'problem'})
self.assertEqual(len(modules), 6)
assert len(modules) == 6
# verify that an error is raised when the revision is not valid
with self.assertRaises(UnsupportedRevisionError):
with pytest.raises(UnsupportedRevisionError):
self.store.get_items(
self.course_locations[self.MONGO_COURSEID].course_key,
revision=ModuleStoreEnum.RevisionOption.draft_preferred
@@ -455,19 +451,19 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
course_version = course.course_version
if default_ms == ModuleStoreEnum.Type.split:
self.assertIsNotNone(course_version)
assert course_version is not None
else:
self.assertIsNone(course_version)
assert course_version is None
blocks = self.store.get_items(self.course.id, qualifiers={'category': 'problem'})
blocks.append(self.store.get_item(self.problem_x1a_1)) # lint-amnesty, pylint: disable=no-member
self.assertEqual(len(blocks), 7)
assert len(blocks) == 7
for block in blocks:
self.assertEqual(block.course_version, course_version)
assert block.course_version == course_version
# ensure that when the block is retrieved from the runtime cache,
# the course version is still present
cached_block = course.runtime.load_item(block.location)
self.assertEqual(cached_block.course_version, block.course_version)
assert cached_block.course_version == block.course_version
@ddt.data((ModuleStoreEnum.Type.split, 2, False), (ModuleStoreEnum.Type.mongo, 3, True))
@ddt.unpack
@@ -496,17 +492,15 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
items = self.store.get_items(course_key)
# Check items found are either course or about type
self.assertTrue(set(['course', 'about']).issubset(set([item.location.block_type for item in items]))) # lint-amnesty, pylint: disable=consider-using-set-comprehension
assert set(['course', 'about']).issubset(set([item.location.block_type for item in items])) # pylint: disable=consider-using-set-comprehension, line-too-long
# Assert that about is a detached category found in get_items
self.assertIn(
[item.location.block_type for item in items if item.location.block_type == 'about'][0],
DETACHED_XBLOCK_TYPES
)
self.assertEqual(len(items), 2)
assert [item.location.block_type for item in items if item.location.block_type == 'about'][0]\
in DETACHED_XBLOCK_TYPES
assert len(items) == 2
# Check that orphans are not found
orphans = self.store.get_orphans(course_key)
self.assertEqual(len(orphans), 0)
assert len(orphans) == 0
# Add an orphan to test course
orphan = course_key.make_usage_key('chapter', 'OrphanChapter')
@@ -514,22 +508,22 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
# Check that now an orphan is found
orphans = self.store.get_orphans(course_key)
self.assertIn(orphan, orphans)
self.assertEqual(len(orphans), 1)
assert orphan in orphans
assert len(orphans) == 1
# Check now `get_items` retrieves an extra item added above which is an orphan.
items = self.store.get_items(course_key)
self.assertIn(orphan, [item.location for item in items])
self.assertEqual(len(items), 3)
assert orphan in [item.location for item in items]
assert len(items) == 3
# Check now `get_items` with `include_orphans` kwarg does not retrieves an orphan block.
items_in_tree = self.store.get_items(course_key, include_orphans=False)
# Check that course and about blocks are found in get_items
self.assertTrue(set(['course', 'about']).issubset(set([item.location.block_type for item in items_in_tree]))) # lint-amnesty, pylint: disable=consider-using-set-comprehension
assert set(['course', 'about']).issubset({item.location.block_type for item in items_in_tree})
# Check orphan is found or not - this is based on mongo/split modulestore. It should be found in mongo.
self.assertEqual(orphan in [item.location for item in items_in_tree], orphan_in_items)
self.assertEqual(len(items_in_tree), expected_items_in_tree)
assert (orphan in [item.location for item in items_in_tree]) == orphan_in_items
assert len(items_in_tree) == expected_items_in_tree
# draft: get draft, get ancestors up to course (2-6), compute inheritance
# sends: update problem and then each ancestor up to course (edit info)
@@ -545,12 +539,12 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self._create_block_hierarchy()
problem = self.store.get_item(self.problem_x1a_1) # lint-amnesty, pylint: disable=no-member
# if following raised, then the test is really a noop, change it
self.assertNotEqual(problem.max_attempts, 2, "Default changed making test meaningless")
assert problem.max_attempts != 2, 'Default changed making test meaningless'
problem.max_attempts = 2
with check_mongo_calls(max_find, max_send):
problem = self.store.update_item(problem, self.user_id)
self.assertEqual(problem.max_attempts, 2, "Update didn't persist")
assert problem.max_attempts == 2, "Update didn't persist"
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_has_changes_direct_only(self, default_ms):
@@ -570,8 +564,8 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
)
# Check that neither xblock has changes
self.assertFalse(self.store.has_changes(test_course))
self.assertFalse(self.store.has_changes(chapter))
assert not self.store.has_changes(test_course)
assert not self.store.has_changes(chapter)
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_has_changes(self, default_ms):
@@ -591,22 +585,22 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
)
# Not yet published, so changes are present
self.assertTrue(self.store.has_changes(xblock))
assert self.store.has_changes(xblock)
# Publish and verify that there are no unpublished changes
newXBlock = self.store.publish(xblock.location, self.user_id)
self.assertFalse(self.store.has_changes(newXBlock))
assert not self.store.has_changes(newXBlock)
# Change the component, then check that there now are changes
component = self.store.get_item(xblock.location)
component.display_name = 'Changed Display Name'
component = self.store.update_item(component, self.user_id)
self.assertTrue(self.store.has_changes(component))
assert self.store.has_changes(component)
# Publish and verify again
component = self.store.publish(component.location, self.user_id)
self.assertFalse(self.store.has_changes(component))
assert not self.store.has_changes(component)
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_unit_stuck_in_draft_mode(self, default_ms):
@@ -626,19 +620,19 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
)
# Not yet published, so changes are present
self.assertTrue(self.store.has_changes(xblock))
assert self.store.has_changes(xblock)
# Publish and verify that there are no unpublished changes
component = self.store.publish(xblock.location, self.user_id)
self.assertFalse(self.store.has_changes(component))
assert not self.store.has_changes(component)
self.store.revert_to_published(component.location, self.user_id)
component = self.store.get_item(component.location)
self.assertFalse(self.store.has_changes(component))
assert not self.store.has_changes(component)
# Publish and verify again
component = self.store.publish(component.location, self.user_id)
self.assertFalse(self.store.has_changes(component))
assert not self.store.has_changes(component)
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_unit_stuck_in_published_mode(self, default_ms):
@@ -658,16 +652,16 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
)
# Not yet published, so changes are present
self.assertTrue(self.store.has_changes(xblock))
assert self.store.has_changes(xblock)
# Publish and verify that there are no unpublished changes
component = self.store.publish(xblock.location, self.user_id)
self.assertFalse(self.store.has_changes(component))
assert not self.store.has_changes(component)
# Discard changes and verify that there are no changes
self.store.revert_to_published(component.location, self.user_id)
component = self.store.get_item(component.location)
self.assertFalse(self.store.has_changes(component))
assert not self.store.has_changes(component)
# Change the component, then check that there now are changes
component = self.store.get_item(component.location)
@@ -675,7 +669,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self.store.update_item(component, self.user_id)
# Verify that changes are present
self.assertTrue(self.store.has_changes(component))
assert self.store.has_changes(component)
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_unit_stuck_in_published_mode_after_delete(self, default_ms):
@@ -703,22 +697,22 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
# publish vertical changes
self.store.publish(vertical.location, self.user_id)
self.assertFalse(self._has_changes(vertical.location))
assert not self._has_changes(vertical.location)
# Change a component, then check that there now are changes
component = self.store.get_item(component.location)
component.display_name = 'Changed Display Name'
self.store.update_item(component, self.user_id)
self.assertTrue(self._has_changes(vertical.location))
assert self._has_changes(vertical.location)
# Discard changes and verify that there are no changes
self.store.revert_to_published(vertical.location, self.user_id)
self.assertFalse(self._has_changes(vertical.location))
assert not self._has_changes(vertical.location)
# Delete the component and verify that the unit has changes
self.store.delete_item(component.location, self.user_id)
vertical = self.store.get_item(vertical.location)
self.assertTrue(self._has_changes(vertical.location))
assert self._has_changes(vertical.location)
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_publish_automatically_after_delete_unit(self, default_ms):
@@ -735,11 +729,11 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
# publish sequential changes
self.store.publish(sequential.location, self.user_id)
self.assertFalse(self._has_changes(sequential.location))
assert not self._has_changes(sequential.location)
# delete vertical and check sequential has no changes
self.store.delete_item(vertical.location, self.user_id)
self.assertFalse(self._has_changes(sequential.location))
assert not self._has_changes(sequential.location)
def setup_has_changes(self, default_ms):
"""
@@ -772,7 +766,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
# Verify that there are no unpublished changes
for key in locations:
self.assertFalse(self._has_changes(locations[key]))
assert not self._has_changes(locations[key])
# Change the child
child = self.store.get_item(locations['child'])
@@ -780,18 +774,18 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self.store.update_item(child, self.user_id)
# All ancestors should have changes, but not siblings
self.assertTrue(self._has_changes(locations['grandparent']))
self.assertTrue(self._has_changes(locations['parent']))
self.assertTrue(self._has_changes(locations['child']))
self.assertFalse(self._has_changes(locations['parent_sibling']))
self.assertFalse(self._has_changes(locations['child_sibling']))
assert self._has_changes(locations['grandparent'])
assert self._has_changes(locations['parent'])
assert self._has_changes(locations['child'])
assert not self._has_changes(locations['parent_sibling'])
assert not self._has_changes(locations['child_sibling'])
# Publish the unit with changes
self.store.publish(locations['parent'], self.user_id)
# Verify that there are no unpublished changes
for key in locations:
self.assertFalse(self._has_changes(locations[key]))
assert not self._has_changes(locations[key])
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_has_changes_publish_ancestors(self, default_ms):
@@ -802,7 +796,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
# Verify that there are no unpublished changes
for key in locations:
self.assertFalse(self._has_changes(locations[key]))
assert not self._has_changes(locations[key])
# Change both children
child = self.store.get_item(locations['child'])
@@ -813,22 +807,22 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self.store.update_item(child_sibling, user_id=self.user_id)
# Verify that ancestors have changes
self.assertTrue(self._has_changes(locations['grandparent']))
self.assertTrue(self._has_changes(locations['parent']))
assert self._has_changes(locations['grandparent'])
assert self._has_changes(locations['parent'])
# Publish one child
self.store.publish(locations['child_sibling'], self.user_id)
# Verify that ancestors still have changes
self.assertTrue(self._has_changes(locations['grandparent']))
self.assertTrue(self._has_changes(locations['parent']))
assert self._has_changes(locations['grandparent'])
assert self._has_changes(locations['parent'])
# Publish the other child
self.store.publish(locations['child'], self.user_id)
# Verify that ancestors now have no changes
self.assertFalse(self._has_changes(locations['grandparent']))
self.assertFalse(self._has_changes(locations['parent']))
assert not self._has_changes(locations['grandparent'])
assert not self._has_changes(locations['parent'])
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_has_changes_add_remove_child(self, default_ms):
@@ -839,8 +833,8 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
locations = self.setup_has_changes(default_ms)
# Test that the ancestors don't have changes
self.assertFalse(self._has_changes(locations['grandparent']))
self.assertFalse(self._has_changes(locations['parent']))
assert not self._has_changes(locations['grandparent'])
assert not self._has_changes(locations['parent'])
# Create a new child and attach it to parent
self.store.create_child(
@@ -851,8 +845,8 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
)
# Verify that the ancestors now have changes
self.assertTrue(self._has_changes(locations['grandparent']))
self.assertTrue(self._has_changes(locations['parent']))
assert self._has_changes(locations['grandparent'])
assert self._has_changes(locations['parent'])
# Remove the child from the parent
parent = self.store.get_item(locations['parent'])
@@ -860,8 +854,8 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self.store.update_item(parent, user_id=self.user_id)
# Verify that ancestors now have no changes
self.assertFalse(self._has_changes(locations['grandparent']))
self.assertFalse(self._has_changes(locations['parent']))
assert not self._has_changes(locations['grandparent'])
assert not self._has_changes(locations['parent'])
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_has_changes_non_direct_only_children(self, default_ms):
@@ -885,16 +879,16 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self.store.publish(parent.location, self.user_id)
# Verify that there are no changes
self.assertFalse(self._has_changes(parent.location))
self.assertFalse(self._has_changes(child.location))
assert not self._has_changes(parent.location)
assert not self._has_changes(child.location)
# Change the child
child.display_name = 'Changed Display Name'
self.store.update_item(child, user_id=self.user_id)
# Verify that both parent and child have changes
self.assertTrue(self._has_changes(parent.location))
self.assertTrue(self._has_changes(child.location))
assert self._has_changes(parent.location)
assert self._has_changes(child.location)
@ddt.data(*itertools.product(
(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split),
@@ -919,7 +913,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
parent = self.store.update_item(parent, self.user_id)
# Check the parent for changes should return True and not throw an exception
self.assertTrue(self.store.has_changes(parent))
assert self.store.has_changes(parent)
# Draft
# Find: find parents (definition.children query), get parent, get course (fill in run?),
@@ -944,10 +938,10 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self.store.delete_item(self.writable_chapter_location, self.user_id)
# verify it's gone
with self.assertRaises(ItemNotFoundError):
with pytest.raises(ItemNotFoundError):
self.store.get_item(self.writable_chapter_location)
# verify it's gone from published too
with self.assertRaises(ItemNotFoundError):
with pytest.raises(ItemNotFoundError):
self.store.get_item(self.writable_chapter_location, revision=ModuleStoreEnum.RevisionOption.published_only)
# Draft:
@@ -984,10 +978,10 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
vert_loc = private_vert.location.for_version(private_leaf.location.version_guid)
else:
vert_loc = private_vert.location
self.assertTrue(self.store.has_item(vert_loc))
self.assertTrue(self.store.has_item(private_leaf.location))
assert self.store.has_item(vert_loc)
assert self.store.has_item(private_leaf.location)
course = self.store.get_course(self.course_locations[self.MONGO_COURSEID].course_key, 0)
self.assertIn(vert_loc, course.children)
assert vert_loc in course.children
# delete the vertical and ensure the course no longer points to it
with check_mongo_calls(max_find, max_send):
@@ -1000,9 +994,9 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
else:
vert_loc = private_vert.location
leaf_loc = private_leaf.location
self.assertFalse(self.store.has_item(vert_loc))
self.assertFalse(self.store.has_item(leaf_loc))
self.assertNotIn(vert_loc, course.children)
assert not self.store.has_item(vert_loc)
assert not self.store.has_item(leaf_loc)
assert vert_loc not in course.children
# Draft:
# find: find parent (definition.children) 2x, find draft item, get inheritance items
@@ -1029,7 +1023,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
)
# verify that an error is raised when the revision is not valid
with self.assertRaises(UnsupportedRevisionError):
with pytest.raises(UnsupportedRevisionError):
self.store.delete_item(
private_leaf.location,
self.user_id,
@@ -1061,14 +1055,14 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
with check_mongo_calls(max_find, max_send):
courses = self.store.get_courses()
course_ids = [course.location for course in courses]
self.assertEqual(len(courses), 1, "Not one course: {}".format(course_ids))
self.assertIn(self.course_locations[self.MONGO_COURSEID], course_ids)
assert len(courses) == 1, 'Not one course: {}'.format(course_ids)
assert self.course_locations[self.MONGO_COURSEID] in course_ids
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred):
draft_courses = self.store.get_courses(remove_branch=True)
with self.store.branch_setting(ModuleStoreEnum.Branch.published_only):
published_courses = self.store.get_courses(remove_branch=True)
self.assertEqual([c.id for c in draft_courses], [c.id for c in published_courses])
assert [c.id for c in draft_courses] == [c.id for c in published_courses]
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_create_child_detached_tabs(self, default_ms):
@@ -1078,7 +1072,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
"""
self.initdb(default_ms)
mongo_course = self.store.get_course(self.course_locations[self.MONGO_COURSEID].course_key)
self.assertEqual(len(mongo_course.children), 1)
assert len(mongo_course.children) == 1
# create a static tab of the course
self.store.create_child(
@@ -1089,7 +1083,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
# now check that the course has same number of children
mongo_course = self.store.get_course(self.course_locations[self.MONGO_COURSEID].course_key)
self.assertEqual(len(mongo_course.children), 1)
assert len(mongo_course.children) == 1
# draft is 2: find out which ms owns course, get item
# split: active_versions, structure, definition (to load course wiki string)
@@ -1103,7 +1097,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self.initdb(default_ms)
with check_mongo_calls(max_find, max_send):
course = self.store.get_item(self.course_locations[self.MONGO_COURSEID])
self.assertEqual(course.id, self.course_locations[self.MONGO_COURSEID].course_key)
assert course.id == self.course_locations[self.MONGO_COURSEID].course_key
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_get_library(self, default_ms):
@@ -1116,15 +1110,15 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
with self.store.default_store(ModuleStoreEnum.Type.split): # The CMS also wraps create_library like this
library = self.store.create_library("org", "lib", self.user_id, {"display_name": "Test Library"})
library_key = library.location.library_key
self.assertIsInstance(library_key, LibraryLocator)
assert isinstance(library_key, LibraryLocator)
# Now load with get_library and make sure it works:
library = self.store.get_library(library_key)
self.assertEqual(library.location.library_key, library_key)
assert library.location.library_key == library_key
# Clear the mappings so we can test get_library code path without mapping set:
self.store.mappings.clear()
library = self.store.get_library(library_key)
self.assertEqual(library.location.library_key, library_key)
assert library.location.library_key == library_key
# notice this doesn't test getting a public item via draft_preferred which draft would have 2 hits (split
# still only 2)
@@ -1141,17 +1135,14 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
with check_mongo_calls(max_find, max_send):
parent = self.store.get_parent_location(self.problem_x1a_1) # lint-amnesty, pylint: disable=no-member
self.assertEqual(parent, self.vertical_x1a) # lint-amnesty, pylint: disable=no-member
assert parent == self.vertical_x1a # lint-amnesty, pylint: disable=no-member
def verify_get_parent_locations_results(self, expected_results):
"""
Verifies the results of calling get_parent_locations matches expected_results.
"""
for child_location, parent_location, revision in expected_results:
self.assertEqual(
parent_location,
self.store.get_parent_location(child_location, revision=revision)
)
assert parent_location == self.store.get_parent_location(child_location, revision=revision)
def verify_item_parent(self, item_location, expected_parent_location, old_parent_location, is_reverted=False):
"""
@@ -1168,7 +1159,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
old_parent = self.store.get_item(old_parent_location)
expected_parent = self.store.get_item(expected_parent_location)
self.assertEqual(expected_parent_location, source_item.get_parent().location)
assert expected_parent_location == source_item.get_parent().location
# If an item is reverted, it means it's actual parent was the one that is the current parent now
# i.e expected_parent_location otherwise old_parent_location.
@@ -1176,9 +1167,9 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
# Check parent locations wrt branches
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred):
self.assertEqual(expected_parent_location, self.store.get_item(item_location).get_parent().location)
assert expected_parent_location == self.store.get_item(item_location).get_parent().location
with self.store.branch_setting(ModuleStoreEnum.Branch.published_only):
self.assertEqual(published_parent_location, self.store.get_item(item_location).get_parent().location)
assert published_parent_location == self.store.get_item(item_location).get_parent().location
# Make location specific to published branch for verify_get_parent_locations_results call.
published_parent_location = published_parent_location.for_branch(ModuleStoreEnum.BranchName.published)
@@ -1191,12 +1182,12 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
])
# Also verify item.parent has correct parent location set.
self.assertEqual(source_item.parent, expected_parent_location)
self.assertEqual(source_item.parent, self.store.get_parent_location(item_location))
assert source_item.parent == expected_parent_location
assert source_item.parent == self.store.get_parent_location(item_location)
# Item should be present in new parent's children list but not in old parent's children list.
self.assertIn(item_location, expected_parent.children)
self.assertNotIn(item_location, old_parent.children)
assert item_location in expected_parent.children
assert item_location not in old_parent.children
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_update_item_parent(self, store_type):
@@ -1216,7 +1207,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
updated_item_location = self.store.update_item_parent(
item_location, new_parent_location, old_parent_location, self.user_id
)
self.assertEqual(updated_item_location, item_location)
assert updated_item_location == item_location
self.verify_item_parent(
item_location=item_location,
@@ -1243,7 +1234,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
updated_item_location = self.store.update_item_parent(
item_location, new_parent_location, old_parent_location, self.user_id
)
self.assertEqual(updated_item_location, item_location)
assert updated_item_location == item_location
self.verify_item_parent(
item_location=item_location,
@@ -1280,7 +1271,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
updated_item_location = self.store.update_item_parent(
item_location, new_parent_location, old_parent_location, self.user_id
)
self.assertEqual(updated_item_location, item_location)
assert updated_item_location == item_location
self.verify_item_parent(
item_location=item_location,
@@ -1321,7 +1312,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
updated_item_location = self.store.update_item_parent(
item_location, new_parent_location, old_parent_location, self.user_id
)
self.assertEqual(updated_item_location, item_location)
assert updated_item_location == item_location
self.verify_item_parent(
item_location=item_location,
@@ -1343,7 +1334,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
updated_item_location = self.store.update_item_parent(
item_location, new_parent_location, old_parent_location, self.user_id
)
self.assertEqual(updated_item_location, item_location)
assert updated_item_location == item_location
self.verify_item_parent(
item_location=item_location,
@@ -1376,13 +1367,13 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self.store.update_item(problem, self.user_id)
updated_problem = self.store.get_item(self.problem_x1a_1) # lint-amnesty, pylint: disable=no-member
self.assertEqual(updated_problem.display_name, 'updated')
assert updated_problem.display_name == 'updated'
# Now, move from x1 to y1.
updated_item_location = self.store.update_item_parent(
item_location, new_parent_location, old_parent_location, self.user_id
)
self.assertEqual(updated_item_location, item_location)
assert updated_item_location == item_location
self.verify_item_parent(
item_location=item_location,
@@ -1395,7 +1386,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
# Check that problem has the original name back.
reverted_problem = self.store.get_item(self.problem_x1a_1) # lint-amnesty, pylint: disable=no-member
self.assertEqual(orig_display_name, reverted_problem.display_name)
assert orig_display_name == reverted_problem.display_name
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_move_1_moved_1_unchanged(self, store_type):
@@ -1420,7 +1411,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
updated_item_location = self.store.update_item_parent(
item_location, new_parent_location, old_parent_location, self.user_id
)
self.assertEqual(updated_item_location, item_location)
assert updated_item_location == item_location
self.verify_item_parent(
item_location=item_location,
@@ -1430,8 +1421,8 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
# Check that problem_item2 is still present in vertical_x1a
problem_item2 = self.store.get_item(problem_item2.location)
self.assertEqual(problem_item2.parent, self.vertical_x1a) # lint-amnesty, pylint: disable=no-member
self.assertIn(problem_item2.location, problem_item2.get_parent().children)
assert problem_item2.parent == self.vertical_x1a # lint-amnesty, pylint: disable=no-member
assert problem_item2.location in problem_item2.get_parent().children
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_move_1_moved_1_edited(self, store_type):
@@ -1455,7 +1446,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self.store.update_item(problem_item2, self.user_id)
updated_problem2 = self.store.get_item(problem_item2.location)
self.assertEqual(updated_problem2.display_name, 'updated')
assert updated_problem2.display_name == 'updated'
item_location = self.problem_x1a_1 # lint-amnesty, pylint: disable=no-member
new_parent_location = self.vertical_y1a # lint-amnesty, pylint: disable=no-member
@@ -1465,7 +1456,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
updated_item_location = self.store.update_item_parent(
item_location, new_parent_location, old_parent_location, self.user_id
)
self.assertEqual(updated_item_location, item_location)
assert updated_item_location == item_location
self.verify_item_parent(
item_location=item_location,
@@ -1478,7 +1469,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
# Check that problem_item2 has the original name back.
reverted_problem2 = self.store.get_item(problem_item2.location)
self.assertEqual(orig_display_name, reverted_problem2.display_name)
assert orig_display_name == reverted_problem2.display_name
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_move_1_moved_1_deleted(self, store_type):
@@ -1509,7 +1500,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
updated_item_location = self.store.update_item_parent(
item_location, new_parent_location, old_parent_location, self.user_id
)
self.assertEqual(updated_item_location, item_location)
assert updated_item_location == item_location
self.verify_item_parent(
item_location=item_location,
@@ -1522,8 +1513,8 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
# Check that problem_item2 is also back in vertical_x1a
problem_item2 = self.store.get_item(problem_item2.location)
self.assertEqual(problem_item2.parent, self.vertical_x1a) # lint-amnesty, pylint: disable=no-member
self.assertIn(problem_item2.location, problem_item2.get_parent().children)
assert problem_item2.parent == self.vertical_x1a # lint-amnesty, pylint: disable=no-member
assert problem_item2.location in problem_item2.get_parent().children
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_get_parent_locations_moved_child(self, default_ms):
@@ -1546,7 +1537,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred):
old_parent = self.store.get_item(child_to_move_location).get_parent()
self.assertEqual(old_parent_location, old_parent.location)
assert old_parent_location == old_parent.location
child_to_move_contextualized = child_to_move_location.map_into_course(old_parent.location.course_key)
old_parent.children.remove(child_to_move_contextualized)
@@ -1557,9 +1548,9 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self.store.update_item(new_parent, self.user_id)
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred):
self.assertEqual(new_parent_location, self.store.get_item(child_to_move_location).get_parent().location)
assert new_parent_location == self.store.get_item(child_to_move_location).get_parent().location
with self.store.branch_setting(ModuleStoreEnum.Branch.published_only):
self.assertEqual(old_parent_location, self.store.get_item(child_to_move_location).get_parent().location)
assert old_parent_location == self.store.get_item(child_to_move_location).get_parent().location
old_parent_published_location = old_parent_location.for_branch(ModuleStoreEnum.BranchName.published)
self.verify_get_parent_locations_results([
(child_to_move_location, new_parent_location, None),
@@ -1631,7 +1622,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
# convert first parent (unit) "vertical_x1a" of problem "problem_x1a_1" to draft
self.store.convert_to_draft(self.vertical_x1a, self.user_id) # lint-amnesty, pylint: disable=no-member
item = self.store.get_item(self.vertical_x1a) # lint-amnesty, pylint: disable=no-member
self.assertTrue(self.store.has_published_version(item))
assert self.store.has_published_version(item)
# now problem "problem_x1a_1" has 3 parents [vertical_x1a (draft),
# vertical_x1a (published), vertical_x1b (published)]
@@ -1640,7 +1631,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
# problem location revision
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred, course_id):
parent = mongo_store.get_parent_location(self.problem_x1a_1) # lint-amnesty, pylint: disable=no-member
self.assertEqual(parent, self.vertical_x1a) # lint-amnesty, pylint: disable=no-member
assert parent == self.vertical_x1a # lint-amnesty, pylint: disable=no-member
# Draft:
# Problem path:
@@ -1673,14 +1664,14 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
# each iteration has different find count, pop this iter's find count
with check_mongo_calls(num_finds.pop(0), num_sends):
path = path_to_location(self.store, location)
self.assertEqual(path, expected)
assert path == expected
not_found = (
course_key.make_usage_key('video', 'WelcomeX'),
course_key.make_usage_key('course', 'NotHome'),
)
for location in not_found:
with self.assertRaises(ItemNotFoundError):
with pytest.raises(ItemNotFoundError):
path_to_location(self.store, location)
# Orphaned items should not be found.
@@ -1692,7 +1683,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
block_id=orphan.block_id
)
with self.assertRaises(NoPathToItem):
with pytest.raises(NoPathToItem):
path_to_location(self.store, orphan)
def test_navigation_index(self):
@@ -1700,12 +1691,12 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
Make sure that navigation_index correctly parses the various position values that we might get from calls to
path_to_location
"""
self.assertEqual(1, navigation_index("1"))
self.assertEqual(10, navigation_index("10"))
self.assertEqual(None, navigation_index(None))
self.assertEqual(1, navigation_index("1_2"))
self.assertEqual(5, navigation_index("5_2"))
self.assertEqual(7, navigation_index("7_3_5_6_"))
assert 1 == navigation_index('1')
assert 10 == navigation_index('10')
assert navigation_index(None) is None
assert 1 == navigation_index('1_2')
assert 5 == navigation_index('5_2')
assert 7 == navigation_index('7_3_5_6_')
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_revert_to_published_root_draft(self, default_ms):
@@ -1719,25 +1710,25 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
vertical_children_num = len(vertical.children)
self.store.publish(self.course.location, self.user_id)
self.assertFalse(self._has_changes(self.vertical_x1a)) # lint-amnesty, pylint: disable=no-member
assert not self._has_changes(self.vertical_x1a) # lint-amnesty, pylint: disable=no-member
# delete leaf problem (will make parent vertical a draft)
self.store.delete_item(self.problem_x1a_1, self.user_id) # lint-amnesty, pylint: disable=no-member
self.assertTrue(self._has_changes(self.vertical_x1a)) # lint-amnesty, pylint: disable=no-member
assert self._has_changes(self.vertical_x1a) # lint-amnesty, pylint: disable=no-member
draft_parent = self.store.get_item(self.vertical_x1a) # lint-amnesty, pylint: disable=no-member
self.assertEqual(vertical_children_num - 1, len(draft_parent.children))
assert (vertical_children_num - 1) == len(draft_parent.children)
published_parent = self.store.get_item(
self.vertical_x1a, # lint-amnesty, pylint: disable=no-member
revision=ModuleStoreEnum.RevisionOption.published_only
)
self.assertEqual(vertical_children_num, len(published_parent.children))
assert vertical_children_num == len(published_parent.children)
self.store.revert_to_published(self.vertical_x1a, self.user_id) # lint-amnesty, pylint: disable=no-member
reverted_parent = self.store.get_item(self.vertical_x1a) # lint-amnesty, pylint: disable=no-member
self.assertEqual(vertical_children_num, len(published_parent.children))
assert vertical_children_num == len(published_parent.children)
self.assertBlocksEqualByFields(reverted_parent, published_parent)
self.assertFalse(self._has_changes(self.vertical_x1a)) # lint-amnesty, pylint: disable=no-member
assert not self._has_changes(self.vertical_x1a) # lint-amnesty, pylint: disable=no-member
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_revert_to_published_root_published(self, default_ms):
@@ -1757,7 +1748,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self.store.revert_to_published(self.vertical_x1a, self.user_id) # lint-amnesty, pylint: disable=no-member
reverted_problem = self.store.get_item(self.problem_x1a_1) # lint-amnesty, pylint: disable=no-member
self.assertEqual(orig_display_name, reverted_problem.display_name)
assert orig_display_name == reverted_problem.display_name
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_revert_to_published_no_draft(self, default_ms):
@@ -1781,7 +1772,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
"""
self.initdb(default_ms)
self._create_block_hierarchy()
with self.assertRaises(InvalidVersionError):
with pytest.raises(InvalidVersionError):
self.store.revert_to_published(self.vertical_x1a, self.user_id) # lint-amnesty, pylint: disable=no-member
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
@@ -1795,7 +1786,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self.store.revert_to_published(self.sequential_x1, self.user_id) # lint-amnesty, pylint: disable=no-member
reverted_parent = self.store.get_item(self.sequential_x1) # lint-amnesty, pylint: disable=no-member
# It does not discard the child vertical, even though that child is a draft (with no published version)
self.assertEqual(num_children, len(reverted_parent.children))
assert num_children == len(reverted_parent.children)
def test_reset_course_to_version(self):
"""
@@ -1943,7 +1934,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
mongo_store = self.store._get_modulestore_for_courselike(course_id) # pylint: disable=protected-access
with self.store.branch_setting(ModuleStoreEnum.Branch.published_only, course_id):
parent = mongo_store.get_parent_location(self.problem_x1a_1) # lint-amnesty, pylint: disable=no-member
self.assertEqual(parent, self.vertical_x1a) # lint-amnesty, pylint: disable=no-member
assert parent == self.vertical_x1a # lint-amnesty, pylint: disable=no-member
# add some published orphans
orphan_sequential = course_id.make_usage_key('sequential', 'OrphanSequential')
@@ -1959,8 +1950,8 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self.store.publish(location, self.user_id)
found_orphans = mongo_store.get_orphans(course_id)
self.assertEqual(set(found_orphans), set(orphan_locations))
self.assertEqual(len(set(found_orphans)), 2)
assert set(found_orphans) == set(orphan_locations)
assert len(set(found_orphans)) == 2
# add orphan vertical and sequential as another parents of problem "problem_x1a_1"
mongo_store.collection.update_one(
@@ -1975,18 +1966,15 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
# problem "problem_x1a_1" since the two other parents are orphans
with self.store.branch_setting(ModuleStoreEnum.Branch.published_only, course_id):
parent = mongo_store.get_parent_location(self.problem_x1a_1) # lint-amnesty, pylint: disable=no-member
self.assertEqual(parent, self.vertical_x1a) # lint-amnesty, pylint: disable=no-member
assert parent == self.vertical_x1a # lint-amnesty, pylint: disable=no-member
# now add valid published vertical as another parent of problem
mongo_store.collection.update_one(
self.sequential_x1.to_deprecated_son('_id.'), # lint-amnesty, pylint: disable=no-member
{'$push': {'definition.children': six.text_type(self.problem_x1a_1)}} # lint-amnesty, pylint: disable=no-member
)
mongo_store.collection.update_one(self.sequential_x1.to_deprecated_son('_id.'), {'$push': {'definition.children': six.text_type(self.problem_x1a_1)}}) # lint-amnesty, pylint: disable=no-member, line-too-long
# now check that "get_parent_location" method of published branch raises "ReferentialIntegrityError" for
# problem "problem_x1a_1" since it has now 2 valid published parents
with self.store.branch_setting(ModuleStoreEnum.Branch.published_only, course_id):
self.assertTrue(self.store.has_item(self.problem_x1a_1)) # lint-amnesty, pylint: disable=no-member
with self.assertRaises(ReferentialIntegrityError):
assert self.store.has_item(self.problem_x1a_1) # lint-amnesty, pylint: disable=no-member
with pytest.raises(ReferentialIntegrityError):
self.store.get_parent_location(self.problem_x1a_1) # lint-amnesty, pylint: disable=no-member
@ddt.data(ModuleStoreEnum.Type.mongo)
@@ -2003,7 +1991,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
block_id='orphan'
)
orphans = self.store.get_orphans(self.course_locations[self.MONGO_COURSEID].course_key)
self.assertEqual(len(orphans), 0, "unexpected orphans: {}".format(orphans))
assert len(orphans) == 0, 'unexpected orphans: {}'.format(orphans)
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_create_item_populates_edited_info(self, default_ms):
@@ -2013,8 +2001,8 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self.course.location.course_key,
'problem'
)
self.assertEqual(self.user_id, block.edited_by)
self.assertGreater(datetime.datetime.now(UTC), block.edited_on)
assert self.user_id == block.edited_by
assert datetime.datetime.now(UTC) > block.edited_on
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_create_item_populates_subtree_edited_info(self, default_ms):
@@ -2024,8 +2012,8 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self.course.location.course_key,
'problem'
)
self.assertEqual(self.user_id, block.subtree_edited_by)
self.assertGreater(datetime.datetime.now(UTC), block.subtree_edited_on)
assert self.user_id == block.subtree_edited_by
assert datetime.datetime.now(UTC) > block.subtree_edited_on
# Draft: wildcard search of draft and split
# Split: wildcard search of draft and split
@@ -2039,14 +2027,11 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
# Test Mongo wiki
with check_mongo_calls(max_find, max_send):
wiki_courses = self.store.get_courses_for_wiki('999')
self.assertEqual(len(wiki_courses), 1)
self.assertIn(
self.course_locations[self.MONGO_COURSEID].course_key.replace(branch=None), # Branch agnostic
wiki_courses
)
assert len(wiki_courses) == 1
assert self.course_locations[self.MONGO_COURSEID].course_key.replace(branch=None) in wiki_courses
self.assertEqual(len(self.store.get_courses_for_wiki('edX.simple.2012_Fall')), 0)
self.assertEqual(len(self.store.get_courses_for_wiki('no_such_wiki')), 0)
assert len(self.store.get_courses_for_wiki('edX.simple.2012_Fall')) == 0
assert len(self.store.get_courses_for_wiki('no_such_wiki')) == 0
# Draft:
# Find: find vertical, find children
@@ -2075,13 +2060,13 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self.vertical_x1a, # lint-amnesty, pylint: disable=no-member
revision=ModuleStoreEnum.RevisionOption.published_only
)
self.assertIsNotNone(published_xblock)
assert published_xblock is not None
# unpublish
with check_mongo_calls(max_find, max_send):
self.store.unpublish(self.vertical_x1a, self.user_id) # lint-amnesty, pylint: disable=no-member
with self.assertRaises(ItemNotFoundError):
with pytest.raises(ItemNotFoundError):
self.store.get_item(
self.vertical_x1a, # lint-amnesty, pylint: disable=no-member
revision=ModuleStoreEnum.RevisionOption.published_only
@@ -2092,7 +2077,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self.vertical_x1a, # lint-amnesty, pylint: disable=no-member
revision=ModuleStoreEnum.RevisionOption.draft_only
)
self.assertIsNotNone(draft_xblock)
assert draft_xblock is not None
# Draft: specific query for revision None
# Split: active_versions, structure
@@ -2109,33 +2094,33 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
item = self.store.create_child(self.user_id, self.writable_chapter_location, 'problem', 'test_compute_publish_state') # lint-amnesty, pylint: disable=line-too-long
item_location = item.location
with check_mongo_calls(max_find, max_send):
self.assertFalse(self.store.has_published_version(item))
assert not self.store.has_published_version(item)
# Private -> Public
self.store.publish(item_location, self.user_id)
item = self.store.get_item(item_location)
self.assertTrue(self.store.has_published_version(item))
assert self.store.has_published_version(item)
# Public -> Private
self.store.unpublish(item_location, self.user_id)
item = self.store.get_item(item_location)
self.assertFalse(self.store.has_published_version(item))
assert not self.store.has_published_version(item)
# Private -> Public
self.store.publish(item_location, self.user_id)
item = self.store.get_item(item_location)
self.assertTrue(self.store.has_published_version(item))
assert self.store.has_published_version(item)
# Public -> Draft with NO changes
self.store.convert_to_draft(item_location, self.user_id)
item = self.store.get_item(item_location)
self.assertTrue(self.store.has_published_version(item))
assert self.store.has_published_version(item)
# Draft WITH changes
item.display_name = 'new name'
item = self.store.update_item(item, self.user_id)
self.assertTrue(self.store.has_changes(item))
self.assertTrue(self.store.has_published_version(item))
assert self.store.has_changes(item)
assert self.store.has_published_version(item)
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_update_edit_info_ancestors(self, default_ms):
@@ -2152,13 +2137,13 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
"""
node = self.store.get_item(location_key)
if after:
self.assertLess(after, node.edited_on)
self.assertLess(node.edited_on, before)
self.assertEqual(node.edited_by, edited_by)
assert after < node.edited_on
assert node.edited_on < before
assert node.edited_by == edited_by
if subtree_after:
self.assertLess(subtree_after, node.subtree_edited_on)
self.assertLess(node.subtree_edited_on, subtree_before)
self.assertEqual(node.subtree_edited_by, subtree_by)
assert subtree_after < node.subtree_edited_on
assert node.subtree_edited_on < subtree_before
assert node.subtree_edited_by == subtree_by
with self.store.bulk_operations(test_course.id):
# Create a dummy vertical & html to test against
@@ -2230,7 +2215,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
)
# Store the current edit time and verify that user created the component
self.assertEqual(component.edited_by, self.user_id)
assert component.edited_by == self.user_id
old_edited_on = component.edited_on
edit_user = self.user_id - 2
@@ -2240,8 +2225,8 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
updated_component = self.store.get_item(component.location)
# Verify the ordering of edit times and that dummy_user made the edit
self.assertLess(old_edited_on, updated_component.edited_on)
self.assertEqual(updated_component.edited_by, edit_user)
assert old_edited_on < updated_component.edited_on
assert updated_component.edited_by == edit_user
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_update_published_info(self, default_ms):
@@ -2267,15 +2252,15 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
updated_component = self.store.get_item(component.location)
# Verify the time order and that publish_user caused publication
self.assertLessEqual(old_time, updated_component.published_on)
self.assertEqual(updated_component.published_by, publish_user)
assert old_time <= updated_component.published_on
assert updated_component.published_by == publish_user
# Verify that changing the item doesn't unset the published info
updated_component.display_name = 'changed'
self.store.update_item(updated_component, self.user_id)
updated_component = self.store.get_item(updated_component.location)
self.assertLessEqual(old_time, updated_component.published_on)
self.assertEqual(updated_component.published_by, publish_user)
assert old_time <= updated_component.published_on
assert updated_component.published_by == publish_user
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_auto_publish(self, default_ms):
@@ -2290,62 +2275,53 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
# test create_course to make sure we are autopublishing
test_course = self.store.create_course('testx', 'GreekHero', 'test_run', self.user_id)
self.assertTrue(self.store.has_published_version(test_course))
assert self.store.has_published_version(test_course)
test_course_key = test_course.id
# test create_item of direct-only category to make sure we are autopublishing
chapter = self.store.create_child(self.user_id, test_course.location, 'chapter', 'Overview')
with self.store.branch_setting(ModuleStoreEnum.Branch.published_only):
self.assertIn(
chapter.location,
self.store.get_item(test_course.location).children,
)
self.assertTrue(self.store.has_published_version(chapter))
assert chapter.location in self.store.get_item(test_course.location).children
assert self.store.has_published_version(chapter)
chapter_location = chapter.location
# test create_child of direct-only category to make sure we are autopublishing
sequential = self.store.create_child(self.user_id, chapter_location, 'sequential', 'Sequence')
with self.store.branch_setting(ModuleStoreEnum.Branch.published_only):
self.assertIn(
sequential.location,
self.store.get_item(chapter_location).children,
)
self.assertTrue(self.store.has_published_version(sequential))
assert sequential.location in self.store.get_item(chapter_location).children
assert self.store.has_published_version(sequential)
# test update_item of direct-only category to make sure we are autopublishing
sequential.display_name = 'sequential1'
sequential = self.store.update_item(sequential, self.user_id)
self.assertTrue(self.store.has_published_version(sequential))
assert self.store.has_published_version(sequential)
# test delete_item of direct-only category to make sure we are autopublishing
self.store.delete_item(sequential.location, self.user_id, revision=ModuleStoreEnum.RevisionOption.all)
with self.store.branch_setting(ModuleStoreEnum.Branch.published_only):
self.assertNotIn(
sequential.location,
self.store.get_item(chapter_location).children,
)
assert sequential.location not in self.store.get_item(chapter_location).children
chapter = self.store.get_item(chapter.location.for_branch(None))
self.assertTrue(self.store.has_published_version(chapter))
assert self.store.has_published_version(chapter)
# test create_child of NOT direct-only category to make sure we aren't autopublishing
problem_child = self.store.create_child(self.user_id, chapter_location, 'problem', 'Problem_Child')
self.assertFalse(self.store.has_published_version(problem_child))
assert not self.store.has_published_version(problem_child)
# test create_item of NOT direct-only category to make sure we aren't autopublishing
problem_item = self.store.create_item(self.user_id, test_course_key, 'problem', 'Problem_Item')
self.assertFalse(self.store.has_published_version(problem_item))
assert not self.store.has_published_version(problem_item)
# test update_item of NOT direct-only category to make sure we aren't autopublishing
problem_item.display_name = 'Problem_Item1'
problem_item = self.store.update_item(problem_item, self.user_id)
self.assertFalse(self.store.has_published_version(problem_item))
assert not self.store.has_published_version(problem_item)
# test delete_item of NOT direct-only category to make sure we aren't autopublishing
self.store.delete_item(problem_child.location, self.user_id)
chapter = self.store.get_item(chapter.location.for_branch(None))
self.assertTrue(self.store.has_published_version(chapter))
assert self.store.has_published_version(chapter)
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_get_courses_for_wiki_shared(self, default_ms):
@@ -2356,10 +2332,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
# verify initial state - initially, we should have a wiki for the Mongo course
wiki_courses = self.store.get_courses_for_wiki('999')
self.assertIn(
self.course_locations[self.MONGO_COURSEID].course_key.replace(branch=None), # Branch agnostic
wiki_courses
)
assert self.course_locations[self.MONGO_COURSEID].course_key.replace(branch=None) in wiki_courses
# set Mongo course to share the wiki with simple course
mongo_course = self.store.get_course(self.course_locations[self.MONGO_COURSEID].course_key)
@@ -2368,15 +2341,12 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
# now mongo_course should not be retrievable with old wiki_slug
wiki_courses = self.store.get_courses_for_wiki('999')
self.assertEqual(len(wiki_courses), 0)
assert len(wiki_courses) == 0
# but there should be one course with wiki_slug 'simple'
wiki_courses = self.store.get_courses_for_wiki('simple')
self.assertEqual(len(wiki_courses), 1)
self.assertIn(
self.course_locations[self.MONGO_COURSEID].course_key.replace(branch=None),
wiki_courses
)
assert len(wiki_courses) == 1
assert self.course_locations[self.MONGO_COURSEID].course_key.replace(branch=None) in wiki_courses
# configure mongo course to use unique wiki_slug.
mongo_course = self.store.get_course(self.course_locations[self.MONGO_COURSEID].course_key)
@@ -2384,18 +2354,12 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self.store.update_item(mongo_course, self.user_id)
# it should be retrievable with its new wiki_slug
wiki_courses = self.store.get_courses_for_wiki('MITx.999.2013_Spring')
self.assertEqual(len(wiki_courses), 1)
self.assertIn(
self.course_locations[self.MONGO_COURSEID].course_key.replace(branch=None),
wiki_courses
)
assert len(wiki_courses) == 1
assert self.course_locations[self.MONGO_COURSEID].course_key.replace(branch=None) in wiki_courses
# and NOT retriveable with its old wiki_slug
wiki_courses = self.store.get_courses_for_wiki('simple')
self.assertEqual(len(wiki_courses), 0)
self.assertNotIn(
self.course_locations[self.MONGO_COURSEID].course_key.replace(branch=None),
wiki_courses
)
assert len(wiki_courses) == 0
assert self.course_locations[self.MONGO_COURSEID].course_key.replace(branch=None) not in wiki_courses
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_branch_setting(self, default_ms):
@@ -2415,10 +2379,8 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
"""
Asserts the number of problems with the given display name is the given expected number.
"""
self.assertEqual(
len(self.store.get_items(course_key.for_branch(None), settings={'display_name': display_name})),
expected_number
)
assert len(self.store.get_items(course_key.for_branch(None), settings={'display_name': display_name})) ==\
expected_number
def assertProblemNameEquals(expected_display_name):
"""
@@ -2426,20 +2388,20 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
"""
# check the display_name of the problem
problem = self.store.get_item(problem_location)
self.assertEqual(problem.display_name, expected_display_name)
assert problem.display_name == expected_display_name
# there should be only 1 problem with the expected_display_name
assertNumProblems(expected_display_name, 1)
# verify Draft problem
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred, course_key):
self.assertTrue(self.store.has_item(problem_location))
assert self.store.has_item(problem_location)
assertProblemNameEquals(problem_original_name)
# verify Published problem doesn't exist
with self.store.branch_setting(ModuleStoreEnum.Branch.published_only, course_key):
self.assertFalse(self.store.has_item(problem_location))
with self.assertRaises(ItemNotFoundError):
assert not self.store.has_item(problem_location)
with pytest.raises(ItemNotFoundError):
self.store.get_item(problem_location)
# PUBLISH the problem
@@ -2448,7 +2410,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
# verify Published problem
with self.store.branch_setting(ModuleStoreEnum.Branch.published_only, course_key):
self.assertTrue(self.store.has_item(problem_location))
assert self.store.has_item(problem_location)
assertProblemNameEquals(problem_original_name)
# verify Draft-preferred
@@ -2481,25 +2443,25 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
# verify branch setting is published-only in manager
with self.store.branch_setting(ModuleStoreEnum.Branch.published_only):
self.assertEqual(self.store.get_branch_setting(), ModuleStoreEnum.Branch.published_only)
assert self.store.get_branch_setting() == ModuleStoreEnum.Branch.published_only
# verify branch setting is draft-preferred in manager
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred):
self.assertEqual(self.store.get_branch_setting(), ModuleStoreEnum.Branch.draft_preferred)
assert self.store.get_branch_setting() == ModuleStoreEnum.Branch.draft_preferred
def verify_default_store(self, store_type):
"""
Verifies the default_store property
"""
self.assertEqual(self.store.default_modulestore.get_modulestore_type(), store_type)
assert self.store.default_modulestore.get_modulestore_type() == store_type
# verify internal helper method
store = self.store._get_modulestore_for_courselike() # pylint: disable=protected-access
self.assertEqual(store.get_modulestore_type(), store_type)
assert store.get_modulestore_type() == store_type
# verify store used for creating a course
course = self.store.create_course("org", "course{}".format(uuid4().hex[:5]), "run", self.user_id)
self.assertEqual(course.system.modulestore.get_modulestore_type(), store_type)
assert course.system.modulestore.get_modulestore_type() == store_type
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_default_store(self, default_ms):
@@ -2619,7 +2581,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self.store.create_item(self.user_id, course_key, block_type)
signal_handler.send.assert_not_called()
self.assertEqual(mock_clear_bulk_ops_record.call_count, 1)
assert mock_clear_bulk_ops_record.call_count == 1
signal_handler.send.assert_called_with('course_published', course_key=course.id)
@@ -2637,7 +2599,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self.addCleanup(self.store.close_all_connections)
with self.store.default_store(default):
self.assertIsNotNone(self.store.thread_cache.default_store.signal_handler)
assert self.store.thread_cache.default_store.signal_handler is not None
signal_handler.send.assert_not_called()
@@ -2678,7 +2640,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self.addCleanup(self.store.close_all_connections)
with self.store.default_store(default):
self.assertIsNotNone(self.store.thread_cache.default_store.signal_handler)
assert self.store.thread_cache.default_store.signal_handler is not None
signal_handler.send.assert_not_called()
@@ -2709,7 +2671,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self.addCleanup(self.store.close_all_connections)
with self.store.default_store(default):
self.assertIsNotNone(self.store.thread_cache.default_store.signal_handler)
assert self.store.thread_cache.default_store.signal_handler is not None
signal_handler.send.assert_not_called()
@@ -2742,7 +2704,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self.addCleanup(self.store.close_all_connections)
with self.store.default_store(default):
self.assertIsNotNone(self.store.thread_cache.default_store.signal_handler)
assert self.store.thread_cache.default_store.signal_handler is not None
signal_handler.send.assert_not_called()
@@ -2798,7 +2760,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self.addCleanup(self.store.close_all_connections)
with self.store.default_store(default):
self.assertIsNotNone(self.store.thread_cache.default_store.signal_handler)
assert self.store.thread_cache.default_store.signal_handler is not None
signal_handler.send.assert_not_called()
@@ -2840,7 +2802,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self.addCleanup(self.store.close_all_connections)
with self.store.default_store(default):
self.assertIsNotNone(self.store.thread_cache.default_store.signal_handler)
assert self.store.thread_cache.default_store.signal_handler is not None
signal_handler.send.assert_not_called()
@@ -2909,7 +2871,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self.addCleanup(self.store.close_all_connections)
with self.store.default_store(default):
self.assertIsNotNone(self.store.thread_cache.default_store.signal_handler)
assert self.store.thread_cache.default_store.signal_handler is not None
signal_handler.send.assert_not_called()
@@ -2949,23 +2911,23 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self.store.publish(chapter.location, self.user_id)
# Verify that there are no changes
self.assertFalse(self._has_changes(chapter.location))
self.assertFalse(self._has_changes(sequential.location))
self.assertFalse(self._has_changes(vertical.location))
self.assertFalse(self._has_changes(problem.location))
assert not self._has_changes(chapter.location)
assert not self._has_changes(sequential.location)
assert not self._has_changes(vertical.location)
assert not self._has_changes(problem.location)
# No orphans in course
course_orphans = self.store.get_orphans(course_locator)
self.assertEqual(len(course_orphans), 0)
assert len(course_orphans) == 0
self.store.delete_item(vertical.location, self.user_id)
# No orphans in course after delete, except
# in old mongo, which still creates orphans
course_orphans = self.store.get_orphans(course_locator)
if default_store == ModuleStoreEnum.Type.mongo:
self.assertEqual(len(course_orphans), 1)
assert len(course_orphans) == 1
else:
self.assertEqual(len(course_orphans), 0)
assert len(course_orphans) == 0
course_locator_publish = course_locator.for_branch(ModuleStoreEnum.BranchName.published)
# No published oprhans after delete, except
@@ -2973,9 +2935,9 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
course_publish_orphans = self.store.get_orphans(course_locator_publish)
if default_store == ModuleStoreEnum.Type.mongo:
self.assertEqual(len(course_publish_orphans), 1)
assert len(course_publish_orphans) == 1
else:
self.assertEqual(len(course_publish_orphans), 0)
assert len(course_publish_orphans) == 0
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_delete_draft_item_orphans(self, default_store):
@@ -3003,28 +2965,28 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
self.store.publish(chapter.location, self.user_id)
# Verify that there are no changes
self.assertFalse(self._has_changes(chapter.location))
self.assertFalse(self._has_changes(sequential.location))
self.assertFalse(self._has_changes(vertical.location))
self.assertFalse(self._has_changes(problem.location))
assert not self._has_changes(chapter.location)
assert not self._has_changes(sequential.location)
assert not self._has_changes(vertical.location)
assert not self._has_changes(problem.location)
# No orphans in course
course_orphans = self.store.get_orphans(course_locator)
self.assertEqual(len(course_orphans), 0)
assert len(course_orphans) == 0
problem.display_name = 'changed'
problem = self.store.update_item(problem, self.user_id)
self.assertTrue(self._has_changes(vertical.location))
self.assertTrue(self._has_changes(problem.location))
assert self._has_changes(vertical.location)
assert self._has_changes(problem.location)
self.store.delete_item(vertical.location, self.user_id)
# No orphans in course after delete, except
# in old mongo, which still creates them
course_orphans = self.store.get_orphans(course_locator)
if default_store == ModuleStoreEnum.Type.mongo:
self.assertEqual(len(course_orphans), 1)
assert len(course_orphans) == 1
else:
self.assertEqual(len(course_orphans), 0)
assert len(course_orphans) == 0
course_locator_publish = course_locator.for_branch(ModuleStoreEnum.BranchName.published)
# No published orphans after delete, except
@@ -3032,9 +2994,9 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup):
course_publish_orphans = self.store.get_orphans(course_locator_publish)
if default_store == ModuleStoreEnum.Type.mongo:
self.assertEqual(len(course_publish_orphans), 1)
assert len(course_publish_orphans) == 1
else:
self.assertEqual(len(course_publish_orphans), 0)
assert len(course_publish_orphans) == 0
@ddt.ddt
@@ -3106,14 +3068,14 @@ class TestPublishOverExportImport(CommonMixedModuleStoreSetup):
block_id='test_vertical'
)
# Not yet published, so changes are present
self.assertTrue(self._has_changes(draft_xblock.location))
assert self._has_changes(draft_xblock.location)
self._export_import_course_round_trip(
self.store, contentstore, source_course_key, self.export_dir
)
# Verify that the imported block still is a draft, i.e. has changes.
self.assertTrue(self._has_changes(draft_xblock.location))
assert self._has_changes(draft_xblock.location)
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_published_has_changes_before_export_and_after_import(self, default_ms):
@@ -3132,7 +3094,7 @@ class TestPublishOverExportImport(CommonMixedModuleStoreSetup):
self.store.publish(published_xblock.location, self.user_id)
# Retrieve the published block and make sure it's published.
self.assertFalse(self._has_changes(published_xblock.location))
assert not self._has_changes(published_xblock.location)
self._export_import_course_round_trip(
self.store, contentstore, source_course_key, self.export_dir
@@ -3140,7 +3102,7 @@ class TestPublishOverExportImport(CommonMixedModuleStoreSetup):
# Get the published xblock from the imported course.
# Verify that it still is published, i.e. has no changes.
self.assertFalse(self._has_changes(published_xblock.location))
assert not self._has_changes(published_xblock.location)
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_changed_published_has_changes_before_export_and_after_import(self, default_ms):
@@ -3159,13 +3121,13 @@ class TestPublishOverExportImport(CommonMixedModuleStoreSetup):
self.store.publish(published_xblock.location, self.user_id)
# Retrieve the published block and make sure it's published.
self.assertFalse(self._has_changes(published_xblock.location))
assert not self._has_changes(published_xblock.location)
updated_display_name = 'Changed Display Name'
component = self.store.get_item(published_xblock.location)
component.display_name = updated_display_name
component = self.store.update_item(component, self.user_id)
self.assertTrue(self.store.has_changes(component))
assert self.store.has_changes(component)
self._export_import_course_round_trip(
self.store, contentstore, source_course_key, self.export_dir
@@ -3173,12 +3135,12 @@ class TestPublishOverExportImport(CommonMixedModuleStoreSetup):
# Get the published xblock from the imported course.
# Verify that the published block still has a draft block, i.e. has changes.
self.assertTrue(self._has_changes(published_xblock.location))
assert self._has_changes(published_xblock.location)
# Verify that the changes in the draft vertical still exist.
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred, source_course_key):
component = self.store.get_item(published_xblock.location)
self.assertEqual(component.display_name, updated_display_name)
assert component.display_name == updated_display_name
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_seq_with_unpublished_vertical_has_changes_before_export_and_after_import(self, default_ms):
@@ -3206,11 +3168,11 @@ class TestPublishOverExportImport(CommonMixedModuleStoreSetup):
# Retrieve the published block and make sure it's published.
# Chapter is published - but the changes in vertical below means it "has_changes".
self.assertTrue(self._has_changes(chapter.location))
assert self._has_changes(chapter.location)
# Sequential is published - but the changes in vertical below means it "has_changes".
self.assertTrue(self._has_changes(sequential.location))
assert self._has_changes(sequential.location)
# Vertical is unpublished - so it "has_changes".
self.assertTrue(self._has_changes(vertical.location))
assert self._has_changes(vertical.location)
self._export_import_course_round_trip(
self.store, contentstore, source_course_key, self.export_dir
@@ -3218,9 +3180,9 @@ class TestPublishOverExportImport(CommonMixedModuleStoreSetup):
# Get the published xblock from the imported course.
# Verify that the published block still has a draft block, i.e. has changes.
self.assertTrue(self._has_changes(chapter.location))
self.assertTrue(self._has_changes(sequential.location))
self.assertTrue(self._has_changes(vertical.location))
assert self._has_changes(chapter.location)
assert self._has_changes(sequential.location)
assert self._has_changes(vertical.location)
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_vertical_with_draft_and_published_unit_has_changes_before_export_and_after_import(self, default_ms):
@@ -3246,41 +3208,41 @@ class TestPublishOverExportImport(CommonMixedModuleStoreSetup):
self.user_id, sequential.location, 'vertical', block_id='moon_unit'
)
# Vertical has changes until it is actually published.
self.assertTrue(self._has_changes(vertical.location))
assert self._has_changes(vertical.location)
self.store.publish(vertical.location, self.user_id)
self.assertFalse(self._has_changes(vertical.location))
assert not self._has_changes(vertical.location)
# create unit
unit = self.store.create_child(
self.user_id, vertical.location, 'html', block_id='html_unit'
)
# Vertical has a new child -and- unit is unpublished. So both have changes.
self.assertTrue(self._has_changes(vertical.location))
self.assertTrue(self._has_changes(unit.location))
assert self._has_changes(vertical.location)
assert self._has_changes(unit.location)
# Publishing the vertical also publishes its unit child.
self.store.publish(vertical.location, self.user_id)
self.assertFalse(self._has_changes(vertical.location))
self.assertFalse(self._has_changes(unit.location))
assert not self._has_changes(vertical.location)
assert not self._has_changes(unit.location)
# Publishing the unit separately has no effect on whether it has changes - it's already published.
self.store.publish(unit.location, self.user_id)
self.assertFalse(self._has_changes(vertical.location))
self.assertFalse(self._has_changes(unit.location))
assert not self._has_changes(vertical.location)
assert not self._has_changes(unit.location)
# Retrieve the published block and make sure it's published.
self.store.publish(chapter.location, self.user_id)
self.assertFalse(self._has_changes(chapter.location))
self.assertFalse(self._has_changes(sequential.location))
self.assertFalse(self._has_changes(vertical.location))
self.assertFalse(self._has_changes(unit.location))
assert not self._has_changes(chapter.location)
assert not self._has_changes(sequential.location)
assert not self._has_changes(vertical.location)
assert not self._has_changes(unit.location)
# Now make changes to the unit - but don't publish them.
component = self.store.get_item(unit.location)
updated_display_name = 'Changed Display Name'
component.display_name = updated_display_name
component = self.store.update_item(component, self.user_id)
self.assertTrue(self._has_changes(component.location))
assert self._has_changes(component.location)
# Export the course - then import the course export.
self._export_import_course_round_trip(
@@ -3289,20 +3251,20 @@ class TestPublishOverExportImport(CommonMixedModuleStoreSetup):
# Get the published xblock from the imported course.
# Verify that the published block still has a draft block, i.e. has changes.
self.assertTrue(self._has_changes(chapter.location))
self.assertTrue(self._has_changes(sequential.location))
self.assertTrue(self._has_changes(vertical.location))
self.assertTrue(self._has_changes(unit.location))
assert self._has_changes(chapter.location)
assert self._has_changes(sequential.location)
assert self._has_changes(vertical.location)
assert self._has_changes(unit.location)
# Verify that the changes in the draft unit still exist.
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred, source_course_key):
component = self.store.get_item(unit.location)
self.assertEqual(component.display_name, updated_display_name)
assert component.display_name == updated_display_name
# Verify that the draft changes don't exist in the published unit - it still uses the default name.
with self.store.branch_setting(ModuleStoreEnum.Branch.published_only, source_course_key):
component = self.store.get_item(unit.location)
self.assertEqual(component.display_name, 'Text')
assert component.display_name == 'Text'
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_vertical_with_published_unit_remains_published_before_export_and_after_import(self, default_ms):
@@ -3328,9 +3290,9 @@ class TestPublishOverExportImport(CommonMixedModuleStoreSetup):
self.user_id, sequential.location, 'vertical', block_id='moon_unit'
)
# Vertical has changes until it is actually published.
self.assertTrue(self._has_changes(vertical.location))
assert self._has_changes(vertical.location)
self.store.publish(vertical.location, self.user_id)
self.assertFalse(self._has_changes(vertical.location))
assert not self._has_changes(vertical.location)
# create unit
unit = self.store.create_child(
@@ -3340,12 +3302,12 @@ class TestPublishOverExportImport(CommonMixedModuleStoreSetup):
updated_display_name = 'Changed Display Name'
unit.display_name = updated_display_name
unit = self.store.update_item(unit, self.user_id)
self.assertTrue(self._has_changes(unit.location))
assert self._has_changes(unit.location)
# Publishing the vertical also publishes its unit child.
self.store.publish(vertical.location, self.user_id)
self.assertFalse(self._has_changes(vertical.location))
self.assertFalse(self._has_changes(unit.location))
assert not self._has_changes(vertical.location)
assert not self._has_changes(unit.location)
# Export the course - then import the course export.
self._export_import_course_round_trip(
@@ -3354,15 +3316,15 @@ class TestPublishOverExportImport(CommonMixedModuleStoreSetup):
# Get the published xblock from the imported course.
# Verify that the published block still has a draft block, i.e. has changes.
self.assertFalse(self._has_changes(chapter.location))
self.assertFalse(self._has_changes(sequential.location))
self.assertFalse(self._has_changes(vertical.location))
self.assertFalse(self._has_changes(unit.location))
assert not self._has_changes(chapter.location)
assert not self._has_changes(sequential.location)
assert not self._has_changes(vertical.location)
assert not self._has_changes(unit.location)
# Verify that the published changes exist in the published unit.
with self.store.branch_setting(ModuleStoreEnum.Branch.published_only, source_course_key):
component = self.store.get_item(unit.location)
self.assertEqual(component.display_name, updated_display_name)
assert component.display_name == updated_display_name
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
@XBlockAside.register_temp_plugin(AsideTestType, 'test_aside')
@@ -3399,11 +3361,11 @@ class TestPublishOverExportImport(CommonMixedModuleStoreSetup):
"""
asides = block.runtime.get_asides(block)
self.assertEqual(len(asides), 1, "Found {} asides but expected only test_aside".format(asides))
self.assertIsInstance(asides[0], AsideTestType)
assert len(asides) == 1, 'Found {} asides but expected only test_aside'.format(asides)
assert isinstance(asides[0], AsideTestType)
category = block.scope_ids.block_type
self.assertEqual(asides[0].data_field, "{} aside data".format(category))
self.assertEqual(asides[0].content, "{} Aside".format(category.capitalize()))
assert asides[0].data_field == '{} aside data'.format(category)
assert asides[0].content == '{} Aside'.format(category.capitalize())
for child in block.get_children():
check_block(child)
@@ -3414,17 +3376,13 @@ class TestPublishOverExportImport(CommonMixedModuleStoreSetup):
new_chapter = self.store.create_child(self.user_id, courses[0].location, 'chapter', 'new_chapter')
asides = new_chapter.runtime.get_asides(new_chapter)
self.assertEqual(len(asides), 1, "Found {} asides but expected only test_aside".format(asides))
assert len(asides) == 1, 'Found {} asides but expected only test_aside'.format(asides)
chapter_aside = asides[0]
self.assertIsInstance(chapter_aside, AsideTestType)
self.assertFalse(
chapter_aside.fields['data_field'].is_set_on(chapter_aside),
"data_field says it's assigned to {}".format(chapter_aside.data_field)
)
self.assertFalse(
chapter_aside.fields['content'].is_set_on(chapter_aside),
"content says it's assigned to {}".format(chapter_aside.content)
)
assert isinstance(chapter_aside, AsideTestType)
assert not chapter_aside.fields['data_field'].is_set_on(chapter_aside), \
f"data_field says it's assigned to {chapter_aside.data_field}"
assert not chapter_aside.fields['content'].is_set_on(chapter_aside), \
f"content says it's assigned to {chapter_aside.content}"
# now update the values
chapter_aside.data_field = 'new value'
@@ -3432,7 +3390,7 @@ class TestPublishOverExportImport(CommonMixedModuleStoreSetup):
new_chapter = self.store.get_item(new_chapter.location)
chapter_aside = new_chapter.runtime.get_asides(new_chapter)[0]
self.assertEqual('new value', chapter_aside.data_field)
assert 'new value' == chapter_aside.data_field
# update the values the second time
chapter_aside.data_field = 'another one value'
@@ -3440,7 +3398,7 @@ class TestPublishOverExportImport(CommonMixedModuleStoreSetup):
new_chapter2 = self.store.get_item(new_chapter.location)
chapter_aside2 = new_chapter2.runtime.get_asides(new_chapter2)[0]
self.assertEqual('another one value', chapter_aside2.data_field)
assert 'another one value' == chapter_aside2.data_field
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
@XBlockAside.register_temp_plugin(AsideTestType, 'test_aside')
@@ -3509,7 +3467,7 @@ class TestPublishOverExportImport(CommonMixedModuleStoreSetup):
raise_on_failure=True,
)
self.assertEqual(1, len(courses2))
assert 1 == len(courses2)
# check that the imported blocks have the right asides and values
def check_block(block):
@@ -3518,11 +3476,11 @@ class TestPublishOverExportImport(CommonMixedModuleStoreSetup):
"""
asides = block.runtime.get_asides(block)
self.assertEqual(len(asides), 1, "Found {} asides but expected only test_aside".format(asides))
self.assertIsInstance(asides[0], AsideTestType)
assert len(asides) == 1, 'Found {} asides but expected only test_aside'.format(asides)
assert isinstance(asides[0], AsideTestType)
category = block.scope_ids.block_type
self.assertEqual(asides[0].data_field, "Exported data_field {} aside data".format(category))
self.assertEqual(asides[0].content, "Exported content {} Aside".format(category.capitalize()))
assert asides[0].data_field == 'Exported data_field {} aside data'.format(category)
assert asides[0].content == 'Exported content {} Aside'.format(category.capitalize())
for child in block.get_children():
check_block(child)
@@ -3565,9 +3523,9 @@ class TestPublishOverExportImport(CommonMixedModuleStoreSetup):
new_chapter.display_name = new_chapter_display_name
asides = new_chapter.runtime.get_asides(new_chapter)
self.assertEqual(len(asides), 1, "Found {} asides but expected only test_aside".format(asides))
assert len(asides) == 1, 'Found {} asides but expected only test_aside'.format(asides)
chapter_aside = asides[0]
self.assertIsInstance(chapter_aside, AsideTestType)
assert isinstance(chapter_aside, AsideTestType)
chapter_aside.data_field = 'new value'
self.store.update_item(new_chapter, self.user_id, asides=[chapter_aside])
@@ -3578,9 +3536,9 @@ class TestPublishOverExportImport(CommonMixedModuleStoreSetup):
new_problem.display_name = new_problem_display_name
asides = new_problem.runtime.get_asides(new_problem)
self.assertEqual(len(asides), 1, "Found {} asides but expected only test_aside".format(asides))
assert len(asides) == 1, 'Found {} asides but expected only test_aside'.format(asides)
problem_aside = asides[0]
self.assertIsInstance(problem_aside, AsideTestType)
assert isinstance(problem_aside, AsideTestType)
problem_aside.data_field = 'new problem value'
problem_aside.content = 'new content value'
self.store.update_item(new_problem, self.user_id, asides=[problem_aside])
@@ -3607,44 +3565,44 @@ class TestPublishOverExportImport(CommonMixedModuleStoreSetup):
raise_on_failure=True,
)
self.assertEqual(1, len(courses2))
assert 1 == len(courses2)
# check that aside for the new chapter was exported/imported properly
chapters = courses2[0].get_children()
self.assertEqual(2, len(chapters))
self.assertIn(new_chapter_display_name, [item.display_name for item in chapters])
assert 2 == len(chapters)
assert new_chapter_display_name in [item.display_name for item in chapters]
found = False
for child in chapters:
if new_chapter.display_name == child.display_name:
found = True
asides = child.runtime.get_asides(child)
self.assertEqual(len(asides), 1)
assert len(asides) == 1
child_aside = asides[0]
self.assertIsInstance(child_aside, AsideTestType)
self.assertEqual(child_aside.data_field, 'new value')
assert isinstance(child_aside, AsideTestType)
assert child_aside.data_field == 'new value'
break
self.assertTrue(found, "new_chapter not found")
assert found, 'new_chapter not found'
# check that aside for the new problem was exported/imported properly
sequence_children = courses2[0].get_children()[0].get_children()[0].get_children()
self.assertEqual(2, len(sequence_children))
self.assertIn(new_problem_display_name, [item.display_name for item in sequence_children])
assert 2 == len(sequence_children)
assert new_problem_display_name in [item.display_name for item in sequence_children]
found = False
for child in sequence_children:
if new_problem.display_name == child.display_name:
found = True
asides = child.runtime.get_asides(child)
self.assertEqual(len(asides), 1)
assert len(asides) == 1
child_aside = asides[0]
self.assertIsInstance(child_aside, AsideTestType)
self.assertEqual(child_aside.data_field, 'new problem value')
self.assertEqual(child_aside.content, 'new content value')
assert isinstance(child_aside, AsideTestType)
assert child_aside.data_field == 'new problem value'
assert child_aside.content == 'new content value'
break
self.assertTrue(found, "new_chapter not found")
assert found, 'new_chapter not found'
@ddt.ddt
@@ -3704,12 +3662,12 @@ class TestAsidesWithMixedModuleStore(CommonMixedModuleStoreSetup):
def _check_asides(asides, field11, field12, field21, field22):
""" Helper function to check asides """
self.assertEqual(len(asides), 2)
self.assertEqual({type(asides[0]), type(asides[1])}, {AsideFoo, AsideBar})
self.assertEqual(asides[0].field11, field11)
self.assertEqual(asides[0].field12, field12)
self.assertEqual(asides[1].field21, field21)
self.assertEqual(asides[1].field22, field22)
assert len(asides) == 2
assert {type(asides[0]), type(asides[1])} == {AsideFoo, AsideBar}
assert asides[0].field11 == field11
assert asides[0].field12 == field12
assert asides[1].field21 == field21
assert asides[1].field22 == field22
# get saved item and check asides
component = self.store.get_item(published_xblock.location)
@@ -3767,13 +3725,13 @@ class TestAsidesWithMixedModuleStore(CommonMixedModuleStoreSetup):
for block in actual_items:
if block.scope_ids.block_type == 'chapter':
asides = block.runtime.get_asides(block)
self.assertEqual(len(asides), 1)
self.assertEqual(asides[0].field11, 'test1')
self.assertEqual(asides[0].field12, 'aside1_default_value2')
assert len(asides) == 1
assert asides[0].field11 == 'test1'
assert asides[0].field12 == 'aside1_default_value2'
chapter_is_found = True
break
self.assertTrue(chapter_is_found)
assert chapter_is_found
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
@XBlockAside.register_temp_plugin(AsideFoo, 'test_aside1')
@@ -3805,8 +3763,8 @@ class TestAsidesWithMixedModuleStore(CommonMixedModuleStoreSetup):
)
asides = published_xblock.runtime.get_asides(published_xblock)
self.assertEqual(asides[0].field11, 'new_value11')
self.assertEqual(asides[0].field12, 'new_value12')
assert asides[0].field11 == 'new_value11'
assert asides[0].field12 == 'new_value12'
# remove item
self.store.delete_item(published_xblock.location, self.user_id)
@@ -3821,8 +3779,8 @@ class TestAsidesWithMixedModuleStore(CommonMixedModuleStoreSetup):
# check that aside has default values
asides2 = published_xblock2.runtime.get_asides(published_xblock2)
self.assertEqual(asides2[0].field11, 'aside1_default_value1')
self.assertEqual(asides2[0].field12, 'aside1_default_value2')
assert asides2[0].field11 == 'aside1_default_value1'
assert asides2[0].field12 == 'aside1_default_value2'
@ddt.data((ModuleStoreEnum.Type.mongo, 1, 0), (ModuleStoreEnum.Type.split, 2, 0))
@XBlockAside.register_temp_plugin(AsideFoo, 'test_aside1')
@@ -3849,15 +3807,15 @@ class TestAsidesWithMixedModuleStore(CommonMixedModuleStoreSetup):
def _check_asides(item):
""" Helper function to check asides """
asides = item.runtime.get_asides(item)
self.assertEqual(asides[0].field11, 'new_value11')
self.assertEqual(asides[0].field12, 'new_value12')
assert asides[0].field11 == 'new_value11'
assert asides[0].field12 == 'new_value12'
# start off as Private
item = self.store.create_child(self.user_id, self.writable_chapter_location, 'problem',
'test_compute_publish_state', asides=[aside1])
item_location = item.location
with check_mongo_calls(max_find, max_send):
self.assertFalse(self.store.has_published_version(item))
assert not self.store.has_published_version(item)
_check_asides(item)
# Private -> Public
@@ -3865,7 +3823,7 @@ class TestAsidesWithMixedModuleStore(CommonMixedModuleStoreSetup):
_check_asides(published_block)
item = self.store.get_item(item_location)
self.assertTrue(self.store.has_published_version(item))
assert self.store.has_published_version(item)
_check_asides(item)
# Public -> Private
@@ -3873,5 +3831,5 @@ class TestAsidesWithMixedModuleStore(CommonMixedModuleStoreSetup):
_check_asides(unpublished_block)
item = self.store.get_item(item_location)
self.assertFalse(self.store.has_published_version(item))
assert not self.store.has_published_version(item)
_check_asides(item)

View File

@@ -5,7 +5,7 @@ Tests for testing the modulestore settings migration code.
import copy
from unittest import TestCase
import pytest
import ddt
from openedx.core.lib.tempdir import mkdtemp_clean
@@ -124,7 +124,7 @@ class ModuleStoreSettingsMigration(TestCase):
"""
store_fields = ["OPTIONS", "DOC_STORE_CONFIG"]
for field in store_fields:
self.assertEqual(store_setting1[field], store_setting2[field])
assert store_setting1[field] == store_setting2[field]
def assertMigrated(self, old_setting):
"""
@@ -135,11 +135,11 @@ class ModuleStoreSettingsMigration(TestCase):
new_mixed_setting = convert_module_store_setting_if_needed(copy.deepcopy(old_setting))
# check whether the configuration is encapsulated within Mixed.
self.assertEqual(new_mixed_setting["default"]["ENGINE"], "xmodule.modulestore.mixed.MixedModuleStore")
assert new_mixed_setting['default']['ENGINE'] == 'xmodule.modulestore.mixed.MixedModuleStore'
# check whether the stores are in an ordered list
new_stores = get_mixed_stores(new_mixed_setting)
self.assertIsInstance(new_stores, list)
assert isinstance(new_stores, list)
return new_mixed_setting, new_stores[0]
@@ -151,9 +151,9 @@ class ModuleStoreSettingsMigration(TestCase):
split_settings = [store for store in stores if store['ENGINE'].endswith('.DraftVersioningModuleStore')]
if len(split_settings): # lint-amnesty, pylint: disable=len-as-condition
# there should only be one setting for split
self.assertEqual(len(split_settings), 1)
assert len(split_settings) == 1
# verify name
self.assertEqual(split_settings[0]['NAME'], 'split')
assert split_settings[0]['NAME'] == 'split'
# verify split config settings equal those of mongo
self.assertStoreValuesEqual(
split_settings[0],
@@ -165,28 +165,28 @@ class ModuleStoreSettingsMigration(TestCase):
old_setting = self.OLD_CONFIG
new_mixed_setting, new_default_store_setting = self.assertMigrated(old_setting)
self.assertStoreValuesEqual(new_default_store_setting, old_setting["default"])
self.assertEqual(new_default_store_setting["ENGINE"], old_setting["default"]["ENGINE"])
self.assertFalse(self.is_split_configured(new_mixed_setting))
assert new_default_store_setting['ENGINE'] == old_setting['default']['ENGINE']
assert not self.is_split_configured(new_mixed_setting)
def test_convert_from_old_mongo_to_draft_store(self):
old_setting = self.OLD_CONFIG_WITH_DIRECT_MONGO
new_mixed_setting, new_default_store_setting = self.assertMigrated(old_setting)
self.assertStoreValuesEqual(new_default_store_setting, old_setting["default"])
self.assertEqual(new_default_store_setting["ENGINE"], "xmodule.modulestore.mongo.draft.DraftModuleStore")
self.assertTrue(self.is_split_configured(new_mixed_setting))
assert new_default_store_setting['ENGINE'] == 'xmodule.modulestore.mongo.draft.DraftModuleStore'
assert self.is_split_configured(new_mixed_setting)
def test_convert_from_dict_to_list(self):
old_mixed_setting = self.OLD_MIXED_CONFIG_WITH_DICT
new_mixed_setting, new_default_store_setting = self.assertMigrated(old_mixed_setting)
self.assertEqual(new_default_store_setting["ENGINE"], "the_default_store")
self.assertTrue(self.is_split_configured(new_mixed_setting))
assert new_default_store_setting['ENGINE'] == 'the_default_store'
assert self.is_split_configured(new_mixed_setting)
# exclude split when comparing old and new, since split was added as part of the migration
new_stores = [store for store in get_mixed_stores(new_mixed_setting) if store['NAME'] != 'split']
old_stores = get_mixed_stores(self.OLD_MIXED_CONFIG_WITH_DICT)
# compare each store configured in mixed
self.assertEqual(len(new_stores), len(old_stores))
assert len(new_stores) == len(old_stores)
for new_store in new_stores:
self.assertStoreValuesEqual(new_store, old_stores[new_store['NAME']])
@@ -194,16 +194,16 @@ class ModuleStoreSettingsMigration(TestCase):
# make sure there is no migration done on an already updated config
old_mixed_setting = self.ALREADY_UPDATED_MIXED_CONFIG
new_mixed_setting, new_default_store_setting = self.assertMigrated(old_mixed_setting) # lint-amnesty, pylint: disable=unused-variable
self.assertTrue(self.is_split_configured(new_mixed_setting))
self.assertEqual(old_mixed_setting, new_mixed_setting)
assert self.is_split_configured(new_mixed_setting)
assert old_mixed_setting == new_mixed_setting
@ddt.data('draft', 'split')
def test_update_settings(self, default_store):
mixed_setting = self.ALREADY_UPDATED_MIXED_CONFIG
update_module_store_settings(mixed_setting, default_store=default_store)
self.assertEqual(get_mixed_stores(mixed_setting)[0]['NAME'], default_store)
assert get_mixed_stores(mixed_setting)[0]['NAME'] == default_store
def test_update_settings_error(self):
mixed_setting = self.ALREADY_UPDATED_MIXED_CONFIG
with self.assertRaises(Exception):
with pytest.raises(Exception):
update_module_store_settings(mixed_setting, default_store='non-existent store')

View File

@@ -298,7 +298,7 @@ class TestMongoModuleStore(TestMongoModuleStoreBase):
"""
course_key = CourseKey.from_string('course-v1:edX+simple+2012_Fall')
with self.assertRaises(ItemNotFoundError):
with pytest.raises(ItemNotFoundError):
self.draft_store.get_course(course_key)
def test_has_mongo_course_with_split_course_key(self):
@@ -307,7 +307,7 @@ class TestMongoModuleStore(TestMongoModuleStoreBase):
"""
course_key = CourseKey.from_string('course-v1:edX+simple+2012_Fall')
self.assertFalse(self.draft_store.has_course(course_key))
assert not self.draft_store.has_course(course_key)
def test_has_course_with_library(self):
"""
@@ -369,10 +369,8 @@ class TestMongoModuleStore(TestMongoModuleStoreBase):
def test_get_courses_has_no_templates(self):
courses = self.draft_store.get_courses()
for course in courses:
self.assertFalse(
course.location.org == 'edx' and course.location.course == 'templates',
assert not ((course.location.org == 'edx') and (course.location.course == 'templates')),\
'{0} is a template course'.format(course)
)
def test_contentstore_attrs(self):
"""
@@ -566,8 +564,8 @@ class TestMongoModuleStore(TestMongoModuleStoreBase):
root_dir = path(mkdtemp())
self.addCleanup(shutil.rmtree, root_dir)
export_course_to_xml(self.draft_store, self.content_store, course_key, root_dir, u'test_export')
self.assertTrue(path(root_dir / 'test_export/static/images/course_image.jpg').isfile())
self.assertTrue(path(root_dir / 'test_export/static/images_course_image.jpg').isfile())
assert path((root_dir / 'test_export/static/images/course_image.jpg')).isfile()
assert path((root_dir / 'test_export/static/images_course_image.jpg')).isfile()
@patch('xmodule.video_module.video_module.edxval_api', None)
@patch('xmodule.tabs.CourseTab.from_json', side_effect=mock_tab_from_json)
@@ -582,8 +580,8 @@ class TestMongoModuleStore(TestMongoModuleStoreBase):
root_dir = path(mkdtemp())
self.addCleanup(shutil.rmtree, root_dir)
export_course_to_xml(self.draft_store, self.content_store, course.id, root_dir, u'test_export')
self.assertTrue(path(root_dir / 'test_export/static/just_a_test.jpg').isfile())
self.assertFalse(path(root_dir / 'test_export/static/images/course_image.jpg').isfile())
assert path((root_dir / 'test_export/static/just_a_test.jpg')).isfile()
assert not path((root_dir / 'test_export/static/images/course_image.jpg')).isfile()
@patch('xmodule.video_module.video_module.edxval_api', None)
def test_course_without_image(self):
@@ -595,8 +593,8 @@ class TestMongoModuleStore(TestMongoModuleStoreBase):
root_dir = path(mkdtemp())
self.addCleanup(shutil.rmtree, root_dir)
export_course_to_xml(self.draft_store, self.content_store, course.id, root_dir, u'test_export')
self.assertFalse(path(root_dir / 'test_export/static/images/course_image.jpg').isfile())
self.assertFalse(path(root_dir / 'test_export/static/images_course_image.jpg').isfile())
assert not path((root_dir / 'test_export/static/images/course_image.jpg')).isfile()
assert not path((root_dir / 'test_export/static/images_course_image.jpg')).isfile()
def _create_test_tree(self, name, user_id=None):
"""
@@ -677,8 +675,8 @@ class TestMongoModuleStore(TestMongoModuleStoreBase):
# Retrieve the block and verify its fields
component = self.draft_store.get_item(location)
self.assertEqual(component.published_on, published_date)
self.assertEqual(component.published_by, published_by)
assert component.published_on == published_date
assert component.published_by == published_by
def test_draft_modulestore_create_child_with_position(self):
"""
@@ -703,8 +701,8 @@ class TestMongoModuleStore(TestMongoModuleStoreBase):
# First child should have been moved to second position, and better child takes the lead
course = self.draft_store.get_course(course.id)
self.assertEqual(six.text_type(course.children[1]), six.text_type(first_child.location))
self.assertEqual(six.text_type(course.children[0]), six.text_type(second_child.location))
assert six.text_type(course.children[1]) == six.text_type(first_child.location)
assert six.text_type(course.children[0]) == six.text_type(second_child.location)
# Clean up the data so we don't break other tests which apparently expect a particular state
self.draft_store.delete_course(course.id, self.dummy_user)
@@ -713,8 +711,8 @@ class TestMongoModuleStore(TestMongoModuleStoreBase):
"""Test that we get back the appropriate usage key for the root of a course key."""
course_key = CourseLocator(org="edX", course="101", run="2015")
root_block_key = self.draft_store.make_course_usage_key(course_key)
self.assertEqual(root_block_key.block_type, "course")
self.assertEqual(root_block_key.block_id, "2015")
assert root_block_key.block_type == 'course'
assert root_block_key.block_id == '2015'
class TestMongoModuleStoreWithNoAssetCollection(TestMongoModuleStore): # lint-amnesty, pylint: disable=test-inherits-tests
@@ -741,12 +739,12 @@ class TestMongoModuleStoreWithNoAssetCollection(TestMongoModuleStore): # lint-a
courses = self.draft_store.get_courses()
course = courses[0]
# Confirm that no specified asset collection name means empty asset metadata.
self.assertEqual(self.draft_store.get_all_asset_metadata(course.id, 'asset'), [])
assert self.draft_store.get_all_asset_metadata(course.id, 'asset') == []
def test_no_asset_invalid_key(self):
course_key = CourseLocator(org="edx3", course="test_course", run=None, deprecated=True)
# Confirm that invalid course key raises ItemNotFoundError
self.assertRaises(ItemNotFoundError, lambda: self.draft_store.get_all_asset_metadata(course_key, 'asset')[:1])
pytest.raises(ItemNotFoundError, (lambda: self.draft_store.get_all_asset_metadata(course_key, 'asset')[:1]))
class TestMongoKeyValueStore(TestCase):

View File

@@ -13,6 +13,7 @@ from contextlib import contextmanager
from shutil import rmtree
from tempfile import mkdtemp
import pytest
import ddt
import six
from six.moves import range
@@ -136,7 +137,7 @@ class TestPublish(SplitWMongoCourseBootstrapper):
# verify status
item = self.draft_mongo.get_item(vert_location, 0)
self.assertFalse(getattr(item, 'is_draft', False), "Item was published. Draft should not exist")
assert not getattr(item, 'is_draft', False), 'Item was published. Draft should not exist'
# however, children are still draft, but I'm not sure that's by design
# delete the draft version of the discussion
@@ -144,8 +145,8 @@ class TestPublish(SplitWMongoCourseBootstrapper):
self.draft_mongo.delete_item(location, self.user_id)
draft_vert = self.draft_mongo.get_item(vert_location, 0)
self.assertTrue(getattr(draft_vert, 'is_draft', False), "Deletion didn't convert parent to draft")
self.assertNotIn(location, draft_vert.children)
assert getattr(draft_vert, 'is_draft', False), "Deletion didn't convert parent to draft"
assert location not in draft_vert.children
# move the other child
other_child_loc = self.old_course_key.make_usage_key('html', block_id='Html2')
draft_vert.children.remove(other_child_loc)
@@ -156,12 +157,12 @@ class TestPublish(SplitWMongoCourseBootstrapper):
# publish
self.draft_mongo.publish(vert_location, self.user_id)
item = self.draft_mongo.get_item(draft_vert.location, revision=ModuleStoreEnum.RevisionOption.published_only)
self.assertNotIn(location, item.children)
self.assertIsNone(self.draft_mongo.get_parent_location(location))
with self.assertRaises(ItemNotFoundError):
assert location not in item.children
assert self.draft_mongo.get_parent_location(location) is None
with pytest.raises(ItemNotFoundError):
self.draft_mongo.get_item(location)
self.assertNotIn(other_child_loc, item.children)
self.assertTrue(self.draft_mongo.has_item(other_child_loc), "Oops, lost moved item")
assert other_child_loc not in item.children
assert self.draft_mongo.has_item(other_child_loc), 'Oops, lost moved item'
class DraftPublishedOpTestCourseSetup(unittest.TestCase):
@@ -305,10 +306,7 @@ class OLXFormatChecker(unittest.TestCase):
self._ensure_exported()
block_path = os.path.join(self.root_export_dir, self.export_dir) # pylint: disable=no-member
self.assertTrue(
os.path.isdir(block_path),
msg='{} is not a dir.'.format(block_path)
)
assert os.path.isdir(block_path), '{} is not a dir.'.format(block_path)
return block_path
def _get_block_type_path(self, course_export_dir, block_type, draft):
@@ -335,10 +333,7 @@ class OLXFormatChecker(unittest.TestCase):
block_file = self._get_block_filename(block_id)
block_file_path = os.path.join(block_subdir_path, block_file)
self.assertTrue(
os.path.isfile(block_file_path),
msg='{} is not an existing file.'.format(block_file_path)
)
assert os.path.isfile(block_file_path), '{} is not an existing file.'.format(block_file_path)
with open(block_file_path, "r") as file_handle:
return file_handle.read()
@@ -350,7 +345,7 @@ class OLXFormatChecker(unittest.TestCase):
element (ElementTree.Element): the element to check.
tag (str): The tag to validate.
"""
self.assertEqual(element.tag, tag)
assert element.tag == tag
def assertElementAttrsSubset(self, element, attrs):
"""
@@ -395,10 +390,7 @@ class OLXFormatChecker(unittest.TestCase):
is_draft = kwargs.pop('draft', False)
block_path = self._get_block_type_path(course_export_dir, block_type, is_draft)
block_file_path = os.path.join(block_path, self._get_block_filename(block_id))
self.assertFalse(
os.path.exists(block_file_path),
msg='{} exists but should not!'.format(block_file_path)
)
assert not os.path.exists(block_file_path), '{} exists but should not!'.format(block_file_path)
def assertParentReferences(self, element, course_key, parent_type, parent_id, index_in_children_list):
"""
@@ -458,7 +450,7 @@ class OLXFormatChecker(unittest.TestCase):
"""
for block_data in block_list:
block_params = self.course_db.get(block_data)
self.assertIsNotNone(block_params)
assert block_params is not None
(block_type, block_id) = block_data
if draft:
element = self.parse_olx(block_type, block_id, draft=True)
@@ -691,7 +683,7 @@ class ElementalPublishingTests(DraftPublishedOpBaseTestSetup):
# In Split, you cannot publish an item whose parents are unpublished.
# Split will raise an exception when the item's parent(s) aren't found
# in the published branch.
with self.assertRaises(ItemNotFoundError):
with pytest.raises(ItemNotFoundError):
self.publish((('html', 'html00'),))
@ddt.data(*MODULESTORE_SETUPS)
@@ -839,7 +831,7 @@ class ElementalUnpublishingTests(DraftPublishedOpBaseTestSetup):
# The unit is a draft.
self.assertOLXIsDraftOnly(block_list_to_unpublish)
# Since there's no published version, attempting an unpublish throws an exception.
with self.assertRaises(ItemNotFoundError):
with pytest.raises(ItemNotFoundError):
self.unpublish(block_list_to_unpublish)
@ddt.data(*MODULESTORE_SETUPS)
@@ -887,7 +879,7 @@ class ElementalUnpublishingTests(DraftPublishedOpBaseTestSetup):
# The vertical is a draft.
self.assertOLXIsDraftOnly(block_list_to_unpublish)
# Since there's no published version, attempting an unpublish throws an exception.
with self.assertRaises(ItemNotFoundError):
with pytest.raises(ItemNotFoundError):
self.unpublish(block_list_to_unpublish)
@ddt.data(*MODULESTORE_SETUPS)
@@ -939,7 +931,7 @@ class ElementalUnpublishingTests(DraftPublishedOpBaseTestSetup):
block_list_to_unpublish = (
('sequential', 'sequential03'),
)
with self.assertRaises(InvalidVersionError):
with pytest.raises(InvalidVersionError):
self.unpublish(block_list_to_unpublish)
@@ -983,7 +975,7 @@ class ElementalDeleteItemTests(DraftPublishedOpBaseTestSetup):
if revision in (ModuleStoreEnum.RevisionOption.published_only, ModuleStoreEnum.RevisionOption.all):
# Split throws an exception when trying to delete an item from the published branch
# that isn't yet published.
with self.assertRaises(ValueError):
with pytest.raises(ValueError):
self.delete_item(block_list_to_delete, revision=revision)
else:
self.delete_item(block_list_to_delete, revision=revision)
@@ -1060,7 +1052,7 @@ class ElementalDeleteItemTests(DraftPublishedOpBaseTestSetup):
# MODULESTORE_DIFFERENCE:
# Split throws an exception when trying to delete an item from the published branch
# that isn't yet published.
with self.assertRaises(ValueError):
with pytest.raises(ValueError):
self.delete_item(block_list_to_delete, revision=revision)
else:
self.delete_item(block_list_to_delete, revision=revision)
@@ -1190,7 +1182,7 @@ class ElementalConvertToDraftTests(DraftPublishedOpBaseTestSetup):
elif self.is_old_mongo_modulestore:
# Old Mongo:
# Direct-only categories are never allowed to be converted to draft.
with self.assertRaises(InvalidVersionError):
with pytest.raises(InvalidVersionError):
self.convert_to_draft(block_list_to_convert)
else:
raise Exception("Must test either Old Mongo or Split modulestore!")
@@ -1212,7 +1204,7 @@ class ElementalRevertToPublishedTests(DraftPublishedOpBaseTestSetup):
self.assertOLXIsDraftOnly(block_list_to_revert)
# Now, without publishing anything first, revert the same vertical to published.
# Since no published version exists, an exception is raised.
with self.assertRaises(InvalidVersionError):
with pytest.raises(InvalidVersionError):
self.revert_to_published(block_list_to_revert)
@ddt.data(*MODULESTORE_SETUPS)

View File

@@ -6,6 +6,7 @@ Tests of modulestore semantics: How do the interfaces methods of ModuleStore rel
import itertools
from collections import namedtuple
import pytest
import ddt
from mock import patch
from xblock.core import XBlock, XBlockAside
@@ -79,12 +80,12 @@ class DirectOnlyCategorySemantics(PureModulestoreTestCase):
"""
if draft is None or draft:
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred):
with self.assertRaises(ItemNotFoundError):
with pytest.raises(ItemNotFoundError):
self.store.get_item(block_usage_key)
if draft is None or not draft:
with self.store.branch_setting(ModuleStoreEnum.Branch.published_only):
with self.assertRaises(ItemNotFoundError):
with pytest.raises(ItemNotFoundError):
self.store.get_item(block_usage_key)
def assertBlockHasContent(self, block_usage_key, field_name, content,
@@ -108,22 +109,22 @@ class DirectOnlyCategorySemantics(PureModulestoreTestCase):
target_block = self.store.get_item(
block_usage_key,
)
self.assertEqual(content, target_block.fields[field_name].read_from(target_block))
assert content == target_block.fields[field_name].read_from(target_block)
if aside_field_name and aside_content:
aside = self._get_aside(target_block)
self.assertIsNotNone(aside)
self.assertEqual(aside_content, aside.fields[aside_field_name].read_from(aside))
assert aside is not None
assert aside_content == aside.fields[aside_field_name].read_from(aside)
if draft is None or draft:
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred):
target_block = self.store.get_item(
block_usage_key,
)
self.assertEqual(content, target_block.fields[field_name].read_from(target_block))
assert content == target_block.fields[field_name].read_from(target_block)
if aside_field_name and aside_content:
aside = self._get_aside(target_block)
self.assertIsNotNone(aside)
self.assertEqual(aside_content, aside.fields[aside_field_name].read_from(aside))
assert aside is not None
assert aside_content == aside.fields[aside_field_name].read_from(aside)
def assertParentOf(self, parent_usage_key, child_usage_key, draft=None):
"""
@@ -142,14 +143,14 @@ class DirectOnlyCategorySemantics(PureModulestoreTestCase):
parent_block = self.store.get_item(
parent_usage_key,
)
self.assertIn(child_usage_key, parent_block.children)
assert child_usage_key in parent_block.children
if draft is None or draft:
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred):
parent_block = self.store.get_item(
parent_usage_key,
)
self.assertIn(child_usage_key, parent_block.children)
assert child_usage_key in parent_block.children
def assertNotParentOf(self, parent_usage_key, child_usage_key, draft=None):
"""
@@ -168,14 +169,14 @@ class DirectOnlyCategorySemantics(PureModulestoreTestCase):
parent_block = self.store.get_item(
parent_usage_key,
)
self.assertNotIn(child_usage_key, parent_block.children)
assert child_usage_key not in parent_block.children
if draft is None or draft:
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred):
parent_block = self.store.get_item(
parent_usage_key,
)
self.assertNotIn(child_usage_key, parent_block.children)
assert child_usage_key not in parent_block.children
def assertCoursePointsToBlock(self, block_usage_key, draft=None):
"""
@@ -215,7 +216,7 @@ class DirectOnlyCategorySemantics(PureModulestoreTestCase):
expected_fields = CourseSummary.course_info_fields + ['id', 'location', 'has_ended']
return all([hasattr(course_summary, field) for field in expected_fields])
self.assertTrue(all(verify_course_summery_fields(course_summary) for course_summary in course_summaries))
assert all((verify_course_summery_fields(course_summary) for course_summary in course_summaries))
def is_detached(self, block_type):
"""
@@ -313,7 +314,7 @@ class DirectOnlyCategorySemantics(PureModulestoreTestCase):
test_data = self.DATA_FIELDS[block_type]
updated_field_value = test_data.updated
self.assertNotEqual(updated_field_value, block.fields[test_data.field_name].read_from(block))
assert updated_field_value != block.fields[test_data.field_name].read_from(block)
block.fields[test_data.field_name].write_to(block, updated_field_value)
@@ -338,13 +339,13 @@ class DirectOnlyCategorySemantics(PureModulestoreTestCase):
course_summaries = self.store.get_course_summaries()
# Verify course summaries
self.assertEqual(len(course_summaries), 1)
assert len(course_summaries) == 1
# Verify that all course summary objects have the required attributes.
self.assertCourseSummaryFields(course_summaries)
# Verify fetched accessible courses list is a list of CourseSummery instances
self.assertTrue(all(isinstance(course, CourseSummary) for course in course_summaries))
assert all((isinstance(course, CourseSummary) for course in course_summaries))
@ddt.data(*itertools.product(['chapter', 'sequential'], [True, False]))
@ddt.unpack
@@ -437,7 +438,7 @@ class TestSplitDirectOnlyCategorySemantics(DirectOnlyCategorySemantics):
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred):
block = self.store.get_item(block_usage_key)
aside = self._get_aside(block)
self.assertIsNotNone(aside)
assert aside is not None
aside.fields[self.ASIDE_DATA_FIELD.field_name].write_to(aside, self.ASIDE_DATA_FIELD.updated)
self.store.update_item(block, ModuleStoreEnum.UserID.test, allow_not_found=True, asides=[aside])

View File

@@ -7,6 +7,7 @@ However for these tests, we make sure it also works when copying from course to
import ddt
from six.moves import range
import pytest
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.exceptions import ItemNotFoundError
@@ -49,20 +50,20 @@ class TestSplitCopyTemplate(MixedSplitTestCase):
# Inherit the vertical and the problem from the library into the course:
source_keys = [source_container.children[0]]
new_blocks = self.store.copy_from_template(source_keys, dest_key=course.location, user_id=self.user_id)
self.assertEqual(len(new_blocks), 1)
assert len(new_blocks) == 1
course = self.store.get_course(course.location.course_key) # Reload from modulestore
self.assertEqual(len(course.children), 1)
assert len(course.children) == 1
vertical_block_course = self.store.get_item(course.children[0])
self.assertEqual(new_blocks[0], vertical_block_course.location)
assert new_blocks[0] == vertical_block_course.location
problem_block_course = self.store.get_item(vertical_block_course.children[0])
self.assertEqual(problem_block_course.display_name, problem_library_display_name)
assert problem_block_course.display_name == problem_library_display_name
# Check that when capa modules are copied, their "markdown" fields (Scope.settings) are removed.
# (See note in split.py:copy_from_template())
self.assertIsNotNone(problem_block.markdown)
self.assertIsNone(problem_block_course.markdown)
assert problem_block.markdown is not None
assert problem_block_course.markdown is None
# Override the display_name and weight:
new_display_name = "The Trouble with Tribbles"
@@ -77,16 +78,16 @@ class TestSplitCopyTemplate(MixedSplitTestCase):
# Repeat the copy_from_template():
new_blocks2 = self.store.copy_from_template(source_keys, dest_key=course.location, user_id=self.user_id)
self.assertEqual(new_blocks, new_blocks2)
assert new_blocks == new_blocks2
# Reload problem_block_course:
problem_block_course = self.store.get_item(problem_block_course.location)
self.assertEqual(problem_block_course.display_name, new_display_name)
self.assertEqual(problem_block_course.weight, new_weight)
assert problem_block_course.display_name == new_display_name
assert problem_block_course.weight == new_weight
# Ensure that extra_block was deleted:
vertical_block_course = self.store.get_item(new_blocks2[0])
self.assertEqual(len(vertical_block_course.children), 1)
with self.assertRaises(ItemNotFoundError):
assert len(vertical_block_course.children) == 1
with pytest.raises(ItemNotFoundError):
self.store.get_item(extra_block.location)
def test_copy_from_template_publish(self):
@@ -119,7 +120,7 @@ class TestSplitCopyTemplate(MixedSplitTestCase):
problem_published = self.store.get_item(
problem_key_in_course.for_branch(ModuleStoreEnum.BranchName.published)
)
self.assertEqual(problem_published.display_name, display_name_expected)
assert problem_published.display_name == display_name_expected
def test_copy_from_template_auto_publish(self):
"""
@@ -146,7 +147,7 @@ class TestSplitCopyTemplate(MixedSplitTestCase):
# Inherit the vertical and the problem from the library into the course:
source_keys = [block.location for block in [about, chapter, html]]
block_keys = self.store.copy_from_template(source_keys, dest_key=course.location, user_id=self.user_id)
self.assertEqual(len(block_keys), len(source_keys))
assert len(block_keys) == len(source_keys)
# Build dict of the new blocks in 'course', keyed by category (which is a unique key in our case)
new_blocks = {}
@@ -167,14 +168,15 @@ class TestSplitCopyTemplate(MixedSplitTestCase):
return False
# Check that the auto-publish blocks have been published:
self.assertFalse(self.store.has_changes(new_blocks["about"]))
assert not self.store.has_changes(new_blocks['about'])
# We can't use has_changes because it includes descendants
self.assertTrue(published_version_exists(new_blocks["chapter"]))
self.assertTrue(published_version_exists(new_blocks["sequential"])) # Ditto
assert published_version_exists(new_blocks['chapter'])
assert published_version_exists(new_blocks['sequential'])
# Ditto
# Check that non-auto-publish blocks and blocks with non-auto-publish descendants show changes:
self.assertTrue(self.store.has_changes(new_blocks["html"]))
self.assertTrue(self.store.has_changes(new_blocks["problem"]))
assert self.store.has_changes(new_blocks['html'])
assert self.store.has_changes(new_blocks['problem'])
# Will have changes since a child block has changes.
self.assertTrue(self.store.has_changes(new_blocks["chapter"]))
assert self.store.has_changes(new_blocks['chapter'])
# Verify that our published_version_exists works
self.assertFalse(published_version_exists(new_blocks["vertical"]))
assert not published_version_exists(new_blocks['vertical'])

View File

@@ -165,7 +165,7 @@ class TestMigration(SplitWMongoCourseBootstrapper):
def compare_dags(self, presplit, presplit_dag_root, split_dag_root, published): # lint-amnesty, pylint: disable=missing-function-docstring
if split_dag_root.category != 'course':
self.assertEqual(presplit_dag_root.location.block_id, split_dag_root.location.block_id)
assert presplit_dag_root.location.block_id == split_dag_root.location.block_id
# compare all fields but references
for name, field in six.iteritems(presplit_dag_root.fields):
# fields generated from UNIQUE_IDs are unique to an XBlock's scope,
@@ -176,23 +176,11 @@ class TestMigration(SplitWMongoCourseBootstrapper):
field_generated_from_unique_id or isinstance(field, (Reference, ReferenceList, ReferenceValueDict))
)
if should_check_field:
self.assertEqual(
getattr(presplit_dag_root, name),
getattr(split_dag_root, name),
u"{}/{}: {} != {}".format(
split_dag_root.location, name, getattr(presplit_dag_root, name), getattr(split_dag_root, name)
)
)
assert getattr(presplit_dag_root, name) == getattr(split_dag_root, name), f'{split_dag_root.location}/{name}: {getattr(presplit_dag_root, name)} != {getattr(split_dag_root, name)}' # pylint: disable=line-too-long
# compare children
if presplit_dag_root.has_children:
self.assertEqual(
# need get_children to filter out drafts
len(presplit_dag_root.get_children()), len(split_dag_root.children),
u"{0.category} '{0.display_name}': children {1} != {2}".format(
presplit_dag_root, presplit_dag_root.children, split_dag_root.children
)
)
assert len(presplit_dag_root.get_children()) == len(split_dag_root.children), f"{presplit_dag_root.category} '{presplit_dag_root.display_name}': children {presplit_dag_root.children} != {split_dag_root.children}" # pylint: disable=line-too-long
for pre_child, split_child in zip(presplit_dag_root.get_children(), split_dag_root.get_children()):
self.compare_dags(presplit, pre_child, split_child, published)

View File

@@ -10,6 +10,7 @@ import re
import unittest
from importlib import import_module
import pytest
import ddt
import six
from ccx_keys.locator import CCXBlockUsageLocator
@@ -589,25 +590,25 @@ class TestHasChildrenAtDepth(SplitModuleTest):
self.assertRaises(
ValueError, block.has_children_at_depth, -1,
)
self.assertTrue(block.has_children_at_depth(0))
self.assertTrue(block.has_children_at_depth(1))
self.assertFalse(block.has_children_at_depth(2))
assert block.has_children_at_depth(0)
assert block.has_children_at_depth(1)
assert not block.has_children_at_depth(2)
ch1 = modulestore().get_item(
BlockUsageLocator(course_locator, 'chapter', block_id='chapter1')
)
self.assertFalse(ch1.has_children_at_depth(0))
assert not ch1.has_children_at_depth(0)
ch2 = modulestore().get_item(
BlockUsageLocator(course_locator, 'chapter', block_id='chapter2')
)
self.assertFalse(ch2.has_children_at_depth(0))
assert not ch2.has_children_at_depth(0)
ch3 = modulestore().get_item(
BlockUsageLocator(course_locator, 'chapter', block_id='chapter3')
)
self.assertTrue(ch3.has_children_at_depth(0))
self.assertFalse(ch3.has_children_at_depth(1))
assert ch3.has_children_at_depth(0)
assert not ch3.has_children_at_depth(1)
@ddt.ddt
@@ -620,23 +621,17 @@ class SplitModuleCourseTests(SplitModuleTest):
def test_get_courses(self, _from_json):
courses = modulestore().get_courses(branch=BRANCH_NAME_DRAFT)
# should have gotten 3 draft courses
self.assertEqual(len(courses), 3, "Wrong number of courses")
assert len(courses) == 3, 'Wrong number of courses'
# check metadata -- NOTE no promised order
course = self.findByIdInResult(courses, "head12345")
self.assertEqual(course.location.org, "testx")
self.assertEqual(course.category, 'course', 'wrong category')
self.assertEqual(len(course.tabs), 6, "wrong number of tabs")
self.assertEqual(
course.display_name, "The Ancient Greek Hero",
"wrong display name"
)
self.assertEqual(
course.advertised_start, "Fall 2013",
"advertised_start"
)
self.assertEqual(len(course.children), 4, "children")
assert course.location.org == 'testx'
assert course.category == 'course', 'wrong category'
assert len(course.tabs) == 6, 'wrong number of tabs'
assert course.display_name == 'The Ancient Greek Hero', 'wrong display name'
assert course.advertised_start == 'Fall 2013', 'advertised_start'
assert len(course.children) == 4, 'children'
# check dates and graders--forces loading of descriptor
self.assertEqual(course.edited_by, "testassist@edx.org")
assert course.edited_by == 'testassist@edx.org'
self.assertDictEqual(course.grade_cutoffs, {"Pass": 0.45})
@patch('xmodule.tabs.CourseTab.from_json', side_effect=mock_tab_from_json)
@@ -647,7 +642,7 @@ class SplitModuleCourseTests(SplitModuleTest):
"""
courses = modulestore().get_courses(branch=BRANCH_NAME_DRAFT)
# Should have gotten 3 draft courses.
self.assertEqual(len(courses), 3)
assert len(courses) == 3
course_index = modulestore().get_course_index_info(courses[0].id)
# Creating a new course with same course index of another course.
@@ -656,44 +651,42 @@ class SplitModuleCourseTests(SplitModuleTest):
)
courses = modulestore().get_courses(branch=BRANCH_NAME_DRAFT)
# Should have gotten 4 draft courses.
self.assertEqual(len(courses), 4)
self.assertIn(new_draft_course.id.version_agnostic(), [c.id for c in courses])
assert len(courses) == 4
assert new_draft_course.id.version_agnostic() in [c.id for c in courses]
@patch('xmodule.tabs.CourseTab.from_json', side_effect=mock_tab_from_json)
def test_get_org_courses(self, _from_json):
courses = modulestore().get_courses(branch=BRANCH_NAME_DRAFT, org='guestx')
# should have gotten 1 draft courses
self.assertEqual(len(courses), 1)
assert len(courses) == 1
courses = modulestore().get_courses(branch=BRANCH_NAME_DRAFT, org='testx')
# should have gotten 2 draft courses
self.assertEqual(len(courses), 2)
assert len(courses) == 2
# although this is already covered in other tests, let's
# also not pass in org= parameter to make sure we get back
# 3 courses
courses = modulestore().get_courses(branch=BRANCH_NAME_DRAFT)
self.assertEqual(len(courses), 3)
assert len(courses) == 3
@patch('xmodule.tabs.CourseTab.from_json', side_effect=mock_tab_from_json)
def test_branch_requests(self, _from_json):
# query w/ branch qualifier (both draft and published)
def _verify_published_course(courses_published):
""" Helper function for verifying published course. """
self.assertEqual(len(courses_published), 1, len(courses_published))
assert len(courses_published) == 1, len(courses_published)
course = self.findByIdInResult(courses_published, "head23456")
self.assertIsNotNone(course, "published courses")
self.assertEqual(course.location.course_key.org, "testx")
self.assertEqual(course.location.course_key.course, "wonderful")
self.assertEqual(course.category, 'course', 'wrong category')
self.assertEqual(len(course.tabs), 4, "wrong number of tabs")
self.assertEqual(course.display_name, "The most wonderful course",
course.display_name)
self.assertIsNone(course.advertised_start)
self.assertEqual(len(course.children), 0,
"children")
assert course is not None, 'published courses'
assert course.location.course_key.org == 'testx'
assert course.location.course_key.course == 'wonderful'
assert course.category == 'course', 'wrong category'
assert len(course.tabs) == 4, 'wrong number of tabs'
assert course.display_name == 'The most wonderful course', course.display_name
assert course.advertised_start is None
assert len(course.children) == 0, 'children'
_verify_published_course(modulestore().get_courses(branch=BRANCH_NAME_PUBLISHED))
@@ -715,34 +708,34 @@ class SplitModuleCourseTests(SplitModuleTest):
'''
locator = CourseLocator(org='testx', course='GreekHero', run="run", branch=BRANCH_NAME_DRAFT)
head_course = modulestore().get_course(locator)
self.assertNotEqual(head_course.location.version_guid, head_course.previous_version)
assert head_course.location.version_guid != head_course.previous_version
locator = CourseLocator(version_guid=head_course.previous_version)
course = modulestore().get_course(locator)
self.assertIsNone(course.location.course_key.org)
self.assertEqual(course.location.version_guid, head_course.previous_version)
self.assertEqual(course.category, 'course')
self.assertEqual(len(course.tabs), 6)
self.assertEqual(course.display_name, "The Ancient Greek Hero")
self.assertEqual(course.graceperiod, datetime.timedelta(hours=2))
self.assertIsNone(course.advertised_start)
self.assertEqual(len(course.children), 0)
self.assertNotEqual(course.definition_locator.definition_id, head_course.definition_locator.definition_id)
assert course.location.course_key.org is None
assert course.location.version_guid == head_course.previous_version
assert course.category == 'course'
assert len(course.tabs) == 6
assert course.display_name == 'The Ancient Greek Hero'
assert course.graceperiod == datetime.timedelta(hours=2)
assert course.advertised_start is None
assert len(course.children) == 0
assert course.definition_locator.definition_id != head_course.definition_locator.definition_id
# check dates and graders--forces loading of descriptor
self.assertEqual(course.edited_by, "testassist@edx.org")
assert course.edited_by == 'testassist@edx.org'
self.assertDictEqual(course.grade_cutoffs, {"Pass": 0.55})
locator = CourseLocator(org='testx', course='GreekHero', run="run", branch=BRANCH_NAME_DRAFT)
course = modulestore().get_course(locator)
self.assertEqual(course.location.course_key.org, "testx")
self.assertEqual(course.location.course_key.course, "GreekHero")
self.assertEqual(course.location.course_key.run, "run")
self.assertEqual(course.category, 'course')
self.assertEqual(len(course.tabs), 6)
self.assertEqual(course.display_name, "The Ancient Greek Hero")
self.assertEqual(course.advertised_start, "Fall 2013")
self.assertEqual(len(course.children), 4)
assert course.location.course_key.org == 'testx'
assert course.location.course_key.course == 'GreekHero'
assert course.location.course_key.run == 'run'
assert course.category == 'course'
assert len(course.tabs) == 6
assert course.display_name == 'The Ancient Greek Hero'
assert course.advertised_start == 'Fall 2013'
assert len(course.children) == 4
# check dates and graders--forces loading of descriptor
self.assertEqual(course.edited_by, "testassist@edx.org")
assert course.edited_by == 'testassist@edx.org'
self.assertDictEqual(course.grade_cutoffs, {"Pass": 0.45})
locator = CourseLocator(org='testx', course='wonderful', run="run", branch=BRANCH_NAME_PUBLISHED)
@@ -751,15 +744,15 @@ class SplitModuleCourseTests(SplitModuleTest):
locator = CourseLocator(org='testx', course='wonderful', run="run", branch=BRANCH_NAME_DRAFT)
course = modulestore().get_course(locator)
self.assertNotEqual(course.location.version_guid, published_version)
assert course.location.version_guid != published_version
def test_get_course_negative(self):
# Now negative testing
with self.assertRaises(InsufficientSpecificationError):
with pytest.raises(InsufficientSpecificationError):
modulestore().get_course(CourseLocator(org='edu', course='meh', run='blah'))
with self.assertRaises(ItemNotFoundError):
with pytest.raises(ItemNotFoundError):
modulestore().get_course(CourseLocator(org='edu', course='nosuchthing', run="run", branch=BRANCH_NAME_DRAFT)) # lint-amnesty, pylint: disable=line-too-long
with self.assertRaises(ItemNotFoundError):
with pytest.raises(ItemNotFoundError):
modulestore().get_course(CourseLocator(org='testx', course='GreekHero', run="run", branch=BRANCH_NAME_PUBLISHED)) # lint-amnesty, pylint: disable=line-too-long
@patch('xmodule.tabs.CourseTab.from_json', side_effect=mock_tab_from_json)
@@ -772,8 +765,8 @@ class SplitModuleCourseTests(SplitModuleTest):
block_map = modulestore().cache_items(
course.system, [BlockKey.from_usage_key(child) for child in course.children], course.id, depth=3
)
self.assertIn(BlockKey('chapter', 'chapter1'), block_map)
self.assertIn(BlockKey('problem', 'problem3_2'), block_map)
assert BlockKey('chapter', 'chapter1') in block_map
assert BlockKey('problem', 'problem3_2') in block_map
@patch('xmodule.tabs.CourseTab.from_json', side_effect=mock_tab_from_json)
def test_course_successors(self, _from_json):
@@ -789,23 +782,23 @@ class SplitModuleCourseTests(SplitModuleTest):
locator = CourseLocator(version_guid=course.previous_version)
result = modulestore().get_course_successors(locator)
self.assertIsInstance(result, VersionTree)
self.assertIsNone(result.locator.org)
self.assertEqual(result.locator.version_guid, versions[-1])
self.assertEqual(len(result.children), 1)
self.assertEqual(result.children[0].locator.version_guid, versions[-2])
self.assertEqual(len(result.children[0].children), 0, "descended more than one level")
assert isinstance(result, VersionTree)
assert result.locator.org is None
assert result.locator.version_guid == versions[(- 1)]
assert len(result.children) == 1
assert result.children[0].locator.version_guid == versions[(- 2)]
assert len(result.children[0].children) == 0, 'descended more than one level'
result = modulestore().get_course_successors(locator, version_history_depth=2)
self.assertEqual(len(result.children), 1)
self.assertEqual(result.children[0].locator.version_guid, versions[-2])
self.assertEqual(len(result.children[0].children), 1)
assert len(result.children) == 1
assert result.children[0].locator.version_guid == versions[(- 2)]
assert len(result.children[0].children) == 1
result = modulestore().get_course_successors(locator, version_history_depth=99)
self.assertEqual(len(result.children), 1)
self.assertEqual(result.children[0].locator.version_guid, versions[-2])
self.assertEqual(len(result.children[0].children), 1)
self.assertEqual(result.children[0].children[0].locator.version_guid, versions[0])
assert len(result.children) == 1
assert result.children[0].locator.version_guid == versions[(- 2)]
assert len(result.children[0].children) == 1
assert result.children[0].children[0].locator.version_guid == versions[0]
@patch('xmodule.tabs.CourseTab.from_json', side_effect=mock_tab_from_json)
def test_persist_dag(self, _from_json):
@@ -821,7 +814,7 @@ class SplitModuleCourseTests(SplitModuleTest):
test_course.system, test_course.id, 'chapter', fields={'display_name': 'chapter n'},
parent_xblock=test_course
)
self.assertEqual(test_chapter.display_name, 'chapter n')
assert test_chapter.display_name == 'chapter n'
test_def_content = '<problem>boo</problem>'
# create child
new_block = modulestore().create_xblock(
@@ -833,24 +826,24 @@ class SplitModuleCourseTests(SplitModuleTest):
},
parent_xblock=test_chapter
)
self.assertIsNotNone(new_block.definition_locator)
self.assertTrue(isinstance(new_block.definition_locator.definition_id, LocalId))
assert new_block.definition_locator is not None
assert isinstance(new_block.definition_locator.definition_id, LocalId)
# better to pass in persisted parent over the subdag so
# subdag gets the parent pointer (otherwise 2 ops, persist dag, update parent children,
# persist parent
persisted_course = modulestore().persist_xblock_dag(test_course, 'testbot')
self.assertEqual(len(persisted_course.children), 1)
assert len(persisted_course.children) == 1
persisted_chapter = persisted_course.get_children()[0]
self.assertEqual(persisted_chapter.category, 'chapter')
self.assertEqual(persisted_chapter.display_name, 'chapter n')
self.assertEqual(len(persisted_chapter.children), 1)
assert persisted_chapter.category == 'chapter'
assert persisted_chapter.display_name == 'chapter n'
assert len(persisted_chapter.children) == 1
persisted_problem = persisted_chapter.get_children()[0]
self.assertEqual(persisted_problem.category, 'problem')
self.assertEqual(persisted_problem.data, test_def_content)
assert persisted_problem.category == 'problem'
assert persisted_problem.data == test_def_content
# update it
persisted_problem.display_name = 'altered problem'
persisted_problem = modulestore().update_item(persisted_problem, 'testbot')
self.assertEqual(persisted_problem.display_name, 'altered problem')
assert persisted_problem.display_name == 'altered problem'
@patch('xmodule.tabs.CourseTab.from_json', side_effect=mock_tab_from_json)
def test_block_generations(self, _from_json):
@@ -886,9 +879,9 @@ class SplitModuleCourseTests(SplitModuleTest):
first_problem.max_attempts = 3
first_problem.save() # decache the above into the kvs
updated_problem = modulestore().update_item(first_problem, 'testbot')
self.assertIsNotNone(updated_problem.previous_version)
self.assertEqual(updated_problem.previous_version, first_problem.update_version)
self.assertNotEqual(updated_problem.update_version, first_problem.update_version)
assert updated_problem.previous_version is not None
assert updated_problem.previous_version == first_problem.update_version
assert updated_problem.update_version != first_problem.update_version
modulestore().delete_item(updated_problem.location, 'testbot')
second_problem = modulestore().create_child(
@@ -901,27 +894,28 @@ class SplitModuleCourseTests(SplitModuleTest):
# The draft course root has 2 revisions: the published revision, and then the subsequent
# changes to the draft revision
version_history = modulestore().get_block_generations(test_course.location)
self.assertIsNotNone(version_history)
self.assertEqual(version_history.locator.version_guid, test_course.location.version_guid)
self.assertEqual(len(version_history.children), 1)
self.assertEqual(version_history.children[0].children, [])
self.assertEqual(version_history.children[0].locator.version_guid, chapter.location.version_guid)
assert version_history is not None
assert version_history.locator.version_guid == test_course.location.version_guid
assert len(version_history.children) == 1
assert version_history.children[0].children == []
assert version_history.children[0].locator.version_guid == chapter.location.version_guid
# sub changed on add, add problem, delete problem, add problem in strict linear seq
version_history = modulestore().get_block_generations(sub.location)
self.assertEqual(len(version_history.children), 1)
self.assertEqual(len(version_history.children[0].children), 1)
self.assertEqual(len(version_history.children[0].children[0].children), 1)
self.assertEqual(len(version_history.children[0].children[0].children[0].children), 0)
assert len(version_history.children) == 1
assert len(version_history.children[0].children) == 1
assert len(version_history.children[0].children[0].children) == 1
assert len(version_history.children[0].children[0].children[0].children) == 0
# first and second problem may show as same usage_id; so, need to ensure their histories are right
version_history = modulestore().get_block_generations(updated_problem.location)
self.assertEqual(version_history.locator.version_guid, first_problem.location.version_guid)
self.assertEqual(len(version_history.children), 1) # updated max_attempts
self.assertEqual(len(version_history.children[0].children), 0)
assert version_history.locator.version_guid == first_problem.location.version_guid
assert len(version_history.children) == 1
# updated max_attempts
assert len(version_history.children[0].children) == 0
version_history = modulestore().get_block_generations(second_problem.location)
self.assertNotEqual(version_history.locator.version_guid, first_problem.location.version_guid)
assert version_history.locator.version_guid != first_problem.location.version_guid
@ddt.data(
("course-v1:edx+test_course+test_run", BlockUsageLocator),
@@ -935,9 +929,9 @@ class SplitModuleCourseTests(SplitModuleTest):
"""
course_key = CourseKey.from_string(course_id)
root_block_key = modulestore().make_course_usage_key(course_key)
self.assertIsInstance(root_block_key, root_block_cls)
self.assertEqual(root_block_key.block_type, "course")
self.assertEqual(root_block_key.block_id, "course")
assert isinstance(root_block_key, root_block_cls)
assert root_block_key.block_type == 'course'
assert root_block_key.block_id == 'course'
class TestCourseStructureCache(SplitModuleTest):
@@ -975,7 +969,7 @@ class TestCourseStructureCache(SplitModuleTest):
cached_structure = self._get_structure(self.new_course)
# now make sure that you get the same structure
self.assertEqual(cached_structure, not_cached_structure)
assert cached_structure == not_cached_structure
# If data is corrupted, get it from mongo again.
cache_key = self.new_course.id.version_guid
@@ -984,7 +978,7 @@ class TestCourseStructureCache(SplitModuleTest):
not_corrupt_structure = self._get_structure(self.new_course)
# now make sure that you get the same structure
self.assertEqual(not_corrupt_structure, not_cached_structure)
assert not_corrupt_structure == not_cached_structure
@patch('xmodule.modulestore.split_mongo.mongo_connection.get_cache')
def test_course_structure_cache_no_cache_configured(self, mock_get_cache):
@@ -999,7 +993,7 @@ class TestCourseStructureCache(SplitModuleTest):
cached_structure = self._get_structure(self.new_course)
# now make sure that you get the same structure
self.assertEqual(cached_structure, not_cached_structure)
assert cached_structure == not_cached_structure
def test_dummy_cache(self):
with check_mongo_calls(1):
@@ -1011,7 +1005,7 @@ class TestCourseStructureCache(SplitModuleTest):
cached_structure = self._get_structure(self.new_course)
# now make sure that you get the same structure
self.assertEqual(cached_structure, not_cached_structure)
assert cached_structure == not_cached_structure
def _get_structure(self, course):
"""
@@ -1040,31 +1034,18 @@ class SplitModuleItemTests(SplitModuleTest):
previous_version = course.previous_version
# positive tests of various forms
locator = course.location.map_into_course(CourseLocator(version_guid=previous_version))
self.assertTrue(
modulestore().has_item(locator), "couldn't find in %s" % previous_version
)
assert modulestore().has_item(locator), ("couldn't find in %s" % previous_version)
locator = course.location.version_agnostic()
self.assertTrue(
modulestore().has_item(locator),
)
self.assertFalse(
modulestore().has_item(
BlockUsageLocator(
locator.course_key.for_branch(BRANCH_NAME_PUBLISHED),
block_type=locator.block_type,
block_id=locator.block_id
)
),
"found in published head"
)
assert modulestore().has_item(locator)
assert not modulestore()\
.has_item(BlockUsageLocator(locator.course_key.for_branch(BRANCH_NAME_PUBLISHED),
block_type=locator.block_type,
block_id=locator.block_id)), 'found in published head'
# not a course obj
locator = BlockUsageLocator(course_locator, block_type='chapter', block_id='chapter1')
self.assertTrue(
modulestore().has_item(locator),
"couldn't find chapter1"
)
assert modulestore().has_item(locator), "couldn't find chapter1"
# in published course
locator = BlockUsageLocator(
@@ -1072,9 +1053,7 @@ class SplitModuleItemTests(SplitModuleTest):
block_type="course",
block_id="head23456"
)
self.assertTrue(
modulestore().has_item(locator.for_branch(BRANCH_NAME_PUBLISHED))
)
assert modulestore().has_item(locator.for_branch(BRANCH_NAME_PUBLISHED))
def test_negative_has_item(self):
# negative tests--not found
@@ -1084,13 +1063,13 @@ class SplitModuleItemTests(SplitModuleTest):
block_type="course",
block_id="head23456"
)
self.assertFalse(modulestore().has_item(locator))
assert not modulestore().has_item(locator)
locator = BlockUsageLocator(
CourseLocator(org="testx", course="wonderful", run="run", branch=BRANCH_NAME_DRAFT),
block_type="vertical",
block_id="doesnotexist"
)
self.assertFalse(modulestore().has_item(locator))
assert not modulestore().has_item(locator)
@patch('xmodule.tabs.CourseTab.from_json', side_effect=mock_tab_from_json)
def test_get_item(self, _from_json):
@@ -1104,22 +1083,22 @@ class SplitModuleItemTests(SplitModuleTest):
# positive tests of various forms
locator = course.location.map_into_course(CourseLocator(version_guid=previous_version))
block = modulestore().get_item(locator)
self.assertIsInstance(block, CourseDescriptor)
self.assertIsInstance(modulestore().get_item(locator), CourseDescriptor)
assert isinstance(block, CourseDescriptor)
assert isinstance(modulestore().get_item(locator), CourseDescriptor)
def verify_greek_hero(block):
"""
Check contents of block
"""
self.assertEqual(block.location.org, "testx")
self.assertEqual(block.location.course, "GreekHero")
self.assertEqual(block.location.run, "run")
self.assertEqual(len(block.tabs), 6, "wrong number of tabs")
self.assertEqual(block.display_name, "The Ancient Greek Hero")
self.assertEqual(block.advertised_start, "Fall 2013")
self.assertEqual(len(block.children), 4)
assert block.location.org == 'testx'
assert block.location.course == 'GreekHero'
assert block.location.run == 'run'
assert len(block.tabs) == 6, 'wrong number of tabs'
assert block.display_name == 'The Ancient Greek Hero'
assert block.advertised_start == 'Fall 2013'
assert len(block.children) == 4
# check dates and graders--forces loading of descriptor
self.assertEqual(block.edited_by, "testassist@edx.org")
assert block.edited_by == 'testassist@edx.org'
self.assertDictEqual(
block.grade_cutoffs, {"Pass": 0.45},
)
@@ -1127,7 +1106,7 @@ class SplitModuleItemTests(SplitModuleTest):
verify_greek_hero(modulestore().get_item(course.location))
# try to look up other branches
with self.assertRaises(ItemNotFoundError):
with pytest.raises(ItemNotFoundError):
modulestore().get_item(course.location.for_branch(BRANCH_NAME_PUBLISHED))
def test_get_non_root(self):
@@ -1136,32 +1115,29 @@ class SplitModuleItemTests(SplitModuleTest):
CourseLocator(org='testx', course='GreekHero', run="run", branch=BRANCH_NAME_DRAFT), 'chapter', 'chapter1'
)
block = modulestore().get_item(locator)
self.assertEqual(block.location.org, "testx")
self.assertEqual(block.location.course, "GreekHero")
self.assertEqual(block.category, 'chapter')
self.assertEqual(block.display_name, "Hercules")
self.assertEqual(block.edited_by, "testassist@edx.org")
assert block.location.org == 'testx'
assert block.location.course == 'GreekHero'
assert block.category == 'chapter'
assert block.display_name == 'Hercules'
assert block.edited_by == 'testassist@edx.org'
# in published course
locator = BlockUsageLocator(
CourseLocator(org='testx', course='wonderful', run="run", branch=BRANCH_NAME_PUBLISHED), 'course', 'head23456' # lint-amnesty, pylint: disable=line-too-long
)
self.assertIsInstance(
modulestore().get_item(locator),
CourseDescriptor
)
assert isinstance(modulestore().get_item(locator), CourseDescriptor)
# negative tests--not found
# no such course or block
locator = BlockUsageLocator(
CourseLocator(org='doesnotexist', course='doesnotexist', run="run", branch=BRANCH_NAME_DRAFT), 'course', 'head23456' # lint-amnesty, pylint: disable=line-too-long
)
with self.assertRaises(ItemNotFoundError):
with pytest.raises(ItemNotFoundError):
modulestore().get_item(locator)
locator = BlockUsageLocator(
CourseLocator(org='testx', course='wonderful', run="run", branch=BRANCH_NAME_DRAFT), 'html', 'doesnotexist'
)
with self.assertRaises(ItemNotFoundError):
with pytest.raises(ItemNotFoundError):
modulestore().get_item(locator)
# pylint: disable=protected-access
@@ -1169,41 +1145,37 @@ class SplitModuleItemTests(SplitModuleTest):
'''
test the block and value matches help functions
'''
self.assertTrue(modulestore()._value_matches('help', 'help'))
self.assertFalse(modulestore()._value_matches('help', 'Help'))
self.assertTrue(modulestore()._value_matches(['distract', 'help', 'notme'], 'help'))
self.assertFalse(modulestore()._value_matches(['distract', 'Help', 'notme'], 'help'))
self.assertFalse(modulestore()._block_matches({'field': ['distract', 'Help', 'notme']}, {'field': 'help'}))
self.assertTrue(modulestore()._block_matches(
{'field': ['distract', 'help', 'notme'],
'irrelevant': 2},
{'field': 'help'}))
self.assertTrue(modulestore()._value_matches('I need some help', re.compile(r'help')))
self.assertTrue(modulestore()._value_matches(['I need some help', 'today'], re.compile(r'help')))
self.assertFalse(modulestore()._value_matches('I need some help', re.compile(r'Help')))
self.assertTrue(modulestore()._value_matches(['I need some help', 'today'], re.compile(r'Help', re.IGNORECASE)))
assert modulestore()._value_matches('help', 'help')
assert not modulestore()._value_matches('help', 'Help')
assert modulestore()._value_matches(['distract', 'help', 'notme'], 'help')
assert not modulestore()._value_matches(['distract', 'Help', 'notme'], 'help')
assert not modulestore()._block_matches({'field': ['distract', 'Help', 'notme']}, {'field': 'help'})
assert modulestore()._block_matches({'field': ['distract', 'help', 'notme'], 'irrelevant': 2},
{'field': 'help'})
assert modulestore()._value_matches('I need some help', re.compile('help'))
assert modulestore()._value_matches(['I need some help', 'today'], re.compile('help'))
assert not modulestore()._value_matches('I need some help', re.compile('Help'))
assert modulestore()._value_matches(['I need some help', 'today'], re.compile('Help', re.IGNORECASE))
self.assertTrue(modulestore()._value_matches('gotcha', {'$in': ['a', 'bunch', 'of', 'gotcha']}))
self.assertFalse(modulestore()._value_matches('gotcha', {'$in': ['a', 'bunch', 'of', 'gotchas']}))
self.assertFalse(modulestore()._value_matches('gotcha', {'$nin': ['a', 'bunch', 'of', 'gotcha']}))
self.assertTrue(modulestore()._value_matches('gotcha', {'$nin': ['a', 'bunch', 'of', 'gotchas']}))
assert modulestore()._value_matches('gotcha', {'$in': ['a', 'bunch', 'of', 'gotcha']})
assert not modulestore()._value_matches('gotcha', {'$in': ['a', 'bunch', 'of', 'gotchas']})
assert not modulestore()._value_matches('gotcha', {'$nin': ['a', 'bunch', 'of', 'gotcha']})
assert modulestore()._value_matches('gotcha', {'$nin': ['a', 'bunch', 'of', 'gotchas']})
self.assertTrue(modulestore()._block_matches({'group_access': {'1': [1]}}, {'group_access': {'$exists': True}}))
self.assertTrue(modulestore()._block_matches({'a': 1, 'b': 2}, {'group_access': {'$exists': False}}))
self.assertTrue(modulestore()._block_matches(
{'a': 1, 'group_access': {'1': [1]}},
{'a': 1, 'group_access': {'$exists': True}}))
self.assertFalse(modulestore()._block_matches(
{'a': 1, 'group_access': {'1': [1]}},
{'a': 111, 'group_access': {'$exists': True}}))
self.assertTrue(modulestore()._block_matches({'a': 1, 'b': 2}, {'a': 1, 'group_access': {'$exists': False}}))
self.assertFalse(modulestore()._block_matches({'a': 1, 'b': 2}, {'a': 9, 'group_access': {'$exists': False}}))
assert modulestore()._block_matches({'group_access': {'1': [1]}}, {'group_access': {'$exists': True}})
assert modulestore()._block_matches({'a': 1, 'b': 2}, {'group_access': {'$exists': False}})
assert modulestore()._block_matches({'a': 1, 'group_access': {'1': [1]}},
{'a': 1, 'group_access': {'$exists': True}})
assert not modulestore()._block_matches({'a': 1, 'group_access': {'1': [1]}},
{'a': 111, 'group_access': {'$exists': True}})
assert modulestore()._block_matches({'a': 1, 'b': 2}, {'a': 1, 'group_access': {'$exists': False}})
assert not modulestore()._block_matches({'a': 1, 'b': 2}, {'a': 9, 'group_access': {'$exists': False}})
self.assertTrue(modulestore()._block_matches({'a': 1, 'b': 2}, {'a': 1}))
self.assertFalse(modulestore()._block_matches({'a': 1, 'b': 2}, {'a': 2}))
self.assertFalse(modulestore()._block_matches({'a': 1, 'b': 2}, {'c': 1}))
self.assertFalse(modulestore()._block_matches({'a': 1, 'b': 2}, {'a': 1, 'c': 1}))
self.assertTrue(modulestore()._block_matches({'a': 1, 'b': 2}, {'a': lambda i: 0 < i < 2}))
assert modulestore()._block_matches({'a': 1, 'b': 2}, {'a': 1})
assert not modulestore()._block_matches({'a': 1, 'b': 2}, {'a': 2})
assert not modulestore()._block_matches({'a': 1, 'b': 2}, {'c': 1})
assert not modulestore()._block_matches({'a': 1, 'b': 2}, {'a': 1, 'c': 1})
assert modulestore()._block_matches({'a': 1, 'b': 2}, {'a': (lambda i: (0 < i < 2))})
def test_get_items(self):
'''
@@ -1212,28 +1184,28 @@ class SplitModuleItemTests(SplitModuleTest):
locator = CourseLocator(org='testx', course='GreekHero', run="run", branch=BRANCH_NAME_DRAFT)
# get all modules
matches = modulestore().get_items(locator)
self.assertEqual(len(matches), 8)
assert len(matches) == 8
matches = modulestore().get_items(locator)
self.assertEqual(len(matches), 8)
assert len(matches) == 8
matches = modulestore().get_items(locator, qualifiers={'category': 'chapter'})
self.assertEqual(len(matches), 4)
assert len(matches) == 4
matches = modulestore().get_items(locator, qualifiers={'category': 'garbage'})
self.assertEqual(len(matches), 0)
assert len(matches) == 0
# Test that we don't accidentally get an item with a similar name.
matches = modulestore().get_items(locator, qualifiers={'name': 'chapter1'})
self.assertEqual(len(matches), 1)
assert len(matches) == 1
matches = modulestore().get_items(locator, qualifiers={'name': ['chapter1', 'chapter2']})
self.assertEqual(len(matches), 2)
assert len(matches) == 2
matches = modulestore().get_items(
locator,
qualifiers={'category': 'chapter'},
settings={'display_name': re.compile(r'Hera')},
)
self.assertEqual(len(matches), 2)
assert len(matches) == 2
matches = modulestore().get_items(locator, settings={'group_access': {'$exists': True}})
self.assertEqual(len(matches), 1)
assert len(matches) == 1
matches = modulestore().get_items(locator, settings={'group_access': {'$exists': False}})
self.assertEqual(len(matches), 7)
assert len(matches) == 7
def test_get_parents(self):
'''
@@ -1244,17 +1216,17 @@ class SplitModuleItemTests(SplitModuleTest):
'chapter', block_id='chapter1'
)
parent = modulestore().get_parent_location(locator)
self.assertIsNotNone(parent)
self.assertEqual(parent.block_id, 'head12345')
self.assertEqual(parent.org, "testx")
self.assertEqual(parent.course, "GreekHero")
assert parent is not None
assert parent.block_id == 'head12345'
assert parent.org == 'testx'
assert parent.course == 'GreekHero'
locator = locator.course_key.make_usage_key('chapter', 'chapter2')
parent = modulestore().get_parent_location(locator)
self.assertIsNotNone(parent)
self.assertEqual(parent.block_id, 'head12345')
assert parent is not None
assert parent.block_id == 'head12345'
locator = locator.course_key.make_usage_key('garbage', 'nosuchblock')
parent = modulestore().get_parent_location(locator)
self.assertIsNone(parent)
assert parent is None
@patch('xmodule.tabs.CourseTab.from_json', side_effect=mock_tab_from_json)
def test_get_children(self, _from_json):
@@ -1270,10 +1242,10 @@ class SplitModuleItemTests(SplitModuleTest):
"chapter1", "chap", "chapter2", "chapter3"
]
for child in children:
self.assertEqual(child.category, "chapter")
self.assertIn(child.location.block_id, expected_ids)
assert child.category == 'chapter'
assert child.location.block_id in expected_ids
expected_ids.remove(child.location.block_id)
self.assertEqual(len(expected_ids), 0)
assert len(expected_ids) == 0
def version_agnostic(children):
@@ -1323,25 +1295,26 @@ class TestItemCrud(SplitModuleTest):
fields={'display_name': 'new sequential'}
)
# check that course version changed and course's previous is the other one
self.assertEqual(new_module.location.course, "GreekHero")
self.assertNotEqual(new_module.location.version_guid, premod_course.location.version_guid)
self.assertIsNone(locator.version_guid, "Version inadvertently filled in") # lint-amnesty, pylint: disable=no-member
assert new_module.location.course == 'GreekHero'
assert new_module.location.version_guid != premod_course.location.version_guid
assert locator.version_guid is None,\
'Version inadvertently filled in' # lint-amnesty, pylint: disable=no-member
current_course = modulestore().get_course(locator)
self.assertEqual(new_module.location.version_guid, current_course.location.version_guid)
assert new_module.location.version_guid == current_course.location.version_guid
history_info = modulestore().get_course_history_info(current_course.location.course_key)
self.assertEqual(history_info['previous_version'], premod_course.location.version_guid)
self.assertEqual(history_info['original_version'], premod_history['original_version'])
self.assertEqual(history_info['edited_by'], "user123")
assert history_info['previous_version'] == premod_course.location.version_guid
assert history_info['original_version'] == premod_history['original_version']
assert history_info['edited_by'] == 'user123'
# check block's info: category, definition_locator, and display_name
self.assertEqual(new_module.category, 'sequential')
self.assertIsNotNone(new_module.definition_locator)
self.assertEqual(new_module.display_name, 'new sequential')
assert new_module.category == 'sequential'
assert new_module.definition_locator is not None
assert new_module.display_name == 'new sequential'
# check that block does not exist in previous version
locator = new_module.location.map_into_course(
CourseLocator(version_guid=premod_course.location.version_guid)
)
with self.assertRaises(ItemNotFoundError):
with pytest.raises(ItemNotFoundError):
modulestore().get_item(locator)
def test_create_parented_item(self):
@@ -1365,10 +1338,10 @@ class TestItemCrud(SplitModuleTest):
definition_locator=original.definition_locator
)
# check that course version changed and course's previous is the other one
self.assertNotEqual(new_module.location.version_guid, premod_course.location.version_guid)
assert new_module.location.version_guid != premod_course.location.version_guid
parent = modulestore().get_item(locator)
self.assertIn(new_module.location.version_agnostic(), version_agnostic(parent.children))
self.assertEqual(new_module.definition_locator.definition_id, original.definition_locator.definition_id)
assert new_module.location.version_agnostic() in version_agnostic(parent.children)
assert new_module.definition_locator.definition_id == original.definition_locator.definition_id
def test_unique_naming(self):
"""
@@ -1399,18 +1372,18 @@ class TestItemCrud(SplitModuleTest):
)
# check that course version changed and course's previous is the other one
parent = modulestore().get_item(locator)
self.assertNotEqual(new_module.location.block_id, another_module.location.block_id)
self.assertIn(new_module.location.version_agnostic(), version_agnostic(parent.children))
self.assertIn(another_module.location.version_agnostic(), version_agnostic(parent.children))
self.assertEqual(new_module.data, new_payload)
self.assertEqual(another_module.data, another_payload)
assert new_module.location.block_id != another_module.location.block_id
assert new_module.location.version_agnostic() in version_agnostic(parent.children)
assert another_module.location.version_agnostic() in version_agnostic(parent.children)
assert new_module.data == new_payload
assert another_module.data == another_payload
# check definition histories
new_history = modulestore().get_definition_history_info(new_module.definition_locator)
self.assertIsNone(new_history['previous_version'])
self.assertEqual(new_history['original_version'], new_module.definition_locator.definition_id)
self.assertEqual(new_history['edited_by'], "anotheruser")
assert new_history['previous_version'] is None
assert new_history['original_version'] == new_module.definition_locator.definition_id
assert new_history['edited_by'] == 'anotheruser'
another_history = modulestore().get_definition_history_info(another_module.definition_locator)
self.assertEqual(another_history['previous_version'], original.definition_locator.definition_id)
assert another_history['previous_version'] == original.definition_locator.definition_id
def test_encoded_naming(self):
"""
@@ -1426,7 +1399,8 @@ class TestItemCrud(SplitModuleTest):
)
# check that course version changed and course's previous is the other one
new_module = modulestore().get_item(chapter_locator)
self.assertEqual(new_module.location.block_id, "foo.bar_-~:0") # hardcode to ensure BUL init didn't change
assert new_module.location.block_id == 'foo.bar_-~:0'
# hardcode to ensure BUL init didn't change
# now try making that a parent of something
new_payload = "<problem>empty</problem>"
problem_locator = BlockUsageLocator(course_key, 'problem', block_id="prob.bar_-~:99a")
@@ -1437,9 +1411,9 @@ class TestItemCrud(SplitModuleTest):
)
# check that course version changed and course's previous is the other one
new_module = modulestore().get_item(problem_locator)
self.assertEqual(new_module.location.block_id, problem_locator.block_id)
assert new_module.location.block_id == problem_locator.block_id
chapter = modulestore().get_item(chapter_locator)
self.assertIn(problem_locator, version_agnostic(chapter.children))
assert problem_locator in version_agnostic(chapter.children)
def test_create_bulk_operations(self):
"""
@@ -1454,7 +1428,7 @@ class TestItemCrud(SplitModuleTest):
index_history_info = modulestore().get_course_history_info(new_course.location.course_key)
course_block_prev_version = new_course.previous_version
course_block_update_version = new_course.update_version
self.assertIsNotNone(new_course_locator.version_guid, "Want to test a definite version")
assert new_course_locator.version_guid is not None, 'Want to test a definite version'
versionless_course_locator = new_course_locator.version_agnostic()
# positive simple case: no force, add chapter
@@ -1463,18 +1437,18 @@ class TestItemCrud(SplitModuleTest):
fields={'display_name': 'chapter 1'},
)
# version info shouldn't change
self.assertEqual(new_ele.update_version, course_block_update_version)
self.assertEqual(new_ele.update_version, new_ele.location.version_guid)
assert new_ele.update_version == course_block_update_version
assert new_ele.update_version == new_ele.location.version_guid
refetch_course = modulestore().get_course(versionless_course_locator)
self.assertEqual(refetch_course.location.version_guid, new_course.location.version_guid)
self.assertEqual(refetch_course.previous_version, course_block_prev_version)
self.assertEqual(refetch_course.update_version, course_block_update_version)
assert refetch_course.location.version_guid == new_course.location.version_guid
assert refetch_course.previous_version == course_block_prev_version
assert refetch_course.update_version == course_block_update_version
refetch_index_history_info = modulestore().get_course_history_info(refetch_course.location.course_key)
self.assertEqual(refetch_index_history_info, index_history_info)
self.assertIn(new_ele.location.version_agnostic(), version_agnostic(refetch_course.children))
assert refetch_index_history_info == index_history_info
assert new_ele.location.version_agnostic() in version_agnostic(refetch_course.children)
# try to create existing item
with self.assertRaises(DuplicateItemError):
with pytest.raises(DuplicateItemError):
_fail = modulestore().create_child(
user, new_course.location, 'chapter',
block_id=new_ele.location.block_id,
@@ -1489,7 +1463,7 @@ class TestItemCrud(SplitModuleTest):
)
transaction_guid = new_ele.location.version_guid
# ensure force w/ continue gives exception
with self.assertRaises(VersionConflictError):
with pytest.raises(VersionConflictError):
_fail = modulestore().create_child(
user, new_course.location, 'chapter',
fields={'display_name': 'chapter 2'},
@@ -1497,7 +1471,7 @@ class TestItemCrud(SplitModuleTest):
)
# ensure trying to continue the old one gives exception
with self.assertRaises(VersionConflictError):
with pytest.raises(VersionConflictError):
_fail = modulestore().create_child(
user, new_course.location, 'chapter',
fields={'display_name': 'chapter 3'},
@@ -1509,14 +1483,14 @@ class TestItemCrud(SplitModuleTest):
user, course_module_locator, 'chapter',
fields={'display_name': 'chapter 4'},
)
self.assertNotEqual(new_ele.update_version, course_block_update_version)
self.assertEqual(new_ele.location.version_guid, transaction_guid)
assert new_ele.update_version != course_block_update_version
assert new_ele.location.version_guid == transaction_guid
# check children, previous_version
refetch_course = modulestore().get_course(versionless_course_locator)
self.assertIn(new_ele.location.version_agnostic(), version_agnostic(refetch_course.children))
self.assertEqual(refetch_course.previous_version, course_block_update_version)
self.assertEqual(refetch_course.update_version, transaction_guid)
assert new_ele.location.version_agnostic() in version_agnostic(refetch_course.children)
assert refetch_course.previous_version == course_block_update_version
assert refetch_course.update_version == transaction_guid
def test_bulk_ops_org_filtering(self):
"""
@@ -1531,23 +1505,23 @@ class TestItemCrud(SplitModuleTest):
modulestore().create_course('test_org', 'test_transaction', 'test_run', user, BRANCH_NAME_DRAFT)
courses = modulestore().get_courses(branch=BRANCH_NAME_DRAFT, org='test_org')
self.assertEqual(len(courses), 1)
self.assertEqual(courses[0].id.org, course_key.org)
self.assertEqual(courses[0].id.course, course_key.course)
self.assertEqual(courses[0].id.run, course_key.run)
assert len(courses) == 1
assert courses[0].id.org == course_key.org
assert courses[0].id.course == course_key.course
assert courses[0].id.run == course_key.run
courses = modulestore().get_courses(branch=BRANCH_NAME_DRAFT, org='other_org')
self.assertEqual(len(courses), 0)
assert len(courses) == 0
# re-assert after the end of the with scope
courses = modulestore().get_courses(branch=BRANCH_NAME_DRAFT, org='test_org')
self.assertEqual(len(courses), 1)
self.assertEqual(courses[0].id.org, course_key.org)
self.assertEqual(courses[0].id.course, course_key.course)
self.assertEqual(courses[0].id.run, course_key.run)
assert len(courses) == 1
assert courses[0].id.org == course_key.org
assert courses[0].id.course == course_key.course
assert courses[0].id.run == course_key.run
courses = modulestore().get_courses(branch=BRANCH_NAME_DRAFT, org='other_org')
self.assertEqual(len(courses), 0)
assert len(courses) == 0
def test_update_metadata(self):
"""
@@ -1560,28 +1534,28 @@ class TestItemCrud(SplitModuleTest):
problem = modulestore().get_item(locator)
pre_def_id = problem.definition_locator.definition_id
pre_version_guid = problem.location.version_guid
self.assertIsNotNone(pre_def_id)
self.assertIsNotNone(pre_version_guid)
self.assertNotEqual(problem.max_attempts, 4, "Invalidates rest of test")
assert pre_def_id is not None
assert pre_version_guid is not None
assert problem.max_attempts != 4, 'Invalidates rest of test'
problem.max_attempts = 4
problem.save() # decache above setting into the kvs
updated_problem = modulestore().update_item(problem, self.user_id)
# check that course version changed and course's previous is the other one
self.assertEqual(updated_problem.definition_locator.definition_id, pre_def_id)
self.assertNotEqual(updated_problem.location.version_guid, pre_version_guid)
self.assertEqual(updated_problem.max_attempts, 4)
assert updated_problem.definition_locator.definition_id == pre_def_id
assert updated_problem.location.version_guid != pre_version_guid
assert updated_problem.max_attempts == 4
# refetch to ensure original didn't change
original_location = problem.location.map_into_course(CourseLocator(version_guid=pre_version_guid))
problem = modulestore().get_item(original_location)
self.assertNotEqual(problem.max_attempts, 4, "original changed")
assert problem.max_attempts != 4, 'original changed'
current_course = modulestore().get_course(locator.course_key)
self.assertEqual(updated_problem.location.version_guid, current_course.location.version_guid)
assert updated_problem.location.version_guid == current_course.location.version_guid
history_info = modulestore().get_course_history_info(current_course.location.course_key)
self.assertEqual(history_info['previous_version'], pre_version_guid)
self.assertEqual(history_info['edited_by'], self.user_id)
assert history_info['previous_version'] == pre_version_guid
assert history_info['edited_by'] == self.user_id
def test_update_children(self):
"""
@@ -1595,20 +1569,20 @@ class TestItemCrud(SplitModuleTest):
pre_version_guid = block.location.version_guid
# reorder children
self.assertGreater(len(block.children), 0, "meaningless test")
assert len(block.children) > 0, 'meaningless test'
moved_child = block.children.pop()
block.save() # decache model changes
updated_problem = modulestore().update_item(block, self.user_id)
# check that course version changed and course's previous is the other one
self.assertEqual(updated_problem.definition_locator.definition_id, pre_def_id)
self.assertNotEqual(updated_problem.location.version_guid, pre_version_guid)
self.assertEqual(version_agnostic(updated_problem.children), version_agnostic(block.children))
self.assertNotIn(moved_child, version_agnostic(updated_problem.children))
assert updated_problem.definition_locator.definition_id == pre_def_id
assert updated_problem.location.version_guid != pre_version_guid
assert version_agnostic(updated_problem.children) == version_agnostic(block.children)
assert moved_child not in version_agnostic(updated_problem.children)
locator = locator.course_key.make_usage_key('chapter', "chapter1")
other_block = modulestore().get_item(locator)
other_block.children.append(moved_child)
other_updated = modulestore().update_item(other_block, self.user_id)
self.assertIn(moved_child.version_agnostic(), version_agnostic(other_updated.children))
assert moved_child.version_agnostic() in version_agnostic(other_updated.children)
@patch('xmodule.tabs.CourseTab.from_json', side_effect=mock_tab_from_json)
def test_update_definition(self, _from_json):
@@ -1626,9 +1600,9 @@ class TestItemCrud(SplitModuleTest):
block.save() # decache model changes
updated_block = modulestore().update_item(block, self.user_id)
self.assertNotEqual(updated_block.definition_locator.definition_id, pre_def_id)
self.assertNotEqual(updated_block.location.version_guid, pre_version_guid)
self.assertEqual(updated_block.grading_policy['GRADER'][0]['min_count'], 13)
assert updated_block.definition_locator.definition_id != pre_def_id
assert updated_block.location.version_guid != pre_version_guid
assert updated_block.grading_policy['GRADER'][0]['min_count'] == 13
def test_update_manifold(self):
"""
@@ -1664,22 +1638,22 @@ class TestItemCrud(SplitModuleTest):
pre_def_id = block.definition_locator.definition_id
pre_version_guid = block.location.version_guid
self.assertNotEqual(block.grading_policy['GRADER'][0]['min_count'], 13)
assert block.grading_policy['GRADER'][0]['min_count'] != 13
block.grading_policy['GRADER'][0]['min_count'] = 13
block.children = block.children[1:] + [block.children[0]]
block.advertised_start = "Soon"
block.save() # decache model changes
updated_block = modulestore().update_item(block, self.user_id)
self.assertNotEqual(updated_block.definition_locator.definition_id, pre_def_id)
self.assertNotEqual(updated_block.location.version_guid, pre_version_guid)
self.assertEqual(updated_block.grading_policy['GRADER'][0]['min_count'], 13)
self.assertEqual(updated_block.children[0].version_agnostic(), block.children[0].version_agnostic())
self.assertEqual(updated_block.advertised_start, "Soon")
assert updated_block.definition_locator.definition_id != pre_def_id
assert updated_block.location.version_guid != pre_version_guid
assert updated_block.grading_policy['GRADER'][0]['min_count'] == 13
assert updated_block.children[0].version_agnostic() == block.children[0].version_agnostic()
assert updated_block.advertised_start == 'Soon'
def test_delete_item(self):
course = self.create_course_for_deletion()
with self.assertRaises(ValueError):
with pytest.raises(ValueError):
modulestore().delete_item(course.location, self.user_id)
reusable_location = course.id.version_agnostic().for_branch(BRANCH_NAME_DRAFT)
@@ -1688,14 +1662,14 @@ class TestItemCrud(SplitModuleTest):
locn_to_del = problems[0].location
new_course_loc = modulestore().delete_item(locn_to_del, self.user_id)
deleted = locn_to_del.version_agnostic()
self.assertFalse(modulestore().has_item(deleted))
with self.assertRaises(VersionConflictError):
assert not modulestore().has_item(deleted)
with pytest.raises(VersionConflictError):
modulestore().has_item(locn_to_del)
with self.assertRaises(ValueError):
with pytest.raises(ValueError):
modulestore().delete_item(deleted, self.user_id)
self.assertTrue(modulestore().has_item(locn_to_del.course_agnostic()))
self.assertNotEqual(new_course_loc.version_guid, course.location.version_guid)
assert modulestore().has_item(locn_to_del.course_agnostic())
assert new_course_loc.version_guid != course.location.version_guid
# delete a subtree
nodes = modulestore().get_items(reusable_location, qualifiers={'category': 'chapter'})
@@ -1708,10 +1682,8 @@ class TestItemCrud(SplitModuleTest):
"""
if node:
node_loc = node.location
self.assertFalse(
modulestore().has_item(node_loc.version_agnostic())
)
self.assertTrue(modulestore().has_item(node_loc.course_agnostic()))
assert not modulestore().has_item(node_loc.version_agnostic())
assert modulestore().has_item(node_loc.course_agnostic())
if node.has_children:
for sub in node.get_children():
check_subtree(sub)
@@ -1769,8 +1741,8 @@ class TestItemCrud(SplitModuleTest):
# First child should have been moved to second position, and better child takes the lead
refetch_course = store.get_course(versionless_course_locator)
children = refetch_course.get_children()
self.assertEqual(six.text_type(children[1].location), six.text_type(first_child.location))
self.assertEqual(six.text_type(children[0].location), six.text_type(second_child.location))
assert six.text_type(children[1].location) == six.text_type(first_child.location)
assert six.text_type(children[0].location) == six.text_type(second_child.location)
# Clean up the data so we don't break other tests which apparently expect a particular state
store.delete_course(refetch_course.id, user)
@@ -1791,22 +1763,22 @@ class TestCourseCreation(SplitModuleTest):
new_locator = new_course.location
# check index entry
index_info = modulestore().get_course_index_info(new_locator.course_key)
self.assertEqual(index_info['org'], 'test_org')
self.assertEqual(index_info['edited_by'], 'create_user')
assert index_info['org'] == 'test_org'
assert index_info['edited_by'] == 'create_user'
# check structure info
structure_info = modulestore().get_course_history_info(new_locator.course_key)
self.assertEqual(structure_info['original_version'], index_info['versions'][BRANCH_NAME_DRAFT])
self.assertIsNone(structure_info['previous_version'])
assert structure_info['original_version'] == index_info['versions'][BRANCH_NAME_DRAFT]
assert structure_info['previous_version'] is None
self.assertEqual(structure_info['edited_by'], 'create_user')
assert structure_info['edited_by'] == 'create_user'
# check the returned course object
self.assertIsInstance(new_course, CourseDescriptor)
self.assertEqual(new_course.category, 'course')
self.assertFalse(new_course.show_calculator)
self.assertTrue(new_course.allow_anonymous)
self.assertEqual(len(new_course.children), 0)
self.assertEqual(new_course.edited_by, "create_user")
self.assertEqual(len(new_course.grading_policy['GRADER']), 4)
assert isinstance(new_course, CourseDescriptor)
assert new_course.category == 'course'
assert not new_course.show_calculator
assert new_course.allow_anonymous
assert len(new_course.children) == 0
assert new_course.edited_by == 'create_user'
assert len(new_course.grading_policy['GRADER']) == 4
self.assertDictEqual(new_course.grade_cutoffs, {"Pass": 0.5})
def test_cloned_course(self):
@@ -1821,16 +1793,16 @@ class TestCourseCreation(SplitModuleTest):
new_draft_locator = new_draft.location
self.assertRegex(new_draft_locator.org, 'best')
# the edited_by and other meta fields on the new course will be the original author not this one
self.assertEqual(new_draft.edited_by, 'test@edx.org')
self.assertEqual(new_draft_locator.version_guid, original_index['versions'][BRANCH_NAME_DRAFT])
assert new_draft.edited_by == 'test@edx.org'
assert new_draft_locator.version_guid == original_index['versions'][BRANCH_NAME_DRAFT]
# however the edited_by and other meta fields on course_index will be this one
new_index = modulestore().get_course_index_info(new_draft_locator.course_key)
self.assertEqual(new_index['edited_by'], 'leech_master')
assert new_index['edited_by'] == 'leech_master'
new_published_locator = new_draft_locator.course_key.for_branch(BRANCH_NAME_PUBLISHED)
new_published = modulestore().get_course(new_published_locator)
self.assertEqual(new_published.edited_by, 'test@edx.org')
self.assertEqual(new_published.location.version_guid, original_index['versions'][BRANCH_NAME_PUBLISHED])
assert new_published.edited_by == 'test@edx.org'
assert new_published.location.version_guid == original_index['versions'][BRANCH_NAME_PUBLISHED]
# changing this course will not change the original course
# using new_draft.location will insert the chapter under the course root
@@ -1840,16 +1812,16 @@ class TestCourseCreation(SplitModuleTest):
)
new_draft_locator = new_draft_locator.course_key.version_agnostic()
new_index = modulestore().get_course_index_info(new_draft_locator)
self.assertNotEqual(new_index['versions'][BRANCH_NAME_DRAFT], original_index['versions'][BRANCH_NAME_DRAFT])
assert new_index['versions'][BRANCH_NAME_DRAFT] != original_index['versions'][BRANCH_NAME_DRAFT]
new_draft = modulestore().get_course(new_draft_locator)
self.assertEqual(new_item.edited_by, 'leech_master')
self.assertNotEqual(new_item.location.version_guid, original_index['versions'][BRANCH_NAME_DRAFT])
self.assertNotEqual(new_draft.location.version_guid, original_index['versions'][BRANCH_NAME_DRAFT])
assert new_item.edited_by == 'leech_master'
assert new_item.location.version_guid != original_index['versions'][BRANCH_NAME_DRAFT]
assert new_draft.location.version_guid != original_index['versions'][BRANCH_NAME_DRAFT]
structure_info = modulestore().get_course_history_info(new_draft_locator)
self.assertEqual(structure_info['edited_by'], 'leech_master')
assert structure_info['edited_by'] == 'leech_master'
original_course = modulestore().get_course(original_locator)
self.assertEqual(original_course.location.version_guid, original_index['versions'][BRANCH_NAME_DRAFT])
assert original_course.location.version_guid == original_index['versions'][BRANCH_NAME_DRAFT]
def test_derived_course(self):
"""
@@ -1871,12 +1843,12 @@ class TestCourseCreation(SplitModuleTest):
new_draft_locator = new_draft.location
self.assertRegex(new_draft_locator.org, 'counter')
# the edited_by and other meta fields on the new course will be the original author not this one
self.assertEqual(new_draft.edited_by, 'leech_master')
self.assertNotEqual(new_draft_locator.version_guid, original_index['versions'][BRANCH_NAME_DRAFT])
assert new_draft.edited_by == 'leech_master'
assert new_draft_locator.version_guid != original_index['versions'][BRANCH_NAME_DRAFT]
# however the edited_by and other meta fields on course_index will be this one
new_index = modulestore().get_course_index_info(new_draft_locator.course_key)
self.assertEqual(new_index['edited_by'], 'leech_master')
self.assertEqual(new_draft.display_name, fields['display_name'])
assert new_index['edited_by'] == 'leech_master'
assert new_draft.display_name == fields['display_name']
self.assertDictEqual(
new_draft.grading_policy['GRADE_CUTOFFS'],
fields['grading_policy']['GRADE_CUTOFFS']
@@ -1898,13 +1870,13 @@ class TestCourseCreation(SplitModuleTest):
versions[BRANCH_NAME_DRAFT] = head_course.previous_version
modulestore().update_course_index(None, course_info)
course = modulestore().get_course(locator)
self.assertEqual(course.location.version_guid, versions[BRANCH_NAME_DRAFT])
assert course.location.version_guid == versions[BRANCH_NAME_DRAFT]
# an allowed but not recommended way to publish a course
versions[BRANCH_NAME_PUBLISHED] = versions[BRANCH_NAME_DRAFT]
modulestore().update_course_index(None, course_info)
course = modulestore().get_course(locator.for_branch(BRANCH_NAME_PUBLISHED))
self.assertEqual(course.location.version_guid, versions[BRANCH_NAME_DRAFT])
assert course.location.version_guid == versions[BRANCH_NAME_DRAFT]
def test_create_with_root(self):
"""
@@ -1915,16 +1887,16 @@ class TestCourseCreation(SplitModuleTest):
'test_org', 'test_transaction', 'test_run', user, BRANCH_NAME_DRAFT,
root_block_id='top', root_category='chapter'
)
self.assertEqual(new_course.location.block_id, 'top')
self.assertEqual(new_course.category, 'chapter')
assert new_course.location.block_id == 'top'
assert new_course.category == 'chapter'
# look at db to verify
db_structure = modulestore().db_connection.get_structure(
new_course.location.as_object_id(new_course.location.version_guid)
)
self.assertIsNotNone(db_structure, "Didn't find course")
self.assertNotIn(BlockKey('course', 'course'), db_structure['blocks'])
self.assertIn(BlockKey('chapter', 'top'), db_structure['blocks'])
self.assertEqual(db_structure['blocks'][BlockKey('chapter', 'top')].block_type, 'chapter')
assert db_structure is not None, "Didn't find course"
assert BlockKey('course', 'course') not in db_structure['blocks']
assert BlockKey('chapter', 'top') in db_structure['blocks']
assert db_structure['blocks'][BlockKey('chapter', 'top')].block_type == 'chapter'
def test_create_id_dupe(self):
"""
@@ -1932,7 +1904,7 @@ class TestCourseCreation(SplitModuleTest):
"""
user = random.getrandbits(32)
courses = modulestore().get_courses(BRANCH_NAME_DRAFT)
with self.assertRaises(DuplicateCourseError):
with pytest.raises(DuplicateCourseError):
dupe_course_key = courses[0].location.course_key
modulestore().create_course(
dupe_course_key.org, dupe_course_key.course, dupe_course_key.run, user, BRANCH_NAME_DRAFT
@@ -1966,12 +1938,12 @@ class TestCourseCreation(SplitModuleTest):
# now get_courses
courses = split_store.get_courses(BRANCH_NAME_DRAFT)
self.assertEqual(len(courses), 3)
assert len(courses) == 3
course_ids = [course.id.for_branch(None) for course in courses]
self.assertNotIn(to_be_deleted, course_ids)
self.assertIn(to_be_created, course_ids)
assert to_be_deleted not in course_ids
assert to_be_created in course_ids
fetched_modified = [course for course in courses if course.id == modified_course_loc][0]
self.assertEqual(fetched_modified.advertised_start, modified_course.advertised_start)
assert fetched_modified.advertised_start == modified_course.advertised_start
class TestInheritance(SplitModuleTest):
@@ -1990,13 +1962,13 @@ class TestInheritance(SplitModuleTest):
)
node = modulestore().get_item(locator)
# inherited
self.assertEqual(node.graceperiod, datetime.timedelta(hours=2))
assert node.graceperiod == datetime.timedelta(hours=2)
locator = BlockUsageLocator(
CourseLocator(org='testx', course='GreekHero', run="run", branch=BRANCH_NAME_DRAFT), 'problem', 'problem1'
)
node = modulestore().get_item(locator)
# overridden
self.assertEqual(node.graceperiod, datetime.timedelta(hours=4))
assert node.graceperiod == datetime.timedelta(hours=4)
def test_inheritance_not_saved(self):
"""
@@ -2013,12 +1985,12 @@ class TestInheritance(SplitModuleTest):
CourseLocator(org='testx', course='GreekHero', run="run", branch=BRANCH_NAME_DRAFT), 'problem', 'problem3_2' # lint-amnesty, pylint: disable=line-too-long
)
)
self.assertFalse(problem.visible_to_staff_only)
assert not problem.visible_to_staff_only
chapter.visible_to_staff_only = True
modulestore().update_item(chapter, self.user_id)
problem = modulestore().get_item(problem.location.version_agnostic())
self.assertTrue(problem.visible_to_staff_only)
assert problem.visible_to_staff_only
# unset on parent, retrieve child, verify unset
chapter = modulestore().get_item(chapter.location.version_agnostic())
@@ -2026,7 +1998,7 @@ class TestInheritance(SplitModuleTest):
modulestore().update_item(chapter, self.user_id)
problem = modulestore().get_item(problem.location.version_agnostic())
self.assertFalse(problem.visible_to_staff_only)
assert not problem.visible_to_staff_only
def test_dynamic_inheritance(self):
"""
@@ -2037,13 +2009,13 @@ class TestInheritance(SplitModuleTest):
chapter.visible_to_staff_only = True
orphan_problem = modulestore().create_item(self.user_id, course_key, 'problem')
self.assertFalse(orphan_problem.visible_to_staff_only)
assert not orphan_problem.visible_to_staff_only
parented_problem = modulestore().create_child(self.user_id, chapter.location.version_agnostic(), 'problem') # lint-amnesty, pylint: disable=unused-variable
# FIXME LMS-11376
# self.assertTrue(parented_problem.visible_to_staff_only)
orphan_problem = modulestore().create_xblock(chapter.runtime, course_key, 'problem')
self.assertFalse(orphan_problem.visible_to_staff_only)
assert not orphan_problem.visible_to_staff_only
parented_problem = modulestore().create_xblock(chapter.runtime, course_key, 'problem', parent_xblock=chapter)
# FIXME LMS-11376
# self.assertTrue(parented_problem.visible_to_staff_only)
@@ -2081,16 +2053,14 @@ class TestPublish(SplitModuleTest):
# remove chapter1 from expected b/c its pub'd version != the source anymore since source changed
expected.remove(BlockKey.from_usage_key(chapter1))
# check that it's not in published course
with self.assertRaises(ItemNotFoundError):
with pytest.raises(ItemNotFoundError):
modulestore().get_item(new_module.location.map_into_course(dest_course))
# publish it
modulestore().copy(self.user_id, source_course, dest_course, [new_module.location], None)
expected.append(BlockKey.from_usage_key(new_module.location))
# check that it is in the published course and that its parent is the chapter
pub_module = modulestore().get_item(new_module.location.map_into_course(dest_course))
self.assertEqual(
modulestore().get_parent_location(pub_module.location).block_id, chapter1.block_id
)
assert modulestore().get_parent_location(pub_module.location).block_id == chapter1.block_id
# ensure intentionally orphaned blocks work (e.g., course_info)
new_module = modulestore().create_item(
self.user_id, source_course, "course_info", block_id="handouts"
@@ -2112,15 +2082,15 @@ class TestPublish(SplitModuleTest):
head = source_course.make_usage_key('course', "head12345")
chapter3 = source_course.make_usage_key('chapter', 'chapter3')
problem1 = source_course.make_usage_key('problem', 'problem1')
with self.assertRaises(ItemNotFoundError):
with pytest.raises(ItemNotFoundError):
modulestore().copy(self.user_id, source_course, destination_course, [chapter3], None)
# publishing into a new branch w/o publishing the root
destination_course = CourseLocator(org='testx', course='GreekHero', run='run', branch=BRANCH_NAME_PUBLISHED)
with self.assertRaises(ItemNotFoundError):
with pytest.raises(ItemNotFoundError):
modulestore().copy(self.user_id, source_course, destination_course, [chapter3], None)
# publishing a subdag w/o the parent already in course
modulestore().copy(self.user_id, source_course, destination_course, [head], [chapter3])
with self.assertRaises(ItemNotFoundError):
with pytest.raises(ItemNotFoundError):
modulestore().copy(self.user_id, source_course, destination_course, [problem1], [])
@patch('xmodule.tabs.CourseTab.from_json', side_effect=mock_tab_from_json)
@@ -2163,31 +2133,25 @@ class TestPublish(SplitModuleTest):
Check that the course has the expected blocks and does not have the unexpected blocks
"""
history_info = modulestore().get_course_history_info(dest_course_loc)
self.assertEqual(history_info['edited_by'], self.user_id)
assert history_info['edited_by'] == self.user_id
for expected in expected_blocks:
source = modulestore().get_item(source_course_loc.make_usage_key(expected.type, expected.id))
pub_copy = modulestore().get_item(dest_course_loc.make_usage_key(expected.type, expected.id))
# everything except previous_version & children should be the same
self.assertEqual(source.category, pub_copy.category)
self.assertEqual(
source.update_version, pub_copy.source_version,
u"Versions don't match for {}: {} != {}".format(
expected, source.update_version, pub_copy.update_version
)
)
self.assertEqual(
self.user_id, pub_copy.edited_by,
"{} edited_by {} not {}".format(pub_copy.location, pub_copy.edited_by, self.user_id)
)
assert source.category == pub_copy.category
assert source.update_version == pub_copy.source_version,\
f"Versions don't match for {expected}: {source.update_version} != {pub_copy.update_version}"
assert self.user_id == pub_copy.edited_by,\
f'{pub_copy.location} edited_by {pub_copy.edited_by} not {self.user_id}'
for field in source.fields.values():
if field.name == 'children':
self._compare_children(field.read_from(source), field.read_from(pub_copy), unexpected_blocks)
elif isinstance(field, (Reference, ReferenceList, ReferenceValueDict)):
self.assertReferenceEqual(field.read_from(source), field.read_from(pub_copy))
else:
self.assertEqual(field.read_from(source), field.read_from(pub_copy))
assert field.read_from(source) == field.read_from(pub_copy)
for unexp in unexpected_blocks:
with self.assertRaises(ItemNotFoundError):
with pytest.raises(ItemNotFoundError):
modulestore().get_item(dest_course_loc.make_usage_key(unexp.type, unexp.id))
def assertReferenceEqual(self, expected, actual): # lint-amnesty, pylint: disable=missing-function-docstring
@@ -2200,7 +2164,7 @@ class TestPublish(SplitModuleTest):
elif isinstance(expected, dict):
expected = {key: BlockKey.from_usage_key(val) for (key, val) in expected}
actual = {key: BlockKey.from_usage_key(val) for (key, val) in actual}
self.assertEqual(expected, actual)
assert expected == actual
@contract(
source_children="list(BlockUsageLocator)",
@@ -2219,9 +2183,9 @@ class TestPublish(SplitModuleTest):
]
dest_block_keys = [BlockKey.from_usage_key(dest) for dest in dest_children]
for unexp in unexpected:
self.assertNotIn(unexp, dest_block_keys)
assert unexp not in dest_block_keys
self.assertEqual(source_block_keys, dest_block_keys)
assert source_block_keys == dest_block_keys
class TestSchema(SplitModuleTest):
@@ -2234,16 +2198,10 @@ class TestSchema(SplitModuleTest):
"""
db_connection = modulestore().db_connection
for collection in [db_connection.course_index, db_connection.structures, db_connection.definitions]:
self.assertEqual(
collection.count_documents({'schema_version': {'$exists': False}}),
0,
"{0.name} has records without schema_version".format(collection)
)
self.assertEqual(
collection.count_documents({'schema_version': {'$ne': SplitMongoModuleStore.SCHEMA_VERSION}}),
0,
"{0.name} has records with wrong schema_version".format(collection)
)
assert collection.count_documents({'schema_version': {'$exists': False}}) == 0, \
f'{collection.name} has records without schema_version'
assert collection.count_documents({'schema_version': {'$ne': SplitMongoModuleStore.SCHEMA_VERSION}}) == 0, \
f'{collection.name} has records with wrong schema_version'
# ===========================================

View File

@@ -42,10 +42,10 @@ class TestBulkWriteMixin(unittest.TestCase): # lint-amnesty, pylint: disable=mi
self.index_entry = {'this': 'is', 'an': 'index'}
def assertConnCalls(self, *calls):
self.assertEqual(list(calls), self.conn.mock_calls)
assert list(calls) == self.conn.mock_calls
def assertCacheNotCleared(self):
self.assertFalse(self.clear_cache.called)
assert not self.clear_cache.called
class TestBulkWriteMixinPreviousTransaction(TestBulkWriteMixin):
@@ -77,7 +77,7 @@ class TestBulkWriteMixinClosed(TestBulkWriteMixin):
self.assertConnCalls(
call.get_structure(self.course_key.as_object_id(version_guid), self.course_key)
)
self.assertEqual(result, self.conn.get_structure.return_value)
assert result == self.conn.get_structure.return_value
self.assertCacheNotCleared()
def test_no_bulk_write_structure(self):
@@ -100,7 +100,7 @@ class TestBulkWriteMixinClosed(TestBulkWriteMixin):
self.course_key
)
)
self.assertEqual(result, self.conn.get_definition.return_value)
assert result == self.conn.get_definition.return_value
def test_no_bulk_write_definition(self):
# Writing a definition when no bulk operation is active should just
@@ -114,7 +114,7 @@ class TestBulkWriteMixinClosed(TestBulkWriteMixin):
# through to the db_connection
result = self.bulk.get_course_index(self.course_key, ignore_case=ignore_case)
self.assertConnCalls(call.get_course_index(self.course_key, ignore_case))
self.assertEqual(result, self.conn.get_course_index.return_value)
assert result == self.conn.get_course_index.return_value
self.assertCacheNotCleared()
def test_no_bulk_write_index(self):
@@ -291,17 +291,14 @@ class TestBulkWriteMixinClosed(TestBulkWriteMixin):
)
def test_version_structure_creates_new_version(self):
self.assertNotEqual(
self.bulk.version_structure(self.course_key, self.structure, 'user_id')['_id'],
self.structure['_id']
)
assert self.bulk.version_structure(self.course_key, self.structure, 'user_id')['_id'] != self.structure['_id']
def test_version_structure_new_course(self):
self.conn.get_course_index.return_value = None
self.bulk._begin_bulk_operation(self.course_key)
version_result = self.bulk.version_structure(self.course_key, self.structure, 'user_id')
get_result = self.bulk.get_structure(self.course_key, version_result['_id'])
self.assertEqual(version_result, get_result)
assert version_result == get_result
class TestBulkWriteMixinClosedAfterPrevTransaction(TestBulkWriteMixinClosed, TestBulkWriteMixinPreviousTransaction): # lint-amnesty, pylint: disable=test-inherits-tests
@@ -330,7 +327,7 @@ class TestBulkWriteMixinFindMethods(TestBulkWriteMixin):
course_keys=None
)
)
self.assertEqual(result, self.conn.find_matching_course_indexes.return_value)
assert result == self.conn.find_matching_course_indexes.return_value
self.assertCacheNotCleared()
@ddt.data(
@@ -399,14 +396,14 @@ class TestBulkWriteMixinFindMethods(TestBulkWriteMixin):
result = self.bulk.find_matching_course_indexes(branch, search_targets)
six.assertCountEqual(self, result, expected)
for item in unmatching:
self.assertNotIn(item, result)
assert item not in result
def test_no_bulk_find_structures_by_id(self):
ids = [Mock(name='id')]
self.conn.find_structures_by_id.return_value = [MagicMock(name='result')]
result = self.bulk.find_structures_by_id(ids)
self.assertConnCalls(call.find_structures_by_id(ids))
self.assertEqual(result, self.conn.find_structures_by_id.return_value)
assert result == self.conn.find_structures_by_id.return_value
self.assertCacheNotCleared()
@ddt.data(
@@ -431,14 +428,14 @@ class TestBulkWriteMixinFindMethods(TestBulkWriteMixin):
self.conn.find_structures_by_id.assert_called_once_with(list(set(search_ids) - set(active_ids)))
for _id in active_ids:
if _id in search_ids:
self.assertIn(active_structure(_id), results)
assert active_structure(_id) in results
else:
self.assertNotIn(active_structure(_id), results)
assert active_structure(_id) not in results
for _id in db_ids:
if _id in search_ids and _id not in active_ids:
self.assertIn(db_structure(_id), results)
assert db_structure(_id) in results
else:
self.assertNotIn(db_structure(_id), results)
assert db_structure(_id) not in results
@ddt.data(
([], [], []),
@@ -463,17 +460,17 @@ class TestBulkWriteMixinFindMethods(TestBulkWriteMixin):
self.conn.get_definitions.assert_called_once_with(definitions_gotten, self.course_key)
else:
# If no definitions to get, then get_definitions() should *not* have been called.
self.assertEqual(self.conn.get_definitions.call_count, 0)
assert self.conn.get_definitions.call_count == 0
for _id in active_ids:
if _id in search_ids:
self.assertIn(active_definition(_id), results)
assert active_definition(_id) in results
else:
self.assertNotIn(active_definition(_id), results)
assert active_definition(_id) not in results
for _id in db_ids:
if _id in search_ids and _id not in active_ids:
self.assertIn(db_definition(_id), results)
assert db_definition(_id) in results
else:
self.assertNotIn(db_definition(_id), results)
assert db_definition(_id) not in results
def test_get_definitions_doesnt_update_db(self):
test_ids = [1, 2]
@@ -484,14 +481,14 @@ class TestBulkWriteMixinFindMethods(TestBulkWriteMixin):
self.bulk._begin_bulk_operation(self.course_key)
self.bulk.get_definitions(self.course_key, test_ids)
self.bulk._end_bulk_operation(self.course_key)
self.assertFalse(self.conn.insert_definition.called)
assert not self.conn.insert_definition.called
def test_no_bulk_find_structures_derived_from(self):
ids = [Mock(name='id')]
self.conn.find_structures_derived_from.return_value = [MagicMock(name='result')]
result = self.bulk.find_structures_derived_from(ids)
self.assertConnCalls(call.find_structures_derived_from(ids))
self.assertEqual(result, self.conn.find_structures_derived_from.return_value)
assert result == self.conn.find_structures_derived_from.return_value
self.assertCacheNotCleared()
@ddt.data(
@@ -529,17 +526,17 @@ class TestBulkWriteMixinFindMethods(TestBulkWriteMixin):
self.conn.find_structures_derived_from.assert_called_once_with(search_ids)
for structure in active_structures:
if structure['previous_version'] in search_ids:
self.assertIn(structure, results)
assert structure in results
else:
self.assertNotIn(structure, results)
assert structure not in results
for structure in db_structures:
if (
structure['previous_version'] in search_ids and # We're searching for this document
not any(active.endswith(structure['_id']) for active in active_ids) # This document doesn't match any active _ids # lint-amnesty, pylint: disable=line-too-long
):
self.assertIn(structure, results)
assert structure in results
else:
self.assertNotIn(structure, results)
assert structure not in results
def test_no_bulk_find_ancestor_structures(self):
original_version = Mock(name='original_version')
@@ -547,7 +544,7 @@ class TestBulkWriteMixinFindMethods(TestBulkWriteMixin):
self.conn.find_ancestor_structures.return_value = [MagicMock(name='result')]
result = self.bulk.find_ancestor_structures(original_version, block_id)
self.assertConnCalls(call.find_ancestor_structures(original_version, block_id))
self.assertEqual(result, self.conn.find_ancestor_structures.return_value)
assert result == self.conn.find_ancestor_structures.return_value
self.assertCacheNotCleared()
@ddt.data(
@@ -604,8 +601,8 @@ class TestBulkWriteMixinOpen(TestBulkWriteMixin):
# returns the structure from the database
version_guid = VERSION_GUID_DICT[version_guid_name]
result = self.bulk.get_structure(self.course_key, version_guid)
self.assertEqual(self.conn.get_structure.call_count, 1)
self.assertEqual(result, self.conn.get_structure.return_value)
assert self.conn.get_structure.call_count == 1
assert result == self.conn.get_structure.return_value
self.assertCacheNotCleared()
@ddt.data(*SAMPLE_GUIDS_LIST)
@@ -615,8 +612,8 @@ class TestBulkWriteMixinOpen(TestBulkWriteMixin):
version_guid = VERSION_GUID_DICT[version_guid_name]
for _ in range(2):
result = self.bulk.get_structure(self.course_key, version_guid)
self.assertEqual(self.conn.get_structure.call_count, 1)
self.assertEqual(result, self.conn.get_structure.return_value)
assert self.conn.get_structure.call_count == 1
assert result == self.conn.get_structure.return_value
self.assertCacheNotCleared()
@ddt.data(*SAMPLE_GUIDS_LIST)
@@ -626,8 +623,8 @@ class TestBulkWriteMixinOpen(TestBulkWriteMixin):
self.structure['_id'] = version_guid
self.bulk.update_structure(self.course_key, self.structure)
result = self.bulk.get_structure(self.course_key, version_guid)
self.assertEqual(self.conn.get_structure.call_count, 0)
self.assertEqual(result, self.structure)
assert self.conn.get_structure.call_count == 0
assert result == self.structure
@ddt.data(*SAMPLE_GUIDS_LIST)
def test_read_structure_after_write_after_read(self, version_guid_name):
@@ -638,8 +635,8 @@ class TestBulkWriteMixinOpen(TestBulkWriteMixin):
self.bulk.get_structure(self.course_key, version_guid)
self.bulk.update_structure(self.course_key, self.structure)
result = self.bulk.get_structure(self.course_key, version_guid)
self.assertEqual(self.conn.get_structure.call_count, 1)
self.assertEqual(result, self.structure)
assert self.conn.get_structure.call_count == 1
assert result == self.structure
@ddt.data(*SAMPLE_GUIDS_LIST)
def test_read_definition_without_write_from_db(self, version_guid_name):
@@ -647,8 +644,8 @@ class TestBulkWriteMixinOpen(TestBulkWriteMixin):
# returns the definition from the database
version_guid = VERSION_GUID_DICT[version_guid_name]
result = self.bulk.get_definition(self.course_key, version_guid)
self.assertEqual(self.conn.get_definition.call_count, 1)
self.assertEqual(result, self.conn.get_definition.return_value)
assert self.conn.get_definition.call_count == 1
assert result == self.conn.get_definition.return_value
self.assertCacheNotCleared()
@ddt.data(*SAMPLE_GUIDS_LIST)
@@ -658,8 +655,8 @@ class TestBulkWriteMixinOpen(TestBulkWriteMixin):
version_guid = VERSION_GUID_DICT[version_guid_name]
for _ in range(2):
result = self.bulk.get_definition(self.course_key, version_guid)
self.assertEqual(self.conn.get_definition.call_count, 1)
self.assertEqual(result, self.conn.get_definition.return_value)
assert self.conn.get_definition.call_count == 1
assert result == self.conn.get_definition.return_value
self.assertCacheNotCleared()
@ddt.data(*SAMPLE_GUIDS_LIST)
@@ -669,8 +666,8 @@ class TestBulkWriteMixinOpen(TestBulkWriteMixin):
self.definition['_id'] = version_guid
self.bulk.update_definition(self.course_key, self.definition)
result = self.bulk.get_definition(self.course_key, version_guid)
self.assertEqual(self.conn.get_definition.call_count, 0)
self.assertEqual(result, self.definition)
assert self.conn.get_definition.call_count == 0
assert result == self.definition
@ddt.data(*SAMPLE_GUIDS_LIST)
def test_read_definition_after_write_after_read(self, version_guid_name):
@@ -681,15 +678,15 @@ class TestBulkWriteMixinOpen(TestBulkWriteMixin):
self.bulk.get_definition(self.course_key, version_guid)
self.bulk.update_definition(self.course_key, self.definition)
result = self.bulk.get_definition(self.course_key, version_guid)
self.assertEqual(self.conn.get_definition.call_count, 1)
self.assertEqual(result, self.definition)
assert self.conn.get_definition.call_count == 1
assert result == self.definition
@ddt.data(True, False)
def test_read_index_without_write_from_db(self, ignore_case):
# Reading the index without writing to it should pull from the database
result = self.bulk.get_course_index(self.course_key, ignore_case=ignore_case)
self.assertEqual(self.conn.get_course_index.call_count, 1)
self.assertEqual(self.conn.get_course_index.return_value, result)
assert self.conn.get_course_index.call_count == 1
assert self.conn.get_course_index.return_value == result
@ddt.data(True, False)
def test_read_index_without_write_only_reads_once(self, ignore_case):
@@ -697,8 +694,8 @@ class TestBulkWriteMixinOpen(TestBulkWriteMixin):
# the database
for _ in range(2):
result = self.bulk.get_course_index(self.course_key, ignore_case=ignore_case)
self.assertEqual(self.conn.get_course_index.call_count, 1)
self.assertEqual(self.conn.get_course_index.return_value, result)
assert self.conn.get_course_index.call_count == 1
assert self.conn.get_course_index.return_value == result
@ddt.data(True, False)
def test_read_index_after_write(self, ignore_case):
@@ -706,8 +703,8 @@ class TestBulkWriteMixinOpen(TestBulkWriteMixin):
# initial index, and should return the written index_entry
self.bulk.insert_course_index(self.course_key, self.index_entry)
result = self.bulk.get_course_index(self.course_key, ignore_case=ignore_case)
self.assertEqual(self.conn.get_course_index.call_count, 1)
self.assertEqual(self.index_entry, result)
assert self.conn.get_course_index.call_count == 1
assert self.index_entry == result
def test_read_index_ignore_case(self):
# Reading using ignore case should find an already written entry with a different case
@@ -720,22 +717,16 @@ class TestBulkWriteMixinOpen(TestBulkWriteMixin):
),
ignore_case=True
)
self.assertEqual(self.conn.get_course_index.call_count, 1)
self.assertEqual(self.index_entry, result)
assert self.conn.get_course_index.call_count == 1
assert self.index_entry == result
def test_version_structure_creates_new_version_before_read(self):
self.assertNotEqual(
self.bulk.version_structure(self.course_key, self.structure, 'user_id')['_id'],
self.structure['_id']
)
assert self.bulk.version_structure(self.course_key, self.structure, 'user_id')['_id'] != self.structure['_id']
def test_version_structure_creates_new_version_after_read(self):
self.conn.get_structure.return_value = copy.deepcopy(self.structure)
self.bulk.get_structure(self.course_key, self.structure['_id'])
self.assertNotEqual(
self.bulk.version_structure(self.course_key, self.structure, 'user_id')['_id'],
self.structure['_id']
)
assert self.bulk.version_structure(self.course_key, self.structure, 'user_id')['_id'] != self.structure['_id']
def test_copy_branch_versions(self):
# Directly updating an index so that the draft branch points to the published index

View File

@@ -2,7 +2,7 @@
import unittest
import pytest
from mock import patch
from pymongo.errors import ConnectionFailure
@@ -21,5 +21,5 @@ class TestHeartbeatFailureException(unittest.TestCase):
mock_proxy.return_value.admin.command.side_effect = ConnectionFailure('Test')
useless_conn = MongoConnection('useless', 'useless', 'useless')
with self.assertRaises(HeartbeatFailure):
with pytest.raises(HeartbeatFailure):
useless_conn.heartbeat()

View File

@@ -81,4 +81,4 @@ class TestUtils(unittest.TestCase):
module_nodes.append(draft_node_constructor(Mock(), node_args[0], node_args[1]))
subtree_roots_urls = [root.url for root in get_draft_subtree_roots(module_nodes)]
# check that we return the expected urls
self.assertEqual(set(subtree_roots_urls), set(expected_roots_urls))
assert set(subtree_roots_urls) == set(expected_roots_urls)

View File

@@ -6,7 +6,7 @@ well-formed and not-well-formed XML.
import os.path
from glob import glob
import pytest
from django.test import TestCase
from mock import Mock, patch
from opaque_keys.edx.keys import CourseKey
@@ -44,7 +44,7 @@ class TestXMLModuleStore(TestCase):
# Ensure that there really is a non-ASCII character in the course.
with open(os.path.join(DATA_DIR, "toy/sequential/vertical_sequential.xml"), 'rb') as xmlf:
xml = xmlf.read()
with self.assertRaises(UnicodeDecodeError):
with pytest.raises(UnicodeDecodeError):
xml.decode('ascii')
# Load the course, but don't make error modules. This will succeed,
@@ -66,23 +66,23 @@ class TestXMLModuleStore(TestCase):
store = XMLModuleStore(DATA_DIR, source_dirs=['toy', 'simple'])
for course in store.get_courses():
course_locations = store.get_courses_for_wiki(course.wiki_slug)
self.assertEqual(len(course_locations), 1)
self.assertIn(course.location.course_key, course_locations)
assert len(course_locations) == 1
assert course.location.course_key in course_locations
course_locations = store.get_courses_for_wiki('no_such_wiki')
self.assertEqual(len(course_locations), 0)
assert len(course_locations) == 0
# now set toy course to share the wiki with simple course
toy_course = store.get_course(CourseKey.from_string('edX/toy/2012_Fall'))
toy_course.wiki_slug = 'simple'
course_locations = store.get_courses_for_wiki('toy')
self.assertEqual(len(course_locations), 0)
assert len(course_locations) == 0
course_locations = store.get_courses_for_wiki('simple')
self.assertEqual(len(course_locations), 2)
assert len(course_locations) == 2
for course_number in ['toy', 'simple']:
self.assertIn(CourseKey.from_string('/'.join(['edX', course_number, '2012_Fall'])), course_locations)
assert CourseKey.from_string('/'.join(['edX', course_number, '2012_Fall'])) in course_locations
def test_has_course(self):
"""
@@ -106,7 +106,7 @@ class TestXMLModuleStore(TestCase):
store.get_item(course.location)
# XML store does NOT allow draft_preferred branch setting
with self.assertRaises(ValueError):
with pytest.raises(ValueError):
with store.branch_setting(ModuleStoreEnum.Branch.draft_preferred, course.id):
# verify that the above context manager raises a ValueError
pass # pragma: no cover
@@ -130,15 +130,15 @@ class TestXMLModuleStore(TestCase):
shared_item_loc = course_key.make_usage_key('html', 'toyhtml')
shared_item = store.get_item(shared_item_loc)
parent = shared_item.get_parent()
self.assertIsNotNone(parent, "get_parent failed to return a value")
assert parent is not None, 'get_parent failed to return a value'
parent_loc = course_key.make_usage_key('vertical', 'vertical_test')
self.assertEqual(parent.location, parent_loc)
self.assertIn(shared_item.location, [x.location for x in parent.get_children()])
assert parent.location == parent_loc
assert shared_item.location in [x.location for x in parent.get_children()]
# ensure it's still a child of the other parent even tho it doesn't claim the other parent as its parent
other_parent_loc = course_key.make_usage_key('vertical', 'zeta')
other_parent = store.get_item(other_parent_loc)
# children rather than get_children b/c the instance returned by get_children != shared_item
self.assertIn(shared_item_loc, other_parent.children)
assert shared_item_loc in other_parent.children
class TestModuleStoreIgnore(TestXMLModuleStore): # lint-amnesty, pylint: disable=missing-class-docstring, test-inherits-tests
@@ -156,5 +156,5 @@ class TestModuleStoreIgnore(TestXMLModuleStore): # lint-amnesty, pylint: disabl
'about', 'index',
)
about_module = modulestore.get_item(about_location)
self.assertIn("GREEN", about_module.data)
self.assertNotIn("RED", about_module.data)
assert 'GREEN' in about_module.data
assert 'RED' not in about_module.data

View File

@@ -7,7 +7,7 @@ import importlib
import os
import unittest
from uuid import uuid4
import pytest
import mock
import six
from opaque_keys.edx.keys import CourseKey
@@ -165,22 +165,16 @@ class RemapNamespaceTest(ModuleStoreNoSettings):
)
# Check the XBlock's location
self.assertEqual(new_version.location.course_key, target_location_namespace)
assert new_version.location.course_key == target_location_namespace
# Check the values of the fields.
# The content and settings fields should be preserved
self.assertEqual(new_version.test_content_field, 'Explicitly set')
self.assertEqual(new_version.test_settings_field, 'Explicitly set')
assert new_version.test_content_field == 'Explicitly set'
assert new_version.test_settings_field == 'Explicitly set'
# Expect that these fields are marked explicitly set
self.assertIn(
'test_content_field',
new_version.get_explicitly_set_fields_by_scope(scope=Scope.content)
)
self.assertIn(
'test_settings_field',
new_version.get_explicitly_set_fields_by_scope(scope=Scope.settings)
)
assert 'test_content_field' in new_version.get_explicitly_set_fields_by_scope(scope=Scope.content)
assert 'test_settings_field' in new_version.get_explicitly_set_fields_by_scope(scope=Scope.settings)
def test_remap_namespace_native_xblock_default_values(self):
@@ -203,18 +197,12 @@ class RemapNamespaceTest(ModuleStoreNoSettings):
# Check the values of the fields.
# The content and settings fields should be the default values
self.assertEqual(new_version.test_content_field, 'default value')
self.assertEqual(new_version.test_settings_field, 'default value')
assert new_version.test_content_field == 'default value'
assert new_version.test_settings_field == 'default value'
# The fields should NOT appear in the explicitly set fields
self.assertNotIn(
'test_content_field',
new_version.get_explicitly_set_fields_by_scope(scope=Scope.content)
)
self.assertNotIn(
'test_settings_field',
new_version.get_explicitly_set_fields_by_scope(scope=Scope.settings)
)
assert 'test_content_field' not in new_version.get_explicitly_set_fields_by_scope(scope=Scope.content)
assert 'test_settings_field' not in new_version.get_explicitly_set_fields_by_scope(scope=Scope.settings)
def test_remap_namespace_native_xblock_inherited_values(self):
@@ -234,12 +222,8 @@ class RemapNamespaceTest(ModuleStoreNoSettings):
)
# Inherited fields should NOT be explicitly set
self.assertNotIn(
'start', new_version.get_explicitly_set_fields_by_scope(scope=Scope.settings)
)
self.assertNotIn(
'graded', new_version.get_explicitly_set_fields_by_scope(scope=Scope.settings)
)
assert 'start' not in new_version.get_explicitly_set_fields_by_scope(scope=Scope.settings)
assert 'graded' not in new_version.get_explicitly_set_fields_by_scope(scope=Scope.settings)
def test_xblock_invalid_field_value_type(self):
# Setting the wrong field-value in Xblock-field will raise TypeError.
@@ -255,7 +239,7 @@ class RemapNamespaceTest(ModuleStoreNoSettings):
# clearing the dirty fields and removing value from cache will fetch the value from field-data.
self.xblock._dirty_fields = {} # pylint: disable=protected-access
self.xblock.fields['test_content_field']._del_cached_value(self.xblock) # lint-amnesty, pylint: disable=protected-access, unsubscriptable-object
with self.assertRaises(TypeError):
with pytest.raises(TypeError):
self.xblock.get_explicitly_set_fields_by_scope(scope=Scope.content)
@@ -326,15 +310,15 @@ class UpdateLocationTest(ModuleStoreNoSettings):
new_version = self.xblock # _update_module_location updates in-place
# Check the XBlock's location
self.assertEqual(new_version.location, target_location)
assert new_version.location == target_location
# Check the values of the fields.
# The content, settings and children fields should be preserved
self.assertEqual(new_version.test_content_field, 'Explicitly set')
self.assertEqual(new_version.test_settings_field, 'Explicitly set')
self.assertEqual(new_version.test_mutable_content_field, [1, 2, 3])
self.assertEqual(new_version.test_mutable_settings_field, ["a", "s", "d"])
self.assertEqual(new_version.children, self.fake_children_locations)
assert new_version.test_content_field == 'Explicitly set'
assert new_version.test_settings_field == 'Explicitly set'
assert new_version.test_mutable_content_field == [1, 2, 3]
assert new_version.test_mutable_settings_field == ['a', 's', 'd']
assert new_version.children == self.fake_children_locations
# Expect that these fields are marked explicitly set
self._check_explicitly_set(new_version, Scope.content, self.CONTENT_FIELDS, should_be_set=True)
@@ -343,7 +327,7 @@ class UpdateLocationTest(ModuleStoreNoSettings):
# Expect these fields pass "is_set_on" test
for field in self.CONTENT_FIELDS + self.SETTINGS_FIELDS + self.CHILDREN_FIELDS:
self.assertTrue(new_version.fields[field].is_set_on(new_version)) # lint-amnesty, pylint: disable=unsubscriptable-object
assert new_version.fields[field].is_set_on(new_version) # pylint: disable=unsubscriptable-object
class StaticContentImporterTest(unittest.TestCase): # lint-amnesty, pylint: disable=missing-class-docstring

View File

@@ -6,6 +6,7 @@ Test the partitions and partitions service
from datetime import datetime
import pytest
import six
from django.test import TestCase
from mock import Mock, patch # lint-amnesty, pylint: disable=unused-import
@@ -31,14 +32,14 @@ class TestGroup(TestCase):
test_id = 10
name = "Grendel"
group = Group(test_id, name)
self.assertEqual(group.id, test_id)
self.assertEqual(group.name, name)
assert group.id == test_id
assert group.name == name
def test_string_id(self):
test_id = "10"
name = "Grendel"
group = Group(test_id, name)
self.assertEqual(group.id, 10)
assert group.id == 10
def test_to_json(self):
test_id = 10
@@ -50,7 +51,7 @@ class TestGroup(TestCase):
"name": name,
"version": group.VERSION
}
self.assertEqual(jsonified, act_jsonified)
assert jsonified == act_jsonified
def test_from_json(self):
test_id = 5
@@ -61,8 +62,8 @@ class TestGroup(TestCase):
"version": Group.VERSION
}
group = Group.from_json(jsonified)
self.assertEqual(group.id, test_id)
self.assertEqual(group.name, name)
assert group.id == test_id
assert group.name == name
def test_from_json_broken(self):
test_id = 5
@@ -92,7 +93,7 @@ class TestGroup(TestCase):
"programmer": "Cale"
}
group = Group.from_json(jsonified)
self.assertNotIn("programmer", group.to_json())
assert 'programmer' not in group.to_json()
class MockUserPartitionScheme(object):
@@ -192,12 +193,12 @@ class TestUserPartition(PartitionTestCase):
MockUserPartitionScheme(),
self.TEST_PARAMETERS,
)
self.assertEqual(user_partition.id, self.TEST_ID)
self.assertEqual(user_partition.name, self.TEST_NAME)
self.assertEqual(user_partition.description, self.TEST_DESCRIPTION)
self.assertEqual(user_partition.groups, self.TEST_GROUPS)
self.assertEqual(user_partition.scheme.name, self.TEST_SCHEME_NAME)
self.assertEqual(user_partition.parameters, self.TEST_PARAMETERS)
assert user_partition.id == self.TEST_ID
assert user_partition.name == self.TEST_NAME
assert user_partition.description == self.TEST_DESCRIPTION
assert user_partition.groups == self.TEST_GROUPS
assert user_partition.scheme.name == self.TEST_SCHEME_NAME
assert user_partition.parameters == self.TEST_PARAMETERS
def test_string_id(self):
user_partition = UserPartition(
@@ -208,7 +209,7 @@ class TestUserPartition(PartitionTestCase):
MockUserPartitionScheme(),
self.TEST_PARAMETERS,
)
self.assertEqual(user_partition.id, 70)
assert user_partition.id == 70
def test_to_json(self):
jsonified = self.user_partition.to_json()
@@ -222,7 +223,7 @@ class TestUserPartition(PartitionTestCase):
"scheme": self.TEST_SCHEME_NAME,
"active": True,
}
self.assertEqual(jsonified, act_jsonified)
assert jsonified == act_jsonified
def test_from_json(self):
jsonified = {
@@ -235,16 +236,16 @@ class TestUserPartition(PartitionTestCase):
"scheme": "mock",
}
user_partition = UserPartition.from_json(jsonified)
self.assertEqual(user_partition.id, self.TEST_ID)
self.assertEqual(user_partition.name, self.TEST_NAME)
self.assertEqual(user_partition.description, self.TEST_DESCRIPTION)
self.assertEqual(user_partition.parameters, self.TEST_PARAMETERS)
assert user_partition.id == self.TEST_ID
assert user_partition.name == self.TEST_NAME
assert user_partition.description == self.TEST_DESCRIPTION
assert user_partition.parameters == self.TEST_PARAMETERS
for act_group in user_partition.groups:
self.assertIn(act_group.id, [0, 1])
assert act_group.id in [0, 1]
exp_group = self.TEST_GROUPS[act_group.id]
self.assertEqual(exp_group.id, act_group.id)
self.assertEqual(exp_group.name, act_group.name)
assert exp_group.id == act_group.id
assert exp_group.name == act_group.name
def test_version_upgrade(self):
# Test that version 1 partitions did not have a scheme specified
@@ -257,9 +258,9 @@ class TestUserPartition(PartitionTestCase):
"version": 1,
}
user_partition = UserPartition.from_json(jsonified)
self.assertEqual(user_partition.scheme.name, "random")
self.assertEqual(user_partition.parameters, {})
self.assertTrue(user_partition.active)
assert user_partition.scheme.name == 'random'
assert user_partition.parameters == {}
assert user_partition.active
def test_version_upgrade_2_to_3(self):
# Test that version 3 user partition raises error if 'scheme' field is
@@ -287,9 +288,9 @@ class TestUserPartition(PartitionTestCase):
"scheme": self.TEST_SCHEME_NAME,
}
user_partition = UserPartition.from_json(jsonified)
self.assertEqual(user_partition.scheme.name, self.TEST_SCHEME_NAME)
self.assertEqual(user_partition.parameters, {})
self.assertTrue(user_partition.active)
assert user_partition.scheme.name == self.TEST_SCHEME_NAME
assert user_partition.parameters == {}
assert user_partition.active
# now test that parameters dict is present in response with same value
# as provided
@@ -303,8 +304,8 @@ class TestUserPartition(PartitionTestCase):
"scheme": self.TEST_SCHEME_NAME,
}
user_partition = UserPartition.from_json(jsonified)
self.assertEqual(user_partition.parameters, self.TEST_PARAMETERS)
self.assertTrue(user_partition.active)
assert user_partition.parameters == self.TEST_PARAMETERS
assert user_partition.active
def test_from_json_broken(self):
# Missing field
@@ -369,7 +370,7 @@ class TestUserPartition(PartitionTestCase):
"programmer": "Cale",
}
user_partition = UserPartition.from_json(jsonified)
self.assertNotIn("programmer", user_partition.to_json())
assert 'programmer' not in user_partition.to_json()
# No error on missing parameters key (which is optional)
jsonified = {
@@ -381,7 +382,7 @@ class TestUserPartition(PartitionTestCase):
"scheme": "mock",
}
user_partition = UserPartition.from_json(jsonified)
self.assertEqual(user_partition.parameters, {})
assert user_partition.parameters == {}
def test_get_group(self):
"""
@@ -389,15 +390,9 @@ class TestUserPartition(PartitionTestCase):
`group_id` parameter, or raises NoSuchUserPartitionGroupError when
the lookup fails.
"""
self.assertEqual(
self.user_partition.get_group(self.TEST_GROUPS[0].id),
self.TEST_GROUPS[0]
)
self.assertEqual(
self.user_partition.get_group(self.TEST_GROUPS[1].id),
self.TEST_GROUPS[1]
)
with self.assertRaises(NoSuchUserPartitionGroupError):
assert self.user_partition.get_group(self.TEST_GROUPS[0].id) == self.TEST_GROUPS[0]
assert self.user_partition.get_group(self.TEST_GROUPS[1].id) == self.TEST_GROUPS[1]
with pytest.raises(NoSuchUserPartitionGroupError):
self.user_partition.get_group(3)
def test_forward_compatibility(self):
@@ -415,8 +410,8 @@ class TestUserPartition(PartitionTestCase):
"additional_new_field": "foo",
}
partition = UserPartition.from_json(newer_version_json)
self.assertEqual(partition.id, self.TEST_ID)
self.assertEqual(partition.name, self.TEST_NAME)
assert partition.id == self.TEST_ID
assert partition.name == self.TEST_NAME
class MockPartitionService(PartitionService):
@@ -506,10 +501,7 @@ class TestPartitionService(PartitionServiceBaseClass):
# Make sure our partition services all return the right thing, but skip
# ps_shared_cache_2 so we can see if its cache got updated anyway.
for part_svc in [ps_shared_cache_1, ps_diff_cache, ps_uncached]:
self.assertEqual(
first_group.id,
part_svc.get_user_group_id_for_partition(self.user, user_partition_id)
)
assert first_group.id == part_svc.get_user_group_id_for_partition(self.user, user_partition_id)
# Now select a new target group
second_group = self.user_partition.groups[1]
@@ -519,23 +511,14 @@ class TestPartitionService(PartitionServiceBaseClass):
# ps_shared_cache_2, which was never asked for the value the first time
# Likewise, our separately cached piece should return the original answer
for part_svc in [ps_shared_cache_1, ps_shared_cache_2, ps_diff_cache]:
self.assertEqual(
first_group.id,
part_svc.get_user_group_id_for_partition(self.user, user_partition_id)
)
assert first_group.id == part_svc.get_user_group_id_for_partition(self.user, user_partition_id)
# Our uncached service should be accurate.
self.assertEqual(
second_group.id,
ps_uncached.get_user_group_id_for_partition(self.user, user_partition_id)
)
assert second_group.id == ps_uncached.get_user_group_id_for_partition(self.user, user_partition_id)
# And a newly created service should see the right thing
ps_new_cache = self._create_service(username, {})
self.assertEqual(
second_group.id,
ps_new_cache.get_user_group_id_for_partition(self.user, user_partition_id)
)
assert second_group.id == ps_new_cache.get_user_group_id_for_partition(self.user, user_partition_id)
def test_get_group(self):
"""
@@ -546,12 +529,12 @@ class TestPartitionService(PartitionServiceBaseClass):
# assign first group and verify that it is returned for the user
self.user_partition.scheme.current_group = groups[0]
group1 = self.partition_service.get_group(self.user, self.user_partition)
self.assertEqual(group1, groups[0])
assert group1 == groups[0]
# switch to the second group and verify that it is returned for the user
self.user_partition.scheme.current_group = groups[1]
group2 = self.partition_service.get_group(self.user, self.user_partition)
self.assertEqual(group2, groups[1])
assert group2 == groups[1]
class TestGetCourseUserPartitions(PartitionServiceBaseClass):
@@ -575,12 +558,12 @@ class TestGetCourseUserPartitions(PartitionServiceBaseClass):
Test that the dynamic enrollment track scheme is added if there is no conflict with the user partition ID.
"""
all_partitions = get_all_partitions_for_course(self.course)
self.assertEqual(2, len(all_partitions))
self.assertEqual(self.TEST_SCHEME_NAME, all_partitions[0].scheme.name)
assert 2 == len(all_partitions)
assert self.TEST_SCHEME_NAME == all_partitions[0].scheme.name
enrollment_track_partition = all_partitions[1]
self.assertEqual(self.ENROLLMENT_TRACK_SCHEME_NAME, enrollment_track_partition.scheme.name)
self.assertEqual(six.text_type(self.course.id), enrollment_track_partition.parameters['course_id'])
self.assertEqual(ENROLLMENT_TRACK_PARTITION_ID, enrollment_track_partition.id)
assert self.ENROLLMENT_TRACK_SCHEME_NAME == enrollment_track_partition.scheme.name
assert six.text_type(self.course.id) == enrollment_track_partition.parameters['course_id']
assert ENROLLMENT_TRACK_PARTITION_ID == enrollment_track_partition.id
def test_enrollment_track_partition_not_added_if_conflict(self):
"""
@@ -596,8 +579,8 @@ class TestGetCourseUserPartitions(PartitionServiceBaseClass):
)
self.course.user_partitions = [self.user_partition]
all_partitions = get_all_partitions_for_course(self.course)
self.assertEqual(1, len(all_partitions))
self.assertEqual(self.TEST_SCHEME_NAME, all_partitions[0].scheme.name)
assert 1 == len(all_partitions)
assert self.TEST_SCHEME_NAME == all_partitions[0].scheme.name
def test_enrollment_track_partition_not_added_if_disabled(self):
"""
@@ -605,8 +588,8 @@ class TestGetCourseUserPartitions(PartitionServiceBaseClass):
"""
TestGetCourseUserPartitions._enable_enrollment_track_partition(False)
all_partitions = get_all_partitions_for_course(self.course)
self.assertEqual(1, len(all_partitions))
self.assertEqual(self.TEST_SCHEME_NAME, all_partitions[0].scheme.name)
assert 1 == len(all_partitions)
assert self.TEST_SCHEME_NAME == all_partitions[0].scheme.name
def test_filter_inactive_user_partitions(self):
"""
@@ -624,10 +607,10 @@ class TestGetCourseUserPartitions(PartitionServiceBaseClass):
self.course.user_partitions = [self.user_partition]
all_partitions = get_all_partitions_for_course(self.course, active_only=True)
self.assertEqual(1, len(all_partitions))
self.assertEqual(self.ENROLLMENT_TRACK_SCHEME_NAME, all_partitions[0].scheme.name)
assert 1 == len(all_partitions)
assert self.ENROLLMENT_TRACK_SCHEME_NAME == all_partitions[0].scheme.name
all_partitions = get_all_partitions_for_course(self.course, active_only=False)
self.assertEqual(2, len(all_partitions))
self.assertEqual(self.TEST_SCHEME_NAME, all_partitions[0].scheme.name)
self.assertEqual(self.ENROLLMENT_TRACK_SCHEME_NAME, all_partitions[1].scheme.name)
assert 2 == len(all_partitions)
assert self.TEST_SCHEME_NAME == all_partitions[0].scheme.name
assert self.ENROLLMENT_TRACK_SCHEME_NAME == all_partitions[1].scheme.name

View File

@@ -187,7 +187,7 @@ class ModelsTest(unittest.TestCase): # lint-amnesty, pylint: disable=missing-cl
def test_load_class(self):
vc = XModuleDescriptor.load_class('sequential')
vc_str = "<class 'xmodule.seq_module.SequenceDescriptor'>"
self.assertEqual(str(vc), vc_str)
assert str(vc) == vc_str
class LogicTest(unittest.TestCase):
@@ -307,24 +307,18 @@ class CourseComparisonTest(TestCase):
elif isinstance(reference_field, ReferenceValueDict):
expected = {key: extract_key(val) for (key, val) in six.iteritems(expected)}
actual = {key: extract_key(val) for (key, val) in six.iteritems(actual)}
self.assertEqual(
expected,
actual,
LazyFormat(
"Field {} doesn't match between usages {} and {}: {!r} != {!r}",
reference_field.name,
expected_block.scope_ids.usage_id,
actual_block.scope_ids.usage_id,
expected,
actual
)
)
assert expected == actual,\
LazyFormat("Field {} doesn't match between usages {} and {}: {!r} != {!r}",
reference_field.name,
expected_block.scope_ids.usage_id,
actual_block.scope_ids.usage_id,
expected, actual)
def assertBlocksEqualByFields(self, expected_block, actual_block):
"""
Compare block fields to check for equivalence.
"""
self.assertEqual(expected_block.fields, actual_block.fields)
assert expected_block.fields == actual_block.fields
for field in expected_block.fields.values():
self.assertFieldEqual(field, expected_block, actual_block)
@@ -337,18 +331,12 @@ class CourseComparisonTest(TestCase):
else:
expected = field.read_from(expected_block)
actual = field.read_from(actual_block)
self.assertEqual(
expected,
actual,
LazyFormat(
"Field {} doesn't match between usages {} and {}: {!r} != {!r}",
field.name,
expected_block.scope_ids.usage_id,
actual_block.scope_ids.usage_id,
expected,
actual
)
)
assert expected == actual,\
LazyFormat("Field {} doesn't match between usages {} and {}: {!r} != {!r}",
field.name,
expected_block.scope_ids.usage_id,
actual_block.scope_ids.usage_id,
expected, actual)
def assertCoursesEqual(self, expected_store, expected_course_key, actual_store, actual_course_key):
"""
@@ -364,7 +352,7 @@ class CourseComparisonTest(TestCase):
with actual_store.branch_setting(ModuleStoreEnum.Branch.published_only, actual_course_key):
expected_items = expected_store.get_items(expected_course_key, revision=ModuleStoreEnum.RevisionOption.published_only) # lint-amnesty, pylint: disable=line-too-long
actual_items = actual_store.get_items(actual_course_key, revision=ModuleStoreEnum.RevisionOption.published_only) # lint-amnesty, pylint: disable=line-too-long
self.assertGreater(len(expected_items), 0)
assert len(expected_items) > 0
self._assertCoursesEqual(expected_items, actual_items, actual_course_key)
# if the modulestore supports having a draft branch
@@ -389,7 +377,7 @@ class CourseComparisonTest(TestCase):
Actual algorithm to compare courses.
"""
self.assertEqual(len(expected_items), len(actual_items))
assert len(expected_items) == len(actual_items)
def map_key(usage_key):
return (usage_key.block_type, usage_key.block_id)
@@ -416,11 +404,11 @@ class CourseComparisonTest(TestCase):
actual_item_location = actual_item_location.replace(name='course')
actual_item = actual_item_map.get(map_key(actual_item_location))
# Formatting the message slows down tests of large courses significantly, so only do it if it would be used
self.assertIn(map_key(actual_item_location), list(actual_item_map.keys()))
assert map_key(actual_item_location) in list(actual_item_map.keys())
if actual_item is None:
continue
# compare fields
self.assertEqual(expected_item.fields, actual_item.fields)
assert expected_item.fields == actual_item.fields
for field_name, field in six.iteritems(expected_item.fields):
if (expected_item.scope_ids.usage_id, field_name) in self.field_exclusions:
continue
@@ -431,7 +419,7 @@ class CourseComparisonTest(TestCase):
continue
self.assertFieldEqual(field, expected_item, actual_item)
# compare children
self.assertEqual(expected_item.has_children, actual_item.has_children)
assert expected_item.has_children == actual_item.has_children
if expected_item.has_children:
expected_children = [
(expected_item_child.location.block_type, expected_item_child.location.block_id)
@@ -443,7 +431,7 @@ class CourseComparisonTest(TestCase):
# get_children() rather than children to strip privates from public parents
for item_child in actual_item.get_children()
]
self.assertEqual(expected_children, actual_children)
assert expected_children == actual_children
def assertAssetEqual(self, expected_course_key, expected_asset, actual_course_key, actual_asset):
"""
@@ -457,20 +445,20 @@ class CourseComparisonTest(TestCase):
expected_key = expected_asset.pop('asset_key')
actual_key = actual_asset.pop('asset_key')
self.assertEqual(expected_key.map_into_course(actual_course_key), actual_key)
self.assertEqual(expected_key, actual_key.map_into_course(expected_course_key))
assert expected_key.map_into_course(actual_course_key) == actual_key
assert expected_key == actual_key.map_into_course(expected_course_key)
expected_filename = expected_asset.pop('filename')
actual_filename = actual_asset.pop('filename')
self.assertEqual(text_type(expected_key), expected_filename)
self.assertEqual(text_type(actual_key), actual_filename)
self.assertEqual(expected_asset, actual_asset)
assert text_type(expected_key) == expected_filename
assert text_type(actual_key) == actual_filename
assert expected_asset == actual_asset
def _assertAssetsEqual(self, expected_course_key, expected_assets, actual_course_key, actual_assets): # pylint: disable=invalid-name
"""
Private helper method for assertAssetsEqual
"""
self.assertEqual(len(expected_assets), len(actual_assets))
assert len(expected_assets) == len(actual_assets)
actual_assets_map = {asset['asset_key']: asset for asset in actual_assets}
for expected_item in expected_assets:
@@ -486,7 +474,7 @@ class CourseComparisonTest(TestCase):
expected_content, expected_count = expected_store.get_all_content_for_course(expected_course_key)
actual_content, actual_count = actual_store.get_all_content_for_course(actual_course_key)
self.assertEqual(expected_count, actual_count)
assert expected_count == actual_count
self._assertAssetsEqual(expected_course_key, expected_content, actual_course_key, actual_content)
expected_thumbs = expected_store.get_all_content_thumbnails_for_course(expected_course_key)
actual_thumbs = actual_store.get_all_content_thumbnails_for_course(actual_course_key)
@@ -503,10 +491,10 @@ class CourseComparisonTest(TestCase):
actual_course_assets = actual_modulestore.get_all_asset_metadata(
actual_course_key, None, sort=('displayname', ModuleStoreEnum.SortOrder.descending)
)
self.assertEqual(len(expected_course_assets), len(actual_course_assets))
assert len(expected_course_assets) == len(actual_course_assets)
for idx, __ in enumerate(expected_course_assets):
for attr in AssetMetadata.ATTRS_ALLOWED_TO_UPDATE:
if attr in ('edited_on',):
# edited_on is updated upon import.
continue
self.assertEqual(getattr(expected_course_assets[idx], attr), getattr(actual_course_assets[idx], attr))
assert getattr(expected_course_assets[idx], attr) == getattr(actual_course_assets[idx], attr)

View File

@@ -51,7 +51,7 @@ class AnnotatableBlockTestCase(unittest.TestCase): # lint-amnesty, pylint: disa
actual_attr = self.annotatable._get_annotation_data_attr(0, el) # lint-amnesty, pylint: disable=protected-access
self.assertIsInstance(actual_attr, dict)
assert isinstance(actual_attr, dict)
self.assertDictEqual(expected_attr, actual_attr)
def test_annotation_class_attr_default(self):
@@ -61,7 +61,7 @@ class AnnotatableBlockTestCase(unittest.TestCase): # lint-amnesty, pylint: disa
expected_attr = {'class': {'value': 'annotatable-span highlight'}}
actual_attr = self.annotatable._get_annotation_class_attr(0, el) # lint-amnesty, pylint: disable=protected-access
self.assertIsInstance(actual_attr, dict)
assert isinstance(actual_attr, dict)
self.assertDictEqual(expected_attr, actual_attr)
def test_annotation_class_attr_with_valid_highlight(self):
@@ -79,7 +79,7 @@ class AnnotatableBlockTestCase(unittest.TestCase): # lint-amnesty, pylint: disa
}
actual_attr = self.annotatable._get_annotation_class_attr(0, el) # lint-amnesty, pylint: disable=protected-access
self.assertIsInstance(actual_attr, dict)
assert isinstance(actual_attr, dict)
self.assertDictEqual(expected_attr, actual_attr)
def test_annotation_class_attr_with_invalid_highlight(self):
@@ -95,7 +95,7 @@ class AnnotatableBlockTestCase(unittest.TestCase): # lint-amnesty, pylint: disa
}
actual_attr = self.annotatable._get_annotation_class_attr(0, el) # lint-amnesty, pylint: disable=protected-access
self.assertIsInstance(actual_attr, dict)
assert isinstance(actual_attr, dict)
self.assertDictEqual(expected_attr, actual_attr)
def test_render_annotation(self):
@@ -105,33 +105,33 @@ class AnnotatableBlockTestCase(unittest.TestCase): # lint-amnesty, pylint: disa
actual_el = etree.fromstring('<annotation title="x" body="y" problem="0" highlight="yellow">z</annotation>')
self.annotatable._render_annotation(0, actual_el) # lint-amnesty, pylint: disable=protected-access
self.assertEqual(expected_el.tag, actual_el.tag)
self.assertEqual(expected_el.text, actual_el.text)
assert expected_el.tag == actual_el.tag
assert expected_el.text == actual_el.text
self.assertDictEqual(dict(expected_el.attrib), dict(actual_el.attrib))
def test_render_content(self):
content = self.annotatable._render_content() # lint-amnesty, pylint: disable=protected-access
el = etree.fromstring(content)
self.assertEqual('div', el.tag, 'root tag is a div')
assert 'div' == el.tag, 'root tag is a div'
expected_num_annotations = 5
actual_num_annotations = el.xpath('count(//span[contains(@class,"annotatable-span")])')
self.assertEqual(expected_num_annotations, actual_num_annotations, 'check number of annotations')
assert expected_num_annotations == actual_num_annotations, 'check number of annotations'
def test_get_html(self):
context = self.annotatable.get_html()
for key in ['display_name', 'element_id', 'content_html', 'instructions_html']:
self.assertIn(key, context)
assert key in context
def test_extract_instructions(self):
xmltree = etree.fromstring(self.sample_xml)
expected_xml = u"<div>Read the text.</div>"
actual_xml = self.annotatable._extract_instructions(xmltree) # lint-amnesty, pylint: disable=protected-access
self.assertIsNotNone(actual_xml)
self.assertEqual(expected_xml.strip(), actual_xml.strip())
assert actual_xml is not None
assert expected_xml.strip() == actual_xml.strip()
xmltree = etree.fromstring('<annotatable>foo</annotatable>')
actual = self.annotatable._extract_instructions(xmltree) # lint-amnesty, pylint: disable=protected-access
self.assertIsNone(actual)
assert actual is None

View File

@@ -32,12 +32,12 @@ class HelperFunctionTest(unittest.TestCase):
expected_xml = u"<div><p>Helper Test Instructions.</p></div>"
actual_xml = get_instructions(xmltree)
self.assertIsNotNone(actual_xml)
self.assertEqual(expected_xml.strip(), actual_xml.strip())
assert actual_xml is not None
assert expected_xml.strip() == actual_xml.strip()
xmltree = etree.fromstring('<annotatable>foo</annotatable>')
actual = get_instructions(xmltree)
self.assertIsNone(actual)
assert actual is None
def test_get_extension(self):
"""
@@ -47,10 +47,10 @@ class HelperFunctionTest(unittest.TestCase):
expectednotyoutube = 'video/mp4'
result1 = get_extension(self.sample_sourceurl)
result2 = get_extension(self.sample_youtubeurl)
self.assertEqual(expectedyoutube, result2)
self.assertEqual(expectednotyoutube, result1)
assert expectedyoutube == result2
assert expectednotyoutube == result1
def test_html_to_text(self):
expectedtext = "Testing here and not bolded here"
result = html_to_text(self.sample_html)
self.assertEqual(expectedtext, result)
assert expectedtext == result

View File

@@ -12,6 +12,7 @@ import random
import textwrap
import unittest
import pytest
import ddt
import requests
import six
@@ -194,22 +195,21 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
def test_import(self):
module = CapaFactory.create()
self.assertEqual(module.get_score().raw_earned, 0)
assert module.get_score().raw_earned == 0
other_module = CapaFactory.create()
self.assertEqual(module.get_score().raw_earned, 0)
self.assertNotEqual(module.url_name, other_module.url_name,
"Factory should be creating unique names for each problem")
assert module.get_score().raw_earned == 0
assert module.url_name != other_module.url_name, 'Factory should be creating unique names for each problem'
def test_correct(self):
"""
Check that the factory creates correct and incorrect problems properly.
"""
module = CapaFactory.create()
self.assertEqual(module.get_score().raw_earned, 0)
assert module.get_score().raw_earned == 0
other_module = CapaFactory.create(correct=True)
self.assertEqual(other_module.get_score().raw_earned, 1)
assert other_module.get_score().raw_earned == 1
def test_get_score(self):
"""
@@ -222,17 +222,17 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
module = CapaFactory.create(correct=True, override_get_score=False)
module.lcp.correct_map = correct_map
module.lcp.student_answers = student_answers
self.assertEqual(module.get_score().raw_earned, 0.0)
assert module.get_score().raw_earned == 0.0
module.set_score(module.score_from_lcp(module.lcp))
self.assertEqual(module.get_score().raw_earned, 0.9)
assert module.get_score().raw_earned == 0.9
other_correct_map = CorrectMap(answer_id='1_2_1', correctness="incorrect", npoints=0.1)
other_module = CapaFactory.create(correct=False, override_get_score=False)
other_module.lcp.correct_map = other_correct_map
other_module.lcp.student_answers = student_answers
self.assertEqual(other_module.get_score().raw_earned, 0.0)
assert other_module.get_score().raw_earned == 0.0
other_module.set_score(other_module.score_from_lcp(other_module.lcp))
self.assertEqual(other_module.get_score().raw_earned, 0.1)
assert other_module.get_score().raw_earned == 0.1
def test_showanswer_default(self):
"""
@@ -241,7 +241,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
# default, no due date, showanswer 'closed', so problem is open, and show_answer
# not visible.
problem = CapaFactory.create()
self.assertFalse(problem.answer_available())
assert not problem.answer_available()
@ddt.data(
(requests.exceptions.ReadTimeout, (1, 'failed to read from the server')),
@@ -257,13 +257,13 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
with patch.object(xqueue_interface.session, 'post', side_effect=exception):
# pylint: disable = protected-access
response = xqueue_interface._http_post('http://some/fake/url', {})
self.assertEqual(response, result)
assert response == result
def test_showanswer_attempted(self):
problem = CapaFactory.create(showanswer='attempted')
self.assertFalse(problem.answer_available())
assert not problem.answer_available()
problem.attempts = 1
self.assertTrue(problem.answer_available())
assert problem.answer_available()
@ddt.data(
# If show_correctness=always, Answer is visible after attempted
@@ -285,9 +285,9 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
if 'due' in problem_data:
problem_data['due'] = getattr(self, problem_data['due'])
problem = CapaFactory.create(**problem_data)
self.assertEqual(problem.answer_available(), answer_available_no_attempt)
assert problem.answer_available() == answer_available_no_attempt
problem.attempts = 1
self.assertEqual(problem.answer_available(), answer_available_after_attempt)
assert problem.answer_available() == answer_available_after_attempt
def test_showanswer_closed(self):
@@ -296,7 +296,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
max_attempts="1",
attempts="1",
due=self.tomorrow_str)
self.assertTrue(used_all_attempts.answer_available())
assert used_all_attempts.answer_available()
# can see after due date
after_due_date = CapaFactory.create(showanswer='closed',
@@ -304,14 +304,14 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
attempts="0",
due=self.yesterday_str)
self.assertTrue(after_due_date.answer_available())
assert after_due_date.answer_available()
# can't see because attempts left
attempts_left_open = CapaFactory.create(showanswer='closed',
max_attempts="1",
attempts="0",
due=self.tomorrow_str)
self.assertFalse(attempts_left_open.answer_available())
assert not attempts_left_open.answer_available()
# Can't see because grace period hasn't expired
still_in_grace = CapaFactory.create(showanswer='closed',
@@ -319,7 +319,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
attempts="0",
due=self.yesterday_str,
graceperiod=self.two_day_delta_str)
self.assertFalse(still_in_grace.answer_available())
assert not still_in_grace.answer_available()
def test_showanswer_correct_or_past_due(self):
"""
@@ -333,14 +333,14 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
attempts="0",
due=self.tomorrow_str,
correct=True)
self.assertTrue(answer_correct.answer_available())
assert answer_correct.answer_available()
# can see after due date, even when answer isn't correct
past_due_date = CapaFactory.create(showanswer='correct_or_past_due',
max_attempts="1",
attempts="0",
due=self.yesterday_str)
self.assertTrue(past_due_date.answer_available())
assert past_due_date.answer_available()
# can also see after due date when answer _is_ correct
past_due_date_correct = CapaFactory.create(showanswer='correct_or_past_due',
@@ -348,7 +348,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
attempts="0",
due=self.yesterday_str,
correct=True)
self.assertTrue(past_due_date_correct.answer_available())
assert past_due_date_correct.answer_available()
# Can't see because grace period hasn't expired and answer isn't correct
still_in_grace = CapaFactory.create(showanswer='correct_or_past_due',
@@ -356,7 +356,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
attempts="1",
due=self.yesterday_str,
graceperiod=self.two_day_delta_str)
self.assertFalse(still_in_grace.answer_available())
assert not still_in_grace.answer_available()
def test_showanswer_past_due(self):
"""
@@ -369,21 +369,21 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
max_attempts="1",
attempts="1",
due=self.tomorrow_str)
self.assertFalse(used_all_attempts.answer_available())
assert not used_all_attempts.answer_available()
# can see after due date
past_due_date = CapaFactory.create(showanswer='past_due',
max_attempts="1",
attempts="0",
due=self.yesterday_str)
self.assertTrue(past_due_date.answer_available())
assert past_due_date.answer_available()
# can't see because attempts left
attempts_left_open = CapaFactory.create(showanswer='past_due',
max_attempts="1",
attempts="0",
due=self.tomorrow_str)
self.assertFalse(attempts_left_open.answer_available())
assert not attempts_left_open.answer_available()
# Can't see because grace period hasn't expired, even though have no more
# attempts.
@@ -392,7 +392,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
attempts="1",
due=self.yesterday_str,
graceperiod=self.two_day_delta_str)
self.assertFalse(still_in_grace.answer_available())
assert not still_in_grace.answer_available()
def test_showanswer_after_attempts_with_max(self):
"""
@@ -408,7 +408,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
attempts_before_showanswer_button='3',
max_attempts='5',
)
self.assertFalse(problem.answer_available())
assert not problem.answer_available()
def test_showanswer_after_attempts_no_max(self):
"""
@@ -423,7 +423,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
attempts='2',
attempts_before_showanswer_button='3',
)
self.assertFalse(problem.answer_available())
assert not problem.answer_available()
def test_showanswer_after_attempts_used_all_attempts(self):
"""
@@ -440,7 +440,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
attempts='3',
due=self.tomorrow_str,
)
self.assertTrue(problem.answer_available())
assert problem.answer_available()
def test_showanswer_after_attempts_past_due_date(self):
"""
@@ -455,7 +455,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
attempts='2',
due=self.yesterday_str,
)
self.assertTrue(problem.answer_available())
assert problem.answer_available()
def test_showanswer_after_attempts_still_in_grace(self):
"""
@@ -471,7 +471,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
due=self.yesterday_str,
graceperiod=self.two_day_delta_str,
)
self.assertTrue(problem.answer_available())
assert problem.answer_available()
def test_showanswer_after_attempts_large(self):
"""
@@ -487,7 +487,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
max_attempts='3',
attempts='3',
)
self.assertTrue(problem.answer_available())
assert problem.answer_available()
def test_showanswer_after_attempts_zero(self):
"""
@@ -501,7 +501,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
attempts_before_showanswer_button='0',
attempts='0',
)
self.assertTrue(problem.answer_available())
assert problem.answer_available()
def test_showanswer_finished(self):
"""
@@ -514,21 +514,21 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
max_attempts="1",
attempts="1",
due=self.tomorrow_str)
self.assertTrue(used_all_attempts.answer_available())
assert used_all_attempts.answer_available()
# can see after due date
past_due_date = CapaFactory.create(showanswer='finished',
max_attempts="1",
attempts="0",
due=self.yesterday_str)
self.assertTrue(past_due_date.answer_available())
assert past_due_date.answer_available()
# can't see because attempts left and wrong
attempts_left_open = CapaFactory.create(showanswer='finished',
max_attempts="1",
attempts="0",
due=self.tomorrow_str)
self.assertFalse(attempts_left_open.answer_available())
assert not attempts_left_open.answer_available()
# _can_ see because attempts left and right
correct_ans = CapaFactory.create(showanswer='finished',
@@ -536,7 +536,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
attempts="0",
due=self.tomorrow_str,
correct=True)
self.assertTrue(correct_ans.answer_available())
assert correct_ans.answer_available()
# Can see even though grace period hasn't expired, because have no more
# attempts.
@@ -545,7 +545,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
attempts="1",
due=self.yesterday_str,
graceperiod=self.two_day_delta_str)
self.assertTrue(still_in_grace.answer_available())
assert still_in_grace.answer_available()
def test_showanswer_answered(self):
"""
@@ -560,7 +560,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
due=self.tomorrow_str,
correct=False
)
self.assertFalse(answer_wrong.answer_available())
assert not answer_wrong.answer_available()
# Expect to see "Show Answer" when answer is correct
answer_correct = CapaFactory.create(
@@ -570,7 +570,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
due=self.tomorrow_str,
correct=True
)
self.assertTrue(answer_correct.answer_available())
assert answer_correct.answer_available()
@ddt.data('', 'other-value')
def test_show_correctness_other(self, show_correctness):
@@ -579,21 +579,21 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
from SHOW_CORRECTNESS constant.
"""
problem = CapaFactory.create(show_correctness=show_correctness)
self.assertTrue(problem.correctness_available())
assert problem.correctness_available()
def test_show_correctness_default(self):
"""
Test that correctness is visible by default.
"""
problem = CapaFactory.create()
self.assertTrue(problem.correctness_available())
assert problem.correctness_available()
def test_show_correctness_never(self):
"""
Test that correctness is hidden when show_correctness turned off.
"""
problem = CapaFactory.create(show_correctness='never')
self.assertFalse(problem.correctness_available())
assert not problem.correctness_available()
@ddt.data(
# Correctness not visible if due date in the future, even after using up all attempts
@@ -616,34 +616,34 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
if 'graceperiod' in problem_data:
problem_data['graceperiod'] = getattr(self, problem_data['graceperiod'])
problem = CapaFactory.create(**problem_data)
self.assertEqual(problem.correctness_available(), expected_result)
assert problem.correctness_available() == expected_result
def test_closed(self):
# Attempts < Max attempts --> NOT closed
module = CapaFactory.create(max_attempts="1", attempts="0")
self.assertFalse(module.closed())
assert not module.closed()
# Attempts < Max attempts --> NOT closed
module = CapaFactory.create(max_attempts="2", attempts="1")
self.assertFalse(module.closed())
assert not module.closed()
# Attempts = Max attempts --> closed
module = CapaFactory.create(max_attempts="1", attempts="1")
self.assertTrue(module.closed())
assert module.closed()
# Attempts > Max attempts --> closed
module = CapaFactory.create(max_attempts="1", attempts="2")
self.assertTrue(module.closed())
assert module.closed()
# Max attempts = 0 --> closed
module = CapaFactory.create(max_attempts="0", attempts="2")
self.assertTrue(module.closed())
assert module.closed()
# Past due --> closed
module = CapaFactory.create(max_attempts="1", attempts="0",
due=self.yesterday_str)
self.assertTrue(module.closed())
assert module.closed()
def test_parse_get_params(self):
@@ -664,25 +664,25 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
# and that we get the same values back
for key in result.keys(): # lint-amnesty, pylint: disable=consider-iterating-dictionary
original_key = "input_" + key
self.assertIn(original_key, valid_get_dict, "Output dict should have key %s" % original_key)
self.assertEqual(valid_get_dict[original_key], result[key])
assert original_key in valid_get_dict, ('Output dict should have key %s' % original_key)
assert valid_get_dict[original_key] == result[key]
# Valid GET param dict with list keys
# Each tuple represents a single parameter in the query string
valid_get_dict = MultiDict((('input_2[]', 'test1'), ('input_2[]', 'test2')))
result = ProblemBlock.make_dict_of_responses(valid_get_dict)
self.assertIn('2', result)
self.assertEqual(['test1', 'test2'], result['2'])
assert '2' in result
assert ['test1', 'test2'] == result['2']
# If we use [] at the end of a key name, we should always
# get a list, even if there's just one value
valid_get_dict = MultiDict({'input_1[]': 'test'})
result = ProblemBlock.make_dict_of_responses(valid_get_dict)
self.assertEqual(result['1'], ['test'])
assert result['1'] == ['test']
# If we have no underscores in the name, then the key is invalid
invalid_get_dict = MultiDict({'input': 'test'})
with self.assertRaises(ValueError):
with pytest.raises(ValueError):
result = ProblemBlock.make_dict_of_responses(invalid_get_dict)
# Two equivalent names (one list, one non-list)
@@ -690,7 +690,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
# and raise an exception
invalid_get_dict = MultiDict({'input_1[]': 'test 1',
'input_1': 'test 2'})
with self.assertRaises(ValueError):
with pytest.raises(ValueError):
result = ProblemBlock.make_dict_of_responses(invalid_get_dict)
def test_submit_problem_correct(self):
@@ -710,15 +710,15 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
result = module.submit_problem(get_request_dict)
# Expect that the problem is marked correct
self.assertEqual(result['success'], 'correct')
assert result['success'] == 'correct'
# Expect that we get the (mocked) HTML
self.assertEqual(result['contents'], 'Test HTML')
assert result['contents'] == 'Test HTML'
# Expect that the number of attempts is incremented by 1
self.assertEqual(module.attempts, 2)
assert module.attempts == 2
# and that this was considered attempt number 2 for grading purposes
self.assertEqual(module.lcp.context['attempt'], 2)
assert module.lcp.context['attempt'] == 2
def test_submit_problem_incorrect(self):
@@ -733,12 +733,12 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
result = module.submit_problem(get_request_dict)
# Expect that the problem is marked correct
self.assertEqual(result['success'], 'incorrect')
assert result['success'] == 'incorrect'
# Expect that the number of attempts is incremented by 1
self.assertEqual(module.attempts, 1)
assert module.attempts == 1
# and that this is considered the first attempt
self.assertEqual(module.lcp.context['attempt'], 1)
assert module.lcp.context['attempt'] == 1
def test_submit_problem_closed(self):
module = CapaFactory.create(attempts=3)
@@ -747,12 +747,12 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
# Simulate that ProblemBlock.closed() always returns True
with patch('xmodule.capa_module.ProblemBlock.closed') as mock_closed:
mock_closed.return_value = True
with self.assertRaises(xmodule.exceptions.NotFoundError):
with pytest.raises(xmodule.exceptions.NotFoundError):
get_request_dict = {CapaFactory.input_key(): '3.14'}
module.submit_problem(get_request_dict)
# Expect that number of attempts NOT incremented
self.assertEqual(module.attempts, 3)
assert module.attempts == 3
@ddt.data(
RANDOMIZATION.ALWAYS,
@@ -766,12 +766,12 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
module.done = True
# Expect that we cannot submit
with self.assertRaises(xmodule.exceptions.NotFoundError):
with pytest.raises(xmodule.exceptions.NotFoundError):
get_request_dict = {CapaFactory.input_key(): '3.14'}
module.submit_problem(get_request_dict)
# Expect that number of attempts NOT incremented
self.assertEqual(module.attempts, 0)
assert module.attempts == 0
@ddt.data(
RANDOMIZATION.NEVER,
@@ -786,11 +786,11 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
get_request_dict = {CapaFactory.input_key(): '3.14'}
result = module.submit_problem(get_request_dict)
self.assertEqual(result['success'], 'correct')
assert result['success'] == 'correct'
# Expect that number of attempts IS incremented, still same attempt
self.assertEqual(module.attempts, 1)
self.assertEqual(module.lcp.context['attempt'], 1)
assert module.attempts == 1
assert module.lcp.context['attempt'] == 1
def test_submit_problem_queued(self):
module = CapaFactory.create(attempts=1)
@@ -809,10 +809,10 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
result = module.submit_problem(get_request_dict)
# Expect an AJAX alert message in 'success'
self.assertIn('You must wait', result['success'])
assert 'You must wait' in result['success']
# Expect that the number of attempts is NOT incremented
self.assertEqual(module.attempts, 1)
assert module.attempts == 1
def test_submit_problem_with_files(self):
# Check a problem with uploaded files, using the submit_problem API.
@@ -859,11 +859,11 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
# )
# pylint: enable=line-too-long
self.assertEqual(xqueue_interface._http_post.call_count, 1)
assert xqueue_interface._http_post.call_count == 1
_, kwargs = xqueue_interface._http_post.call_args
six.assertCountEqual(self, fpaths, list(kwargs['files'].keys()))
for fpath, fileobj in six.iteritems(kwargs['files']):
self.assertEqual(fpath, fileobj.name)
assert fpath == fileobj.name
def test_submit_problem_with_files_as_xblock(self):
# Check a problem with uploaded files, using the XBlock API.
@@ -892,11 +892,11 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
module.handle('xmodule_handler', request, 'problem_check')
self.assertEqual(xqueue_interface._http_post.call_count, 1)
assert xqueue_interface._http_post.call_count == 1
_, kwargs = xqueue_interface._http_post.call_args
six.assertCountEqual(self, fnames, list(kwargs['files'].keys()))
for fpath, fileobj in six.iteritems(kwargs['files']):
self.assertEqual(fpath, fileobj.name)
assert fpath == fileobj.name
def test_submit_problem_error(self):
@@ -918,12 +918,12 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
# Expect an AJAX alert message in 'success'
expected_msg = 'test error'
self.assertEqual(expected_msg, result['success'])
assert expected_msg == result['success']
# Expect that the number of attempts is NOT incremented
self.assertEqual(module.attempts, 1)
assert module.attempts == 1
# but that this was considered attempt number 2 for grading purposes
self.assertEqual(module.lcp.context['attempt'], 2)
assert module.lcp.context['attempt'] == 2
def test_submit_problem_error_with_codejail_exception(self):
@@ -953,12 +953,12 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
# Expect an AJAX alert message in 'success' without the text of the stack trace
expected_msg = 'Couldn\'t execute jailed code'
self.assertEqual(expected_msg, result['success'])
assert expected_msg == result['success']
# Expect that the number of attempts is NOT incremented
self.assertEqual(module.attempts, 1)
assert module.attempts == 1
# but that this was considered the second attempt for grading purposes
self.assertEqual(module.lcp.context['attempt'], 2)
assert module.lcp.context['attempt'] == 2
def test_submit_problem_other_errors(self):
"""
@@ -981,7 +981,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
result = module.submit_problem(get_request_dict)
# Expect an AJAX alert message in 'success'
self.assertIn(error_msg, result['success'])
assert error_msg in result['success']
def test_submit_problem_zero_max_grade(self):
"""
@@ -1017,12 +1017,12 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
# Expect an AJAX alert message in 'success'
expected_msg = u'ȧƈƈḗƞŧḗḓ ŧḗẋŧ ƒǿř ŧḗşŧīƞɠ'
self.assertEqual(expected_msg, result['success'])
assert expected_msg == result['success']
# Expect that the number of attempts is NOT incremented
self.assertEqual(module.attempts, 1)
assert module.attempts == 1
# but that this was considered the second attempt for grading purposes
self.assertEqual(module.lcp.context['attempt'], 2)
assert module.lcp.context['attempt'] == 2
def test_submit_problem_error_with_staff_user(self):
@@ -1041,15 +1041,15 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
result = module.submit_problem(get_request_dict)
# Expect an AJAX alert message in 'success'
self.assertIn('test error', result['success'])
assert 'test error' in result['success']
# We DO include traceback information for staff users
self.assertIn('Traceback', result['success'])
assert 'Traceback' in result['success']
# Expect that the number of attempts is NOT incremented
self.assertEqual(module.attempts, 1)
assert module.attempts == 1
# but that it was considered the second attempt for grading purposes
self.assertEqual(module.lcp.context['attempt'], 2)
assert module.lcp.context['attempt'] == 2
@ddt.data(
("never", True, None, 'submitted'),
@@ -1075,12 +1075,12 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
result = json.loads(json_result)
# Expect that the AJAX result withholds correctness and score
self.assertEqual(result['current_score'], expected_score)
self.assertEqual(result['success'], expected_success)
assert result['current_score'] == expected_score
assert result['success'] == expected_success
# Expect that the number of attempts is incremented by 1
self.assertEqual(module.attempts, 1)
self.assertEqual(module.lcp.context['attempt'], 1)
assert module.attempts == 1
assert module.lcp.context['attempt'] == 1
def test_reset_problem(self):
module = CapaFactory.create(done=True)
@@ -1096,11 +1096,11 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
result = module.reset_problem(get_request_dict)
# Expect that the request was successful
self.assertTrue('success' in result and result['success'])
assert (('success' in result) and result['success'])
# Expect that the problem HTML is retrieved
self.assertIn('html', result)
self.assertEqual(result['html'], "<div>Test HTML</div>")
assert 'html' in result
assert result['html'] == '<div>Test HTML</div>'
# Expect that the problem was reset
module.new_lcp.assert_called_once_with(None)
@@ -1118,7 +1118,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
result = module.reset_problem(get_request_dict)
# Expect that the problem was NOT reset
self.assertTrue('success' in result and not result['success'])
assert (('success' in result) and (not result['success']))
def test_reset_problem_not_done(self):
# Simulate that the problem is NOT done
@@ -1129,7 +1129,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
result = module.reset_problem(get_request_dict)
# Expect that the problem was NOT reset
self.assertTrue('success' in result and not result['success'])
assert (('success' in result) and (not result['success']))
def test_rescore_problem_correct(self):
@@ -1152,12 +1152,12 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
module.rescore(only_if_higher=False)
# Expect that the problem is marked correct
self.assertEqual(module.is_correct(), True)
assert module.is_correct() is True
# Expect that the number of attempts is not incremented
self.assertEqual(module.attempts, 1)
assert module.attempts == 1
# and that this was considered attempt number 1 for grading purposes
self.assertEqual(module.lcp.context['attempt'], 1)
assert module.lcp.context['attempt'] == 1
def test_rescore_problem_additional_correct(self):
# make sure it also works when new correct answer has been added
@@ -1169,13 +1169,13 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
result = module.submit_problem(get_request_dict)
# Expect that the problem is marked incorrect and user didn't earn score
self.assertEqual(result['success'], 'incorrect')
self.assertEqual(module.get_score(), (0, 1))
self.assertEqual(module.correct_map[answer_id]['correctness'], 'incorrect')
assert result['success'] == 'incorrect'
assert module.get_score() == (0, 1)
assert module.correct_map[answer_id]['correctness'] == 'incorrect'
# Expect that the number of attempts has incremented to 1
self.assertEqual(module.attempts, 1)
self.assertEqual(module.lcp.context['attempt'], 1)
assert module.attempts == 1
assert module.lcp.context['attempt'] == 1
# Simulate that after making an incorrect answer to the correct answer
# the new calculated score is (1,1)
@@ -1191,12 +1191,12 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
module.rescore(only_if_higher=True)
# Expect that the problem is marked correct and user earned the score
self.assertEqual(module.get_score(), (1, 1))
self.assertEqual(module.correct_map[answer_id]['correctness'], 'correct')
assert module.get_score() == (1, 1)
assert module.correct_map[answer_id]['correctness'] == 'correct'
# Expect that the number of attempts is not incremented
self.assertEqual(module.attempts, 1)
assert module.attempts == 1
# and hence that this was still considered the first attempt for grading purposes
self.assertEqual(module.lcp.context['attempt'], 1)
assert module.lcp.context['attempt'] == 1
def test_rescore_problem_incorrect(self):
# make sure it also works when attempts have been reset,
@@ -1210,19 +1210,19 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
module.rescore(only_if_higher=False)
# Expect that the problem is marked incorrect
self.assertEqual(module.is_correct(), False)
assert module.is_correct() is False
# Expect that the number of attempts is not incremented
self.assertEqual(module.attempts, 0)
assert module.attempts == 0
# and that this is treated as the first attempt for grading purposes
self.assertEqual(module.lcp.context['attempt'], 1)
assert module.lcp.context['attempt'] == 1
def test_rescore_problem_not_done(self):
# Simulate that the problem is NOT done
module = CapaFactory.create(done=False)
# Try to rescore the problem, and get exception
with self.assertRaises(xmodule.exceptions.NotFoundError):
with pytest.raises(xmodule.exceptions.NotFoundError):
module.rescore(only_if_higher=False)
def test_rescore_problem_not_supported(self):
@@ -1231,7 +1231,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
# Try to rescore the problem, and get exception
with patch('capa.capa_problem.LoncapaProblem.supports_rescoring') as mock_supports_rescoring:
mock_supports_rescoring.return_value = False
with self.assertRaises(NotImplementedError):
with pytest.raises(NotImplementedError):
module.rescore(only_if_higher=False)
def _rescore_problem_error_helper(self, exception_class):
@@ -1242,13 +1242,13 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
# Simulate answering a problem that raises the exception
with patch('capa.capa_problem.LoncapaProblem.get_grade_from_current_answers') as mock_rescore:
mock_rescore.side_effect = exception_class(u'test error \u03a9')
with self.assertRaises(exception_class):
with pytest.raises(exception_class):
module.rescore(only_if_higher=False)
# Expect that the number of attempts is NOT incremented
self.assertEqual(module.attempts, 1)
assert module.attempts == 1
# and that this was considered the first attempt for grading purposes
self.assertEqual(module.lcp.context['attempt'], 1)
assert module.lcp.context['attempt'] == 1
def test_rescore_problem_student_input_error(self):
self._rescore_problem_error_helper(StudentInputError)
@@ -1268,10 +1268,10 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
# Expect that answers are saved to the problem
expected_answers = {CapaFactory.answer_key(): '3.14'}
self.assertEqual(module.lcp.student_answers, expected_answers)
assert module.lcp.student_answers == expected_answers
# Expect that the result is success
self.assertTrue('success' in result and result['success'])
assert (('success' in result) and result['success'])
def test_save_problem_closed(self):
module = CapaFactory.create(done=False)
@@ -1285,7 +1285,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
result = module.save_problem(get_request_dict)
# Expect that the result is failure
self.assertTrue('success' in result and not result['success'])
assert (('success' in result) and (not result['success']))
@ddt.data(
RANDOMIZATION.ALWAYS,
@@ -1300,7 +1300,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
result = module.save_problem(get_request_dict)
# Expect that we cannot save
self.assertTrue('success' in result and not result['success'])
assert (('success' in result) and (not result['success']))
@ddt.data(
RANDOMIZATION.NEVER,
@@ -1316,15 +1316,15 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
result = module.save_problem(get_request_dict)
# Expect that we succeed
self.assertTrue('success' in result and result['success'])
assert (('success' in result) and result['success'])
def test_submit_button_name(self):
module = CapaFactory.create(attempts=0)
self.assertEqual(module.submit_button_name(), "Submit")
assert module.submit_button_name() == 'Submit'
def test_submit_button_submitting_name(self):
module = CapaFactory.create(attempts=1, max_attempts=10)
self.assertEqual(module.submit_button_submitting_name(), "Submitting")
assert module.submit_button_submitting_name() == 'Submitting'
def test_should_enable_submit_button(self):
@@ -1332,41 +1332,41 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
# If we're after the deadline, disable the submit button
module = CapaFactory.create(due=self.yesterday_str)
self.assertFalse(module.should_enable_submit_button())
assert not module.should_enable_submit_button()
# If user is out of attempts, disable the submit button
module = CapaFactory.create(attempts=attempts, max_attempts=attempts)
self.assertFalse(module.should_enable_submit_button())
assert not module.should_enable_submit_button()
# If survey question (max_attempts = 0), disable the submit button
module = CapaFactory.create(max_attempts=0)
self.assertFalse(module.should_enable_submit_button())
assert not module.should_enable_submit_button()
# If user submitted a problem but hasn't reset,
# disable the submit button
# Note: we can only reset when rerandomize="always" or "true"
module = CapaFactory.create(rerandomize=RANDOMIZATION.ALWAYS, done=True)
self.assertFalse(module.should_enable_submit_button())
assert not module.should_enable_submit_button()
module = CapaFactory.create(rerandomize="true", done=True)
self.assertFalse(module.should_enable_submit_button())
assert not module.should_enable_submit_button()
# Otherwise, enable the submit button
module = CapaFactory.create()
self.assertTrue(module.should_enable_submit_button())
assert module.should_enable_submit_button()
# If the user has submitted the problem
# and we do NOT have a reset button, then we can enable the submit button
# Setting rerandomize to "never" or "false" ensures that the reset button
# is not shown
module = CapaFactory.create(rerandomize=RANDOMIZATION.NEVER, done=True)
self.assertTrue(module.should_enable_submit_button())
assert module.should_enable_submit_button()
module = CapaFactory.create(rerandomize="false", done=True)
self.assertTrue(module.should_enable_submit_button())
assert module.should_enable_submit_button()
module = CapaFactory.create(rerandomize=RANDOMIZATION.PER_STUDENT, done=True)
self.assertTrue(module.should_enable_submit_button())
assert module.should_enable_submit_button()
def test_should_show_reset_button(self):
@@ -1374,43 +1374,43 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
# If we're after the deadline, do NOT show the reset button
module = CapaFactory.create(due=self.yesterday_str, done=True)
self.assertFalse(module.should_show_reset_button())
assert not module.should_show_reset_button()
# If the user is out of attempts, do NOT show the reset button
module = CapaFactory.create(attempts=attempts, max_attempts=attempts, done=True)
self.assertFalse(module.should_show_reset_button())
assert not module.should_show_reset_button()
# pre studio default value, DO show the reset button
module = CapaFactory.create(rerandomize=RANDOMIZATION.ALWAYS, done=True)
self.assertTrue(module.should_show_reset_button())
assert module.should_show_reset_button()
# If survey question for capa (max_attempts = 0),
# DO show the reset button
module = CapaFactory.create(rerandomize=RANDOMIZATION.ALWAYS, max_attempts=0, done=True)
self.assertTrue(module.should_show_reset_button())
assert module.should_show_reset_button()
# If the question is not correct
# DO show the reset button
module = CapaFactory.create(rerandomize=RANDOMIZATION.ALWAYS, max_attempts=0, done=True, correct=False)
self.assertTrue(module.should_show_reset_button())
assert module.should_show_reset_button()
# If the question is correct and randomization is never
# DO not show the reset button
module = CapaFactory.create(rerandomize=RANDOMIZATION.NEVER, max_attempts=0, done=True, correct=True)
self.assertFalse(module.should_show_reset_button())
assert not module.should_show_reset_button()
# If the question is correct and randomization is always
# Show the reset button
module = CapaFactory.create(rerandomize=RANDOMIZATION.ALWAYS, max_attempts=0, done=True, correct=True)
self.assertTrue(module.should_show_reset_button())
assert module.should_show_reset_button()
# Don't show reset button if randomization is turned on and the question is not done
module = CapaFactory.create(rerandomize=RANDOMIZATION.ALWAYS, show_reset_button=False, done=False)
self.assertFalse(module.should_show_reset_button())
assert not module.should_show_reset_button()
# Show reset button if randomization is turned on and the problem is done
module = CapaFactory.create(rerandomize=RANDOMIZATION.ALWAYS, show_reset_button=False, done=True)
self.assertTrue(module.should_show_reset_button())
assert module.should_show_reset_button()
def test_should_show_save_button(self):
@@ -1418,49 +1418,49 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
# If we're after the deadline, do NOT show the save button
module = CapaFactory.create(due=self.yesterday_str, done=True)
self.assertFalse(module.should_show_save_button())
assert not module.should_show_save_button()
# If the user is out of attempts, do NOT show the save button
module = CapaFactory.create(attempts=attempts, max_attempts=attempts, done=True)
self.assertFalse(module.should_show_save_button())
assert not module.should_show_save_button()
# If user submitted a problem but hasn't reset, do NOT show the save button
module = CapaFactory.create(rerandomize=RANDOMIZATION.ALWAYS, done=True)
self.assertFalse(module.should_show_save_button())
assert not module.should_show_save_button()
module = CapaFactory.create(rerandomize="true", done=True)
self.assertFalse(module.should_show_save_button())
assert not module.should_show_save_button()
# If the user has unlimited attempts and we are not randomizing,
# then do NOT show a save button
# because they can keep using "Check"
module = CapaFactory.create(max_attempts=None, rerandomize=RANDOMIZATION.NEVER, done=False)
self.assertFalse(module.should_show_save_button())
assert not module.should_show_save_button()
module = CapaFactory.create(max_attempts=None, rerandomize="false", done=True)
self.assertFalse(module.should_show_save_button())
assert not module.should_show_save_button()
module = CapaFactory.create(max_attempts=None, rerandomize=RANDOMIZATION.PER_STUDENT, done=True)
self.assertFalse(module.should_show_save_button())
assert not module.should_show_save_button()
# pre-studio default, DO show the save button
module = CapaFactory.create(rerandomize=RANDOMIZATION.ALWAYS, done=False)
self.assertTrue(module.should_show_save_button())
assert module.should_show_save_button()
# If we're not randomizing and we have limited attempts, then we can save
module = CapaFactory.create(rerandomize=RANDOMIZATION.NEVER, max_attempts=2, done=True)
self.assertTrue(module.should_show_save_button())
assert module.should_show_save_button()
module = CapaFactory.create(rerandomize="false", max_attempts=2, done=True)
self.assertTrue(module.should_show_save_button())
assert module.should_show_save_button()
module = CapaFactory.create(rerandomize=RANDOMIZATION.PER_STUDENT, max_attempts=2, done=True)
self.assertTrue(module.should_show_save_button())
assert module.should_show_save_button()
# If survey question for capa (max_attempts = 0),
# DO show the save button
module = CapaFactory.create(max_attempts=0, done=False)
self.assertTrue(module.should_show_save_button())
assert module.should_show_save_button()
def test_should_show_save_button_force_save_button(self):
# If we're after the deadline, do NOT show the save button
@@ -1468,7 +1468,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
module = CapaFactory.create(due=self.yesterday_str,
force_save_button="true",
done=True)
self.assertFalse(module.should_show_save_button())
assert not module.should_show_save_button()
# If the user is out of attempts, do NOT show the save button
attempts = random.randint(1, 10)
@@ -1476,7 +1476,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
max_attempts=attempts,
force_save_button="true",
done=True)
self.assertFalse(module.should_show_save_button())
assert not module.should_show_save_button()
# Otherwise, if we force the save button,
# then show it even if we would ordinarily
@@ -1484,17 +1484,17 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
module = CapaFactory.create(force_save_button="true",
rerandomize=RANDOMIZATION.ALWAYS,
done=True)
self.assertTrue(module.should_show_save_button())
assert module.should_show_save_button()
module = CapaFactory.create(force_save_button="true",
rerandomize="true",
done=True)
self.assertTrue(module.should_show_save_button())
assert module.should_show_save_button()
def test_no_max_attempts(self):
module = CapaFactory.create(max_attempts='')
html = module.get_problem_html()
self.assertIsNotNone(html)
assert html is not None
# assert that we got here without exploding
def test_get_problem_html(self):
@@ -1524,24 +1524,24 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
html_encapsulated = module.get_problem_html(encapsulate=True)
# Expect that we get the rendered template back
self.assertEqual(html, "<div>Test Template HTML</div>")
assert html == '<div>Test Template HTML</div>'
# Check the rendering context
render_args, _ = module.system.render_template.call_args
self.assertEqual(len(render_args), 2)
assert len(render_args) == 2
template_name = render_args[0]
self.assertEqual(template_name, "problem.html")
assert template_name == 'problem.html'
context = render_args[1]
self.assertEqual(context['problem']['html'], "<div>Test Problem HTML</div>")
self.assertEqual(bool(context['should_enable_submit_button']), enable_submit_button)
self.assertEqual(bool(context['reset_button']), show_reset_button)
self.assertEqual(bool(context['save_button']), show_save_button)
self.assertFalse(context['demand_hint_possible'])
assert context['problem']['html'] == '<div>Test Problem HTML</div>'
assert bool(context['should_enable_submit_button']) == enable_submit_button
assert bool(context['reset_button']) == show_reset_button
assert bool(context['save_button']) == show_save_button
assert not context['demand_hint_possible']
# Assert that the encapsulated html contains the original html
self.assertIn(html, html_encapsulated)
assert html in html_encapsulated
demand_xml = """
<problem>
@@ -1565,21 +1565,21 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
module = CapaFactory.create(xml=self.demand_xml)
module.get_problem_html() # ignoring html result
context = module.system.render_template.call_args[0][1]
self.assertTrue(context['demand_hint_possible'])
self.assertTrue(context['should_enable_next_hint'])
assert context['demand_hint_possible']
assert context['should_enable_next_hint']
# Check the AJAX call that gets the hint by index
result = module.get_demand_hint(0)
self.assertEqual(result['hint_index'], 0)
self.assertTrue(result['should_enable_next_hint'])
assert result['hint_index'] == 0
assert result['should_enable_next_hint']
result = module.get_demand_hint(1)
self.assertEqual(result['hint_index'], 1)
self.assertFalse(result['should_enable_next_hint'])
assert result['hint_index'] == 1
assert not result['should_enable_next_hint']
result = module.get_demand_hint(2) # here the server wraps around to index 0
self.assertEqual(result['hint_index'], 0)
self.assertTrue(result['should_enable_next_hint'])
assert result['hint_index'] == 0
assert result['should_enable_next_hint']
def test_single_demand_hint(self):
"""
@@ -1602,13 +1602,13 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
module = CapaFactory.create(xml=test_xml)
module.get_problem_html() # ignoring html result
context = module.system.render_template.call_args[0][1]
self.assertTrue(context['demand_hint_possible'])
self.assertTrue(context['should_enable_next_hint'])
assert context['demand_hint_possible']
assert context['should_enable_next_hint']
# Check the AJAX call that gets the hint by index
result = module.get_demand_hint(0)
self.assertEqual(result['hint_index'], 0)
self.assertFalse(result['should_enable_next_hint'])
assert result['hint_index'] == 0
assert not result['should_enable_next_hint']
def test_image_hint(self):
"""
@@ -1633,13 +1633,13 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
module = CapaFactory.create(xml=test_xml)
module.get_problem_html() # ignoring html result
context = module.system.render_template.call_args[0][1]
self.assertTrue(context['demand_hint_possible'])
self.assertTrue(context['should_enable_next_hint'])
assert context['demand_hint_possible']
assert context['should_enable_next_hint']
# Check the AJAX call that gets the hint by index
result = module.get_demand_hint(0)
self.assertEqual(result['hint_index'], 0)
self.assertFalse(result['should_enable_next_hint'])
assert result['hint_index'] == 0
assert not result['should_enable_next_hint']
def test_demand_hint_logging(self):
def mock_location_text(self): # lint-amnesty, pylint: disable=unused-argument
@@ -1671,12 +1671,12 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
# check to make sure that the input_state and the keys have the same values
module1.set_state_from_lcp()
self.assertEqual(list(module1.lcp.inputs.keys()), list(module1.input_state.keys()))
assert list(module1.lcp.inputs.keys()) == list(module1.input_state.keys())
module2.set_state_from_lcp()
intersection = set(module2.input_state.keys()).intersection(set(module1.input_state.keys()))
self.assertEqual(len(intersection), 0)
assert len(intersection) == 0
def test_get_problem_html_error(self):
"""
@@ -1702,15 +1702,15 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
# Try to render the module with DEBUG turned off
html = module.get_problem_html()
self.assertIsNotNone(html)
assert html is not None
# Check the rendering context
render_args, _ = module.system.render_template.call_args
context = render_args[1]
self.assertIn("error", context['problem']['html'])
assert 'error' in context['problem']['html']
# Expect that the module has created a new dummy problem with the error
self.assertNotEqual(original_problem, module.lcp)
assert original_problem != module.lcp
def test_get_problem_html_error_w_debug(self):
"""
@@ -1732,12 +1732,12 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
# Try to render the module with DEBUG turned on
html = module.get_problem_html()
self.assertIsNotNone(html)
assert html is not None
# Check the rendering context
render_args, _ = module.system.render_template.call_args
context = render_args[1]
self.assertIn(error_msg, context['problem']['html'])
assert error_msg in context['problem']['html']
@ddt.data(
'false',
@@ -1756,26 +1756,25 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
# Get the seed
# By this point, the module should have persisted the seed
seed = module.seed
self.assertIsNotNone(seed)
assert seed is not None
# If we're not rerandomizing, the seed is always set
# to the same value (1)
if rerandomize == RANDOMIZATION.NEVER:
self.assertEqual(seed, 1,
msg="Seed should always be 1 when rerandomize='%s'" % rerandomize)
assert seed == 1, "Seed should always be 1 when rerandomize='%s'" % rerandomize
# Check the problem
get_request_dict = {CapaFactory.input_key(): '3.14'}
module.submit_problem(get_request_dict)
# Expect that the seed is the same
self.assertEqual(seed, module.seed)
assert seed == module.seed
# Save the problem
module.save_problem(get_request_dict)
# Expect that the seed is the same
self.assertEqual(seed, module.seed)
assert seed == module.seed
@ddt.data(
'false',
@@ -1827,7 +1826,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
# Get the seed
# By this point, the module should have persisted the seed
seed = module.seed
self.assertIsNotNone(seed)
assert seed is not None
# We do NOT want the seed to reset if rerandomize
# is set to 'never' -- it should still be 1
@@ -1836,7 +1835,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
if rerandomize in [RANDOMIZATION.NEVER,
'false',
RANDOMIZATION.PER_STUDENT]:
self.assertEqual(seed, _reset_and_get_seed(module))
assert seed == _reset_and_get_seed(module)
# Otherwise, we expect the seed to change
# to another valid seed
@@ -1847,9 +1846,9 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
# to generate a different seed
success = _retry_and_check(10, lambda: _reset_and_get_seed(module) != seed)
self.assertIsNotNone(module.seed)
assert module.seed is not None
msg = 'Could not get a new seed from reset after 10 tries'
self.assertTrue(success, msg)
assert success, msg
@ddt.data(
'false',
@@ -1881,10 +1880,10 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
# Get the seed
# By this point, the module should have persisted the seed
seed = module.seed
self.assertIsNotNone(seed)
assert seed is not None
# the seed should never change because the student hasn't finished the problem
self.assertEqual(seed, _reset_and_get_seed(module))
assert seed == _reset_and_get_seed(module)
@ddt.data(
RANDOMIZATION.ALWAYS,
@@ -1911,7 +1910,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
for error_type in error_types:
mock_progress.side_effect = error_type
module = CapaFactory.create()
self.assertIsNone(module.get_progress())
assert module.get_progress() is None
mock_log.exception.assert_called_once_with('Got bad progress')
mock_log.reset_mock()
@@ -1924,8 +1923,8 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
module = CapaFactory.create()
module.weight = 0
progress = module.get_progress()
self.assertIsNone(progress)
self.assertFalse(mock_progress.called)
assert progress is None
assert not mock_progress.called
@patch('xmodule.capa_base.Progress')
def test_get_progress_calculate_progress_fraction(self, mock_progress):
@@ -1960,8 +1959,8 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
due=self.tomorrow_str)
module.weight = 1
score, total = module.get_display_progress()
self.assertEqual(score, expected_score)
self.assertEqual(total, 1)
assert score == expected_score
assert total == 1
def test_get_html(self):
"""
@@ -1977,7 +1976,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
Check that get_problem() returns the expected dictionary.
"""
module = CapaFactory.create()
self.assertEqual(module.get_problem("data"), {'html': module.get_problem_html(encapsulate=False)})
assert module.get_problem('data') == {'html': module.get_problem_html(encapsulate=False)}
# Standard question with shuffle="true" used by a few tests
common_shuffle_xml = textwrap.dedent("""
@@ -2004,11 +2003,11 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
module.submit_problem(get_request_dict)
mock_call = mock_track_function.mock_calls[1]
event_info = mock_call[1][2]
self.assertEqual(event_info['answers'][CapaFactory.answer_key()], 'choice_3')
assert event_info['answers'][CapaFactory.answer_key()] == 'choice_3'
# 'permutation' key added to record how problem was shown
self.assertEqual(event_info['permutation'][CapaFactory.answer_key()],
('shuffle', ['choice_3', 'choice_1', 'choice_2', 'choice_0']))
self.assertEqual(event_info['success'], 'correct')
assert event_info['permutation'][CapaFactory.answer_key()] ==\
('shuffle', ['choice_3', 'choice_1', 'choice_2', 'choice_0'])
assert event_info['success'] == 'correct'
@unittest.skip("masking temporarily disabled")
def test_save_unmask(self):
@@ -2019,8 +2018,8 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
module.save_problem(get_request_dict)
mock_call = mock_track_function.mock_calls[0]
event_info = mock_call[1][1]
self.assertEqual(event_info['answers'][CapaFactory.answer_key()], 'choice_2')
self.assertIsNotNone(event_info['permutation'][CapaFactory.answer_key()])
assert event_info['answers'][CapaFactory.answer_key()] == 'choice_2'
assert event_info['permutation'][CapaFactory.answer_key()] is not None
@unittest.skip("masking temporarily disabled")
def test_reset_unmask(self):
@@ -2033,9 +2032,9 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
module.reset_problem(None)
mock_call = mock_track_function.mock_calls[0]
event_info = mock_call[1][1]
self.assertEqual(mock_call[1][0], 'reset_problem')
self.assertEqual(event_info['old_state']['student_answers'][CapaFactory.answer_key()], 'choice_2')
self.assertIsNotNone(event_info['permutation'][CapaFactory.answer_key()])
assert mock_call[1][0] == 'reset_problem'
assert event_info['old_state']['student_answers'][CapaFactory.answer_key()] == 'choice_2'
assert event_info['permutation'][CapaFactory.answer_key()] is not None
@unittest.skip("masking temporarily disabled")
def test_rescore_unmask(self):
@@ -2048,9 +2047,9 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
module.rescore_problem(only_if_higher=False) # lint-amnesty, pylint: disable=no-member
mock_call = mock_track_function.mock_calls[0]
event_info = mock_call[1][1]
self.assertEqual(mock_call[1][0], 'problem_rescore')
self.assertEqual(event_info['state']['student_answers'][CapaFactory.answer_key()], 'choice_2')
self.assertIsNotNone(event_info['permutation'][CapaFactory.answer_key()])
assert mock_call[1][0] == 'problem_rescore'
assert event_info['state']['student_answers'][CapaFactory.answer_key()] == 'choice_2'
assert event_info['permutation'][CapaFactory.answer_key()] is not None
def test_check_unmask_answerpool(self):
"""Check answer-pool question track_function uses unmasked names"""
@@ -2072,11 +2071,11 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
module.submit_problem(get_request_dict)
mock_call = mock_track_function.mock_calls[1]
event_info = mock_call[1][2]
self.assertEqual(event_info['answers'][CapaFactory.answer_key()], 'choice_2')
assert event_info['answers'][CapaFactory.answer_key()] == 'choice_2'
# 'permutation' key added to record how problem was shown
self.assertEqual(event_info['permutation'][CapaFactory.answer_key()],
('answerpool', ['choice_1', 'choice_3', 'choice_2', 'choice_0']))
self.assertEqual(event_info['success'], 'incorrect')
assert event_info['permutation'][CapaFactory.answer_key()] ==\
('answerpool', ['choice_1', 'choice_3', 'choice_2', 'choice_0'])
assert event_info['success'] == 'incorrect'
@ddt.unpack
@ddt.data(
@@ -2090,7 +2089,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
Verify that display_name_with_default works as expected.
"""
module = CapaFactory.create(display_name=display_name)
self.assertEqual(module.display_name_with_default, expected_display_name)
assert module.display_name_with_default == expected_display_name
@ddt.data(
'',
@@ -2104,7 +2103,7 @@ class ProblemBlockTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
module.get_problem_html()
render_args, _ = module.system.render_template.call_args
context = render_args[1]
self.assertEqual(context['problem']['name'], module.location.block_type)
assert context['problem']['name'] == module.location.block_type
@ddt.ddt
@@ -2476,15 +2475,11 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
xml = "<problem><{response_tag}></{response_tag}></problem>".format(response_tag=response_tag)
name = "Some Capa Problem"
descriptor = self._create_descriptor(xml, name=name)
self.assertEqual(descriptor.problem_types, {response_tag})
self.assertEqual(descriptor.index_dictionary(), {
'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': [response_tag],
'content': {
'display_name': name,
'capa_content': ''
}
})
assert descriptor.problem_types == {response_tag}
assert descriptor.index_dictionary() ==\
{'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': [response_tag],
'content': {'display_name': name, 'capa_content': ''}}
def test_response_types_ignores_non_response_tags(self):
xml = textwrap.dedent("""
@@ -2503,15 +2498,11 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
""")
name = "Test Capa Problem"
descriptor = self._create_descriptor(xml, name=name)
self.assertEqual(descriptor.problem_types, {"multiplechoiceresponse"})
self.assertEqual(descriptor.index_dictionary(), {
'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ["multiplechoiceresponse"],
'content': {
'display_name': name,
'capa_content': ' Label Some comment Apple Banana Chocolate Donut '
}
})
assert descriptor.problem_types == {'multiplechoiceresponse'}
assert descriptor.index_dictionary() ==\
{'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ['multiplechoiceresponse'],
'content': {'display_name': name, 'capa_content': ' Label Some comment Apple Banana Chocolate Donut '}}
def test_response_types_multiple_tags(self):
xml = textwrap.dedent("""
@@ -2535,7 +2526,7 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
""")
name = "Other Test Capa Problem"
descriptor = self._create_descriptor(xml, name=name)
self.assertEqual(descriptor.problem_types, {"multiplechoiceresponse", "optionresponse"})
assert descriptor.problem_types == {'multiplechoiceresponse', 'optionresponse'}
# We are converting problem_types to a set to compare it later without taking into account the order
# the reasoning behind is that the problem_types (property) is represented by dict and when it is converted
@@ -2580,16 +2571,10 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
""")
name = "Blank Common Capa Problem"
descriptor = self._create_descriptor(xml, name=name)
self.assertEqual(
descriptor.index_dictionary(), {
'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
assert descriptor.index_dictionary() ==\
{'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': [],
'content': {
'display_name': name,
'capa_content': ' '
}
}
)
'content': {'display_name': name, 'capa_content': ' '}}
def test_indexing_checkboxes(self):
name = "Checkboxes"
@@ -2606,18 +2591,11 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
Hungarian
Note: Make sure you select all of the correct options—there may be more than one!
""")
self.assertEqual(descriptor.problem_types, {"choiceresponse"})
self.assertEqual(
descriptor.index_dictionary(),
{
'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ["choiceresponse"],
'content': {
'display_name': name,
'capa_content': capa_content.replace("\n", " ")
}
}
)
assert descriptor.problem_types == {'choiceresponse'}
assert descriptor.index_dictionary() ==\
{'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ['choiceresponse'],
'content': {'display_name': name, 'capa_content': capa_content.replace('\n', ' ')}}
def test_indexing_dropdown(self):
name = "Dropdown"
@@ -2628,17 +2606,11 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
You can use the following example problem as a model.
Which of the following countries celebrates its independence on August 15? 'India','Spain','China','Bermuda'
""")
self.assertEqual(descriptor.problem_types, {"optionresponse"})
self.assertEqual(
descriptor.index_dictionary(), {
'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ["optionresponse"],
'content': {
'display_name': name,
'capa_content': capa_content.replace("\n", " ")
}
}
)
assert descriptor.problem_types == {'optionresponse'}
assert descriptor.index_dictionary() ==\
{'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ['optionresponse'],
'content': {'display_name': name, 'capa_content': capa_content.replace('\n', ' ')}}
def test_indexing_multiple_choice(self):
name = "Multiple Choice"
@@ -2653,17 +2625,11 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
Indonesia
Russia
""")
self.assertEqual(descriptor.problem_types, {"multiplechoiceresponse"})
self.assertEqual(
descriptor.index_dictionary(), {
'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ["multiplechoiceresponse"],
'content': {
'display_name': name,
'capa_content': capa_content.replace("\n", " ")
}
}
)
assert descriptor.problem_types == {'multiplechoiceresponse'}
assert descriptor.index_dictionary() ==\
{'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ['multiplechoiceresponse'],
'content': {'display_name': name, 'capa_content': capa_content.replace('\n', ' ')}}
def test_indexing_numerical_input(self):
name = "Numerical Input"
@@ -2681,17 +2647,11 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
How many miles away from Earth is the sun? Use scientific notation to answer.
The square of what number is -100?
""")
self.assertEqual(descriptor.problem_types, {"numericalresponse"})
self.assertEqual(
descriptor.index_dictionary(), {
'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ["numericalresponse"],
'content': {
'display_name': name,
'capa_content': capa_content.replace("\n", " ")
}
}
)
assert descriptor.problem_types == {'numericalresponse'}
assert descriptor.index_dictionary() ==\
{'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ['numericalresponse'],
'content': {'display_name': name, 'capa_content': capa_content.replace('\n', ' ')}}
def test_indexing_text_input(self):
name = "Text Input"
@@ -2706,17 +2666,11 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
You can use the following example problem as a model.
What was the first post-secondary school in China to allow both male and female students?
""")
self.assertEqual(descriptor.problem_types, {"stringresponse"})
self.assertEqual(
descriptor.index_dictionary(), {
'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ["stringresponse"],
'content': {
'display_name': name,
'capa_content': capa_content.replace("\n", " ")
}
}
)
assert descriptor.problem_types == {'stringresponse'}
assert descriptor.index_dictionary() ==\
{'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ['stringresponse'],
'content': {'display_name': name, 'capa_content': capa_content.replace('\n', ' ')}}
def test_indexing_non_latin_problem(self):
sample_text_input_problem_xml = textwrap.dedent("""
@@ -2730,9 +2684,7 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
capa_content = " FX1_VAL='Καλημέρα' Δοκιμή με μεταβλητές με Ελληνικούς χαρακτήρες μέσα σε python: $FX1_VAL "
descriptor_dict = descriptor.index_dictionary()
self.assertEqual(
descriptor_dict['content']['capa_content'], smart_text(capa_content)
)
assert descriptor_dict['content']['capa_content'] == smart_text(capa_content)
def test_indexing_checkboxes_with_hints_and_feedback(self):
name = "Checkboxes with Hints and Feedback"
@@ -2752,17 +2704,11 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
potato
tomato
""")
self.assertEqual(descriptor.problem_types, {"choiceresponse"})
self.assertEqual(
descriptor.index_dictionary(), {
'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ["choiceresponse"],
'content': {
'display_name': name,
'capa_content': capa_content.replace("\n", " ")
}
}
)
assert descriptor.problem_types == {'choiceresponse'}
assert descriptor.index_dictionary() ==\
{'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ['choiceresponse'],
'content': {'display_name': name, 'capa_content': capa_content.replace('\n', ' ')}}
def test_indexing_dropdown_with_hints_and_feedback(self):
name = "Dropdown with Hints and Feedback"
@@ -2778,17 +2724,11 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
potato
tomato
""")
self.assertEqual(descriptor.problem_types, {"optionresponse"})
self.assertEqual(
descriptor.index_dictionary(), {
'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ["optionresponse"],
'content': {
'display_name': name,
'capa_content': capa_content.replace("\n", " ")
}
}
)
assert descriptor.problem_types == {'optionresponse'}
assert descriptor.index_dictionary() ==\
{'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ['optionresponse'],
'content': {'display_name': name, 'capa_content': capa_content.replace('\n', ' ')}}
def test_indexing_multiple_choice_with_hints_and_feedback(self):
name = "Multiple Choice with Hints and Feedback"
@@ -2804,17 +2744,11 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
potato
tomato
""")
self.assertEqual(descriptor.problem_types, {"multiplechoiceresponse"})
self.assertEqual(
descriptor.index_dictionary(), {
'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ["multiplechoiceresponse"],
'content': {
'display_name': name,
'capa_content': capa_content.replace("\n", " ")
}
}
)
assert descriptor.problem_types == {'multiplechoiceresponse'}
assert descriptor.index_dictionary() ==\
{'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ['multiplechoiceresponse'],
'content': {'display_name': name, 'capa_content': capa_content.replace('\n', ' ')}}
def test_indexing_numerical_input_with_hints_and_feedback(self):
name = "Numerical Input with Hints and Feedback"
@@ -2828,17 +2762,11 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
Use the following example problem as a model.
What is the arithmetic mean for the following set of numbers? (1, 5, 6, 3, 5)
""")
self.assertEqual(descriptor.problem_types, {"numericalresponse"})
self.assertEqual(
descriptor.index_dictionary(), {
'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ["numericalresponse"],
'content': {
'display_name': name,
'capa_content': capa_content.replace("\n", " ")
}
}
)
assert descriptor.problem_types == {'numericalresponse'}
assert descriptor.index_dictionary() ==\
{'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ['numericalresponse'],
'content': {'display_name': name, 'capa_content': capa_content.replace('\n', ' ')}}
def test_indexing_text_input_with_hints_and_feedback(self):
name = "Text Input with Hints and Feedback"
@@ -2852,17 +2780,11 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
Use the following example problem as a model.
Which U.S. state has the largest land area?
""")
self.assertEqual(descriptor.problem_types, {"stringresponse"})
self.assertEqual(
descriptor.index_dictionary(), {
'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ["stringresponse"],
'content': {
'display_name': name,
'capa_content': capa_content.replace("\n", " ")
}
}
)
assert descriptor.problem_types == {'stringresponse'}
assert descriptor.index_dictionary() ==\
{'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': ['stringresponse'],
'content': {'display_name': name, 'capa_content': capa_content.replace('\n', ' ')}}
def test_indexing_problem_with_html_tags(self):
sample_problem_xml = textwrap.dedent("""
@@ -2885,16 +2807,10 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
This has HTML comment in it.
HTML end.
""")
self.assertEqual(
descriptor.index_dictionary(), {
'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
assert descriptor.index_dictionary() ==\
{'content_type': ProblemBlock.INDEX_CONTENT_TYPE,
'problem_types': [],
'content': {
'display_name': name,
'capa_content': capa_content.replace("\n", " ")
}
}
)
'content': {'display_name': name, 'capa_content': capa_content.replace('\n', ' ')}}
def test_invalid_xml_handling(self):
"""
@@ -2905,7 +2821,7 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
<problem>
</proble-oh no my finger broke and I can't close the problem tag properly...
""")
with self.assertRaises(etree.XMLSyntaxError):
with pytest.raises(etree.XMLSyntaxError):
self._create_descriptor(sample_invalid_xml, name="Invalid XML")
def test_invalid_dropdown_xml(self):
@@ -2915,7 +2831,8 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
problem_xml = textwrap.dedent("""
<problem>
<optionresponse>
<p>You can use this template as a guide to the simple editor markdown and OLX markup to use for dropdown problems. Edit this component to replace this template with your own assessment.</p>
<p>You can use this template as a guide to the simple editor markdown and OLX markup to use for dropdown
problems. Edit this component to replace this template with your own assessment.</p>
<label>Add the question text, or prompt, here. This text is required.</label>
<description>You can add an optional tip or note related to the prompt like this. </description>
<optioninput>
@@ -2926,7 +2843,7 @@ class ProblemBlockXMLTest(unittest.TestCase): # lint-amnesty, pylint: disable=m
</optionresponse>
</problem>
""")
with self.assertRaises(Exception):
with pytest.raises(Exception):
CapaFactory.create(xml=problem_xml)
@@ -2939,7 +2856,8 @@ class ComplexEncoderTest(unittest.TestCase): # lint-amnesty, pylint: disable=mi
complex_num = 1 - 1j
expected_str = '1-1*j'
json_str = json.dumps(complex_num, cls=ComplexEncoder)
self.assertEqual(expected_str, json_str[1:-1]) # ignore quotes
assert expected_str == json_str[1:(- 1)]
# ignore quotes
class ProblemCheckTrackingTest(unittest.TestCase):
@@ -2993,35 +2911,27 @@ class ProblemCheckTrackingTest(unittest.TestCase):
}
event = self.get_event_for_answers(module, answer_input_dict)
self.assertEqual(event['submission'], {
factory.answer_key(2): {
'question': 'What color is the open ocean on a sunny day?',
'answer': 'blue',
'response_type': 'optionresponse',
'input_type': 'optioninput',
'correct': True,
'group_label': '',
'variant': '',
},
factory.answer_key(3): {
'question': 'Which piece of furniture is built for sitting?',
'answer': u'<text>a table</text>',
'response_type': 'multiplechoiceresponse',
'input_type': 'choicegroup',
'correct': False,
'group_label': '',
'variant': '',
},
factory.answer_key(4): {
'question': 'Which of the following are musical instruments?',
'answer': [u'a piano', u'a tree'],
'response_type': 'choiceresponse',
'input_type': 'checkboxgroup',
'correct': False,
'group_label': '',
'variant': '',
},
})
assert event['submission'] ==\
{factory.answer_key(2): {'question': 'What color is the open ocean on a sunny day?',
'answer': 'blue', 'response_type': 'optionresponse',
'input_type': 'optioninput',
'correct': True,
'group_label': '',
'variant': ''},
factory.answer_key(3): {'question': 'Which piece of furniture is built for sitting?',
'answer': u'<text>a table</text>',
'response_type': 'multiplechoiceresponse',
'input_type': 'choicegroup',
'correct': False,
'group_label': '',
'variant': ''},
factory.answer_key(4): {'question': 'Which of the following are musical instruments?',
'answer': [u'a piano', u'a tree'],
'response_type': 'choiceresponse',
'input_type': 'checkboxgroup',
'correct': False,
'group_label': '',
'variant': ''}}
def capa_factory_for_problem_xml(self, xml): # lint-amnesty, pylint: disable=missing-function-docstring
class CustomCapaFactory(CapaFactory):
@@ -3036,7 +2946,7 @@ class ProblemCheckTrackingTest(unittest.TestCase):
with patch.object(module.runtime, 'publish') as mock_track_function:
module.submit_problem(answer_input_dict)
self.assertGreaterEqual(len(mock_track_function.mock_calls), 2)
assert len(mock_track_function.mock_calls) >= 2
# There are potentially 2 track logs: answers and hint. [-1]=answers.
mock_call = mock_track_function.mock_calls[-1]
event = mock_call[1][2]
@@ -3052,17 +2962,13 @@ class ProblemCheckTrackingTest(unittest.TestCase):
}
event = self.get_event_for_answers(module, answer_input_dict)
self.assertEqual(event['submission'], {
factory.answer_key(2): {
'question': '',
'answer': '3.14',
'response_type': 'numericalresponse',
'input_type': 'textline',
'correct': True,
'group_label': '',
'variant': '',
}
})
assert event['submission'] ==\
{factory.answer_key(2): {'question': '', 'answer': '3.14',
'response_type': 'numericalresponse',
'input_type': 'textline',
'correct': True,
'group_label': '',
'variant': ''}}
def test_multiple_inputs(self):
group_label = 'Choose the correct color'
@@ -3084,26 +2990,19 @@ class ProblemCheckTrackingTest(unittest.TestCase):
}
event = self.get_event_for_answers(module, answer_input_dict)
self.assertEqual(event['submission'], {
factory.answer_key(2, 1): {
'group_label': group_label,
'question': input1_label,
'answer': 'blue',
'response_type': 'optionresponse',
'input_type': 'optioninput',
'correct': True,
'variant': '',
},
factory.answer_key(2, 2): {
'group_label': group_label,
'question': input2_label,
'answer': 'yellow',
'response_type': 'optionresponse',
'input_type': 'optioninput',
'correct': False,
'variant': '',
},
})
assert event['submission'] ==\
{factory.answer_key(2, 1): {'group_label': group_label,
'question': input1_label,
'answer': 'blue',
'response_type': 'optionresponse',
'input_type': 'optioninput',
'correct': True, 'variant': ''},
factory.answer_key(2, 2): {'group_label': group_label,
'question': input2_label,
'answer': 'yellow',
'response_type': 'optionresponse',
'input_type': 'optioninput',
'correct': False, 'variant': ''}}
def test_optioninput_extended_xml(self):
"""Test the new XML form of writing with <option> tag instead of options= attribute."""
@@ -3154,26 +3053,19 @@ class ProblemCheckTrackingTest(unittest.TestCase):
}
event = self.get_event_for_answers(module, answer_input_dict)
self.assertEqual(event['submission'], {
factory.answer_key(2, 1): {
'group_label': group_label,
'question': input1_label,
'answer': 'apple',
'response_type': 'optionresponse',
'input_type': 'optioninput',
'correct': True,
'variant': '',
},
factory.answer_key(2, 2): {
'group_label': group_label,
'question': input2_label,
'answer': 'cucumber',
'response_type': 'optionresponse',
'input_type': 'optioninput',
'correct': False,
'variant': '',
},
})
assert event['submission'] ==\
{factory.answer_key(2, 1): {'group_label': group_label,
'question': input1_label,
'answer': 'apple',
'response_type': 'optionresponse',
'input_type': 'optioninput',
'correct': True, 'variant': ''},
factory.answer_key(2, 2): {'group_label': group_label,
'question': input2_label,
'answer': 'cucumber',
'response_type': 'optionresponse',
'input_type': 'optioninput',
'correct': False, 'variant': ''}}
def test_rerandomized_inputs(self):
factory = CapaFactory
@@ -3184,17 +3076,14 @@ class ProblemCheckTrackingTest(unittest.TestCase):
}
event = self.get_event_for_answers(module, answer_input_dict)
self.assertEqual(event['submission'], {
factory.answer_key(2): {
'question': '',
'answer': '3.14',
'response_type': 'numericalresponse',
'input_type': 'textline',
'correct': True,
'group_label': '',
'variant': module.seed,
}
})
assert event['submission'] ==\
{factory.answer_key(2): {'question': '',
'answer': '3.14',
'response_type': 'numericalresponse',
'input_type': 'textline',
'correct': True,
'group_label': '',
'variant': module.seed}}
def test_file_inputs(self):
fnames = ["prog1.py", "prog2.py", "prog3.py"]
@@ -3217,26 +3106,21 @@ class ProblemCheckTrackingTest(unittest.TestCase):
}
event = self.get_event_for_answers(module, answer_input_dict)
self.assertEqual(event['submission'], {
factory.answer_key(2): {
'question': '',
'answer': fpaths,
'response_type': 'coderesponse',
'input_type': 'filesubmission',
'correct': False,
'group_label': '',
'variant': '',
},
factory.answer_key(3): {
'answer': 'None',
'correct': True,
'group_label': '',
'question': '',
'response_type': 'customresponse',
'input_type': 'textline',
'variant': ''
}
})
assert event['submission'] ==\
{factory.answer_key(2): {'question': '',
'answer': fpaths,
'response_type': 'coderesponse',
'input_type': 'filesubmission',
'correct': False,
'group_label': '',
'variant': ''},
factory.answer_key(3): {'answer': 'None',
'correct': True,
'group_label': '',
'question': '',
'response_type': 'customresponse',
'input_type': 'textline',
'variant': ''}}
def test_get_answer_with_jump_to_id_urls(self):
"""
@@ -3262,7 +3146,7 @@ class ProblemCheckTrackingTest(unittest.TestCase):
problem = CapaFactory.create(showanswer='always', xml=problem_xml)
problem.runtime.replace_jump_to_id_urls = Mock()
problem.get_answer(data)
self.assertTrue(problem.runtime.replace_jump_to_id_urls.called)
assert problem.runtime.replace_jump_to_id_urls.called
class ProblemBlockReportGenerationTest(unittest.TestCase):
@@ -3314,13 +3198,13 @@ class ProblemBlockReportGenerationTest(unittest.TestCase):
def test_generate_report_data_not_implemented(self):
scope_ids = Mock(block_type='noproblem')
descriptor = ProblemBlock(get_test_system(), scope_ids=scope_ids)
with self.assertRaises(NotImplementedError):
with pytest.raises(NotImplementedError):
next(descriptor.generate_report_data(iter([])))
def test_generate_report_data_limit_responses(self):
descriptor = self._get_descriptor()
report_data = list(descriptor.generate_report_data(self._mock_user_state_generator(), 2))
self.assertEqual(2, len(report_data))
assert 2 == len(report_data)
def test_generate_report_data_dont_limit_responses(self):
descriptor = self._get_descriptor()
@@ -3332,10 +3216,10 @@ class ProblemBlockReportGenerationTest(unittest.TestCase):
response_count=response_count,
)
))
self.assertEqual(user_count * response_count, len(report_data))
assert (user_count * response_count) == len(report_data)
def test_generate_report_data_skip_dynamath(self):
descriptor = self._get_descriptor()
iterator = iter([self._user_state(suffix='_dynamath')])
report_data = list(descriptor.generate_report_data(iterator))
self.assertEqual(0, len(report_data))
assert 0 == len(report_data)

View File

@@ -159,7 +159,7 @@ class ConditionalBlockBasicTest(unittest.TestCase):
for icon_class in ['other', 'problem', 'video']:
modules['source_module'].is_attempted = attempted
modules['child_module'].get_icon_class = lambda: icon_class # lint-amnesty, pylint: disable=cell-var-from-loop
self.assertEqual(modules['cond_module'].get_icon_class(), icon_class)
assert modules['cond_module'].get_icon_class() == icon_class
def test_get_html(self):
modules = ConditionalFactory.create(self.test_system)
@@ -171,7 +171,7 @@ class ConditionalBlockBasicTest(unittest.TestCase):
'element_id': u'i4x-edX-conditional_test-conditional-SampleConditional',
'depends': u'i4x-edX-conditional_test-problem-SampleProblem',
})
self.assertEqual(expected, html)
assert expected == html
def test_handle_ajax(self):
modules = ConditionalFactory.create(self.test_system)
@@ -180,7 +180,7 @@ class ConditionalBlockBasicTest(unittest.TestCase):
ajax = json.loads(modules['cond_module'].handle_ajax('', ''))
print("ajax: ", ajax)
fragments = ajax['fragments']
self.assertFalse(any(['This is a secret' in item['content'] for item in fragments]))
assert not any([('This is a secret' in item['content']) for item in fragments])
# now change state of the capa problem to make it completed
modules['source_module'].is_attempted = "true"
@@ -188,7 +188,7 @@ class ConditionalBlockBasicTest(unittest.TestCase):
modules['cond_module'].save()
print("post-attempt ajax: ", ajax)
fragments = ajax['fragments']
self.assertTrue(any(['This is a secret' in item['content'] for item in fragments]))
assert any([('This is a secret' in item['content']) for item in fragments])
def test_error_as_source(self):
'''
@@ -199,7 +199,7 @@ class ConditionalBlockBasicTest(unittest.TestCase):
modules['cond_module'].save()
ajax = json.loads(modules['cond_module'].handle_ajax('', ''))
fragments = ajax['fragments']
self.assertFalse(any(['This is a secret' in item['content'] for item in fragments]))
assert not any([('This is a secret' in item['content']) for item in fragments])
@patch('xmodule.conditional_module.log')
def test_conditional_with_staff_only_source_module(self, mock_log):
@@ -211,8 +211,8 @@ class ConditionalBlockBasicTest(unittest.TestCase):
cond_module.save()
cond_module.is_attempted = "false"
cond_module.handle_ajax('', '')
self.assertFalse(mock_log.warn.called)
self.assertIn(None, cond_module.get_required_blocks)
assert not mock_log.warn.called
assert None in cond_module.get_required_blocks
class ConditionalBlockXmlTest(unittest.TestCase):
@@ -236,7 +236,7 @@ class ConditionalBlockXmlTest(unittest.TestCase):
modulestore = XMLModuleStore(DATA_DIR, source_dirs=[name])
courses = modulestore.get_courses()
self.modulestore = modulestore # lint-amnesty, pylint: disable=attribute-defined-outside-init
self.assertEqual(len(courses), 1)
assert len(courses) == 1
return courses[0]
@patch('xmodule.x_module.descriptor_global_local_resource_url')
@@ -285,7 +285,7 @@ class ConditionalBlockXmlTest(unittest.TestCase):
'depends': u'i4x-HarvardX-ER22x-problem-choiceprob'
}
)
self.assertEqual(html, html_expect)
assert html == html_expect
gdi = module.get_display_items()
print("gdi=", gdi)
@@ -294,7 +294,7 @@ class ConditionalBlockXmlTest(unittest.TestCase):
module.save()
print("ajax: ", ajax)
fragments = ajax['fragments']
self.assertFalse(any(['This is a secret' in item['content'] for item in fragments]))
assert not any([('This is a secret' in item['content']) for item in fragments])
# Now change state of the capa problem to make it completed
inner_module = inner_get_module(location.replace(category="problem", name='choiceprob'))
@@ -306,7 +306,7 @@ class ConditionalBlockXmlTest(unittest.TestCase):
module.save()
print("post-attempt ajax: ", ajax)
fragments = ajax['fragments']
self.assertTrue(any(['This is a secret' in item['content'] for item in fragments]))
assert any([('This is a secret' in item['content']) for item in fragments])
maxDiff = None
@@ -331,12 +331,8 @@ class ConditionalBlockXmlTest(unittest.TestCase):
)
new_run = conditional.location.course_key.run # lint-amnesty, pylint: disable=unused-variable
self.assertEqual(
conditional.sources_list[0],
BlockUsageLocator.from_string(
conditional.xml_attributes['sources']
).replace(run=dummy_location.course_key.run)
)
assert conditional.sources_list[0] == BlockUsageLocator.from_string(conditional.xml_attributes['sources'])\
.replace(run=dummy_location.course_key.run)
def test_conditional_module_parse_sources(self):
dummy_system = Mock()
@@ -353,10 +349,8 @@ class ConditionalBlockXmlTest(unittest.TestCase):
dummy_field_data,
dummy_scope_ids,
)
self.assertEqual(
conditional.parse_sources(conditional.xml_attributes),
['i4x://HarvardX/ER22x/poll_question/T15_poll', 'i4x://HarvardX/ER22x/poll_question/T16_poll']
)
assert conditional.parse_sources(conditional.xml_attributes) == ['i4x://HarvardX/ER22x/poll_question/T15_poll',
'i4x://HarvardX/ER22x/poll_question/T16_poll']
def test_conditional_module_parse_attr_values(self):
root = '<conditional attempted="false"></conditional>'
@@ -369,7 +363,7 @@ class ConditionalBlockXmlTest(unittest.TestCase):
'conditional_message': ''
}
self.assertEqual(definition, expected_definition)
assert definition == expected_definition
def test_presence_attributes_in_xml_attributes(self):
modules = ConditionalFactory.create(self.test_system)
@@ -430,18 +424,18 @@ class ConditionalBlockStudioTest(XModuleXmlImportTest):
context = create_studio_context(self.conditional, False)
html = self.module_system.render(self.conditional, AUTHOR_VIEW, context).content
self.assertIn('This is a secret HTML', html)
assert 'This is a secret HTML' in html
context = create_studio_context(self.sequence, True)
html = self.module_system.render(self.conditional, AUTHOR_VIEW, context).content
self.assertNotIn('This is a secret HTML', html)
assert 'This is a secret HTML' not in html
def test_non_editable_settings(self):
"""
Test the settings that are marked as "non-editable".
"""
non_editable_metadata_fields = self.conditional.non_editable_metadata_fields
self.assertIn(ConditionalBlock.due, non_editable_metadata_fields)
assert ConditionalBlock.due in non_editable_metadata_fields
def test_validation_messages(self):
"""
@@ -449,10 +443,7 @@ class ConditionalBlockStudioTest(XModuleXmlImportTest):
"""
self.conditional.sources_list = None
validation = self.conditional.validate()
self.assertEqual(
validation.summary.text,
u"This component has no source components configured yet."
)
self.assertEqual(validation.summary.type, StudioValidationMessage.NOT_CONFIGURED)
self.assertEqual(validation.summary.action_class, 'edit-button')
self.assertEqual(validation.summary.action_label, u"Configure list of sources")
assert validation.summary.text == u'This component has no source components configured yet.'
assert validation.summary.type == StudioValidationMessage.NOT_CONFIGURED
assert validation.summary.action_class == 'edit-button'
assert validation.summary.action_label == u'Configure list of sources'

View File

@@ -106,10 +106,10 @@ class ContentTest(unittest.TestCase): # lint-amnesty, pylint: disable=missing-c
# We had a bug where a thumbnail location of None was getting transformed into a Location tuple, with
# all elements being None. It is important that the location be just None for rendering.
content = StaticContent('loc', 'name', 'content_type', 'data', None, None, None)
self.assertIsNone(content.thumbnail_location)
assert content.thumbnail_location is None
content = StaticContent('loc', 'name', 'content_type', 'data')
self.assertIsNone(content.thumbnail_location)
assert content.thumbnail_location is None
@ddt.data(
(u"monsters__.jpg", u"monsters__.jpg"),
@@ -123,11 +123,9 @@ class ContentTest(unittest.TestCase): # lint-amnesty, pylint: disable=missing-c
content = Content(AssetLocator(CourseLocator(u'mitX', u'800', u'ignore_run'), u'asset', original_filename),
None)
(thumbnail_content, thumbnail_file_location) = content_store.generate_thumbnail(content)
self.assertIsNone(thumbnail_content)
self.assertEqual(
AssetLocator(CourseLocator(u'mitX', u'800', u'ignore_run'), u'thumbnail', thumbnail_filename),
thumbnail_file_location
)
assert thumbnail_content is None
assert AssetLocator(CourseLocator(u'mitX', u'800', u'ignore_run'), u'thumbnail', thumbnail_filename) ==\
thumbnail_file_location
@patch('xmodule.contentstore.content.Image')
def test_image_is_closed_when_generating_thumbnail(self, image_class_mock):
@@ -141,8 +139,8 @@ class ContentTest(unittest.TestCase): # lint-amnesty, pylint: disable=missing-c
"image/jpeg")
content.data = b'mock data'
content_store.generate_thumbnail(content)
self.assertTrue(image_class_mock.open.called, "Image.open not called")
self.assertTrue(mock_image.close.called, "mock_image.close not called")
assert image_class_mock.open.called, 'Image.open not called'
assert mock_image.close.called, 'mock_image.close not called'
def test_store_svg_as_thumbnail(self):
# We had a bug that caused generate_thumbnail to attempt to pass SVG to PIL to generate a thumbnail.
@@ -154,11 +152,9 @@ class ContentTest(unittest.TestCase): # lint-amnesty, pylint: disable=missing-c
'image/svg+xml')
content.data = b'mock svg file'
(thumbnail_content, thumbnail_file_location) = content_store.generate_thumbnail(content)
self.assertEqual(thumbnail_content.data.read(), b'mock svg file')
self.assertEqual(
AssetLocator(CourseLocator(u'mitX', u'800', u'ignore_run'), u'thumbnail', thumbnail_filename),
thumbnail_file_location
)
assert thumbnail_content.data.read() == b'mock svg file'
assert AssetLocator(CourseLocator(u'mitX', u'800', u'ignore_run'), u'thumbnail', thumbnail_filename) ==\
thumbnail_file_location
def test_compute_location(self):
# We had a bug that __ got converted into a single _. Make sure that substitution of INVALID_CHARS (like space)
@@ -166,19 +162,13 @@ class ContentTest(unittest.TestCase): # lint-amnesty, pylint: disable=missing-c
asset_location = StaticContent.compute_location(
CourseKey.from_string('mitX/400/ignore'), 'subs__1eo_jXvZnE .srt.sjson'
)
self.assertEqual(
AssetLocator(CourseLocator(u'mitX', u'400', u'ignore', deprecated=True),
u'asset', u'subs__1eo_jXvZnE_.srt.sjson'),
asset_location
)
assert AssetLocator(CourseLocator(u'mitX', u'400', u'ignore', deprecated=True),
u'asset', u'subs__1eo_jXvZnE_.srt.sjson') == asset_location
def test_get_location_from_path(self):
asset_location = StaticContent.get_location_from_path(u'/c4x/a/b/asset/images_course_image.jpg')
self.assertEqual(
AssetLocator(CourseLocator(u'a', u'b', None, deprecated=True),
u'asset', u'images_course_image.jpg', deprecated=True),
asset_location
)
assert AssetLocator(CourseLocator(u'a', u'b', None, deprecated=True),
u'asset', u'images_course_image.jpg', deprecated=True) == asset_location
def test_static_content_stream_stream_data(self):
"""
@@ -193,7 +183,7 @@ class ContentTest(unittest.TestCase): # lint-amnesty, pylint: disable=missing-c
for chunck in stream:
total_length += len(chunck)
self.assertEqual(total_length, static_content_stream.length)
assert total_length == static_content_stream.length
def test_static_content_stream_stream_data_in_range(self):
"""
@@ -214,7 +204,7 @@ class ContentTest(unittest.TestCase): # lint-amnesty, pylint: disable=missing-c
for chunck in stream:
total_length += len(chunck)
self.assertEqual(total_length, last_byte - first_byte + 1)
assert total_length == ((last_byte - first_byte) + 1)
def test_static_content_write_js(self):
"""
@@ -223,5 +213,5 @@ class ContentTest(unittest.TestCase): # lint-amnesty, pylint: disable=missing-c
output_root = path(u'common/static/xmodule/descriptors/js')
file_owners = _write_js(output_root, _list_descriptors(), 'get_studio_view_js')
js_file_paths = set(file_path for file_path in sum(list(file_owners.values()), []) if os.path.basename(file_path).startswith('000-')) # lint-amnesty, pylint: disable=line-too-long
self.assertEqual(len(js_file_paths), 1)
self.assertIn("XModule.Descriptor = (function() {", open(js_file_paths.pop()).read())
assert len(js_file_paths) == 1
assert 'XModule.Descriptor = (function() {' in open(js_file_paths.pop()).read()

View File

@@ -8,7 +8,7 @@ from datetime import datetime, timedelta
from unittest import TestCase
from pytz import utc
import pytest
from xmodule.block_metadata_utils import (
display_name_with_default,
display_name_with_default_escaped,
@@ -179,10 +179,10 @@ class CourseMetadataUtilsTestCase(TestCase):
for function_test in function_tests:
for scenario in function_test.scenarios:
actual_return = function_test.function(*scenario.arguments)
self.assertEqual(actual_return, scenario.expected_return)
assert actual_return == scenario.expected_return
# Even though we don't care about testing mock_strftime_localized,
# we still need to test it with a bad format string in order to
# satisfy the coverage checker.
with self.assertRaises(ValueError):
with pytest.raises(ValueError):
mock_strftime_localized(test_datetime, 'BAD_FORMAT_SPECIFIER')

View File

@@ -4,7 +4,7 @@
import itertools
import unittest
from datetime import datetime, timedelta
import pytest
import ddt
from dateutil import parser
from django.conf import settings
@@ -32,10 +32,7 @@ _NEXT_WEEK = _TODAY + timedelta(days=7)
class CourseFieldsTestCase(unittest.TestCase):
def test_default_start_date(self):
self.assertEqual(
xmodule.course_module.CourseFields.start.default,
datetime(2030, 1, 1, tzinfo=utc)
)
assert xmodule.course_module.CourseFields.start.default == datetime(2030, 1, 1, tzinfo=utc)
class DummySystem(ImportSystem): # lint-amnesty, pylint: disable=abstract-method, missing-class-docstring
@@ -132,21 +129,21 @@ class HasEndedMayCertifyTestCase(unittest.TestCase):
def test_has_ended(self):
"""Check that has_ended correctly tells us when a course is over."""
self.assertTrue(self.past_show_certs.has_ended())
self.assertTrue(self.past_show_certs_no_info.has_ended())
self.assertTrue(self.past_noshow_certs.has_ended())
self.assertFalse(self.future_show_certs.has_ended())
self.assertFalse(self.future_show_certs_no_info.has_ended())
self.assertFalse(self.future_noshow_certs.has_ended())
assert self.past_show_certs.has_ended()
assert self.past_show_certs_no_info.has_ended()
assert self.past_noshow_certs.has_ended()
assert not self.future_show_certs.has_ended()
assert not self.future_show_certs_no_info.has_ended()
assert not self.future_noshow_certs.has_ended()
def test_may_certify(self):
"""Check that may_certify correctly tells us when a course may wrap."""
self.assertTrue(self.past_show_certs.may_certify())
self.assertTrue(self.past_noshow_certs.may_certify())
self.assertTrue(self.past_show_certs_no_info.may_certify())
self.assertTrue(self.future_show_certs.may_certify())
self.assertTrue(self.future_show_certs_no_info.may_certify())
self.assertFalse(self.future_noshow_certs.may_certify())
assert self.past_show_certs.may_certify()
assert self.past_noshow_certs.may_certify()
assert self.past_show_certs_no_info.may_certify()
assert self.future_show_certs.may_certify()
assert self.future_show_certs_no_info.may_certify()
assert not self.future_noshow_certs.may_certify()
class CourseSummaryHasEnded(unittest.TestCase):
@@ -156,7 +153,7 @@ class CourseSummaryHasEnded(unittest.TestCase):
test_course = get_dummy_course("2012-01-01T12:00")
bad_end_date = parser.parse("2012-02-21 10:28:45")
summary = xmodule.course_module.CourseSummary(test_course.id, end=bad_end_date)
self.assertTrue(summary.has_ended())
assert summary.has_ended()
@ddt.ddt
@@ -229,17 +226,17 @@ class IsNewCourseTestCase(unittest.TestCase):
def test_start_date_is_default(self):
for s in self.start_advertised_settings:
d = get_dummy_course(start=s[0], advertised_start=s[1])
self.assertEqual(d.start_date_is_still_default, s[3])
assert d.start_date_is_still_default == s[3]
def test_display_organization(self):
descriptor = get_dummy_course(start='2012-12-02T12:00', is_new=True)
self.assertNotEqual(descriptor.location.org, descriptor.display_org_with_default)
self.assertEqual(descriptor.display_org_with_default, "{0}_display".format(ORG))
assert descriptor.location.org != descriptor.display_org_with_default
assert descriptor.display_org_with_default == '{0}_display'.format(ORG)
def test_display_coursenumber(self):
descriptor = get_dummy_course(start='2012-12-02T12:00', is_new=True)
self.assertNotEqual(descriptor.location.course, descriptor.display_number_with_default)
self.assertEqual(descriptor.display_number_with_default, "{0}_display".format(COURSE))
assert descriptor.location.course != descriptor.display_number_with_default
assert descriptor.display_number_with_default == '{0}_display'.format(COURSE)
def test_is_newish(self):
descriptor = get_dummy_course(start='2012-12-02T12:00', is_new=True)
@@ -268,7 +265,7 @@ class DiscussionTopicsTestCase(unittest.TestCase):
def test_default_discussion_topics(self):
d = get_dummy_course('2012-12-02T12:00')
self.assertEqual({'General': {'id': 'i4x-test_org-test_course-course-test'}}, d.discussion_topics)
assert {'General': {'id': 'i4x-test_org-test_course-course-test'}} == d.discussion_topics
class TeamsConfigurationTestCase(unittest.TestCase):
@@ -306,52 +303,49 @@ class TeamsConfigurationTestCase(unittest.TestCase):
def test_teams_enabled_new_course(self):
# Make sure we can detect when no teams exist.
self.assertFalse(self.course.teams_enabled)
assert not self.course.teams_enabled
# add topics
self.add_team_configuration(max_team_size=4, topics=[self.make_topic()])
self.assertTrue(self.course.teams_enabled)
assert self.course.teams_enabled
# remove them again
self.add_team_configuration(max_team_size=4, topics=[])
self.assertFalse(self.course.teams_enabled)
assert not self.course.teams_enabled
def test_teams_enabled_max_size_only(self):
self.add_team_configuration(max_team_size=4)
self.assertFalse(self.course.teams_enabled)
assert not self.course.teams_enabled
def test_teams_enabled_no_max_size(self):
self.add_team_configuration(max_team_size=None, topics=[self.make_topic()])
self.assertTrue(self.course.teams_enabled)
assert self.course.teams_enabled
def test_teams_max_size_no_teams_configuration(self):
self.assertEqual(
self.course.teams_configuration.default_max_team_size,
DEFAULT_COURSE_RUN_MAX_TEAM_SIZE,
)
assert self.course.teams_configuration.default_max_team_size == DEFAULT_COURSE_RUN_MAX_TEAM_SIZE
def test_teams_max_size_with_teams_configured(self):
size = 4
self.add_team_configuration(max_team_size=size, topics=[self.make_topic(), self.make_topic()])
self.assertTrue(self.course.teams_enabled)
self.assertEqual(size, self.course.teams_configuration.default_max_team_size)
assert self.course.teams_enabled
assert size == self.course.teams_configuration.default_max_team_size
def test_teamsets_no_config(self):
self.assertEqual(self.course.teamsets, [])
assert self.course.teamsets == []
def test_teamsets_empty(self):
self.add_team_configuration(max_team_size=4)
self.assertEqual(self.course.teamsets, [])
assert self.course.teamsets == []
def test_teamsets_present(self):
topics = [self.make_topic(), self.make_topic()]
self.add_team_configuration(max_team_size=4, topics=topics)
self.assertTrue(self.course.teams_enabled)
assert self.course.teams_enabled
expected_teamsets_data = [
teamset.cleaned_data
for teamset in self.course.teamsets
]
self.assertEqual(expected_teamsets_data, topics)
assert expected_teamsets_data == topics
def test_teams_conf_cached_by_xblock_field(self):
self.add_team_configuration(max_team_size=5, topics=[self.make_topic()])
@@ -360,9 +354,9 @@ class TeamsConfigurationTestCase(unittest.TestCase):
self.add_team_configuration(max_team_size=5, topics=[self.make_topic(), self.make_topic()])
new_cold_cache_conf = self.course.teams_configuration
new_warm_cache_conf = self.course.teams_configuration
self.assertIs(cold_cache_conf, warm_cache_conf)
self.assertIs(new_cold_cache_conf, new_warm_cache_conf)
self.assertIsNot(cold_cache_conf, new_cold_cache_conf)
assert cold_cache_conf is warm_cache_conf
assert new_cold_cache_conf is new_warm_cache_conf
assert cold_cache_conf is not new_cold_cache_conf
class SelfPacedTestCase(unittest.TestCase):
@@ -373,7 +367,7 @@ class SelfPacedTestCase(unittest.TestCase):
self.course = get_dummy_course('2012-12-02T12:00')
def test_default(self):
self.assertFalse(self.course.self_paced)
assert not self.course.self_paced
class CourseDescriptorTestCase(unittest.TestCase):
@@ -397,29 +391,23 @@ class CourseDescriptorTestCase(unittest.TestCase):
"""
Test CourseDescriptor.clean_id.
"""
self.assertEqual(
self.course.clean_id(),
"course_ORSXG5C7N5ZGOL3UMVZXIX3DN52XE43FF52GK43UL5ZHK3Q="
)
self.assertEqual(
self.course.clean_id(padding_char='$'),
"course_ORSXG5C7N5ZGOL3UMVZXIX3DN52XE43FF52GK43UL5ZHK3Q$"
)
assert self.course.clean_id() == 'course_ORSXG5C7N5ZGOL3UMVZXIX3DN52XE43FF52GK43UL5ZHK3Q='
assert self.course.clean_id(padding_char='$') == 'course_ORSXG5C7N5ZGOL3UMVZXIX3DN52XE43FF52GK43UL5ZHK3Q$'
def test_has_started(self):
"""
Test CourseDescriptor.has_started.
"""
self.course.start = _LAST_WEEK
self.assertTrue(self.course.has_started())
assert self.course.has_started()
self.course.start = _NEXT_WEEK
self.assertFalse(self.course.has_started())
assert not self.course.has_started()
def test_number(self):
"""
Test CourseDescriptor.number.
"""
self.assertEqual(self.course.number, COURSE)
assert self.course.number == COURSE
def test_set_default_certificate_available_date(self):
"""
@@ -427,7 +415,7 @@ class CourseDescriptorTestCase(unittest.TestCase):
after the course end date.
"""
expected_certificate_available_date = self.course.end + timedelta(days=2)
self.assertEqual(expected_certificate_available_date, self.course.certificate_available_date)
assert expected_certificate_available_date == self.course.certificate_available_date
class ProctoringProviderTestCase(unittest.TestCase):
@@ -451,7 +439,7 @@ class ProctoringProviderTestCase(unittest.TestCase):
# we expect the validated value to be equivalent to the value passed in,
# since there are no validation errors or missing data
self.assertEqual(self.proctoring_provider.from_json(default_provider), default_provider)
assert self.proctoring_provider.from_json(default_provider) == default_provider
def test_from_json_with_invalid_provider(self):
"""
@@ -461,13 +449,11 @@ class ProctoringProviderTestCase(unittest.TestCase):
provider = 'invalid-provider'
allowed_proctoring_providers = [u'mock', u'mock_proctoring_without_rules']
with self.assertRaises(ValueError) as context_manager:
with pytest.raises(ValueError) as context_manager:
self.proctoring_provider.from_json(provider)
self.assertEqual(
context_manager.exception.args[0],
['The selected proctoring provider, {}, is not a valid provider. Please select from one of {}.'
.format(provider, allowed_proctoring_providers)]
)
assert context_manager.exception.args[0] ==\
[f'The selected proctoring provider, {provider},'
f' is not a valid provider. Please select from one of {allowed_proctoring_providers}.']
def test_from_json_adds_platform_default_for_missing_provider(self):
"""
@@ -476,7 +462,7 @@ class ProctoringProviderTestCase(unittest.TestCase):
"""
default_provider = 'mock'
self.assertEqual(self.proctoring_provider.from_json(None), default_provider)
assert self.proctoring_provider.from_json(None) == default_provider
@override_settings(
PROCTORING_BACKENDS={
@@ -488,7 +474,7 @@ class ProctoringProviderTestCase(unittest.TestCase):
"""
Test that, when the platform defaults are not set, the default is correct.
"""
self. assertEqual(self.proctoring_provider.default, None)
assert self.proctoring_provider.default is None
@override_settings(PROCTORING_BACKENDS=None)
def test_default_with_no_platform_configuration(self):
@@ -496,4 +482,4 @@ class ProctoringProviderTestCase(unittest.TestCase):
Test that, when the platform default is not specified, the default is correct.
"""
default = self.proctoring_provider.default
self.assertEqual(default, None)
assert default is None

View File

@@ -12,6 +12,7 @@ import datetime
import textwrap
import unittest
import pytest
from mock import Mock
from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator
from pytz import UTC
@@ -156,8 +157,8 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase):
)
# Successfully submitted and answered
# Also, the number of attempts should increment by 1
self.assertEqual(result['success'], 'correct')
self.assertEqual(module.attempts, num_attempts + 1)
assert result['success'] == 'correct'
assert module.attempts == (num_attempts + 1)
def test_no_wait_time(self):
num_attempts = 1
@@ -168,8 +169,8 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase):
)
# Successfully submitted and answered
# Also, the number of attempts should increment by 1
self.assertEqual(result['success'], 'correct')
self.assertEqual(module.attempts, num_attempts + 1)
assert result['success'] == 'correct'
assert module.attempts == (num_attempts + 1)
def test_submit_quiz_in_rapid_succession(self):
# Already attempted once (just now) and thus has a submitted time
@@ -182,7 +183,7 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase):
# You should get a dialog that tells you to wait
# Also, the number of attempts should not be incremented
self.assertRegex(result['success'], r"You must wait at least.*")
self.assertEqual(module.attempts, num_attempts)
assert module.attempts == num_attempts
def test_submit_quiz_too_soon(self):
# Already attempted once (just now)
@@ -196,7 +197,7 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase):
# You should get a dialog that tells you to wait 2 minutes
# Also, the number of attempts should not be incremented
self.assertRegex(result['success'], r"You must wait at least 3 minutes between submissions. 2 minutes remaining\..*") # lint-amnesty, pylint: disable=line-too-long
self.assertEqual(module.attempts, num_attempts)
assert module.attempts == num_attempts
def test_submit_quiz_1_second_too_soon(self):
# Already attempted once (just now)
@@ -210,7 +211,7 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase):
# You should get a dialog that tells you to wait 2 minutes
# Also, the number of attempts should not be incremented
self.assertRegex(result['success'], r"You must wait at least 3 minutes between submissions. 1 second remaining\..*") # lint-amnesty, pylint: disable=line-too-long
self.assertEqual(module.attempts, num_attempts)
assert module.attempts == num_attempts
def test_submit_quiz_as_soon_as_allowed(self):
# Already attempted once (just now)
@@ -223,8 +224,8 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase):
)
# Successfully submitted and answered
# Also, the number of attempts should increment by 1
self.assertEqual(result['success'], 'correct')
self.assertEqual(module.attempts, num_attempts + 1)
assert result['success'] == 'correct'
assert module.attempts == (num_attempts + 1)
def test_submit_quiz_after_delay_expired(self):
# Already attempted once (just now)
@@ -237,14 +238,14 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase):
)
# Successfully submitted and answered
# Also, the number of attempts should increment by 1
self.assertEqual(result['success'], 'correct')
self.assertEqual(module.attempts, num_attempts + 1)
assert result['success'] == 'correct'
assert module.attempts == (num_attempts + 1)
def test_still_cannot_submit_after_max_attempts(self):
# Already attempted once (just now) and thus has a submitted time
num_attempts = 99
# Regular create_and_check should fail
with self.assertRaises(xmodule.exceptions.NotFoundError):
with pytest.raises(xmodule.exceptions.NotFoundError):
(module, unused_result) = self.create_and_check(
num_attempts=num_attempts,
last_submission_time=datetime.datetime(2013, 12, 6, 0, 17, 36, tzinfo=UTC),
@@ -261,7 +262,7 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase):
skip_submit_problem=True
)
# Expect that number of attempts NOT incremented
self.assertEqual(module.attempts, num_attempts)
assert module.attempts == num_attempts
def test_submit_quiz_with_long_delay(self):
# Already attempted once (just now)
@@ -275,7 +276,7 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase):
# You should get a dialog that tells you to wait 2 minutes
# Also, the number of attempts should not be incremented
self.assertRegex(result['success'], r"You must wait at least 2 hours between submissions. 2 minutes 1 second remaining\..*") # lint-amnesty, pylint: disable=line-too-long
self.assertEqual(module.attempts, num_attempts)
assert module.attempts == num_attempts
def test_submit_quiz_with_involved_pretty_print(self):
# Already attempted once (just now)
@@ -289,7 +290,7 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase):
# You should get a dialog that tells you to wait 2 minutes
# Also, the number of attempts should not be incremented
self.assertRegex(result['success'], r"You must wait at least 2 hours 1 minute 3 seconds between submissions. 1 hour 2 minutes 59 seconds remaining\..*") # lint-amnesty, pylint: disable=line-too-long
self.assertEqual(module.attempts, num_attempts)
assert module.attempts == num_attempts
def test_submit_quiz_with_nonplural_pretty_print(self):
# Already attempted once (just now)
@@ -303,4 +304,4 @@ class XModuleQuizAttemptsDelayTest(unittest.TestCase):
# You should get a dialog that tells you to wait 2 minutes
# Also, the number of attempts should not be incremented
self.assertRegex(result['success'], r"You must wait at least 1 minute between submissions. 1 minute remaining\..*") # lint-amnesty, pylint: disable=line-too-long
self.assertEqual(module.attempts, num_attempts)
assert module.attempts == num_attempts

View File

@@ -70,8 +70,8 @@ class TabsEditingDescriptorTestCase(unittest.TestCase):
test_css_file = os.path.join(current_dir, 'test_files/test_tabseditingdescriptor.scss')
with open(test_css_file) as new_css:
added_css = new_css.read()
self.assertEqual(css['scss'].pop().decode('utf-8'), added_css)
self.assertEqual(css['css'].pop().decode('utf-8'), added_css)
assert css['scss'].pop().decode('utf-8') == added_css
assert css['css'].pop().decode('utf-8') == added_css
def test_get_context(self):
""""test get_context"""

View File

@@ -5,6 +5,7 @@ Tests for ErrorBlock and NonStaffErrorBlock
import unittest
import pytest
from mock import MagicMock, Mock, patch
from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator
from xblock.field_data import DictFieldData
@@ -42,11 +43,11 @@ class TestErrorBlock(SetupTestErrorBlock):
CourseLocationManager(self.course_id),
self.error_msg
)
self.assertIsInstance(descriptor, ErrorBlock)
assert isinstance(descriptor, ErrorBlock)
descriptor.xmodule_runtime = self.system
context_repr = self.system.render(descriptor, STUDENT_VIEW).content
self.assertIn(self.error_msg, context_repr)
self.assertIn(repr(self.valid_xml), context_repr)
assert self.error_msg in context_repr
assert repr(self.valid_xml) in context_repr
def test_error_block_from_descriptor(self):
descriptor = MagicMock(
@@ -57,11 +58,11 @@ class TestErrorBlock(SetupTestErrorBlock):
error_descriptor = ErrorBlock.from_descriptor(
descriptor, self.error_msg)
self.assertIsInstance(error_descriptor, ErrorBlock)
assert isinstance(error_descriptor, ErrorBlock)
error_descriptor.xmodule_runtime = self.system
context_repr = self.system.render(error_descriptor, STUDENT_VIEW).content
self.assertIn(self.error_msg, context_repr)
self.assertIn(repr(descriptor), context_repr)
assert self.error_msg in context_repr
assert repr(descriptor) in context_repr
class TestNonStaffErrorBlock(SetupTestErrorBlock):
@@ -75,7 +76,7 @@ class TestNonStaffErrorBlock(SetupTestErrorBlock):
self.system,
CourseLocationManager(self.course_id)
)
self.assertIsInstance(descriptor, NonStaffErrorBlock)
assert isinstance(descriptor, NonStaffErrorBlock)
def test_from_xml_render(self):
descriptor = NonStaffErrorBlock.from_xml(
@@ -85,8 +86,8 @@ class TestNonStaffErrorBlock(SetupTestErrorBlock):
)
descriptor.xmodule_runtime = self.system
context_repr = self.system.render(descriptor, STUDENT_VIEW).content
self.assertNotIn(self.error_msg, context_repr)
self.assertNotIn(repr(self.valid_xml), context_repr)
assert self.error_msg not in context_repr
assert repr(self.valid_xml) not in context_repr
def test_error_block_from_descriptor(self):
descriptor = MagicMock(
@@ -97,11 +98,11 @@ class TestNonStaffErrorBlock(SetupTestErrorBlock):
error_descriptor = NonStaffErrorBlock.from_descriptor(
descriptor, self.error_msg)
self.assertIsInstance(error_descriptor, ErrorBlock)
assert isinstance(error_descriptor, ErrorBlock)
error_descriptor.xmodule_runtime = self.system
context_repr = self.system.render(error_descriptor, STUDENT_VIEW).content
self.assertNotIn(self.error_msg, context_repr)
self.assertNotIn(str(descriptor), context_repr)
assert self.error_msg not in context_repr
assert str(descriptor) not in context_repr
class BrokenModule(XModule): # lint-amnesty, pylint: disable=abstract-method
@@ -149,14 +150,14 @@ class TestErrorBlockConstruction(unittest.TestCase):
get an ErrorBlock back from XModuleDescriptor._xmodule
"""
module = self.descriptor._xmodule # lint-amnesty, pylint: disable=protected-access
self.assertIsInstance(module, ErrorBlock)
assert isinstance(module, ErrorBlock)
@patch.object(ErrorBlock, '__init__', Mock(side_effect=TestException))
def test_broken_error_descriptor(self):
"""
Test that a broken block descriptor doesn't cause an infinite loop
"""
with self.assertRaises(TestException):
with pytest.raises(TestException):
module = self.descriptor._xmodule # lint-amnesty, pylint: disable=protected-access, unused-variable
@patch.object(ErrorBlock, '__init__', Mock(side_effect=TestException))
@@ -164,5 +165,5 @@ class TestErrorBlockConstruction(unittest.TestCase):
"""
Test that a broken block module doesn't cause an infinite loop
"""
with self.assertRaises(TestException):
with pytest.raises(TestException):
module = self.descriptor._xmodule # lint-amnesty, pylint: disable=protected-access, unused-variable

View File

@@ -9,7 +9,7 @@ import unittest
from datetime import datetime, timedelta, tzinfo
from tempfile import mkdtemp
from textwrap import dedent
import pytest
import ddt
import lxml.etree
import mock
@@ -104,7 +104,7 @@ class RoundTripTestCase(unittest.TestCase):
initial_import = XMLModuleStore(root_dir, source_dirs=[course_dir], xblock_mixins=(XModuleMixin,))
courses = initial_import.get_courses()
self.assertEqual(len(courses), 1)
assert len(courses) == 1
initial_course = courses[0]
# export to the same directory--that way things like the custom_tags/ folder
@@ -122,7 +122,7 @@ class RoundTripTestCase(unittest.TestCase):
second_import = XMLModuleStore(root_dir, source_dirs=[course_dir], xblock_mixins=(XModuleMixin,))
courses2 = second_import.get_courses()
self.assertEqual(len(courses2), 1)
assert len(courses2) == 1
exported_course = courses2[0]
print("Checking course equality")
@@ -132,8 +132,8 @@ class RoundTripTestCase(unittest.TestCase):
strip_filenames(initial_course)
strip_filenames(exported_course)
self.assertTrue(blocks_are_equivalent(initial_course, exported_course))
self.assertEqual(initial_course.id, exported_course.id)
assert blocks_are_equivalent(initial_course, exported_course)
assert initial_course.id == exported_course.id
course_id = initial_course.id
print("Checking key equality")
@@ -146,10 +146,8 @@ class RoundTripTestCase(unittest.TestCase):
print("Checking module equality")
for location in initial_import.modules[course_id].keys():
print(("Checking", location))
self.assertTrue(blocks_are_equivalent(
initial_import.modules[course_id][location],
second_import.modules[course_id][location]
))
assert blocks_are_equivalent(initial_import.modules[course_id][location],
second_import.modules[course_id][location])
class TestEdxJsonEncoder(unittest.TestCase):
@@ -177,42 +175,27 @@ class TestEdxJsonEncoder(unittest.TestCase):
def test_encode_location(self):
loc = BlockUsageLocator(CourseLocator('org', 'course', 'run'), 'category', 'name')
self.assertEqual(text_type(loc), self.encoder.default(loc))
assert text_type(loc) == self.encoder.default(loc)
loc = BlockUsageLocator(CourseLocator('org', 'course', 'run', branch='version'), 'category', 'name')
self.assertEqual(text_type(loc), self.encoder.default(loc))
assert text_type(loc) == self.encoder.default(loc)
def test_encode_naive_datetime(self):
self.assertEqual(
"2013-05-03T10:20:30.000100",
self.encoder.default(datetime(2013, 5, 3, 10, 20, 30, 100))
)
self.assertEqual(
"2013-05-03T10:20:30",
self.encoder.default(datetime(2013, 5, 3, 10, 20, 30))
)
assert '2013-05-03T10:20:30.000100' == self.encoder.default(datetime(2013, 5, 3, 10, 20, 30, 100))
assert '2013-05-03T10:20:30' == self.encoder.default(datetime(2013, 5, 3, 10, 20, 30))
def test_encode_utc_datetime(self):
self.assertEqual(
"2013-05-03T10:20:30+00:00",
self.encoder.default(datetime(2013, 5, 3, 10, 20, 30, 0, pytz.UTC))
)
assert '2013-05-03T10:20:30+00:00' == self.encoder.default(datetime(2013, 5, 3, 10, 20, 30, 0, pytz.UTC))
self.assertEqual(
"2013-05-03T10:20:30+04:00",
self.encoder.default(datetime(2013, 5, 3, 10, 20, 30, 0, self.offset_tz))
)
assert '2013-05-03T10:20:30+04:00' == self.encoder.default(datetime(2013, 5, 3, 10, 20, 30, 0, self.offset_tz))
self.assertEqual(
"2013-05-03T10:20:30Z",
self.encoder.default(datetime(2013, 5, 3, 10, 20, 30, 0, self.null_utc_tz))
)
assert '2013-05-03T10:20:30Z' == self.encoder.default(datetime(2013, 5, 3, 10, 20, 30, 0, self.null_utc_tz))
def test_fallthrough(self):
with self.assertRaises(TypeError):
with pytest.raises(TypeError):
self.encoder.default(None)
with self.assertRaises(TypeError):
with pytest.raises(TypeError):
self.encoder.default({})
def test_encode_unicode_lazy_text(self):
@@ -224,7 +207,4 @@ class TestEdxJsonEncoder(unittest.TestCase):
unicode_text = u"Your 𝓟𝓵𝓪𝓽𝓯𝓸𝓻𝓶 Name Here"
lazy_text = ugettext_lazy(unicode_text) # lint-amnesty, pylint: disable=translation-of-non-string
self.assertEqual(
unicode_text,
self.encoder.default(lazy_text)
)
assert unicode_text == self.encoder.default(lazy_text)

View File

@@ -3,7 +3,7 @@
import datetime
import unittest
import pytest
from pytz import UTC
from xmodule.fields import Date, RelativeTime, Timedelta
@@ -14,11 +14,7 @@ class DateTest(unittest.TestCase): # lint-amnesty, pylint: disable=missing-clas
date = Date()
def compare_dates(self, dt1, dt2, expected_delta):
self.assertEqual(
dt1 - dt2,
expected_delta,
str(dt1) + "-" + str(dt2) + "!=" + str(expected_delta)
)
assert (dt1 - dt2) == expected_delta, ((((str(dt1) + '-') + str(dt2)) + '!=') + str(expected_delta))
def test_from_json(self):
"""Test conversion from iso compatible date strings to struct_time"""
@@ -54,40 +50,27 @@ class DateTest(unittest.TestCase): # lint-amnesty, pylint: disable=missing-clas
)
def test_enforce_type(self):
self.assertEqual(DateTest.date.enforce_type(None), None)
self.assertEqual(DateTest.date.enforce_type(""), None)
self.assertEqual(
DateTest.date.enforce_type("2012-12-31T23:00:01"),
datetime.datetime(2012, 12, 31, 23, 0, 1, tzinfo=UTC)
)
self.assertEqual(
DateTest.date.enforce_type(1234567890000),
datetime.datetime(2009, 2, 13, 23, 31, 30, tzinfo=UTC)
)
self.assertEqual(
DateTest.date.enforce_type(datetime.datetime(2014, 5, 9, 21, 1, 27, tzinfo=UTC)),
datetime.datetime(2014, 5, 9, 21, 1, 27, tzinfo=UTC)
)
with self.assertRaises(TypeError):
assert DateTest.date.enforce_type(None) is None
assert DateTest.date.enforce_type('') is None
assert DateTest.date.enforce_type('2012-12-31T23:00:01') ==\
datetime.datetime(2012, 12, 31, 23, 0, 1, tzinfo=UTC)
assert DateTest.date.enforce_type(1234567890000) == datetime.datetime(2009, 2, 13, 23, 31, 30, tzinfo=UTC)
assert DateTest.date.enforce_type(datetime.datetime(2014, 5, 9, 21, 1, 27, tzinfo=UTC)) ==\
datetime.datetime(2014, 5, 9, 21, 1, 27, tzinfo=UTC)
with pytest.raises(TypeError):
DateTest.date.enforce_type([1])
def test_return_None(self):
self.assertIsNone(DateTest.date.from_json(""))
self.assertIsNone(DateTest.date.from_json(None))
with self.assertRaises(TypeError):
assert DateTest.date.from_json('') is None
assert DateTest.date.from_json(None) is None
with pytest.raises(TypeError):
DateTest.date.from_json(['unknown value'])
def test_old_due_date_format(self):
current = datetime.datetime.today()
self.assertEqual(
datetime.datetime(current.year, 3, 12, 12, tzinfo=UTC),
DateTest.date.from_json("March 12 12:00")
)
self.assertEqual(
datetime.datetime(current.year, 12, 4, 16, 30, tzinfo=UTC),
DateTest.date.from_json("December 4 16:30")
)
self.assertIsNone(DateTest.date.from_json("12 12:00"))
assert datetime.datetime(current.year, 3, 12, 12, tzinfo=UTC) == DateTest.date.from_json('March 12 12:00')
assert datetime.datetime(current.year, 12, 4, 16, 30, tzinfo=UTC) == DateTest.date.from_json('December 4 16:30')
assert DateTest.date.from_json('12 12:00') is None
def test_non_std_from_json(self):
"""
@@ -95,30 +78,20 @@ class DateTest(unittest.TestCase): # lint-amnesty, pylint: disable=missing-clas
"""
now = datetime.datetime.now(UTC)
delta = now - datetime.datetime.fromtimestamp(0, UTC)
self.assertEqual(
DateTest.date.from_json(delta.total_seconds() * 1000),
now
)
assert DateTest.date.from_json((delta.total_seconds() * 1000)) == now
yesterday = datetime.datetime.now(UTC) - datetime.timedelta(days=-1)
self.assertEqual(DateTest.date.from_json(yesterday), yesterday)
assert DateTest.date.from_json(yesterday) == yesterday
def test_to_json(self):
"""
Test converting time reprs to iso dates
"""
self.assertEqual(
DateTest.date.to_json(datetime.datetime.strptime("2012-12-31T23:59:59Z", "%Y-%m-%dT%H:%M:%SZ")),
"2012-12-31T23:59:59Z"
)
self.assertEqual(
DateTest.date.to_json(DateTest.date.from_json("2012-12-31T23:59:59Z")),
"2012-12-31T23:59:59Z"
)
self.assertEqual(
DateTest.date.to_json(DateTest.date.from_json("2012-12-31T23:00:01-01:00")),
"2012-12-31T23:00:01-01:00"
)
with self.assertRaises(TypeError):
assert DateTest.date.to_json(datetime.datetime.strptime('2012-12-31T23:59:59Z', '%Y-%m-%dT%H:%M:%SZ')) ==\
'2012-12-31T23:59:59Z'
assert DateTest.date.to_json(DateTest.date.from_json('2012-12-31T23:59:59Z')) == '2012-12-31T23:59:59Z'
assert DateTest.date.to_json(DateTest.date.from_json('2012-12-31T23:00:01-01:00')) ==\
'2012-12-31T23:00:01-01:00'
with pytest.raises(TypeError):
DateTest.date.to_json('2012-12-31T23:00:01-01:00')
@@ -126,34 +99,22 @@ class TimedeltaTest(unittest.TestCase): # lint-amnesty, pylint: disable=missing
delta = Timedelta()
def test_from_json(self):
self.assertEqual(
TimedeltaTest.delta.from_json('1 day 12 hours 59 minutes 59 seconds'),
datetime.timedelta(days=1, hours=12, minutes=59, seconds=59)
)
assert TimedeltaTest.delta.from_json('1 day 12 hours 59 minutes 59 seconds') ==\
datetime.timedelta(days=1, hours=12, minutes=59, seconds=59)
self.assertEqual(
TimedeltaTest.delta.from_json('1 day 46799 seconds'),
datetime.timedelta(days=1, seconds=46799)
)
assert TimedeltaTest.delta.from_json('1 day 46799 seconds') == datetime.timedelta(days=1, seconds=46799)
def test_enforce_type(self):
self.assertEqual(TimedeltaTest.delta.enforce_type(None), None)
self.assertEqual(
TimedeltaTest.delta.enforce_type(datetime.timedelta(days=1, seconds=46799)),
datetime.timedelta(days=1, seconds=46799)
)
self.assertEqual(
TimedeltaTest.delta.enforce_type('1 day 46799 seconds'),
datetime.timedelta(days=1, seconds=46799)
)
with self.assertRaises(TypeError):
assert TimedeltaTest.delta.enforce_type(None) is None
assert TimedeltaTest.delta.enforce_type(datetime.timedelta(days=1, seconds=46799)) ==\
datetime.timedelta(days=1, seconds=46799)
assert TimedeltaTest.delta.enforce_type('1 day 46799 seconds') == datetime.timedelta(days=1, seconds=46799)
with pytest.raises(TypeError):
TimedeltaTest.delta.enforce_type([1])
def test_to_json(self):
self.assertEqual(
'1 days 46799 seconds',
TimedeltaTest.delta.to_json(datetime.timedelta(days=1, hours=12, minutes=59, seconds=59))
)
assert '1 days 46799 seconds' ==\
TimedeltaTest.delta.to_json(datetime.timedelta(days=1, hours=12, minutes=59, seconds=59))
class TimeInfoTest(unittest.TestCase): # lint-amnesty, pylint: disable=missing-class-docstring
@@ -162,10 +123,7 @@ class TimeInfoTest(unittest.TestCase): # lint-amnesty, pylint: disable=missing-
due_date = datetime.datetime(2000, 4, 14, 10, tzinfo=UTC)
grace_pd_string = '1 day 12 hours 59 minutes 59 seconds'
timeinfo = TimeInfo(due_date, grace_pd_string)
self.assertEqual(
timeinfo.close_date,
due_date + Timedelta().from_json(grace_pd_string)
)
assert timeinfo.close_date == (due_date + Timedelta().from_json(grace_pd_string))
class RelativeTimeTest(unittest.TestCase): # lint-amnesty, pylint: disable=missing-class-docstring
@@ -173,66 +131,37 @@ class RelativeTimeTest(unittest.TestCase): # lint-amnesty, pylint: disable=miss
delta = RelativeTime()
def test_from_json(self):
self.assertEqual(
RelativeTimeTest.delta.from_json('0:05:07'),
datetime.timedelta(seconds=307)
)
assert RelativeTimeTest.delta.from_json('0:05:07') == datetime.timedelta(seconds=307)
self.assertEqual(
RelativeTimeTest.delta.from_json(100.0),
datetime.timedelta(seconds=100)
)
self.assertEqual(
RelativeTimeTest.delta.from_json(None),
datetime.timedelta(seconds=0)
)
assert RelativeTimeTest.delta.from_json(100.0) == datetime.timedelta(seconds=100)
assert RelativeTimeTest.delta.from_json(None) == datetime.timedelta(seconds=0)
with self.assertRaises(TypeError):
with pytest.raises(TypeError):
RelativeTimeTest.delta.from_json(1234) # int
with self.assertRaises(ValueError):
with pytest.raises(ValueError):
RelativeTimeTest.delta.from_json("77:77:77")
def test_enforce_type(self):
self.assertEqual(RelativeTimeTest.delta.enforce_type(None), None)
self.assertEqual(
RelativeTimeTest.delta.enforce_type(datetime.timedelta(days=1, seconds=46799)),
datetime.timedelta(days=1, seconds=46799)
)
self.assertEqual(
RelativeTimeTest.delta.enforce_type('0:05:07'),
datetime.timedelta(seconds=307)
)
with self.assertRaises(TypeError):
assert RelativeTimeTest.delta.enforce_type(None) is None
assert RelativeTimeTest.delta.enforce_type(datetime.timedelta(days=1, seconds=46799)) ==\
datetime.timedelta(days=1, seconds=46799)
assert RelativeTimeTest.delta.enforce_type('0:05:07') == datetime.timedelta(seconds=307)
with pytest.raises(TypeError):
RelativeTimeTest.delta.enforce_type([1])
def test_to_json(self):
self.assertEqual(
"01:02:03",
RelativeTimeTest.delta.to_json(datetime.timedelta(seconds=3723))
)
self.assertEqual(
"00:00:00",
RelativeTimeTest.delta.to_json(None)
)
self.assertEqual(
"00:01:40",
RelativeTimeTest.delta.to_json(100.0)
)
assert '01:02:03' == RelativeTimeTest.delta.to_json(datetime.timedelta(seconds=3723))
assert '00:00:00' == RelativeTimeTest.delta.to_json(None)
assert '00:01:40' == RelativeTimeTest.delta.to_json(100.0)
error_msg = "RelativeTime max value is 23:59:59=86400.0 seconds, but 90000.0 seconds is passed"
with self.assertRaisesRegex(ValueError, error_msg):
RelativeTimeTest.delta.to_json(datetime.timedelta(seconds=90000))
with self.assertRaises(TypeError):
with pytest.raises(TypeError):
RelativeTimeTest.delta.to_json("123")
def test_str(self):
self.assertEqual(
"01:02:03",
RelativeTimeTest.delta.to_json(datetime.timedelta(seconds=3723))
)
self.assertEqual(
"11:02:03",
RelativeTimeTest.delta.to_json(datetime.timedelta(seconds=39723))
)
assert '01:02:03' == RelativeTimeTest.delta.to_json(datetime.timedelta(seconds=3723))
assert '11:02:03' == RelativeTimeTest.delta.to_json(datetime.timedelta(seconds=39723))

View File

@@ -5,7 +5,7 @@ Grading tests
import unittest
from datetime import datetime, timedelta
import pytest
import ddt
from pytz import UTC
import six
@@ -28,26 +28,14 @@ class GradesheetTest(unittest.TestCase):
# No scores
all_total, graded_total = aggregate_scores(scores)
self.assertEqual(
all_total,
AggregatedScore(tw_earned=0, tw_possible=0, graded=False, **agg_fields),
)
self.assertEqual(
graded_total,
AggregatedScore(tw_earned=0, tw_possible=0, graded=True, **agg_fields),
)
assert all_total == AggregatedScore(tw_earned=0, tw_possible=0, graded=False, **agg_fields)
assert graded_total == AggregatedScore(tw_earned=0, tw_possible=0, graded=True, **agg_fields)
# (0/5 non-graded)
scores.append(ProblemScore(weighted_earned=0, weighted_possible=5, graded=False, **prob_fields))
all_total, graded_total = aggregate_scores(scores)
self.assertEqual(
all_total,
AggregatedScore(tw_earned=0, tw_possible=5, graded=False, **agg_fields),
)
self.assertEqual(
graded_total,
AggregatedScore(tw_earned=0, tw_possible=0, graded=True, **agg_fields),
)
assert all_total == AggregatedScore(tw_earned=0, tw_possible=5, graded=False, **agg_fields)
assert graded_total == AggregatedScore(tw_earned=0, tw_possible=0, graded=True, **agg_fields)
# (0/5 non-graded) + (3/5 graded) = 3/10 total, 3/5 graded
now = datetime.now()
@@ -55,26 +43,14 @@ class GradesheetTest(unittest.TestCase):
agg_fields['first_attempted'] = now
scores.append(ProblemScore(weighted_earned=3, weighted_possible=5, graded=True, **prob_fields))
all_total, graded_total = aggregate_scores(scores)
self.assertAlmostEqual(
all_total,
AggregatedScore(tw_earned=3, tw_possible=10, graded=False, **agg_fields),
)
self.assertAlmostEqual(
graded_total,
AggregatedScore(tw_earned=3, tw_possible=5, graded=True, **agg_fields),
)
assert round(all_total - AggregatedScore(tw_earned=3, tw_possible=10, graded=False, **agg_fields), 7) >= 0
assert round(graded_total - AggregatedScore(tw_earned=3, tw_possible=5, graded=True, **agg_fields), 7) >= 0
# (0/5 non-graded) + (3/5 graded) + (2/5 graded) = 5/15 total, 5/10 graded
scores.append(ProblemScore(weighted_earned=2, weighted_possible=5, graded=True, **prob_fields))
all_total, graded_total = aggregate_scores(scores)
self.assertAlmostEqual(
all_total,
AggregatedScore(tw_earned=5, tw_possible=15, graded=False, **agg_fields),
)
self.assertAlmostEqual(
graded_total,
AggregatedScore(tw_earned=5, tw_possible=10, graded=True, **agg_fields),
)
assert round(all_total - AggregatedScore(tw_earned=5, tw_possible=15, graded=False, **agg_fields), 7) >= 0
assert round(graded_total - AggregatedScore(tw_earned=5, tw_possible=10, graded=True, **agg_fields), 7) >= 0
@ddt.ddt
@@ -147,25 +123,28 @@ class GraderTest(unittest.TestCase):
homework_grader.grade(self.incomplete_gradesheet),
no_drop_grader.grade(self.incomplete_gradesheet),
]:
self.assertAlmostEqual(graded['percent'], 0.0)
assert round(graded['percent'] - 0.0, 7) >= 0
# Make sure the breakdown includes 12 sections, plus one summary
self.assertEqual(len(graded['section_breakdown']), 12 + 1)
assert len(graded['section_breakdown']) == (12 + 1)
graded = homework_grader.grade(self.test_gradesheet)
self.assertAlmostEqual(graded['percent'], 0.11) # 100% + 10% / 10 assignments
self.assertEqual(len(graded['section_breakdown']), 12 + 1)
assert round(graded['percent'] - 0.11, 7) >= 0
# 100% + 10% / 10 assignments
assert len(graded['section_breakdown']) == (12 + 1)
graded = no_drop_grader.grade(self.test_gradesheet)
self.assertAlmostEqual(graded['percent'], 0.0916666666666666) # 100% + 10% / 12 assignments
self.assertEqual(len(graded['section_breakdown']), 12 + 1)
assert round(graded['percent'] - 0.0916666666666666, 7) >= 0
# 100% + 10% / 12 assignments
assert len(graded['section_breakdown']) == (12 + 1)
graded = overflow_grader.grade(self.test_gradesheet)
self.assertAlmostEqual(graded['percent'], 0.8879999999999999) # 100% + 10% / 5 assignments
self.assertEqual(len(graded['section_breakdown']), 7 + 1)
assert round(graded['percent'] - 0.8879999999999999, 7) >= 0
# 100% + 10% / 5 assignments
assert len(graded['section_breakdown']) == (7 + 1)
graded = lab_grader.grade(self.test_gradesheet)
self.assertAlmostEqual(graded['percent'], 0.92249999999999999)
self.assertEqual(len(graded['section_breakdown']), 7 + 1)
assert round(graded['percent'] - 0.9225, 7) >= 0
assert len(graded['section_breakdown']) == (7 + 1)
def test_assignment_format_grader_on_single_section_entry(self):
midterm_grader = graders.AssignmentFormatGrader("Midterm", 1, 0)
@@ -174,14 +153,14 @@ class GraderTest(unittest.TestCase):
midterm_grader.grade(self.empty_gradesheet),
midterm_grader.grade(self.incomplete_gradesheet),
]:
self.assertAlmostEqual(graded['percent'], 0.0)
assert round(graded['percent'] - 0.0, 7) >= 0
# Make sure the breakdown includes just the one summary
self.assertEqual(len(graded['section_breakdown']), 0 + 1)
self.assertEqual(graded['section_breakdown'][0]['label'], 'Midterm')
assert len(graded['section_breakdown']) == (0 + 1)
assert graded['section_breakdown'][0]['label'] == 'Midterm'
graded = midterm_grader.grade(self.test_gradesheet)
self.assertAlmostEqual(graded['percent'], 0.50)
self.assertEqual(len(graded['section_breakdown']), 0 + 1)
assert round(graded['percent'] - 0.5, 7) >= 0
assert len(graded['section_breakdown']) == (0 + 1)
def test_weighted_subsections_grader(self):
# First, a few sub graders
@@ -218,24 +197,24 @@ class GraderTest(unittest.TestCase):
empty_grader = graders.WeightedSubsectionsGrader([])
graded = weighted_grader.grade(self.test_gradesheet)
self.assertAlmostEqual(graded['percent'], 0.50812499999999994)
self.assertEqual(len(graded['section_breakdown']), (12 + 1) + (7 + 1) + 1)
self.assertEqual(len(graded['grade_breakdown']), 3)
assert round(graded['percent'] - 0.5081249999999999, 7) >= 0
assert len(graded['section_breakdown']) == (((12 + 1) + (7 + 1)) + 1)
assert len(graded['grade_breakdown']) == 3
graded = over_one_weights_grader.grade(self.test_gradesheet)
self.assertAlmostEqual(graded['percent'], 0.76624999999999999)
self.assertEqual(len(graded['section_breakdown']), (12 + 1) + (7 + 1) + 1)
self.assertEqual(len(graded['grade_breakdown']), 3)
assert round(graded['percent'] - 0.76625, 7) >= 0
assert len(graded['section_breakdown']) == (((12 + 1) + (7 + 1)) + 1)
assert len(graded['grade_breakdown']) == 3
graded = zero_weights_grader.grade(self.test_gradesheet)
self.assertAlmostEqual(graded['percent'], 0.25)
self.assertEqual(len(graded['section_breakdown']), (12 + 1) + (7 + 1) + 1)
self.assertEqual(len(graded['grade_breakdown']), 3)
assert round(graded['percent'] - 0.25, 7) >= 0
assert len(graded['section_breakdown']) == (((12 + 1) + (7 + 1)) + 1)
assert len(graded['grade_breakdown']) == 3
graded = all_zero_weights_grader.grade(self.test_gradesheet)
self.assertAlmostEqual(graded['percent'], 0.0)
self.assertEqual(len(graded['section_breakdown']), (12 + 1) + (7 + 1) + 1)
self.assertEqual(len(graded['grade_breakdown']), 3)
assert round(graded['percent'] - 0.0, 7) >= 0
assert len(graded['section_breakdown']) == (((12 + 1) + (7 + 1)) + 1)
assert len(graded['grade_breakdown']) == 3
for graded in [
weighted_grader.grade(self.empty_gradesheet),
@@ -243,14 +222,14 @@ class GraderTest(unittest.TestCase):
zero_weights_grader.grade(self.empty_gradesheet),
all_zero_weights_grader.grade(self.empty_gradesheet),
]:
self.assertAlmostEqual(graded['percent'], 0.0)
self.assertEqual(len(graded['section_breakdown']), (12 + 1) + (7 + 1) + 1)
self.assertEqual(len(graded['grade_breakdown']), 3)
assert round(graded['percent'] - 0.0, 7) >= 0
assert len(graded['section_breakdown']) == (((12 + 1) + (7 + 1)) + 1)
assert len(graded['grade_breakdown']) == 3
graded = empty_grader.grade(self.test_gradesheet)
self.assertAlmostEqual(graded['percent'], 0.0)
self.assertEqual(len(graded['section_breakdown']), 0)
self.assertEqual(len(graded['grade_breakdown']), 0)
assert round(graded['percent'] - 0.0, 7) >= 0
assert len(graded['section_breakdown']) == 0
assert len(graded['grade_breakdown']) == 0
def test_grade_with_string_min_count(self):
"""
@@ -282,9 +261,9 @@ class GraderTest(unittest.TestCase):
])
graded = weighted_grader.grade(self.test_gradesheet)
self.assertAlmostEqual(graded['percent'], 0.50812499999999994)
self.assertEqual(len(graded['section_breakdown']), (12 + 1) + (7 + 1) + 1)
self.assertEqual(len(graded['grade_breakdown']), 3)
assert round(graded['percent'] - 0.50812499999999994, 7) >= 0
assert len(graded['section_breakdown']) == (((12 + 1) + (7 + 1)) + 1)
assert len(graded['grade_breakdown']) == 3
def test_grader_from_conf(self):
@@ -319,22 +298,22 @@ class GraderTest(unittest.TestCase):
empty_grader = graders.grader_from_conf([])
graded = weighted_grader.grade(self.test_gradesheet)
self.assertAlmostEqual(graded['percent'], 0.50812499999999994)
self.assertEqual(len(graded['section_breakdown']), (12 + 1) + (7 + 1) + 1)
self.assertEqual(len(graded['grade_breakdown']), 3)
assert round(graded['percent'] - 0.5081249999999999, 7) >= 0
assert len(graded['section_breakdown']) == (((12 + 1) + (7 + 1)) + 1)
assert len(graded['grade_breakdown']) == 3
graded = empty_grader.grade(self.test_gradesheet)
self.assertAlmostEqual(graded['percent'], 0.0)
self.assertEqual(len(graded['section_breakdown']), 0)
self.assertEqual(len(graded['grade_breakdown']), 0)
assert round(graded['percent'] - 0.0, 7) >= 0
assert len(graded['section_breakdown']) == 0
assert len(graded['grade_breakdown']) == 0
# Test that graders can also be used instead of lists of dictionaries
homework_grader = graders.AssignmentFormatGrader("Homework", 12, 2)
homework_grader2 = graders.grader_from_conf(homework_grader)
graded = homework_grader2.grade(self.test_gradesheet)
self.assertAlmostEqual(graded['percent'], 0.11)
self.assertEqual(len(graded['section_breakdown']), 12 + 1)
assert round(graded['percent'] - 0.11, 7) >= 0
assert len(graded['section_breakdown']) == (12 + 1)
@ddt.data(
(
@@ -356,9 +335,9 @@ class GraderTest(unittest.TestCase):
)
@ddt.unpack
def test_grader_with_invalid_conf(self, invalid_conf, expected_error_message):
with self.assertRaises(ValueError) as error:
with pytest.raises(ValueError) as error:
graders.grader_from_conf([invalid_conf])
self.assertIn(expected_error_message, text_type(error.exception))
assert expected_error_message in text_type(error.exception)
@ddt.ddt
@@ -380,7 +359,7 @@ class ShowCorrectnessTest(unittest.TestCase):
"""
Test that correctness is visible by default.
"""
self.assertTrue(ShowCorrectness.correctness_available())
assert ShowCorrectness.correctness_available()
@ddt.data(
(ShowCorrectness.ALWAYS, True),
@@ -396,20 +375,16 @@ class ShowCorrectnessTest(unittest.TestCase):
"""
Test that correctness is visible when show_correctness is turned on.
"""
self.assertTrue(ShowCorrectness.correctness_available(
show_correctness=show_correctness,
has_staff_access=has_staff_access
))
assert ShowCorrectness.correctness_available(show_correctness=show_correctness,
has_staff_access=has_staff_access)
@ddt.data(True, False)
def test_show_correctness_never(self, has_staff_access):
"""
Test that show_correctness="never" hides correctness from learners and course staff.
"""
self.assertFalse(ShowCorrectness.correctness_available(
show_correctness=ShowCorrectness.NEVER,
has_staff_access=has_staff_access
))
assert not ShowCorrectness.correctness_available(show_correctness=ShowCorrectness.NEVER,
has_staff_access=has_staff_access)
@ddt.data(
# Correctness not visible to learners if due date in the future
@@ -439,7 +414,5 @@ class ShowCorrectnessTest(unittest.TestCase):
due_date = None
else:
due_date = getattr(self, due_date_str)
self.assertEqual(
ShowCorrectness.correctness_available(ShowCorrectness.PAST_DUE, due_date, has_staff_access),
expected_result
)
assert ShowCorrectness.correctness_available(ShowCorrectness.PAST_DUE, due_date, has_staff_access) ==\
expected_result

View File

@@ -50,10 +50,8 @@ class HtmlBlockCourseApiTestCase(unittest.TestCase):
module = HtmlBlock(module_system, field_data, Mock())
with override_settings(**settings):
self.assertEqual(module.student_view_data(), dict(
enabled=False,
message='To enable, set FEATURES["ENABLE_HTML_XBLOCK_STUDENT_VIEW_DATA"]',
))
assert module.student_view_data() ==\
dict(enabled=False, message='To enable, set FEATURES["ENABLE_HTML_XBLOCK_STUDENT_VIEW_DATA"]')
@ddt.data(
'<h1>Some content</h1>', # Valid HTML
@@ -78,7 +76,7 @@ class HtmlBlockCourseApiTestCase(unittest.TestCase):
field_data = DictFieldData({'data': html})
module_system = get_test_system()
module = HtmlBlock(module_system, field_data, Mock())
self.assertEqual(module.student_view_data(), dict(enabled=True, html=html))
assert module.student_view_data() == dict(enabled=True, html=html)
@ddt.data(
STUDENT_VIEW,
@@ -93,7 +91,7 @@ class HtmlBlockCourseApiTestCase(unittest.TestCase):
module_system = get_test_system()
module = HtmlBlock(module_system, field_data, Mock())
rendered = module_system.render(module, view, {}).content
self.assertIn(html, rendered)
assert html in rendered
class HtmlBlockSubstitutionTestCase(unittest.TestCase): # lint-amnesty, pylint: disable=missing-class-docstring
@@ -103,7 +101,7 @@ class HtmlBlockSubstitutionTestCase(unittest.TestCase): # lint-amnesty, pylint:
field_data = DictFieldData({'data': sample_xml})
module_system = get_test_system()
module = HtmlBlock(module_system, field_data, Mock())
self.assertEqual(module.get_html(), str(module_system.anonymous_student_id))
assert module.get_html() == str(module_system.anonymous_student_id)
def test_substitution_course_id(self):
sample_xml = '''%%COURSE_ID%%'''
@@ -121,7 +119,7 @@ class HtmlBlockSubstitutionTestCase(unittest.TestCase): # lint-amnesty, pylint:
block_id='block_id'
)
module.scope_ids.usage_id = usage_key
self.assertEqual(module.get_html(), str(course_key))
assert module.get_html() == str(course_key)
def test_substitution_without_magic_string(self):
sample_xml = '''
@@ -132,7 +130,7 @@ class HtmlBlockSubstitutionTestCase(unittest.TestCase): # lint-amnesty, pylint:
field_data = DictFieldData({'data': sample_xml})
module_system = get_test_system()
module = HtmlBlock(module_system, field_data, Mock())
self.assertEqual(module.get_html(), sample_xml)
assert module.get_html() == sample_xml
def test_substitution_without_anonymous_student_id(self):
sample_xml = '''%%USER_ID%%'''
@@ -140,7 +138,7 @@ class HtmlBlockSubstitutionTestCase(unittest.TestCase): # lint-amnesty, pylint:
module_system = get_test_system()
module_system.anonymous_student_id = None
module = HtmlBlock(module_system, field_data, Mock())
self.assertEqual(module.get_html(), sample_xml)
assert module.get_html() == sample_xml
class HtmlBlockIndexingTestCase(unittest.TestCase):
@@ -155,10 +153,8 @@ class HtmlBlockIndexingTestCase(unittest.TestCase):
</html>
'''
descriptor = instantiate_descriptor(data=sample_xml)
self.assertEqual(descriptor.index_dictionary(), {
"content": {"html_content": " Hello World! ", "display_name": "Text"},
"content_type": "Text"
})
assert descriptor.index_dictionary() ==\
{'content': {'html_content': ' Hello World! ', 'display_name': 'Text'}, 'content_type': 'Text'}
def test_index_dictionary_cdata_html_module(self):
sample_xml_cdata = '''
@@ -168,10 +164,8 @@ class HtmlBlockIndexingTestCase(unittest.TestCase):
</html>
'''
descriptor = instantiate_descriptor(data=sample_xml_cdata)
self.assertEqual(descriptor.index_dictionary(), {
"content": {"html_content": " This has CDATA in it. ", "display_name": "Text"},
"content_type": "Text"
})
assert descriptor.index_dictionary() ==\
{'content': {'html_content': ' This has CDATA in it. ', 'display_name': 'Text'}, 'content_type': 'Text'}
def test_index_dictionary_multiple_spaces_html_module(self):
sample_xml_tab_spaces = '''
@@ -180,10 +174,8 @@ class HtmlBlockIndexingTestCase(unittest.TestCase):
</html>
'''
descriptor = instantiate_descriptor(data=sample_xml_tab_spaces)
self.assertEqual(descriptor.index_dictionary(), {
"content": {"html_content": " Text has spaces :) ", "display_name": "Text"},
"content_type": "Text"
})
assert descriptor.index_dictionary() ==\
{'content': {'html_content': ' Text has spaces :) ', 'display_name': 'Text'}, 'content_type': 'Text'}
def test_index_dictionary_html_module_with_comment(self):
sample_xml_comment = '''
@@ -193,10 +185,7 @@ class HtmlBlockIndexingTestCase(unittest.TestCase):
</html>
'''
descriptor = instantiate_descriptor(data=sample_xml_comment)
self.assertEqual(descriptor.index_dictionary(), {
"content": {"html_content": " This has HTML comment in it. ", "display_name": "Text"},
"content_type": "Text"
})
assert descriptor.index_dictionary() == {'content': {'html_content': ' This has HTML comment in it. ', 'display_name': 'Text'}, 'content_type': 'Text'} # pylint: disable=line-too-long
def test_index_dictionary_html_module_with_both_comments_and_cdata(self):
sample_xml_mix_comment_cdata = '''
@@ -209,10 +198,9 @@ class HtmlBlockIndexingTestCase(unittest.TestCase):
</html>
'''
descriptor = instantiate_descriptor(data=sample_xml_mix_comment_cdata)
self.assertEqual(descriptor.index_dictionary(), {
"content": {"html_content": " This has HTML comment in it. HTML end. ", "display_name": "Text"},
"content_type": "Text"
})
assert descriptor.index_dictionary() ==\
{'content': {'html_content': ' This has HTML comment in it. HTML end. ',
'display_name': 'Text'}, 'content_type': 'Text'}
def test_index_dictionary_html_module_with_script_and_style_tags(self):
sample_xml_style_script_tags = '''
@@ -229,10 +217,9 @@ class HtmlBlockIndexingTestCase(unittest.TestCase):
</html>
'''
descriptor = instantiate_descriptor(data=sample_xml_style_script_tags)
self.assertEqual(descriptor.index_dictionary(), {
"content": {"html_content": " This has HTML comment in it. HTML end. ", "display_name": "Text"},
"content_type": "Text"
})
assert descriptor.index_dictionary() ==\
{'content': {'html_content': ' This has HTML comment in it. HTML end. ',
'display_name': 'Text'}, 'content_type': 'Text'}
class CourseInfoBlockTestCase(unittest.TestCase):

View File

@@ -77,7 +77,7 @@ class BaseCourseTestCase(TestCase):
xblock_select=only_xmodules,
)
courses = modulestore.get_courses()
self.assertEqual(len(courses), 1)
assert len(courses) == 1
return courses[0]
@@ -97,8 +97,8 @@ class PureXBlockImportTest(BaseCourseTestCase):
def assert_xblocks_are_good(self, block):
"""Assert a number of conditions that must be true for `block` to be good."""
scope_ids = block.scope_ids
self.assertIsNotNone(scope_ids.usage_id)
self.assertIsNotNone(scope_ids.def_id)
assert scope_ids.usage_id is not None
assert scope_ids.def_id is not None
for child_id in block.children:
child = block.runtime.get_block(child_id)
@@ -114,9 +114,9 @@ class PureXBlockImportTest(BaseCourseTestCase):
def test_parsing_pure_xblock(self, xml, mock_location):
system = self.get_system(load_error_modules=False)
descriptor = system.process_xml(xml)
self.assertIsInstance(descriptor, GenericXBlock)
assert isinstance(descriptor, GenericXBlock)
self.assert_xblocks_are_good(descriptor)
self.assertFalse(mock_location.called)
assert not mock_location.called
class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missing-class-docstring
@@ -131,7 +131,7 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
descriptor = system.process_xml(bad_xml)
self.assertEqual(descriptor.__class__.__name__, 'ErrorBlockWithMixins')
assert descriptor.__class__.__name__ == 'ErrorBlockWithMixins'
def test_unique_url_names(self):
'''Check that each error gets its very own url_name'''
@@ -142,7 +142,7 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
descriptor1 = system.process_xml(bad_xml)
descriptor2 = system.process_xml(bad_xml2)
self.assertNotEqual(descriptor1.location, descriptor2.location)
assert descriptor1.location != descriptor2.location
# Check that each vertical gets its very own url_name
bad_xml = '''<vertical display_name="abc"><problem url_name="exam1:2013_Spring:abc"/></vertical>'''
@@ -151,7 +151,7 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
descriptor1 = system.process_xml(bad_xml)
descriptor2 = system.process_xml(bad_xml2)
self.assertNotEqual(descriptor1.location, descriptor2.location)
assert descriptor1.location != descriptor2.location
def test_reimport(self):
'''Make sure an already-exported error xml tag loads properly'''
@@ -165,10 +165,10 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
descriptor.add_xml_to_node(node)
re_import_descriptor = system.process_xml(etree.tostring(node))
self.assertEqual(re_import_descriptor.__class__.__name__, 'ErrorBlockWithMixins')
assert re_import_descriptor.__class__.__name__ == 'ErrorBlockWithMixins'
self.assertEqual(descriptor.contents, re_import_descriptor.contents)
self.assertEqual(descriptor.error_msg, re_import_descriptor.error_msg)
assert descriptor.contents == re_import_descriptor.contents
assert descriptor.error_msg == re_import_descriptor.error_msg
def test_fixed_xml_tag(self):
"""Make sure a tag that's been fixed exports as the original tag type"""
@@ -189,7 +189,7 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
descriptor.add_xml_to_node(node)
# Now make sure the exported xml is a sequential
self.assertEqual(node.tag, 'sequential')
assert node.tag == 'sequential'
def course_descriptor_inheritance_check(self, descriptor, from_date_string, unicorn_color, course_run=RUN):
"""
@@ -197,16 +197,14 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
"""
# pylint: disable=protected-access
print((descriptor, descriptor._field_data))
self.assertEqual(descriptor.due, ImportTestCase.date.from_json(from_date_string))
assert descriptor.due == ImportTestCase.date.from_json(from_date_string)
# Check that the child inherits due correctly
child = descriptor.get_children()[0]
self.assertEqual(child.due, ImportTestCase.date.from_json(from_date_string))
assert child.due == ImportTestCase.date.from_json(from_date_string)
# need to convert v to canonical json b4 comparing
self.assertEqual(
ImportTestCase.date.to_json(ImportTestCase.date.from_json(from_date_string)),
child.xblock_kvs.inherited_settings['due']
)
assert ImportTestCase.date.to_json(ImportTestCase.date.from_json(from_date_string)) ==\
child.xblock_kvs.inherited_settings['due']
# Now export and check things
file_system = OSFS(mkdtemp())
@@ -216,30 +214,30 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
# Check that the exported xml is just a pointer
print(("Exported xml:", etree.tostring(node)))
self.assertTrue(is_pointer_tag(node))
assert is_pointer_tag(node)
# but it's a special case course pointer
self.assertEqual(node.attrib['course'], COURSE)
self.assertEqual(node.attrib['org'], ORG)
assert node.attrib['course'] == COURSE
assert node.attrib['org'] == ORG
# Does the course still have unicorns?
with descriptor.runtime.export_fs.open(u'course/{course_run}.xml'.format(course_run=course_run)) as f:
course_xml = etree.fromstring(f.read())
self.assertEqual(course_xml.attrib['unicorn'], unicorn_color)
assert course_xml.attrib['unicorn'] == unicorn_color
# the course and org tags should be _only_ in the pointer
self.assertNotIn('course', course_xml.attrib)
self.assertNotIn('org', course_xml.attrib)
assert 'course' not in course_xml.attrib
assert 'org' not in course_xml.attrib
# did we successfully strip the url_name from the definition contents?
self.assertNotIn('url_name', course_xml.attrib)
assert 'url_name' not in course_xml.attrib
# Does the chapter tag now have a due attribute?
# hardcoded path to child
with descriptor.runtime.export_fs.open(u'chapter/ch.xml') as f:
chapter_xml = etree.fromstring(f.read())
self.assertEqual(chapter_xml.tag, 'chapter')
self.assertNotIn('due', chapter_xml.attrib)
assert chapter_xml.tag == 'chapter'
assert 'due' not in chapter_xml.attrib
def test_metadata_import_export(self):
"""Two checks:
@@ -290,7 +288,7 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
LibraryXMLModuleStore.patch_descriptor_kvs(descriptor)
# '_unwrapped_field_data' is reset in `patch_descriptor_kvs`
# pylint: disable=protected-access
self.assertIsNot(original_unwrapped, descriptor._unwrapped_field_data)
assert original_unwrapped is not descriptor._unwrapped_field_data
compute_inherited_metadata(descriptor)
# Check the course module, since it has inheritance
descriptor = descriptor.get_children()[0]
@@ -341,29 +339,23 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
"""
Verifies that a default value of None (for due) does not get marked as inherited.
"""
self.assertEqual(descriptor.due, None)
assert descriptor.due is None
# Check that the child does not inherit a value for due
child = descriptor.get_children()[0]
self.assertEqual(child.due, None)
assert child.due is None
# Check that the child hasn't started yet
self.assertLessEqual(
datetime.datetime.now(UTC),
child.start
)
assert datetime.datetime.now(UTC) <= child.start
def override_metadata_check(self, descriptor, child, course_due, child_due):
"""
Verifies that due date can be overriden at child level.
"""
self.assertEqual(descriptor.due, ImportTestCase.date.from_json(course_due))
self.assertEqual(child.due, ImportTestCase.date.from_json(child_due))
assert descriptor.due == ImportTestCase.date.from_json(course_due)
assert child.due == ImportTestCase.date.from_json(child_due)
# Test inherited metadata. Due does not appear here (because explicitly set on child).
self.assertEqual(
ImportTestCase.date.to_json(ImportTestCase.date.from_json(course_due)),
child.xblock_kvs.inherited_settings['due']
)
assert ImportTestCase.date.to_json(ImportTestCase.date.from_json(course_due)) == child.xblock_kvs.inherited_settings['due'] # pylint: disable=line-too-long
def test_metadata_override_default(self):
"""
@@ -435,11 +427,11 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
for xml_str in yes:
print("should be True for {0}".format(xml_str))
self.assertTrue(is_pointer_tag(etree.fromstring(xml_str)))
assert is_pointer_tag(etree.fromstring(xml_str))
for xml_str in no:
print("should be False for {0}".format(xml_str))
self.assertFalse(is_pointer_tag(etree.fromstring(xml_str)))
assert not is_pointer_tag(etree.fromstring(xml_str))
def test_metadata_inherit(self):
"""Make sure that metadata is inherited properly"""
@@ -450,7 +442,7 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
def check_for_key(key, node, value):
"recursive check for presence of key"
print("Checking {0}".format(text_type(node.location)))
self.assertEqual(getattr(node, key), value)
assert getattr(node, key) == value
for c in node.get_children():
check_for_key(key, c, value)
@@ -463,21 +455,21 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
toy = self.get_course('toy')
two_toys = self.get_course('two_toys')
self.assertEqual(toy.url_name, "2012_Fall")
self.assertEqual(two_toys.url_name, "TT_2012_Fall")
assert toy.url_name == '2012_Fall'
assert two_toys.url_name == 'TT_2012_Fall'
toy_ch = toy.get_children()[0]
two_toys_ch = two_toys.get_children()[0]
self.assertEqual(toy_ch.display_name, "Overview")
self.assertEqual(two_toys_ch.display_name, "Two Toy Overview")
assert toy_ch.display_name == 'Overview'
assert two_toys_ch.display_name == 'Two Toy Overview'
# Also check that the grading policy loaded
self.assertEqual(two_toys.grade_cutoffs['C'], 0.5999)
assert two_toys.grade_cutoffs['C'] == 0.5999
# Also check that keys from policy are run through the
# appropriate attribute maps -- 'graded' should be True, not 'true'
self.assertEqual(toy.graded, True)
assert toy.graded is True
def test_static_tabs_import(self):
"""Make sure that the static tabs are imported correctly"""
@@ -487,14 +479,14 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
location_tab_syllabus = BlockUsageLocator(CourseLocator("edX", "toy", "2012_Fall", deprecated=True),
"static_tab", "syllabus", deprecated=True)
toy_tab_syllabus = modulestore.get_item(location_tab_syllabus)
self.assertEqual(toy_tab_syllabus.display_name, 'Syllabus')
self.assertEqual(toy_tab_syllabus.course_staff_only, False)
assert toy_tab_syllabus.display_name == 'Syllabus'
assert toy_tab_syllabus.course_staff_only is False
location_tab_resources = BlockUsageLocator(CourseLocator("edX", "toy", "2012_Fall", deprecated=True),
"static_tab", "resources", deprecated=True)
toy_tab_resources = modulestore.get_item(location_tab_resources)
self.assertEqual(toy_tab_resources.display_name, 'Resources')
self.assertEqual(toy_tab_resources.course_staff_only, True)
assert toy_tab_resources.display_name == 'Resources'
assert toy_tab_resources.course_staff_only is True
def test_definition_loading(self):
"""When two courses share the same org and course name and
@@ -512,8 +504,8 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
location_two = BlockUsageLocator(CourseLocator("edX", "toy", "TT_2012_Fall", deprecated=True),
"video", "Welcome", deprecated=True)
two_toy_video = modulestore.get_item(location_two)
self.assertEqual(toy_video.youtube_id_1_0, "p2Q6BrNhdh8")
self.assertEqual(two_toy_video.youtube_id_1_0, "p2Q6BrNhdh9")
assert toy_video.youtube_id_1_0 == 'p2Q6BrNhdh8'
assert two_toy_video.youtube_id_1_0 == 'p2Q6BrNhdh9'
def test_colon_in_url_name(self):
"""Ensure that colons in url_names convert to file paths properly"""
@@ -522,7 +514,7 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
# Not using get_courses because we need the modulestore object too afterward
modulestore = XMLModuleStore(DATA_DIR, source_dirs=['toy'])
courses = modulestore.get_courses()
self.assertEqual(len(courses), 1)
assert len(courses) == 1
course = courses[0]
print("course errors:")
@@ -531,20 +523,20 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
print(err)
chapters = course.get_children()
self.assertEqual(len(chapters), 5)
assert len(chapters) == 5
ch2 = chapters[1]
self.assertEqual(ch2.url_name, "secret:magic")
assert ch2.url_name == 'secret:magic'
print("Ch2 location: ", ch2.location)
also_ch2 = modulestore.get_item(ch2.location)
self.assertEqual(ch2, also_ch2)
assert ch2 == also_ch2
print("making sure html loaded")
loc = course.id.make_usage_key('html', 'secret:toylab')
html = modulestore.get_item(loc)
self.assertEqual(html.display_name, "Toy lab")
assert html.display_name == 'Toy lab'
def test_unicode(self):
"""Check that courses with unicode characters in filenames and in
@@ -556,7 +548,7 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
print("Starting import")
modulestore = XMLModuleStore(DATA_DIR, source_dirs=['test_unicode'])
courses = modulestore.get_courses()
self.assertEqual(len(courses), 1)
assert len(courses) == 1
course = courses[0]
print("course errors:")
@@ -569,12 +561,9 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
in modulestore.get_course_errors(course.id)
]
self.assertTrue(any(
expect in msg or expect in err
for msg, err in errors
))
assert any((((expect in msg) or (expect in err)) for (msg, err) in errors))
chapters = course.get_children()
self.assertEqual(len(chapters), 4)
assert len(chapters) == 4
def test_url_name_mangling(self):
"""
@@ -590,13 +579,13 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
ch1 = chapters[0]
sections = ch1.get_children()
self.assertEqual(len(sections), 4)
assert len(sections) == 4
for i in (2, 3):
video = sections[i]
# Name should be 'video_{hash}'
print("video {0} url_name: {1}".format(i, video.url_name))
self.assertEqual(len(video.url_name), len('video_') + 12)
assert len(video.url_name) == (len('video_') + 12)
def test_poll_and_conditional_import(self):
modulestore = XMLModuleStore(DATA_DIR, source_dirs=['conditional_and_poll'])
@@ -606,26 +595,20 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
ch1 = chapters[0]
sections = ch1.get_children()
self.assertEqual(len(sections), 1)
assert len(sections) == 1
conditional_location = course.id.make_usage_key('conditional', 'condone')
module = modulestore.get_item(conditional_location)
self.assertEqual(len(module.children), 1)
assert len(module.children) == 1
poll_location = course.id.make_usage_key('poll_question', 'first_poll')
module = modulestore.get_item(poll_location)
self.assertEqual(len(module.get_children()), 0)
self.assertEqual(module.voted, False)
self.assertEqual(module.poll_answer, '')
self.assertEqual(module.poll_answers, {})
self.assertEqual(
module.answers,
[
{'text': u'Yes', 'id': 'Yes'},
{'text': u'No', 'id': 'No'},
{'text': u"Don't know", 'id': 'Dont_know'}
]
)
assert len(module.get_children()) == 0
assert module.voted is False
assert module.poll_answer == ''
assert module.poll_answers == {}
assert module.answers ==\
[{'text': u'Yes', 'id': 'Yes'}, {'text': u'No', 'id': 'No'}, {'text': u"Don't know", 'id': 'Dont_know'}]
def test_error_on_import(self):
'''Check that when load_error_module is false, an exception is raised, rather than returning an ErrorBlock'''
@@ -643,13 +626,13 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
ch1 = chapters[0]
sections = ch1.get_children()
self.assertEqual(len(sections), 1)
assert len(sections) == 1
location = course.id.make_usage_key('word_cloud', 'cloud1')
module = modulestore.get_item(location)
self.assertEqual(len(module.get_children()), 0)
self.assertEqual(module.num_inputs, 5)
self.assertEqual(module.num_top_words, 250)
assert len(module.get_children()) == 0
assert module.num_inputs == 5
assert module.num_top_words == 250
def test_cohort_config(self):
"""
@@ -665,16 +648,16 @@ class ImportTestCase(BaseCourseTestCase): # lint-amnesty, pylint: disable=missi
course = modulestore.get_course(toy_id)
# No config -> False
self.assertFalse(course.is_cohorted)
assert not course.is_cohorted
# empty config -> False
course.cohort_config = {}
self.assertFalse(course.is_cohorted)
assert not course.is_cohorted
# false config -> False
course.cohort_config = {'cohorted': False}
self.assertFalse(course.is_cohorted)
assert not course.is_cohorted
# and finally...
course.cohort_config = {'cohorted': True}
self.assertTrue(course.is_cohorted)
assert course.is_cohorted

View File

@@ -47,10 +47,10 @@ class IgnoredFilesTestCase(unittest.TestCase):
static_content_importer.import_static_content_directory()
saved_static_content = [call[0][0] for call in content_store.save.call_args_list]
name_val = {sc.name: sc.data for sc in saved_static_content}
self.assertIn("example.txt", name_val)
self.assertIn(".example.txt", name_val)
self.assertIn(b"GREEN", name_val["example.txt"])
self.assertIn(b"BLUE", name_val[".example.txt"])
self.assertNotIn("._example.txt", name_val)
self.assertNotIn(".DS_Store", name_val)
self.assertNotIn("example.txt~", name_val)
assert 'example.txt' in name_val
assert '.example.txt' in name_val
assert b'GREEN' in name_val['example.txt']
assert b'BLUE' in name_val['.example.txt']
assert '._example.txt' not in name_val
assert '.DS_Store' not in name_val
assert 'example.txt~' not in name_val

View File

@@ -117,7 +117,7 @@ class TestLibraryContentExportImport(LibraryContentTest):
exported_olx = f.read()
# And compare.
self.assertEqual(exported_olx, expected_olx)
assert exported_olx == expected_olx
runtime = TestImportSystem(load_error_modules=True, course_id=lc_block.location.course_key)
runtime.resources_fs = export_fs
@@ -128,14 +128,14 @@ class TestLibraryContentExportImport(LibraryContentTest):
imported_lc_block = LibraryContentBlock.parse_xml(olx_element, runtime, None, id_generator)
# Check the new XBlock has the same properties as the old one.
self.assertEqual(imported_lc_block.display_name, lc_block.display_name)
self.assertEqual(imported_lc_block.source_library_id, lc_block.source_library_id)
self.assertEqual(imported_lc_block.source_library_version, lc_block.source_library_version)
self.assertEqual(imported_lc_block.mode, lc_block.mode)
self.assertEqual(imported_lc_block.max_count, lc_block.max_count)
self.assertEqual(imported_lc_block.capa_type, lc_block.capa_type)
self.assertEqual(len(imported_lc_block.children), 4)
self.assertEqual(imported_lc_block.children, lc_block.children)
assert imported_lc_block.display_name == lc_block.display_name
assert imported_lc_block.source_library_id == lc_block.source_library_id
assert imported_lc_block.source_library_version == lc_block.source_library_version
assert imported_lc_block.mode == lc_block.mode
assert imported_lc_block.max_count == lc_block.max_count
assert imported_lc_block.capa_type == lc_block.capa_type
assert len(imported_lc_block.children) == 4
assert imported_lc_block.children == lc_block.children
class LibraryContentBlockTestMixin(object):
@@ -175,12 +175,12 @@ class LibraryContentBlockTestMixin(object):
# Check that the LibraryContent block has no children initially
# Normally the children get added when the "source_libraries" setting
# is updated, but the way we do it through a factory doesn't do that.
self.assertEqual(len(self.lc_block.children), 0)
assert len(self.lc_block.children) == 0
# Update the LibraryContent module:
self.lc_block.refresh_children()
self.lc_block = self.store.get_item(self.lc_block.location)
# Check that all blocks from the library are now children of the block:
self.assertEqual(len(self.lc_block.children), len(self.lib_blocks))
assert len(self.lc_block.children) == len(self.lib_blocks)
def test_children_seen_by_a_user(self):
"""
@@ -190,14 +190,14 @@ class LibraryContentBlockTestMixin(object):
self.lc_block = self.store.get_item(self.lc_block.location)
self._bind_course_module(self.lc_block)
# Make sure the runtime knows that the block's children vary per-user:
self.assertTrue(self.lc_block.has_dynamic_children())
assert self.lc_block.has_dynamic_children()
self.assertEqual(len(self.lc_block.children), len(self.lib_blocks))
assert len(self.lc_block.children) == len(self.lib_blocks)
# Check how many children each user will see:
self.assertEqual(len(self.lc_block.get_child_descriptors()), 1)
assert len(self.lc_block.get_child_descriptors()) == 1
# Check that get_content_titles() doesn't return titles for hidden/unused children
self.assertEqual(len(self.lc_block.get_content_titles()), 1)
assert len(self.lc_block.get_content_titles()) == 1
def test_validation_of_course_libraries(self):
"""
@@ -207,29 +207,32 @@ class LibraryContentBlockTestMixin(object):
# When source_library_id is blank, the validation summary should say this block needs to be configured:
self.lc_block.source_library_id = ""
result = self.lc_block.validate()
self.assertFalse(result) # Validation fails due to at least one warning/message
self.assertTrue(result.summary)
self.assertEqual(StudioValidationMessage.NOT_CONFIGURED, result.summary.type)
assert not result
# Validation fails due to at least one warning/message
assert result.summary
assert StudioValidationMessage.NOT_CONFIGURED == result.summary.type
# When source_library_id references a non-existent library, we should get an error:
self.lc_block.source_library_id = "library-v1:BAD+WOLF"
result = self.lc_block.validate()
self.assertFalse(result) # Validation fails due to at least one warning/message
self.assertTrue(result.summary)
self.assertEqual(StudioValidationMessage.ERROR, result.summary.type)
self.assertIn("invalid", result.summary.text)
assert not result
# Validation fails due to at least one warning/message
assert result.summary
assert StudioValidationMessage.ERROR == result.summary.type
assert 'invalid' in result.summary.text
# When source_library_id is set but the block needs to be updated, the summary should say so:
self.lc_block.source_library_id = six.text_type(self.library.location.library_key)
result = self.lc_block.validate()
self.assertFalse(result) # Validation fails due to at least one warning/message
self.assertTrue(result.summary)
self.assertEqual(StudioValidationMessage.WARNING, result.summary.type)
self.assertIn("out of date", result.summary.text)
assert not result
# Validation fails due to at least one warning/message
assert result.summary
assert StudioValidationMessage.WARNING == result.summary.type
assert 'out of date' in result.summary.text
# Now if we update the block, all validation should pass:
self.lc_block.refresh_children()
self.assertTrue(self.lc_block.validate())
assert self.lc_block.validate()
def test_validation_of_matching_blocks(self):
"""
@@ -241,76 +244,80 @@ class LibraryContentBlockTestMixin(object):
# In the normal studio editing process, editor_saved() calls refresh_children at this point
self.lc_block.refresh_children()
result = self.lc_block.validate()
self.assertFalse(result) # Validation fails due to at least one warning/message
self.assertTrue(result.summary)
self.assertEqual(StudioValidationMessage.WARNING, result.summary.type)
self.assertIn("only 4 matching problems", result.summary.text)
assert not result
# Validation fails due to at least one warning/message
assert result.summary
assert StudioValidationMessage.WARNING == result.summary.type
assert 'only 4 matching problems' in result.summary.text
# Add some capa problems so we can check problem type validation messages
self.lc_block.max_count = 1
self._create_capa_problems()
self.lc_block.refresh_children()
self.assertTrue(self.lc_block.validate())
assert self.lc_block.validate()
# Existing problem type should pass validation
self.lc_block.max_count = 1
self.lc_block.capa_type = 'multiplechoiceresponse'
self.lc_block.refresh_children()
self.assertTrue(self.lc_block.validate())
assert self.lc_block.validate()
# ... unless requested more blocks than exists in library
self.lc_block.max_count = 10
self.lc_block.capa_type = 'multiplechoiceresponse'
self.lc_block.refresh_children()
result = self.lc_block.validate()
self.assertFalse(result) # Validation fails due to at least one warning/message
self.assertTrue(result.summary)
self.assertEqual(StudioValidationMessage.WARNING, result.summary.type)
self.assertIn("only 1 matching problem", result.summary.text)
assert not result
# Validation fails due to at least one warning/message
assert result.summary
assert StudioValidationMessage.WARNING == result.summary.type
assert 'only 1 matching problem' in result.summary.text
# Missing problem type should always fail validation
self.lc_block.max_count = 1
self.lc_block.capa_type = 'customresponse'
self.lc_block.refresh_children()
result = self.lc_block.validate()
self.assertFalse(result) # Validation fails due to at least one warning/message
self.assertTrue(result.summary)
self.assertEqual(StudioValidationMessage.WARNING, result.summary.type)
self.assertIn("no matching problem types", result.summary.text)
assert not result
# Validation fails due to at least one warning/message
assert result.summary
assert StudioValidationMessage.WARNING == result.summary.type
assert 'no matching problem types' in result.summary.text
def test_capa_type_filtering(self):
"""
Test that the capa type filter is actually filtering children
"""
self._create_capa_problems()
self.assertEqual(len(self.lc_block.children), 0) # precondition check
assert len(self.lc_block.children) == 0
# precondition check
self.lc_block.capa_type = "multiplechoiceresponse"
self.lc_block.refresh_children()
self.assertEqual(len(self.lc_block.children), 1)
assert len(self.lc_block.children) == 1
self.lc_block.capa_type = "optionresponse"
self.lc_block.refresh_children()
self.assertEqual(len(self.lc_block.children), 3)
assert len(self.lc_block.children) == 3
self.lc_block.capa_type = "coderesponse"
self.lc_block.refresh_children()
self.assertEqual(len(self.lc_block.children), 2)
assert len(self.lc_block.children) == 2
self.lc_block.capa_type = "customresponse"
self.lc_block.refresh_children()
self.assertEqual(len(self.lc_block.children), 0)
assert len(self.lc_block.children) == 0
self.lc_block.capa_type = ANY_CAPA_TYPE_VALUE
self.lc_block.refresh_children()
self.assertEqual(len(self.lc_block.children), len(self.lib_blocks) + 4)
assert len(self.lc_block.children) == (len(self.lib_blocks) + 4)
def test_non_editable_settings(self):
"""
Test the settings that are marked as "non-editable".
"""
non_editable_metadata_fields = self.lc_block.non_editable_metadata_fields
self.assertIn(LibraryContentBlock.mode, non_editable_metadata_fields)
self.assertNotIn(LibraryContentBlock.display_name, non_editable_metadata_fields)
assert LibraryContentBlock.mode in non_editable_metadata_fields
assert LibraryContentBlock.display_name not in non_editable_metadata_fields
def test_overlimit_blocks_chosen_randomly(self):
"""
@@ -342,7 +349,7 @@ class LibraryContentBlockTestMixin(object):
"""
self.lc_block.max_count = count
selected = self.lc_block.get_child_descriptors()
self.assertEqual(len(selected), count)
assert len(selected) == count
return selected
@@ -396,20 +403,22 @@ class TestLibraryContentRender(LibraryContentTest):
""" Test preview view rendering """
self.lc_block.refresh_children()
self.lc_block = self.store.get_item(self.lc_block.location)
self.assertEqual(len(self.lc_block.children), len(self.lib_blocks))
assert len(self.lc_block.children) == len(self.lib_blocks)
self._bind_course_module(self.lc_block)
rendered = self.lc_block.render(AUTHOR_VIEW, {'root_xblock': self.lc_block})
self.assertIn("Hello world from block 1", rendered.content)
assert 'Hello world from block 1' in rendered.content
def test_author_view(self):
""" Test author view rendering """
self.lc_block.refresh_children()
self.lc_block = self.store.get_item(self.lc_block.location)
self.assertEqual(len(self.lc_block.children), len(self.lib_blocks))
assert len(self.lc_block.children) == len(self.lib_blocks)
self._bind_course_module(self.lc_block)
rendered = self.lc_block.render(AUTHOR_VIEW, {})
self.assertEqual("", rendered.content) # content should be empty
self.assertEqual("LibraryContentAuthorView", rendered.js_init_fn) # but some js initialization should happen
assert '' == rendered.content
# content should be empty
assert 'LibraryContentAuthorView' == rendered.js_init_fn
# but some js initialization should happen
class TestLibraryContentAnalytics(LibraryContentTest):
@@ -429,11 +438,11 @@ class TestLibraryContentAnalytics(LibraryContentTest):
"""
Check that a LibraryContentBlock analytics event was published by self.lc_block.
"""
self.assertTrue(self.publisher.called)
self.assertTrue(len(self.publisher.call_args[0]), 3) # pylint:disable=unsubscriptable-object
assert self.publisher.called
assert len(self.publisher.call_args[0]) == 3 # pylint:disable=unsubscriptable-object
_, event_name, event_data = self.publisher.call_args[0] # pylint:disable=unsubscriptable-object
self.assertEqual(event_name, "edx.librarycontentblock.content.{}".format(event_type))
self.assertEqual(event_data["location"], six.text_type(self.lc_block.location))
assert event_name == 'edx.librarycontentblock.content.{}'.format(event_type)
assert event_data['location'] == six.text_type(self.lc_block.location)
return event_data
def test_assigned_event(self):
@@ -443,7 +452,7 @@ class TestLibraryContentAnalytics(LibraryContentTest):
# In the beginning was the lc_block and it assigned one child to the student:
child = self.lc_block.get_child_descriptors()[0]
child_lib_location, child_lib_version = self.store.get_block_original_usage(child.location)
self.assertIsInstance(child_lib_version, ObjectId)
assert isinstance(child_lib_version, ObjectId)
event_data = self._assert_event_was_published("assigned")
block_info = {
"usage_key": six.text_type(child.location),
@@ -451,25 +460,23 @@ class TestLibraryContentAnalytics(LibraryContentTest):
"original_usage_version": six.text_type(child_lib_version),
"descendants": [],
}
self.assertEqual(event_data, {
"location": six.text_type(self.lc_block.location),
"added": [block_info],
"result": [block_info],
"previous_count": 0,
"max_count": 1,
})
assert event_data ==\
{'location': six.text_type(self.lc_block.location),
'added': [block_info],
'result': [block_info],
'previous_count': 0, 'max_count': 1}
self.publisher.reset_mock()
# Now increase max_count so that one more child will be added:
self.lc_block.max_count = 2
children = self.lc_block.get_child_descriptors()
self.assertEqual(len(children), 2)
assert len(children) == 2
child, new_child = children if children[0].location == child.location else reversed(children)
event_data = self._assert_event_was_published("assigned")
self.assertEqual(event_data["added"][0]["usage_key"], six.text_type(new_child.location))
self.assertEqual(len(event_data["result"]), 2)
self.assertEqual(event_data["previous_count"], 1)
self.assertEqual(event_data["max_count"], 2)
assert event_data['added'][0]['usage_key'] == six.text_type(new_child.location)
assert len(event_data['result']) == 2
assert event_data['previous_count'] == 1
assert event_data['max_count'] == 2
def test_assigned_event_published(self):
"""
@@ -512,8 +519,9 @@ class TestLibraryContentAnalytics(LibraryContentTest):
event_data = self._assert_event_was_published("assigned")
for block_list in (event_data["added"], event_data["result"]):
self.assertEqual(len(block_list), 1) # main_vertical is the only root block added, and is the only result.
self.assertEqual(block_list[0]["usage_key"], six.text_type(course_usage_main_vertical))
assert len(block_list) == 1
# main_vertical is the only root block added, and is the only result.
assert block_list[0]['usage_key'] == six.text_type(course_usage_main_vertical)
# Check that "descendants" is a flat, unordered list of all of main_vertical's descendants:
descendants_expected = (
@@ -528,9 +536,9 @@ class TestLibraryContentAnalytics(LibraryContentTest):
"original_usage_key": six.text_type(lib_key),
"original_usage_version": six.text_type(self.store.get_block_original_usage(course_usage_key)[1]),
}
self.assertEqual(len(block_list[0]["descendants"]), len(descendant_data_expected))
assert len(block_list[0]['descendants']) == len(descendant_data_expected)
for descendant in block_list[0]["descendants"]:
self.assertEqual(descendant, descendant_data_expected.get(descendant["usage_key"]))
assert descendant == descendant_data_expected.get(descendant['usage_key'])
def test_removed_overlimit(self):
"""
@@ -544,11 +552,11 @@ class TestLibraryContentAnalytics(LibraryContentTest):
# Check that the event says that one block was removed, leaving no blocks left:
children = self.lc_block.get_child_descriptors()
self.assertEqual(len(children), 0)
assert len(children) == 0
event_data = self._assert_event_was_published("removed")
self.assertEqual(len(event_data["removed"]), 1)
self.assertEqual(event_data["result"], [])
self.assertEqual(event_data["reason"], "overlimit")
assert len(event_data['removed']) == 1
assert event_data['result'] == []
assert event_data['reason'] == 'overlimit'
def test_removed_invalid(self):
"""
@@ -559,14 +567,14 @@ class TestLibraryContentAnalytics(LibraryContentTest):
self.lc_block.get_child_descriptors() # This line is needed in the test environment or the change has no effect
self.lc_block.max_count = 2
initial_blocks_assigned = self.lc_block.get_child_descriptors()
self.assertEqual(len(initial_blocks_assigned), 2)
assert len(initial_blocks_assigned) == 2
self.publisher.reset_mock() # Clear the "assigned" event that was just published.
# Now make sure that one of the assigned blocks will have to be un-assigned.
# To cause an "invalid" event, we delete all blocks from the content library
# except for one of the two already assigned to the student:
keep_block_key = initial_blocks_assigned[0].location
keep_block_lib_usage_key, keep_block_lib_version = self.store.get_block_original_usage(keep_block_key)
self.assertIsNotNone(keep_block_lib_usage_key)
assert keep_block_lib_usage_key is not None
deleted_block_key = initial_blocks_assigned[1].location
self.library.children = [keep_block_lib_usage_key]
self.store.update_item(self.library, self.user_id)
@@ -574,19 +582,15 @@ class TestLibraryContentAnalytics(LibraryContentTest):
# Check that the event says that one block was removed, leaving one block left:
children = self.lc_block.get_child_descriptors()
self.assertEqual(len(children), 1)
assert len(children) == 1
event_data = self._assert_event_was_published("removed")
self.assertEqual(event_data["removed"], [{
"usage_key": six.text_type(deleted_block_key),
"original_usage_key": None, # Note: original_usage_key info is sadly unavailable because the block has been
# deleted so that info can no longer be retrieved
"original_usage_version": None,
"descendants": [],
}])
self.assertEqual(event_data["result"], [{
"usage_key": six.text_type(keep_block_key),
"original_usage_key": six.text_type(keep_block_lib_usage_key),
"original_usage_version": six.text_type(keep_block_lib_version),
"descendants": [],
}])
self.assertEqual(event_data["reason"], "invalid")
assert event_data['removed'] ==\
[{'usage_key': six.text_type(deleted_block_key),
'original_usage_key': None,
'original_usage_version': None,
'descendants': []}]
assert event_data['result'] ==\
[{'usage_key': six.text_type(keep_block_key),
'original_usage_key': six.text_type(keep_block_lib_usage_key),
'original_usage_version': six.text_type(keep_block_lib_version), 'descendants': []}]
assert event_data['reason'] == 'invalid'

View File

@@ -51,7 +51,7 @@ class TestLibraryRoot(MixedSplitTestCase):
# Patch the HTML block to always render "Hello world"
result = library.render(AUTHOR_VIEW, context)
self.assertIn(message, result.content)
assert message in result.content
def test_library_author_view_with_paging(self):
"""
@@ -81,7 +81,7 @@ class TestLibraryRoot(MixedSplitTestCase):
result = library.render(AUTHOR_VIEW, context)
for expected_block in expected_blocks:
self.assertIn(expected_block.data, result.content)
assert expected_block.data in result.content
render_and_check_contents(0, 3)
render_and_check_contents(1, 3)

View File

@@ -47,8 +47,8 @@ class LibrarySourcedBlockTestCase(ContentLibrariesRestApiTest):
# Check if student_view renders the children correctly
res = self.get_block_view(self.source_block, STUDENT_VIEW)
self.assertIn('Student Preview Test 1', res)
self.assertIn('Student Preview Test 2', res)
assert 'Student Preview Test 1' in res
assert 'Student Preview Test 2' in res
def test_block_limits(self):
# Create a blockstore content library
@@ -59,8 +59,8 @@ class LibrarySourcedBlockTestCase(ContentLibrariesRestApiTest):
# Import the html blocks from the library to the course
post_data = {"values": {"source_block_ids": blocks}, "defaults": ["display_name"]}
res = self.client.post(self.submit_url, data=post_data, format='json')
self.assertEqual(res.status_code, 400)
self.assertEqual(res.json()['error']['messages'][0]['text'], "A maximum of 10 components may be added.")
assert res.status_code == 400
assert res.json()['error']['messages'][0]['text'] == 'A maximum of 10 components may be added.'
def get_block_view(self, block, view, context=None):
"""

View File

@@ -28,8 +28,8 @@ class LibraryToolsServiceTest(MixedSplitTestCase):
"""
_ = LibraryFactory.create(modulestore=self.store)
all_libraries = self.tools.list_available_libraries()
self.assertTrue(all_libraries)
self.assertEqual(len(all_libraries), 1)
assert all_libraries
assert len(all_libraries) == 1
@patch('xmodule.modulestore.split_mongo.split.SplitMongoModuleStore.get_library_summaries')
def test_list_available_libraries_fetch(self, mock_get_library_summaries):
@@ -37,7 +37,7 @@ class LibraryToolsServiceTest(MixedSplitTestCase):
Test that library list is compiled using light weight library summary objects.
"""
_ = self.tools.list_available_libraries()
self.assertTrue(mock_get_library_summaries.called)
assert mock_get_library_summaries.called
class ContentLibraryToolsTest(MixedSplitTestCase, ContentLibrariesRestApiTest):
@@ -69,28 +69,28 @@ class ContentLibraryToolsTest(MixedSplitTestCase, ContentLibrariesRestApiTest):
self.tools.import_from_blockstore(sourced_block, [unit_block_id])
# Verify imported block with its children
self.assertEqual(len(sourced_block.children), 1)
self.assertEqual(sourced_block.children[0].category, 'unit')
assert len(sourced_block.children) == 1
assert sourced_block.children[0].category == 'unit'
imported_unit_block = self.store.get_item(sourced_block.children[0])
self.assertEqual(len(imported_unit_block.children), 1)
self.assertEqual(imported_unit_block.children[0].category, 'html')
assert len(imported_unit_block.children) == 1
assert imported_unit_block.children[0].category == 'html'
imported_html_block = self.store.get_item(imported_unit_block.children[0])
self.assertIn('Hello world', imported_html_block.data)
assert 'Hello world' in imported_html_block.data
# Check that assets were imported and static paths were modified after importing
assets = library_api.get_library_block_static_asset_files(html_block.scope_ids.usage_id)
self.assertEqual(len(assets), 1)
self.assertIn(assets[0].url, imported_html_block.data)
assert len(assets) == 1
assert assets[0].url in imported_html_block.data
# Check that reimporting updates the target block
self._set_library_block_olx(html_block_id, '<html><a href="/static/test.txt">Foo bar</a></html>')
self.tools.import_from_blockstore(sourced_block, [unit_block_id])
self.assertEqual(len(sourced_block.children), 1)
assert len(sourced_block.children) == 1
imported_unit_block = self.store.get_item(sourced_block.children[0])
self.assertEqual(len(imported_unit_block.children), 1)
assert len(imported_unit_block.children) == 1
imported_html_block = self.store.get_item(imported_unit_block.children[0])
self.assertNotIn('Hello world', imported_html_block.data)
self.assertIn('Foo bar', imported_html_block.data)
assert 'Hello world' not in imported_html_block.data
assert 'Foo bar' in imported_html_block.data

View File

@@ -49,10 +49,7 @@ class LTI20RESTResultServiceTest(unittest.TestCase):
)
for case in test_cases:
self.xmodule.score_comment = case[0]
self.assertEqual(
case[1],
self.xmodule.get_context()['comment']
)
assert case[1] == self.xmodule.get_context()['comment']
def test_lti20_rest_bad_contenttype(self):
"""
@@ -81,7 +78,7 @@ class LTI20RESTResultServiceTest(unittest.TestCase):
request = Mock(headers={u'Content-Type': u'application/vnd.ims.lis.v2.result+json'})
self.xmodule.verify_lti_2_0_result_rest_headers(request)
# We just want the above call to complete without exceptions, and to have called verify_oauth_body_sign
self.assertTrue(self.xmodule.verify_oauth_body_sign.called)
assert self.xmodule.verify_oauth_body_sign.called
BAD_DISPATCH_INPUTS = [
None,
@@ -115,7 +112,7 @@ class LTI20RESTResultServiceTest(unittest.TestCase):
fit the form user/<anon_id>
"""
for ginput, expected in self.GOOD_DISPATCH_INPUTS:
self.assertEqual(self.xmodule.parse_lti_2_0_handler_suffix(ginput), expected)
assert self.xmodule.parse_lti_2_0_handler_suffix(ginput) == expected
BAD_JSON_INPUTS = [
# (bad inputs, error message expected)
@@ -188,8 +185,8 @@ class LTI20RESTResultServiceTest(unittest.TestCase):
"""
for json_str, expected_comment in self.GOOD_JSON_INPUTS:
score, comment = self.xmodule.parse_lti_2_0_result_json(json_str)
self.assertEqual(score, 0.1)
self.assertEqual(comment, expected_comment)
assert score == 0.1
assert comment == expected_comment
GOOD_JSON_PUT = textwrap.dedent(u"""
{"@type": "Result",
@@ -253,15 +250,13 @@ class LTI20RESTResultServiceTest(unittest.TestCase):
# Now call the handler
response = self.xmodule.lti_2_0_result_rest_handler(mock_request, u"user/abcd")
# Now assert there's no score
self.assertEqual(response.status_code, 200)
self.assertIsNone(self.xmodule.module_score)
self.assertEqual(self.xmodule.score_comment, u"")
(_, evt_type, called_grade_obj), _ = self.system.publish.call_args # lint-amnesty, pylint: disable=unpacking-non-sequence
self.assertEqual(
called_grade_obj,
{'user_id': self.USER_STANDIN.id, 'value': None, 'max_value': None, 'score_deleted': True},
)
self.assertEqual(evt_type, 'grade')
assert response.status_code == 200
assert self.xmodule.module_score is None
assert self.xmodule.score_comment == u''
(_, evt_type, called_grade_obj), _ = self.system.publish.call_args # pylint: disable=unpacking-non-sequence
assert called_grade_obj ==\
{'user_id': self.USER_STANDIN.id, 'value': None, 'max_value': None, 'score_deleted': True}
assert evt_type == 'grade'
def test_lti20_delete_success(self):
"""
@@ -276,15 +271,13 @@ class LTI20RESTResultServiceTest(unittest.TestCase):
# Now call the handler
response = self.xmodule.lti_2_0_result_rest_handler(mock_request, u"user/abcd")
# Now assert there's no score
self.assertEqual(response.status_code, 200)
self.assertIsNone(self.xmodule.module_score)
self.assertEqual(self.xmodule.score_comment, u"")
(_, evt_type, called_grade_obj), _ = self.system.publish.call_args # lint-amnesty, pylint: disable=unpacking-non-sequence
self.assertEqual(
called_grade_obj,
{'user_id': self.USER_STANDIN.id, 'value': None, 'max_value': None, 'score_deleted': True},
)
self.assertEqual(evt_type, 'grade')
assert response.status_code == 200
assert self.xmodule.module_score is None
assert self.xmodule.score_comment == u''
(_, evt_type, called_grade_obj), _ = self.system.publish.call_args # pylint: disable=unpacking-non-sequence
assert called_grade_obj ==\
{'user_id': self.USER_STANDIN.id, 'value': None, 'max_value': None, 'score_deleted': True}
assert evt_type == 'grade'
def test_lti20_put_set_score_success(self):
"""
@@ -295,15 +288,13 @@ class LTI20RESTResultServiceTest(unittest.TestCase):
# Now call the handler
response = self.xmodule.lti_2_0_result_rest_handler(mock_request, u"user/abcd")
# Now assert
self.assertEqual(response.status_code, 200)
self.assertEqual(self.xmodule.module_score, 0.1)
self.assertEqual(self.xmodule.score_comment, u"ಠ益ಠ")
(_, evt_type, called_grade_obj), _ = self.system.publish.call_args # lint-amnesty, pylint: disable=unpacking-non-sequence
self.assertEqual(evt_type, 'grade')
self.assertEqual(
called_grade_obj,
{'user_id': self.USER_STANDIN.id, 'value': 0.1, 'max_value': 1.0, 'score_deleted': False},
)
assert response.status_code == 200
assert self.xmodule.module_score == 0.1
assert self.xmodule.score_comment == u'ಠ益ಠ'
(_, evt_type, called_grade_obj), _ = self.system.publish.call_args # pylint: disable=unpacking-non-sequence
assert evt_type == 'grade'
assert called_grade_obj ==\
{'user_id': self.USER_STANDIN.id, 'value': 0.1, 'max_value': 1.0, 'score_deleted': False}
def test_lti20_get_no_score_success(self):
"""
@@ -314,9 +305,8 @@ class LTI20RESTResultServiceTest(unittest.TestCase):
# Now call the handler
response = self.xmodule.lti_2_0_result_rest_handler(mock_request, u"user/abcd")
# Now assert
self.assertEqual(response.status_code, 200)
self.assertEqual(response.json, {"@context": "http://purl.imsglobal.org/ctx/lis/v2/Result",
"@type": "Result"})
assert response.status_code == 200
assert response.json == {'@context': 'http://purl.imsglobal.org/ctx/lis/v2/Result', '@type': 'Result'}
def test_lti20_get_with_score_success(self):
"""
@@ -331,11 +321,10 @@ class LTI20RESTResultServiceTest(unittest.TestCase):
# Now call the handler
response = self.xmodule.lti_2_0_result_rest_handler(mock_request, u"user/abcd")
# Now assert
self.assertEqual(response.status_code, 200)
self.assertEqual(response.json, {"@context": "http://purl.imsglobal.org/ctx/lis/v2/Result",
"@type": "Result",
"resultScore": SCORE,
"comment": COMMENT})
assert response.status_code == 200
assert response.json ==\
{'@context': 'http://purl.imsglobal.org/ctx/lis/v2/Result',
'@type': 'Result', 'resultScore': SCORE, 'comment': COMMENT}
UNSUPPORTED_HTTP_METHODS = ["OPTIONS", "HEAD", "POST", "TRACE", "CONNECT"]
@@ -348,7 +337,7 @@ class LTI20RESTResultServiceTest(unittest.TestCase):
for bad_method in self.UNSUPPORTED_HTTP_METHODS:
mock_request.method = bad_method
response = self.xmodule.lti_2_0_result_rest_handler(mock_request, u"user/abcd")
self.assertEqual(response.status_code, 404)
assert response.status_code == 404
def test_lti20_request_handler_bad_headers(self):
"""
@@ -358,7 +347,7 @@ class LTI20RESTResultServiceTest(unittest.TestCase):
self.xmodule.verify_lti_2_0_result_rest_headers = Mock(side_effect=LTIError())
mock_request = self.get_signed_lti20_mock_request(self.GOOD_JSON_PUT)
response = self.xmodule.lti_2_0_result_rest_handler(mock_request, u"user/abcd")
self.assertEqual(response.status_code, 401)
assert response.status_code == 401
def test_lti20_request_handler_bad_dispatch_user(self):
"""
@@ -367,7 +356,7 @@ class LTI20RESTResultServiceTest(unittest.TestCase):
self.setup_system_xmodule_mocks_for_lti20_request_test()
mock_request = self.get_signed_lti20_mock_request(self.GOOD_JSON_PUT)
response = self.xmodule.lti_2_0_result_rest_handler(mock_request, None)
self.assertEqual(response.status_code, 404)
assert response.status_code == 404
def test_lti20_request_handler_bad_json(self):
"""
@@ -377,7 +366,7 @@ class LTI20RESTResultServiceTest(unittest.TestCase):
self.xmodule.parse_lti_2_0_result_json = Mock(side_effect=LTIError())
mock_request = self.get_signed_lti20_mock_request(self.GOOD_JSON_PUT)
response = self.xmodule.lti_2_0_result_rest_handler(mock_request, u"user/abcd")
self.assertEqual(response.status_code, 404)
assert response.status_code == 404
def test_lti20_request_handler_bad_user(self):
"""
@@ -387,7 +376,7 @@ class LTI20RESTResultServiceTest(unittest.TestCase):
self.system.get_real_user = Mock(return_value=None)
mock_request = self.get_signed_lti20_mock_request(self.GOOD_JSON_PUT)
response = self.xmodule.lti_2_0_result_rest_handler(mock_request, u"user/abcd")
self.assertEqual(response.status_code, 404)
assert response.status_code == 404
def test_lti20_request_handler_grade_past_due(self):
"""
@@ -398,4 +387,4 @@ class LTI20RESTResultServiceTest(unittest.TestCase):
self.xmodule.accept_grades_past_due = False
mock_request = self.get_signed_lti20_mock_request(self.GOOD_JSON_PUT)
response = self.xmodule.lti_2_0_result_rest_handler(mock_request, u"user/abcd")
self.assertEqual(response.status_code, 404)
assert response.status_code == 404

View File

@@ -7,6 +7,7 @@ import textwrap
import unittest
from copy import copy
import pytest
import six
from lxml import etree
from mock import Mock, PropertyMock, patch
@@ -139,7 +140,7 @@ class LTIBlockTest(unittest.TestCase):
'messageIdentifier': self.defaults['messageIdentifier'],
}
self.assertEqual(response.status_code, 200)
assert response.status_code == 200
self.assertDictEqual(expected_response, real_response)
@patch(
@@ -163,7 +164,7 @@ class LTIBlockTest(unittest.TestCase):
'description': 'OAuth verification error: Malformed authorization header',
'messageIdentifier': self.defaults['messageIdentifier'],
}
self.assertEqual(response.status_code, 200)
assert response.status_code == 200
self.assertDictEqual(expected_response, real_response)
def test_real_user_is_none(self):
@@ -183,7 +184,7 @@ class LTIBlockTest(unittest.TestCase):
'description': 'User not found.',
'messageIdentifier': self.defaults['messageIdentifier'],
}
self.assertEqual(response.status_code, 200)
assert response.status_code == 200
self.assertDictEqual(expected_response, real_response)
def test_grade_past_due(self):
@@ -203,8 +204,8 @@ class LTIBlockTest(unittest.TestCase):
'description': 'Grade is past due',
'messageIdentifier': 'unknown',
}
self.assertEqual(response.status_code, 200)
self.assertEqual(expected_response, real_response)
assert response.status_code == 200
assert expected_response == real_response
def test_grade_not_in_range(self):
"""
@@ -221,7 +222,7 @@ class LTIBlockTest(unittest.TestCase):
'description': 'Request body XML parsing error: score value outside the permitted range of 0-1.',
'messageIdentifier': 'unknown',
}
self.assertEqual(response.status_code, 200)
assert response.status_code == 200
self.assertDictEqual(expected_response, real_response)
def test_bad_grade_decimal(self):
@@ -243,7 +244,7 @@ class LTIBlockTest(unittest.TestCase):
'description': u'Request body XML parsing error: {}'.format(msg),
'messageIdentifier': 'unknown',
}
self.assertEqual(response.status_code, 200)
assert response.status_code == 200
self.assertDictEqual(expected_response, real_response)
def test_unsupported_action(self):
@@ -262,7 +263,7 @@ class LTIBlockTest(unittest.TestCase):
'description': 'Target does not support the requested operation.',
'messageIdentifier': self.defaults['messageIdentifier'],
}
self.assertEqual(response.status_code, 200)
assert response.status_code == 200
self.assertDictEqual(expected_response, real_response)
def test_good_request(self):
@@ -286,14 +287,14 @@ class LTIBlockTest(unittest.TestCase):
'messageIdentifier': self.defaults['messageIdentifier'],
}
self.assertEqual(response.status_code, 200)
assert response.status_code == 200
self.assertDictEqual(expected_response, real_response)
self.assertEqual(self.xmodule.module_score, float(self.defaults['grade']))
assert self.xmodule.module_score == float(self.defaults['grade'])
def test_user_id(self):
expected_user_id = text_type(six.moves.urllib.parse.quote(self.xmodule.runtime.anonymous_student_id))
real_user_id = self.xmodule.get_user_id()
self.assertEqual(real_user_id, expected_user_id)
assert real_user_id == expected_user_id
def test_outcome_service_url(self):
mock_url_prefix = 'https://hostname/'
@@ -305,14 +306,14 @@ class LTIBlockTest(unittest.TestCase):
self.xmodule.runtime.handler_url = Mock(side_effect=mock_handler_url)
real_outcome_service_url = self.xmodule.get_outcome_service_url(service_name=test_service_name)
self.assertEqual(real_outcome_service_url, mock_url_prefix + test_service_name)
assert real_outcome_service_url == (mock_url_prefix + test_service_name)
def test_resource_link_id(self):
with patch('xmodule.lti_module.LTIBlock.location', new_callable=PropertyMock):
self.xmodule.location.html_id = lambda: 'i4x-2-3-lti-31de800015cf4afb973356dbe81496df'
expected_resource_link_id = text_type(six.moves.urllib.parse.quote(self.unquoted_resource_link_id))
real_resource_link_id = self.xmodule.get_resource_link_id()
self.assertEqual(real_resource_link_id, expected_resource_link_id)
assert real_resource_link_id == expected_resource_link_id
def test_lis_result_sourcedid(self):
expected_sourced_id = u':'.join(six.moves.urllib.parse.quote(i) for i in (
@@ -321,7 +322,7 @@ class LTIBlockTest(unittest.TestCase):
self.user_id
))
real_lis_result_sourcedid = self.xmodule.get_lis_result_sourcedid()
self.assertEqual(real_lis_result_sourcedid, expected_sourced_id)
assert real_lis_result_sourcedid == expected_sourced_id
def test_client_key_secret(self):
"""
@@ -336,7 +337,7 @@ class LTIBlockTest(unittest.TestCase):
self.xmodule.lti_id = "lti_id"
key, secret = self.xmodule.get_client_key_secret()
expected = ('test_client', 'test_secret')
self.assertEqual(expected, (key, secret))
assert expected == (key, secret)
def test_client_key_secret_not_provided(self):
"""
@@ -355,7 +356,7 @@ class LTIBlockTest(unittest.TestCase):
self.xmodule.lti_id = "another_lti_id"
key_secret = self.xmodule.get_client_key_secret()
expected = ('', '')
self.assertEqual(expected, key_secret)
assert expected == key_secret
def test_bad_client_key_secret(self):
"""
@@ -370,7 +371,7 @@ class LTIBlockTest(unittest.TestCase):
runtime = Mock(modulestore=modulestore)
self.xmodule.runtime = runtime
self.xmodule.lti_id = 'lti_id'
with self.assertRaises(LTIError):
with pytest.raises(LTIError):
self.xmodule.get_client_key_secret()
@patch('xmodule.lti_module.signature.verify_hmac_sha1', Mock(return_value=True))
@@ -438,7 +439,7 @@ class LTIBlockTest(unittest.TestCase):
Tests that tool provider returned grade back with wrong XML Namespace.
"""
with self.assertRaises(IndexError):
with pytest.raises(IndexError):
mocked_request = self.get_signed_grade_mock_request(namespace_lti_v1p1=False)
self.xmodule.parse_grade_xml_body(mocked_request.body)
@@ -450,10 +451,10 @@ class LTIBlockTest(unittest.TestCase):
"""
mocked_request = self.get_signed_grade_mock_request()
message_identifier, sourced_id, grade, action = self.xmodule.parse_grade_xml_body(mocked_request.body)
self.assertEqual(self.defaults['messageIdentifier'], message_identifier)
self.assertEqual(self.defaults['sourcedId'], sourced_id)
self.assertEqual(self.defaults['grade'], grade)
self.assertEqual(self.defaults['action'], action)
assert self.defaults['messageIdentifier'] == message_identifier
assert self.defaults['sourcedId'] == sourced_id
assert self.defaults['grade'] == grade
assert self.defaults['action'] == action
@patch('xmodule.lti_module.signature.verify_hmac_sha1', Mock(return_value=False))
@patch(
@@ -464,7 +465,7 @@ class LTIBlockTest(unittest.TestCase):
"""
Oauth signing verify fail.
"""
with self.assertRaises(LTIError):
with pytest.raises(LTIError):
req = self.get_signed_grade_mock_request()
self.xmodule.verify_oauth_body_sign(req)
@@ -519,21 +520,21 @@ class LTIBlockTest(unittest.TestCase):
self.xmodule.custom_parameters = bad_custom_params
self.xmodule.get_client_key_secret = Mock(return_value=('test_client_key', 'test_client_secret'))
self.xmodule.oauth_params = Mock()
with self.assertRaises(LTIError):
with pytest.raises(LTIError):
self.xmodule.get_input_fields()
def test_max_score(self):
self.xmodule.weight = 100.0
self.assertFalse(self.xmodule.has_score)
self.assertEqual(self.xmodule.max_score(), None)
assert not self.xmodule.has_score
assert self.xmodule.max_score() is None
self.xmodule.has_score = True
self.assertEqual(self.xmodule.max_score(), 100.0)
assert self.xmodule.max_score() == 100.0
def test_context_id(self):
"""
Tests that LTI parameter context_id is equal to course_id.
"""
self.assertEqual(text_type(self.system.course_id), self.xmodule.context_id)
assert text_type(self.system.course_id) == self.xmodule.context_id

View File

@@ -2,7 +2,7 @@
from unittest import TestCase
import pytest
from mock import Mock
from xmodule.mako_module import MakoModuleDescriptor
@@ -15,10 +15,10 @@ class MakoModuleTest(TestCase):
mock_system = Mock()
mock_system.render_template = None
with self.assertRaises(TypeError):
with pytest.raises(TypeError):
MakoModuleDescriptor(mock_system, {})
del mock_system.render_template
with self.assertRaises(TypeError):
with pytest.raises(TypeError):
MakoModuleDescriptor(mock_system, {})

View File

@@ -33,7 +33,7 @@ class MongoUtilsTests(TestCase):
db = 'test_read_preference_%s' % uuid4().hex
# Support for read_preference given in constant name form (ie. PRIMARY, SECONDARY_PREFERRED)
connection = connect_to_mongodb(db, host, read_preference=enum_name)
self.assertEqual(connection.client.read_preference, expected_read_preference)
assert connection.client.read_preference == expected_read_preference
# Support for read_preference given as mongos name.
connection = connect_to_mongodb(db, host, read_preference=mongos_name)
self.assertEqual(connection.client.read_preference, expected_read_preference)
assert connection.client.read_preference == expected_read_preference

View File

@@ -33,9 +33,9 @@ class PollModuleTest(LogicTest):
callback = response['callback']
self.assertDictEqual(poll_answers, {'Yes': 1, 'Dont_know': 0, 'No': 1})
self.assertEqual(total, 2)
assert total == 2
self.assertDictEqual(callback, {'objectName': 'Conditional'})
self.assertEqual(self.xmodule.poll_answer, 'No')
assert self.xmodule.poll_answer == 'No'
def test_poll_export_with_unescaped_characters_xml(self):
"""
@@ -64,4 +64,4 @@ class PollModuleTest(LogicTest):
# Extract texts of all children.
child_texts = xml.xpath('//text()')
# Last index of child_texts contains text of answer tag.
self.assertEqual(child_texts[-1], '< 18')
assert child_texts[(- 1)] == '< 18'

View File

@@ -41,50 +41,50 @@ class ProgressTest(unittest.TestCase):
self.assertRaises(TypeError, Progress, 2j, 3)
def test_clamp(self):
self.assertEqual((2, 2), Progress(3, 2).frac())
self.assertEqual((0, 2), Progress(-2, 2).frac())
assert (2, 2) == Progress(3, 2).frac()
assert (0, 2) == Progress((- 2), 2).frac()
def test_frac(self):
prg = Progress(1, 2)
(a_mem, b_mem) = prg.frac()
self.assertEqual(a_mem, 1)
self.assertEqual(b_mem, 2)
assert a_mem == 1
assert b_mem == 2
def test_percent(self):
self.assertEqual(self.not_started.percent(), 0)
self.assertAlmostEqual(self.part_done.percent(), 33.33333333333333)
self.assertEqual(self.half_done.percent(), 50)
self.assertEqual(self.done.percent(), 100)
assert self.not_started.percent() == 0
assert round(self.part_done.percent() - 33.33333333333333, 7) >= 0
assert self.half_done.percent() == 50
assert self.done.percent() == 100
self.assertEqual(self.half_done.percent(), self.also_half_done.percent())
assert self.half_done.percent() == self.also_half_done.percent()
def test_started(self):
self.assertFalse(self.not_started.started())
assert not self.not_started.started()
self.assertTrue(self.part_done.started())
self.assertTrue(self.half_done.started())
self.assertTrue(self.done.started())
assert self.part_done.started()
assert self.half_done.started()
assert self.done.started()
def test_inprogress(self):
# only true if working on it
self.assertFalse(self.done.inprogress())
self.assertFalse(self.not_started.inprogress())
assert not self.done.inprogress()
assert not self.not_started.inprogress()
self.assertTrue(self.part_done.inprogress())
self.assertTrue(self.half_done.inprogress())
assert self.part_done.inprogress()
assert self.half_done.inprogress()
def test_done(self):
self.assertTrue(self.done.done())
self.assertFalse(self.half_done.done())
self.assertFalse(self.not_started.done())
assert self.done.done()
assert not self.half_done.done()
assert not self.not_started.done()
def test_str(self):
self.assertEqual(str(self.not_started), "0/17")
self.assertEqual(str(self.part_done), "2/6")
self.assertEqual(str(self.done), "7/7")
self.assertEqual(str(Progress(2.1234, 7)), '2.12/7')
self.assertEqual(str(Progress(2.0034, 7)), '2/7')
self.assertEqual(str(Progress(0.999, 7)), '1/7')
assert str(self.not_started) == '0/17'
assert str(self.part_done) == '2/6'
assert str(self.done) == '7/7'
assert str(Progress(2.1234, 7)) == '2.12/7'
assert str(Progress(2.0034, 7)) == '2/7'
assert str(Progress(0.999, 7)) == '1/7'
def test_add(self):
'''Test the Progress.add_counts() method'''
@@ -94,12 +94,12 @@ class ProgressTest(unittest.TestCase):
prg_none = None
add = lambda a, b: Progress.add_counts(a, b).frac()
self.assertEqual(add(prg1, prg1), (0, 4))
self.assertEqual(add(prg1, prg2), (1, 5))
self.assertEqual(add(prg2, prg3), (3, 8))
assert add(prg1, prg1) == (0, 4)
assert add(prg1, prg2) == (1, 5)
assert add(prg2, prg3) == (3, 8)
self.assertEqual(add(prg2, prg_none), prg2.frac())
self.assertEqual(add(prg_none, prg2), prg2.frac())
assert add(prg2, prg_none) == prg2.frac()
assert add(prg_none, prg2) == prg2.frac()
def test_equality(self):
'''Test that comparing Progress objects for equality
@@ -107,12 +107,12 @@ class ProgressTest(unittest.TestCase):
prg1 = Progress(1, 2)
prg2 = Progress(2, 4)
prg3 = Progress(1, 2)
self.assertEqual(prg1, prg3)
self.assertNotEqual(prg1, prg2)
assert prg1 == prg3
assert prg1 != prg2
# Check != while we're at it
self.assertNotEqual(prg1, prg2)
self.assertEqual(prg1, prg3)
assert prg1 != prg2
assert prg1 == prg3
class ModuleProgressTest(unittest.TestCase):
@@ -123,4 +123,4 @@ class ModuleProgressTest(unittest.TestCase):
'''Make sure default get_progress exists, returns None'''
xmod = x_module.XModule(Mock(), get_test_system(), DictFieldData({'location': 'a://b/c/d/e'}), Mock())
prg = xmod.get_progress() # lint-amnesty, pylint: disable=assignment-from-none
self.assertEqual(prg, None)
assert prg is None

View File

@@ -78,7 +78,7 @@ class RandomizeBlockTest(MixedSplitTestCase):
exported_olx = f.read()
# And compare.
self.assertEqual(exported_olx, expected_olx)
assert exported_olx == expected_olx
runtime = TestImportSystem(load_error_modules=True, course_id=randomize_block.location.course_key)
runtime.resources_fs = export_fs
@@ -89,9 +89,9 @@ class RandomizeBlockTest(MixedSplitTestCase):
imported_randomize_block = RandomizeBlock.parse_xml(olx_element, runtime, None, id_generator)
# Check the new XBlock has the same properties as the old one.
self.assertEqual(imported_randomize_block.display_name, randomize_block.display_name)
self.assertEqual(len(imported_randomize_block.children), 3)
self.assertEqual(imported_randomize_block.children, randomize_block.children)
assert imported_randomize_block.display_name == randomize_block.display_name
assert len(imported_randomize_block.children) == 3
assert imported_randomize_block.children == randomize_block.children
def test_children_seen_by_a_user(self):
"""
@@ -101,18 +101,18 @@ class RandomizeBlockTest(MixedSplitTestCase):
self._bind_module_system(randomize_block, 3)
# Make sure the runtime knows that the block's children vary per-user:
self.assertTrue(randomize_block.has_dynamic_children())
assert randomize_block.has_dynamic_children()
self.assertEqual(len(randomize_block.children), 3)
assert len(randomize_block.children) == 3
# Check how many children each user will see:
self.assertEqual(len(randomize_block.get_child_descriptors()), 1)
self.assertEqual(randomize_block.get_child_descriptors()[0].display_name, 'Hello HTML 1')
assert len(randomize_block.get_child_descriptors()) == 1
assert randomize_block.get_child_descriptors()[0].display_name == 'Hello HTML 1'
# Check that get_content_titles() doesn't return titles for hidden/unused children
# get_content_titles() is not overridden in RandomizeBlock so titles of the 3 children are returned.
self.assertEqual(len(randomize_block.get_content_titles()), 3)
assert len(randomize_block.get_content_titles()) == 3
# Bind to another user and check a different child block is displayed to user.
randomize_block = self.store.get_item(self.randomize_block.location)
self._bind_module_system(randomize_block, 1)
self.assertEqual(randomize_block.get_child_descriptors()[0].display_name, 'Hello HTML 2')
assert randomize_block.get_child_descriptors()[0].display_name == 'Hello HTML 2'

View File

@@ -20,15 +20,13 @@ class ResourceTemplatesTests(unittest.TestCase):
'announcement.yaml',
'anon_user_id.yaml'])
got = set((t['template_id'] for t in TestClass.templates()))
self.assertEqual(expected, got)
assert expected == got
def test_templates_no_suchdir(self):
self.assertEqual(len(TestClass2.templates()), 0)
assert len(TestClass2.templates()) == 0
def test_get_template(self):
self.assertEqual(
TestClass.get_template('latex_html.yaml')['template_id'],
'latex_html.yaml')
assert TestClass.get_template('latex_html.yaml')['template_id'] == 'latex_html.yaml'
class TestClass(ResourceTemplates):

View File

@@ -138,11 +138,12 @@ class SequenceBlockTestCase(XModuleXmlImportTest):
"""
Verifies that the rendered view contains the expected position.
"""
self.assertIn("'position': {}".format(expected_position), rendered_html)
assert "'position': {}".format(expected_position) in rendered_html
def test_student_view_init(self):
seq_module = SequenceModule(runtime=Mock(position=2), descriptor=Mock(), scope_ids=Mock())
self.assertEqual(seq_module.position, 2) # matches position set in the runtime
assert seq_module.position == 2
# matches position set in the runtime
@ddt.unpack
@ddt.data(
@@ -156,11 +157,11 @@ class SequenceBlockTestCase(XModuleXmlImportTest):
view=view
)
self._assert_view_at_position(html, expected_position=1)
self.assertIn(six.text_type(self.sequence_3_1.location), html)
self.assertIn("'gated': False", html)
self.assertIn("'next_url': 'NextSequential'", html)
self.assertIn("'prev_url': 'PrevSequential'", html)
self.assertNotIn("fa fa-check-circle check-circle is-hidden", html)
assert six.text_type(self.sequence_3_1.location) in html
assert "'gated': False" in html
assert "'next_url': 'NextSequential'" in html
assert "'prev_url': 'PrevSequential'" in html
assert 'fa fa-check-circle check-circle is-hidden' not in html
# pylint: disable=line-too-long
@patch('xmodule.seq_module.SequenceModule.gate_entire_sequence_if_it_is_a_timed_exam_and_contains_content_type_gated_problems')
@@ -205,11 +206,11 @@ class SequenceBlockTestCase(XModuleXmlImportTest):
extra_context=dict(next_url='NextSequential', prev_url='PrevSequential'),
view=STUDENT_VIEW
)
self.assertIn('i_am_gated', view)
assert 'i_am_gated' in view
# check a few elements to ensure the correct page was loaded
self.assertIn("seq_module.html", view)
self.assertIn('NextSequential', view)
self.assertIn('PrevSequential', view)
assert 'seq_module.html' in view
assert 'NextSequential' in view
assert 'PrevSequential' in view
@ddt.unpack
@ddt.data(
@@ -234,12 +235,12 @@ class SequenceBlockTestCase(XModuleXmlImportTest):
def test_tooltip(self):
html = self._get_rendered_view(self.sequence_3_1, requested_child=None)
for child in self.sequence_3_1.children:
self.assertIn("'page_title': '{}'".format(child.block_id), html)
assert "'page_title': '{}'".format(child.block_id) in html
def test_hidden_content_before_due(self):
html = self._get_rendered_view(self.sequence_4_1)
self.assertIn("seq_module.html", html)
self.assertIn("'banner_text': None", html)
assert 'seq_module.html' in html
assert "'banner_text': None" in html
def test_hidden_content_past_due(self):
with freeze_time(COURSE_END_DATE):
@@ -248,8 +249,8 @@ class SequenceBlockTestCase(XModuleXmlImportTest):
self.sequence_4_1,
extra_context=dict(progress_url=progress_url),
)
self.assertIn("hidden_content.html", html)
self.assertIn(progress_url, html)
assert 'hidden_content.html' in html
assert progress_url in html
def test_masquerade_hidden_content_past_due(self):
with freeze_time(COURSE_END_DATE):
@@ -257,18 +258,15 @@ class SequenceBlockTestCase(XModuleXmlImportTest):
self.sequence_4_1,
extra_context=dict(specific_masquerade=True),
)
self.assertIn("seq_module.html", html)
assert 'seq_module.html' in html
html = self.get_context_dict_from_string(html)
self.assertEqual(
'Because the due date has passed, this assignment is hidden from the learner.',
html['banner_text']
)
assert 'Because the due date has passed, this assignment is hidden from the learner.' == html['banner_text']
def test_hidden_content_self_paced_past_due_before_end(self):
with freeze_time(PAST_DUE_BEFORE_END_DATE):
html = self._get_rendered_view(self.sequence_4_1, self_paced=True)
self.assertIn("seq_module.html", html)
self.assertIn("'banner_text': None", html)
assert 'seq_module.html' in html
assert "'banner_text': None" in html
def test_hidden_content_self_paced_past_end(self):
with freeze_time(COURSE_END_DATE + timedelta(days=7)):
@@ -278,56 +276,50 @@ class SequenceBlockTestCase(XModuleXmlImportTest):
extra_context=dict(progress_url=progress_url),
self_paced=True,
)
self.assertIn("hidden_content.html", html)
self.assertIn(progress_url, html)
assert 'hidden_content.html' in html
assert progress_url in html
def _assert_gated(self, html, sequence):
"""
Assert sequence content is gated
"""
self.assertIn("seq_module.html", html)
assert 'seq_module.html' in html
html = self.get_context_dict_from_string(html)
self.assertIsNone(html['banner_text'])
self.assertEqual([], html['items'])
self.assertTrue(html['gated_content']['gated'])
self.assertEqual('PrereqUrl', html['gated_content']['prereq_url'])
self.assertEqual('PrereqSectionName', html['gated_content']['prereq_section_name'])
self.assertIn(
six.text_type(sequence.display_name),
html['gated_content']['gated_section_name']
)
self.assertEqual('NextSequential', html['next_url'])
self.assertEqual('PrevSequential', html['prev_url'])
assert html['banner_text'] is None
assert [] == html['items']
assert html['gated_content']['gated']
assert 'PrereqUrl' == html['gated_content']['prereq_url']
assert 'PrereqSectionName' == html['gated_content']['prereq_section_name']
assert six.text_type(sequence.display_name) in html['gated_content']['gated_section_name']
assert 'NextSequential' == html['next_url']
assert 'PrevSequential' == html['prev_url']
def _assert_prereq(self, html, sequence):
"""
Assert sequence is a prerequisite with unfulfilled gates
"""
self.assertIn("seq_module.html", html)
assert 'seq_module.html' in html
html = self.get_context_dict_from_string(html)
self.assertEqual(
"This section is a prerequisite. You must complete this section in order to unlock additional content.",
html['banner_text']
)
self.assertFalse(html['gated_content']['gated'])
self.assertEqual(six.text_type(sequence.location), html['item_id'])
self.assertIsNone(html['gated_content']['prereq_url'])
self.assertIsNone(html['gated_content']['prereq_section_name'])
self.assertEqual('NextSequential', html['next_url'])
self.assertEqual('PrevSequential', html['prev_url'])
assert 'This section is a prerequisite. You must complete this section in order to unlock additional content.' == html['banner_text']
assert not html['gated_content']['gated']
assert six.text_type(sequence.location) == html['item_id']
assert html['gated_content']['prereq_url'] is None
assert html['gated_content']['prereq_section_name'] is None
assert 'NextSequential' == html['next_url']
assert 'PrevSequential' == html['prev_url']
def _assert_ungated(self, html, sequence):
"""
Assert sequence is not gated
"""
self.assertIn("seq_module.html", html)
self.assertIn("'banner_text': None", html)
self.assertIn("'gated': False", html)
self.assertIn(six.text_type(sequence.location), html)
self.assertIn("'prereq_url': None", html)
self.assertIn("'prereq_section_name': None", html)
self.assertIn("'next_url': 'NextSequential'", html)
self.assertIn("'prev_url': 'PrevSequential'", html)
assert 'seq_module.html' in html
assert "'banner_text': None" in html
assert "'gated': False" in html
assert six.text_type(sequence.location) in html
assert "'prereq_url': None" in html
assert "'prereq_section_name': None" in html
assert "'next_url': 'NextSequential'" in html
assert "'prev_url': 'PrevSequential'" in html
def test_gated_content(self):
"""
@@ -389,9 +381,9 @@ class SequenceBlockTestCase(XModuleXmlImportTest):
'get_completion',
{'usage_key': usage_key}
))
self.assertIsNot(completion_return, None)
self.assertTrue('complete' in completion_return) # lint-amnesty, pylint: disable=wrong-assert-type
self.assertEqual(completion_return['complete'], True)
assert completion_return is not None
assert 'complete' in completion_return
assert completion_return['complete'] is True
def test_handle_ajax_get_completion_return_none(self):
"""
@@ -403,7 +395,7 @@ class SequenceBlockTestCase(XModuleXmlImportTest):
'get_completion',
{'usage_key': usage_key}
)
self.assertIs(completion_return, None)
assert completion_return is None
def test_handle_ajax_metadata(self):
"""
@@ -414,9 +406,9 @@ class SequenceBlockTestCase(XModuleXmlImportTest):
# let's just disable the bookmarks service
self.sequence_3_1.xmodule_runtime._services['bookmarks'] = None # lint-amnesty, pylint: disable=protected-access
metadata = json.loads(self.sequence_3_1.handle_ajax('metadata', {}))
self.assertEqual(len(metadata['items']), 3)
self.assertEqual(metadata['tag'], 'sequential')
self.assertEqual(metadata['display_name'], self.sequence_3_1.display_name_with_default)
assert len(metadata['items']) == 3
assert metadata['tag'] == 'sequential'
assert metadata['display_name'] == self.sequence_3_1.display_name_with_default
@override_settings(FIELD_OVERRIDE_PROVIDERS=(
'openedx.features.content_type_gating.field_override.ContentTypeGatingFieldOverride',
@@ -429,7 +421,7 @@ class SequenceBlockTestCase(XModuleXmlImportTest):
self.sequence_5_1.xmodule_runtime._services['bookmarks'] = None # pylint: disable=protected-access
ContentTypeGatingConfig.objects.create(enabled=True, enabled_as_of=datetime(2018, 1, 1))
metadata = json.loads(self.sequence_5_1.handle_ajax('metadata', {}))
self.assertEqual(metadata['items'][0]['contains_content_type_gated_content'], False)
assert metadata['items'][0]['contains_content_type_gated_content'] is False
# When a block contains content type gated problems, set the contains_content_type_gated_content field
self.sequence_5_1.get_children()[0].get_children()[0].graded = True
@@ -438,7 +430,7 @@ class SequenceBlockTestCase(XModuleXmlImportTest):
content_type_gate_for_block=Mock(return_value=Fragment('i_am_gated'))
))
metadata = json.loads(self.sequence_5_1.handle_ajax('metadata', {}))
self.assertEqual(metadata['items'][0]['contains_content_type_gated_content'], True)
assert metadata['items'][0]['contains_content_type_gated_content'] is True
def get_context_dict_from_string(self, data):
"""

View File

@@ -4,6 +4,7 @@ Tests for SettingsService
import unittest
import pytest
from django.test import TestCase
import ddt
@@ -57,46 +58,48 @@ class TestSettingsService(unittest.TestCase):
def test_get_given_none_throws_value_error(self):
""" Test that given None throws value error """
with self.assertRaises(ValueError):
with pytest.raises(ValueError):
self.settings_service.get_settings_bucket(None)
def test_get_return_default_if_xblock_settings_is_missing(self):
""" Test that returns default (or None if default not set) if XBLOCK_SETTINGS is not set """
self.assertFalse(hasattr(settings, 'XBLOCK_SETTINGS')) # precondition check
self.assertEqual(self.settings_service.get_settings_bucket(self.xblock_mock, 'zzz'), 'zzz')
assert not hasattr(settings, 'XBLOCK_SETTINGS')
# precondition check
assert self.settings_service.get_settings_bucket(self.xblock_mock, 'zzz') == 'zzz'
def test_get_return_empty_dictionary_if_xblock_settings_and_default_is_missing(self):
""" Test that returns default (or None if default not set) if XBLOCK_SETTINGS is not set """
self.assertFalse(hasattr(settings, 'XBLOCK_SETTINGS')) # precondition check
self.assertEqual(self.settings_service.get_settings_bucket(self.xblock_mock), {})
assert not hasattr(settings, 'XBLOCK_SETTINGS')
# precondition check
assert self.settings_service.get_settings_bucket(self.xblock_mock) == {}
@override_settings(XBLOCK_SETTINGS={xblock_setting_key2: {'b': 1}})
def test_get_returns_none_or_default_if_bucket_not_found(self):
""" Test if settings service returns default if setting not found """
self.assertEqual(settings.XBLOCK_SETTINGS, {self.xblock_setting_key2: {'b': 1}})
self.assertEqual(self.settings_service.get_settings_bucket(self.xblock_mock), {})
self.assertEqual(self.settings_service.get_settings_bucket(self.xblock_mock, 123), 123)
assert settings.XBLOCK_SETTINGS == {self.xblock_setting_key2: {'b': 1}}
assert self.settings_service.get_settings_bucket(self.xblock_mock) == {}
assert self.settings_service.get_settings_bucket(self.xblock_mock, 123) == 123
@override_settings(XBLOCK_SETTINGS={xblock_setting_key1: 42})
def test_get_returns_correct_value(self):
""" Test if settings service returns correct bucket """
self.assertEqual(settings.XBLOCK_SETTINGS, {self.xblock_setting_key1: 42})
self.assertEqual(self.settings_service.get_settings_bucket(self.xblock_mock), 42)
assert settings.XBLOCK_SETTINGS == {self.xblock_setting_key1: 42}
assert self.settings_service.get_settings_bucket(self.xblock_mock) == 42
@override_settings(XBLOCK_SETTINGS={xblock_setting_key2: "I'm a setting"})
def test_get_respects_block_settings_key(self):
""" Test if settings service respects block_settings_key value """
self.assertEqual(settings.XBLOCK_SETTINGS, {self.xblock_setting_key2: "I'm a setting"})
assert settings.XBLOCK_SETTINGS == {self.xblock_setting_key2: "I'm a setting"}
self.xblock_mock.block_settings_key = self.xblock_setting_key2
self.assertEqual(self.settings_service.get_settings_bucket(self.xblock_mock), "I'm a setting")
assert self.settings_service.get_settings_bucket(self.xblock_mock) == "I'm a setting"
@override_settings(XBLOCK_SETTINGS={_DummyBlock.__name__: [1, 2, 3]})
def test_get_uses_class_name_if_block_settings_key_is_not_set(self):
""" Test if settings service uses class name if block_settings_key attribute does not exist """
mixologist = Mixologist([])
block = mixologist.mix(_DummyBlock)
self.assertEqual(settings.XBLOCK_SETTINGS, {"_DummyBlock": [1, 2, 3]})
self.assertEqual(self.settings_service.get_settings_bucket(block), [1, 2, 3])
assert settings.XBLOCK_SETTINGS == {'_DummyBlock': [1, 2, 3]}
assert self.settings_service.get_settings_bucket(block) == [1, 2, 3]
class TestConfigurationService(unittest.TestCase):
@@ -109,7 +112,7 @@ class TestConfigurationService(unittest.TestCase):
Test that instantiating ConfigurationService raises exception on passing
a class which is not subclass of ConfigurationModel.
"""
with self.assertRaises(ValueError):
with pytest.raises(ValueError):
ConfigurationService(DummyUnexpected)
def test_configuration_service(self):
@@ -117,7 +120,7 @@ class TestConfigurationService(unittest.TestCase):
Test the correct configuration on instantiating ConfigurationService.
"""
config_service = ConfigurationService(DummyConfig)
self.assertEqual(config_service.configuration, DummyConfig)
assert config_service.configuration == DummyConfig
class MockConfigurationService(TeamsConfigurationService):
@@ -157,4 +160,4 @@ class TestTeamsConfigurationService(ConfigurationServiceBaseClass):
def test_get_teamsconfiguration(self):
teams_config = self.configuration_service.get_teams_configuration(self.course.id)
self.assertEqual(teams_config, self.teams_config)
assert teams_config == self.teams_config

View File

@@ -60,10 +60,7 @@ class SplitTestUtilitiesTest(PartitionTestCase):
),
second_random_partition
]
self.assertEqual(
[first_random_partition, second_random_partition],
get_split_user_partitions(all_partitions)
)
assert [first_random_partition, second_random_partition] == get_split_user_partitions(all_partitions)
class SplitTestBlockTest(XModuleXmlImportTest, PartitionTestCase):
@@ -150,31 +147,25 @@ class SplitTestBlockLMSTest(SplitTestBlockTest):
@ddt.unpack
def test_child(self, user_tag, child_url_name):
self.user_partition.scheme.current_group = self.user_partition.groups[user_tag]
self.assertEqual(self.split_test_module.child_descriptor.url_name, child_url_name)
assert self.split_test_module.child_descriptor.url_name == child_url_name
@ddt.data((0, 'HTML FOR GROUP 0'), (1, 'HTML FOR GROUP 1'))
@ddt.unpack
def test_get_html(self, user_tag, child_content):
self.user_partition.scheme.current_group = self.user_partition.groups[user_tag]
self.assertIn(
child_content,
self.module_system.render(self.split_test_module, STUDENT_VIEW).content
)
assert child_content in self.module_system.render(self.split_test_module, STUDENT_VIEW).content
@ddt.data(0, 1)
def test_child_missing_tag_value(self, _user_tag):
# If user_tag has a missing value, we should still get back a valid child url
self.assertIn(self.split_test_module.child_descriptor.url_name, ['split_test_cond0', 'split_test_cond1'])
assert self.split_test_module.child_descriptor.url_name in ['split_test_cond0', 'split_test_cond1']
@ddt.data(100, 200, 300, 400, 500, 600, 700, 800, 900, 1000)
def test_child_persist_new_tag_value_when_tag_missing(self, _user_tag):
# If a user_tag has a missing value, a group should be saved/persisted for that user.
# So, we check that we get the same url_name when we call on the url_name twice.
# We run the test ten times so that, if our storage is failing, we'll be most likely to notice it.
self.assertEqual(
self.split_test_module.child_descriptor.url_name,
self.split_test_module.child_descriptor.url_name
)
assert self.split_test_module.child_descriptor.url_name == self.split_test_module.child_descriptor.url_name
# Patch the definition_to_xml for the html children.
@patch('xmodule.html_module.HtmlBlock.definition_to_xml')
@@ -190,14 +181,14 @@ class SplitTestBlockLMSTest(SplitTestBlockTest):
# Write out the xml.
xml_obj = self.split_test_module.definition_to_xml(MemoryFS())
self.assertEqual(xml_obj.get('user_partition_id'), '0')
self.assertIsNotNone(xml_obj.get('group_id_to_child'))
assert xml_obj.get('user_partition_id') == '0'
assert xml_obj.get('group_id_to_child') is not None
# Read the xml back in.
fields, children = SplitTestBlock.definition_from_xml(xml_obj, self.module_system)
self.assertEqual(fields.get('user_partition_id'), '0')
self.assertIsNotNone(fields.get('group_id_to_child'))
self.assertEqual(len(children), 2)
assert fields.get('user_partition_id') == '0'
assert fields.get('group_id_to_child') is not None
assert len(children) == 2
class SplitTestBlockStudioTest(SplitTestBlockTest):
@@ -223,14 +214,14 @@ class SplitTestBlockStudioTest(SplitTestBlockTest):
# The split_test module should render both its groups when it is the root
context = create_studio_context(self.split_test_module)
html = self.module_system.render(self.split_test_module, AUTHOR_VIEW, context).content
self.assertIn('HTML FOR GROUP 0', html)
self.assertIn('HTML FOR GROUP 1', html)
assert 'HTML FOR GROUP 0' in html
assert 'HTML FOR GROUP 1' in html
# When rendering as a child, it shouldn't render either of its groups
context = create_studio_context(self.course_sequence)
html = self.module_system.render(self.split_test_module, AUTHOR_VIEW, context).content
self.assertNotIn('HTML FOR GROUP 0', html)
self.assertNotIn('HTML FOR GROUP 1', html)
assert 'HTML FOR GROUP 0' not in html
assert 'HTML FOR GROUP 1' not in html
# The "Create Missing Groups" button should be rendered when groups are missing
context = create_studio_context(self.split_test_module)
@@ -239,8 +230,8 @@ class SplitTestBlockStudioTest(SplitTestBlockTest):
[Group("0", 'alpha'), Group("1", 'beta'), Group("2", 'gamma')])
]
html = self.module_system.render(self.split_test_module, AUTHOR_VIEW, context).content
self.assertIn('HTML FOR GROUP 0', html)
self.assertIn('HTML FOR GROUP 1', html)
assert 'HTML FOR GROUP 0' in html
assert 'HTML FOR GROUP 1' in html
def test_group_configuration_url(self):
"""
@@ -256,29 +247,29 @@ class SplitTestBlockStudioTest(SplitTestBlockTest):
]
expected_url = '/group_configurations/edX/xml_test_course/101#0'
self.assertEqual(expected_url, self.split_test_module.group_configuration_url)
assert expected_url == self.split_test_module.group_configuration_url
def test_editable_settings(self):
"""
Test the setting information passed back from editable_metadata_fields.
"""
editable_metadata_fields = self.split_test_module.editable_metadata_fields
self.assertIn(SplitTestBlock.display_name.name, editable_metadata_fields)
self.assertNotIn(SplitTestBlock.due.name, editable_metadata_fields)
self.assertNotIn(SplitTestBlock.user_partitions.name, editable_metadata_fields)
assert SplitTestBlock.display_name.name in editable_metadata_fields
assert SplitTestBlock.due.name not in editable_metadata_fields
assert SplitTestBlock.user_partitions.name not in editable_metadata_fields
# user_partition_id will always appear in editable_metadata_settings, regardless
# of the selected value.
self.assertIn(SplitTestBlock.user_partition_id.name, editable_metadata_fields)
assert SplitTestBlock.user_partition_id.name in editable_metadata_fields
def test_non_editable_settings(self):
"""
Test the settings that are marked as "non-editable".
"""
non_editable_metadata_fields = self.split_test_module.non_editable_metadata_fields
self.assertIn(SplitTestBlock.due, non_editable_metadata_fields)
self.assertIn(SplitTestBlock.user_partitions, non_editable_metadata_fields)
self.assertNotIn(SplitTestBlock.display_name, non_editable_metadata_fields)
assert SplitTestBlock.due in non_editable_metadata_fields
assert SplitTestBlock.user_partitions in non_editable_metadata_fields
assert SplitTestBlock.display_name not in non_editable_metadata_fields
@patch('xmodule.split_test_module.user_partition_values.values')
def test_available_partitions(self, _):
@@ -289,8 +280,8 @@ class SplitTestBlockStudioTest(SplitTestBlockTest):
self.split_test_module.user_partition_id = SplitTestFields.no_partition_selected['value']
self.split_test_module.editable_metadata_fields # pylint: disable=pointless-statement
partitions = user_partition_values.values
self.assertEqual(1, len(partitions))
self.assertEqual(SplitTestFields.no_partition_selected['value'], partitions[0]['value'])
assert 1 == len(partitions)
assert SplitTestFields.no_partition_selected['value'] == partitions[0]['value']
# Populate user_partitions and call editable_metadata_fields again
self.split_test_module.user_partitions = [
@@ -306,27 +297,27 @@ class SplitTestBlockStudioTest(SplitTestBlockTest):
]
self.split_test_module.editable_metadata_fields # pylint: disable=pointless-statement
partitions = user_partition_values.values
self.assertEqual(2, len(partitions))
self.assertEqual(SplitTestFields.no_partition_selected['value'], partitions[0]['value'])
self.assertEqual(0, partitions[1]['value'])
self.assertEqual("first_partition", partitions[1]['display_name'])
assert 2 == len(partitions)
assert SplitTestFields.no_partition_selected['value'] == partitions[0]['value']
assert 0 == partitions[1]['value']
assert 'first_partition' == partitions[1]['display_name']
# Try again with a selected partition and verify that there is no option for "No Selection"
self.split_test_module.user_partition_id = 0
self.split_test_module.editable_metadata_fields # pylint: disable=pointless-statement
partitions = user_partition_values.values
self.assertEqual(1, len(partitions))
self.assertEqual(0, partitions[0]['value'])
self.assertEqual("first_partition", partitions[0]['display_name'])
assert 1 == len(partitions)
assert 0 == partitions[0]['value']
assert 'first_partition' == partitions[0]['display_name']
# Finally try again with an invalid selected partition and verify that "No Selection" is an option
self.split_test_module.user_partition_id = 999
self.split_test_module.editable_metadata_fields # pylint: disable=pointless-statement
partitions = user_partition_values.values
self.assertEqual(2, len(partitions))
self.assertEqual(SplitTestFields.no_partition_selected['value'], partitions[0]['value'])
self.assertEqual(0, partitions[1]['value'])
self.assertEqual("first_partition", partitions[1]['display_name'])
assert 2 == len(partitions)
assert SplitTestFields.no_partition_selected['value'] == partitions[0]['value']
assert 0 == partitions[1]['value']
assert 'first_partition' == partitions[1]['display_name']
def test_active_and_inactive_children(self):
"""
@@ -338,8 +329,8 @@ class SplitTestBlockStudioTest(SplitTestBlockTest):
# Verify that a split test has no active children if it has no specified user partition.
split_test_module.user_partition_id = -1
[active_children, inactive_children] = split_test_module.active_and_inactive_children()
self.assertEqual(active_children, [])
self.assertEqual(inactive_children, children)
assert active_children == []
assert inactive_children == children
# Verify that all the children are returned as active for a correctly configured split_test
split_test_module.user_partition_id = 0
@@ -347,30 +338,30 @@ class SplitTestBlockStudioTest(SplitTestBlockTest):
UserPartition(0, 'first_partition', 'First Partition', [Group("0", 'alpha'), Group("1", 'beta')])
]
[active_children, inactive_children] = split_test_module.active_and_inactive_children()
self.assertEqual(active_children, children)
self.assertEqual(inactive_children, [])
assert active_children == children
assert inactive_children == []
# Verify that a split_test does not return inactive children in the active children
self.split_test_module.user_partitions = [
UserPartition(0, 'first_partition', 'First Partition', [Group("0", 'alpha')])
]
[active_children, inactive_children] = split_test_module.active_and_inactive_children()
self.assertEqual(active_children, [children[0]])
self.assertEqual(inactive_children, [children[1]])
assert active_children == [children[0]]
assert inactive_children == [children[1]]
# Verify that a split_test ignores misconfigured children
self.split_test_module.user_partitions = [
UserPartition(0, 'first_partition', 'First Partition', [Group("0", 'alpha'), Group("2", 'gamma')])
]
[active_children, inactive_children] = split_test_module.active_and_inactive_children()
self.assertEqual(active_children, [children[0]])
self.assertEqual(inactive_children, [children[1]])
assert active_children == [children[0]]
assert inactive_children == [children[1]]
# Verify that a split_test referring to a non-existent user partition has no active children
self.split_test_module.user_partition_id = 2
[active_children, inactive_children] = split_test_module.active_and_inactive_children()
self.assertEqual(active_children, [])
self.assertEqual(inactive_children, children)
assert active_children == []
assert inactive_children == children
def test_validation_messages(self): # lint-amnesty, pylint: disable=too-many-statements
"""
@@ -384,32 +375,32 @@ class SplitTestBlockStudioTest(SplitTestBlockTest):
"""
Verify that the validation message has the expected validation message and type.
"""
self.assertEqual(message.text, expected_message)
self.assertEqual(message.type, expected_message_type)
assert message.text == expected_message
assert message.type == expected_message_type
if expected_action_class:
self.assertEqual(message.action_class, expected_action_class)
assert message.action_class == expected_action_class
else:
self.assertFalse(hasattr(message, "action_class"))
assert not hasattr(message, 'action_class')
if expected_action_label:
self.assertEqual(message.action_label, expected_action_label)
assert message.action_label == expected_action_label
else:
self.assertFalse(hasattr(message, "action_label"))
assert not hasattr(message, 'action_label')
if expected_action_runtime_event:
self.assertEqual(message.action_runtime_event, expected_action_runtime_event)
assert message.action_runtime_event == expected_action_runtime_event
else:
self.assertFalse(hasattr(message, "action_runtime_event"))
assert not hasattr(message, 'action_runtime_event')
def verify_summary_message(general_validation, expected_message, expected_message_type):
"""
Verify that the general validation message has the expected validation message and type.
"""
self.assertEqual(general_validation.text, expected_message)
self.assertEqual(general_validation.type, expected_message_type)
assert general_validation.text == expected_message
assert general_validation.type == expected_message_type
# Verify the messages for an unconfigured user partition
split_test_module.user_partition_id = -1
validation = split_test_module.validate()
self.assertEqual(len(validation.messages), 0)
assert len(validation.messages) == 0
verify_validation_message(
validation.summary,
u"The experiment is not associated with a group configuration.",
@@ -424,8 +415,8 @@ class SplitTestBlockStudioTest(SplitTestBlockTest):
UserPartition(0, 'first_partition', 'First Partition', [Group("0", 'alpha'), Group("1", 'beta')])
]
validation = split_test_module.validate_split_test()
self.assertTrue(validation)
self.assertIsNone(split_test_module.general_validation_message(), None)
assert validation
assert split_test_module.general_validation_message() is None, None
# Verify the messages for a split test with too few groups
split_test_module.user_partitions = [
@@ -433,7 +424,7 @@ class SplitTestBlockStudioTest(SplitTestBlockTest):
[Group("0", 'alpha'), Group("1", 'beta'), Group("2", 'gamma')])
]
validation = split_test_module.validate()
self.assertEqual(len(validation.messages), 1)
assert len(validation.messages) == 1
verify_validation_message(
validation.messages[0],
u"The experiment does not contain all of the groups in the configuration.",
@@ -452,7 +443,7 @@ class SplitTestBlockStudioTest(SplitTestBlockTest):
[Group("0", 'alpha')])
]
validation = split_test_module.validate()
self.assertEqual(len(validation.messages), 1)
assert len(validation.messages) == 1
verify_validation_message(
validation.messages[0],
u"The experiment has an inactive group. Move content into active groups, then delete the inactive group.",
@@ -469,7 +460,7 @@ class SplitTestBlockStudioTest(SplitTestBlockTest):
[Group("0", 'alpha'), Group("2", 'gamma')])
]
validation = split_test_module.validate()
self.assertEqual(len(validation.messages), 2)
assert len(validation.messages) == 2
verify_validation_message(
validation.messages[0],
u"The experiment does not contain all of the groups in the configuration.",
@@ -492,7 +483,7 @@ class SplitTestBlockStudioTest(SplitTestBlockTest):
# Verify the messages for a split test referring to a non-existent user partition
split_test_module.user_partition_id = 2
validation = split_test_module.validate()
self.assertEqual(len(validation.messages), 1)
assert len(validation.messages) == 1
verify_validation_message(
validation.messages[0],
u"The experiment uses a deleted group configuration. "
@@ -514,7 +505,7 @@ class SplitTestBlockStudioTest(SplitTestBlockTest):
]
split_test_module.user_partition_id = 10
validation = split_test_module.validate()
self.assertEqual(len(validation.messages), 1)
assert len(validation.messages) == 1
verify_validation_message(
validation.messages[0],
u"The experiment uses a group configuration that is not supported for experiments. "
@@ -593,7 +584,7 @@ class SplitTestBlockExportImportTest(MixedSplitTestCase):
exported_olx = f.read()
# And compare.
self.assertEqual(exported_olx, expected_olx)
assert exported_olx == expected_olx
runtime = TestImportSystem(load_error_modules=True, course_id=split_test_block.location.course_key)
runtime.resources_fs = export_fs
@@ -604,9 +595,9 @@ class SplitTestBlockExportImportTest(MixedSplitTestCase):
imported_split_test_block = SplitTestBlock.parse_xml(olx_element, runtime, None, id_generator)
# Check the new XBlock has the same properties as the old one.
self.assertEqual(imported_split_test_block.display_name, split_test_block.display_name)
self.assertEqual(len(imported_split_test_block.children), len(split_test_block.children))
self.assertEqual(imported_split_test_block.children, split_test_block.children)
self.assertEqual(imported_split_test_block.user_partition_id, split_test_block.user_partition_id)
self.assertEqual(imported_split_test_block.group_id_to_child['0'], str(split_test_block.group_id_to_child['0']))
self.assertEqual(imported_split_test_block.group_id_to_child['1'], str(split_test_block.group_id_to_child['1']))
assert imported_split_test_block.display_name == split_test_block.display_name
assert len(imported_split_test_block.children) == len(split_test_block.children)
assert imported_split_test_block.children == split_test_block.children
assert imported_split_test_block.user_partition_id == split_test_block.user_partition_id
assert imported_split_test_block.group_id_to_child['0'] == str(split_test_block.group_id_to_child['0'])
assert imported_split_test_block.group_id_to_child['1'] == str(split_test_block.group_id_to_child['1'])

View File

@@ -25,5 +25,5 @@ class StudioEditableModuleTestCase(BaseVerticalBlockTest):
# Both children of the vertical should be rendered as reorderable
self.module_system.render(self.vertical, AUTHOR_VIEW, context).content # pylint: disable=expression-not-assigned
self.assertIn(self.vertical.get_children()[0].location, reorderable_items)
self.assertIn(self.vertical.get_children()[1].location, reorderable_items)
assert self.vertical.get_children()[0].location in reorderable_items
assert self.vertical.get_children()[1].location in reorderable_items

View File

@@ -72,7 +72,7 @@ class UnitBlockTests(XmlTest, unittest.TestCase):
The unit XBlock is designed to hold other XBlocks, so check that its
completion status is defined as the aggregation of its child blocks.
"""
self.assertEqual(XBlockCompletionMode.get_mode(UnitBlock), XBlockCompletionMode.AGGREGATOR)
assert XBlockCompletionMode.get_mode(UnitBlock) == XBlockCompletionMode.AGGREGATOR
def assertXmlEqual(self, xml_str_a, xml_str_b):
"""
@@ -84,4 +84,4 @@ class UnitBlockTests(XmlTest, unittest.TestCase):
xml_str = re.sub(r'(\s)\s+', r'\1', xml_str)
xml_bytes = xml_str.encode('utf8')
return minidom.parseString(xml_bytes).toprettyxml()
self.assertEqual(clean(xml_str_a), clean(xml_str_b))
assert clean(xml_str_a) == clean(xml_str_b)

View File

@@ -27,39 +27,39 @@ class TestGetExtendedDueDate(unittest.TestCase):
Test no due date.
"""
node = object()
self.assertEqual(self.call_fut(node), None)
assert self.call_fut(node) is None
def test_due_date_no_extension(self):
"""
Test due date without extension.
"""
node = mock.Mock(due=1, extended_due=None)
self.assertEqual(self.call_fut(node), 1)
assert self.call_fut(node) == 1
def test_due_date_with_extension(self):
"""
Test due date with extension.
"""
node = mock.Mock(due=1, extended_due=2)
self.assertEqual(self.call_fut(node), 2)
assert self.call_fut(node) == 2
def test_due_date_extension_is_earlier(self):
"""
Test due date with extension, but due date is later than extension.
"""
node = mock.Mock(due=2, extended_due=1)
self.assertEqual(self.call_fut(node), 2)
assert self.call_fut(node) == 2
def test_extension_without_due_date(self):
"""
Test non-sensical extension without due date.
"""
node = mock.Mock(due=None, extended_due=1)
self.assertEqual(self.call_fut(node), None)
assert self.call_fut(node) is None
def test_due_date_with_extension_dict(self):
"""
Test due date with extension when node is a dict.
"""
node = {'due': 1, 'extended_due': 2}
self.assertEqual(self.call_fut(node), 2)
assert self.call_fut(node) == 2

View File

@@ -19,7 +19,7 @@ class UtilHtmlEscapeTests(TestCase):
This is a paragraph.
"""
self.assertEqual(escape_html_characters(html_content), self.final_content)
assert escape_html_characters(html_content) == self.final_content
def test_escape_cdata_comments(self):
html_content = """
@@ -39,7 +39,7 @@ class UtilHtmlEscapeTests(TestCase):
This is a paragraph.
"""
self.assertEqual(escape_html_characters(html_content), self.final_content)
assert escape_html_characters(html_content) == self.final_content
def test_escape_non_breaking_space(self):
html_content = """
@@ -60,4 +60,4 @@ class UtilHtmlEscapeTests(TestCase):
]]>
This is a paragraph.&nbsp;
"""
self.assertEqual(escape_html_characters(html_content), self.final_content)
assert escape_html_characters(html_content) == self.final_content

View File

@@ -36,38 +36,24 @@ class StudioValidationMessageTest(unittest.TestCase):
"""
Test the `to_json` method.
"""
self.assertEqual(
{
"type": StudioValidationMessage.NOT_CONFIGURED,
"text": u"Not Configured message",
"action_label": u"Action label"
},
StudioValidationMessage(
StudioValidationMessage.NOT_CONFIGURED, u"Not Configured message", action_label=u"Action label"
).to_json()
)
assert \
{'type': StudioValidationMessage.NOT_CONFIGURED,
'text': u'Not Configured message', 'action_label': u'Action label'} == \
StudioValidationMessage(StudioValidationMessage.NOT_CONFIGURED,
u'Not Configured message', action_label=u'Action label').to_json()
self.assertEqual(
{
"type": StudioValidationMessage.WARNING,
"text": u"Warning message",
"action_class": "class-for-action"
},
StudioValidationMessage(
StudioValidationMessage.WARNING, u"Warning message", action_class="class-for-action"
).to_json()
)
assert \
{'type': StudioValidationMessage.WARNING,
'text': u'Warning message',
'action_class': 'class-for-action'} ==\
StudioValidationMessage(StudioValidationMessage.WARNING, u'Warning message',
action_class='class-for-action').to_json()
self.assertEqual(
{
"type": StudioValidationMessage.ERROR,
"text": u"Error message",
"action_runtime_event": "do-fix-up"
},
StudioValidationMessage(
StudioValidationMessage.ERROR, u"Error message", action_runtime_event="do-fix-up"
).to_json()
)
assert \
{'type': StudioValidationMessage.ERROR,
'text': u'Error message', 'action_runtime_event': 'do-fix-up'} ==\
StudioValidationMessage(StudioValidationMessage.ERROR,
u'Error message', action_runtime_event='do-fix-up').to_json()
class StudioValidationTest(unittest.TestCase):
@@ -80,15 +66,15 @@ class StudioValidationTest(unittest.TestCase):
validation.add(ValidationMessage(ValidationMessage.ERROR, u"Error message"))
studio_validation = StudioValidation.copy(validation)
self.assertIsInstance(studio_validation, StudioValidation)
self.assertFalse(studio_validation)
self.assertEqual(1, len(studio_validation.messages))
assert isinstance(studio_validation, StudioValidation)
assert not studio_validation
assert 1 == len(studio_validation.messages)
expected = {
"type": StudioValidationMessage.ERROR,
"text": u"Error message"
}
self.assertEqual(expected, studio_validation.messages[0].to_json())
self.assertIsNone(studio_validation.summary)
assert expected == studio_validation.messages[0].to_json()
assert studio_validation.summary is None
def test_copy_studio_validation(self):
validation = StudioValidation("id")
@@ -97,14 +83,14 @@ class StudioValidationTest(unittest.TestCase):
)
validation_copy = StudioValidation.copy(validation)
self.assertFalse(validation_copy)
self.assertEqual(1, len(validation_copy.messages))
assert not validation_copy
assert 1 == len(validation_copy.messages)
expected = {
"type": StudioValidationMessage.WARNING,
"text": u"Warning message",
"action_label": u"Action Label"
}
self.assertEqual(expected, validation_copy.messages[0].to_json())
assert expected == validation_copy.messages[0].to_json()
def test_copy_errors(self):
with pytest.raises(TypeError):
@@ -116,19 +102,19 @@ class StudioValidationTest(unittest.TestCase):
Also test the "bool" property of `Validation`.
"""
validation = StudioValidation("id")
self.assertTrue(validation.empty)
self.assertTrue(validation)
assert validation.empty
assert validation
validation.add(StudioValidationMessage(StudioValidationMessage.ERROR, u"Error message"))
self.assertFalse(validation.empty)
self.assertFalse(validation)
assert not validation.empty
assert not validation
validation_with_summary = StudioValidation("id")
validation_with_summary.set_summary(
StudioValidationMessage(StudioValidationMessage.NOT_CONFIGURED, u"Summary message")
)
self.assertFalse(validation.empty)
self.assertFalse(validation)
assert not validation.empty
assert not validation
def test_add_messages(self):
"""
@@ -143,16 +129,16 @@ class StudioValidationTest(unittest.TestCase):
validation_2.add(StudioValidationMessage(StudioValidationMessage.NOT_CONFIGURED, u"Not configured"))
validation_1.add_messages(validation_2)
self.assertEqual(2, len(validation_1.messages))
assert 2 == len(validation_1.messages)
self.assertEqual(StudioValidationMessage.ERROR, validation_1.messages[0].type)
self.assertEqual(u"Error message", validation_1.messages[0].text)
assert StudioValidationMessage.ERROR == validation_1.messages[0].type
assert u'Error message' == validation_1.messages[0].text
self.assertEqual(StudioValidationMessage.NOT_CONFIGURED, validation_1.messages[1].type)
self.assertEqual(u"Not configured", validation_1.messages[1].text)
assert StudioValidationMessage.NOT_CONFIGURED == validation_1.messages[1].type
assert u'Not configured' == validation_1.messages[1].text
self.assertEqual(StudioValidationMessage.WARNING, validation_1.summary.type)
self.assertEqual(u"Summary message", validation_1.summary.text)
assert StudioValidationMessage.WARNING == validation_1.summary.type
assert u'Summary message' == validation_1.summary.text
def test_set_summary_accepts_validation_message(self):
"""
@@ -160,8 +146,8 @@ class StudioValidationTest(unittest.TestCase):
"""
validation = StudioValidation("id")
validation.set_summary(ValidationMessage(ValidationMessage.WARNING, u"Summary message"))
self.assertEqual(ValidationMessage.WARNING, validation.summary.type)
self.assertEqual(u"Summary message", validation.summary.text)
assert ValidationMessage.WARNING == validation.summary.type
assert u'Summary message' == validation.summary.text
def test_set_summary_errors(self):
"""
@@ -180,7 +166,7 @@ class StudioValidationTest(unittest.TestCase):
"messages": [],
"empty": True
}
self.assertEqual(expected, validation.to_json())
assert expected == validation.to_json()
validation.add(
StudioValidationMessage(
@@ -233,4 +219,4 @@ class StudioValidationTest(unittest.TestCase):
},
"empty": False
}
self.assertEqual(expected, validation.to_json())
assert expected == validation.to_json()

View File

@@ -156,22 +156,22 @@ class VerticalBlockTestCase(BaseVerticalBlockTest):
html = self.module_system.render(
self.vertical, view, self.default_context if context is None else context
).content
self.assertIn(self.test_html, html)
assert self.test_html in html
if view == STUDENT_VIEW:
self.assertIn(self.test_problem, html)
assert self.test_problem in html
else:
self.assertNotIn(self.test_problem, html)
self.assertIn("'due': datetime.datetime({year}, {month}, {day}".format(
year=self.vertical.due.year, month=self.vertical.due.month, day=self.vertical.due.day), html)
assert self.test_problem not in html
assert f"'due': datetime.datetime({self.vertical.due.year}, {self.vertical.due.month}, {self.vertical.due.day}"\
in html
if view == STUDENT_VIEW:
self.assert_bookmark_info(self.assertIn, html)
else:
self.assert_bookmark_info(self.assertNotIn, html)
if context:
self.assertIn("'has_assignments': True", html)
self.assertIn("'subsection_format': '{}'".format(context['format']), html)
self.assertIn("'completed': {}".format(completion_value == 1), html)
self.assertIn("'past_due': {}".format(self.vertical.due < now), html)
assert "'has_assignments': True" in html
assert "'subsection_format': '{}'".format(context['format']) in html
assert "'completed': {}".format((completion_value == 1)) in html
assert "'past_due': {}".format((self.vertical.due < now)) in html
@ddt.data(True, False)
def test_render_problem_without_score(self, has_score):
@@ -188,13 +188,13 @@ class VerticalBlockTestCase(BaseVerticalBlockTest):
html = self.module_system.render(self.vertical, STUDENT_VIEW, self.default_context).content
if has_score:
self.assertIn("'has_assignments': True", html)
self.assertIn("'completed': False", html)
self.assertIn("'past_due': True", html)
assert "'has_assignments': True" in html
assert "'completed': False" in html
assert "'past_due': True" in html
else:
self.assertIn("'has_assignments': False", html)
self.assertIn("'completed': None", html)
self.assertIn("'past_due': False", html)
assert "'has_assignments': False" in html
assert "'completed': None" in html
assert "'past_due': False" in html
@ddt.data(True, False)
def test_render_access_denied_blocks(self, has_access_error):
@@ -208,9 +208,9 @@ class VerticalBlockTestCase(BaseVerticalBlockTest):
html = self.module_system.render(self.vertical, STUDENT_VIEW, context).content
if has_access_error:
self.assertNotIn(self.test_problem, html)
assert self.test_problem not in html
else:
self.assertIn(self.test_problem, html)
assert self.test_problem in html
@ddt.unpack
@ddt.data(
@@ -231,11 +231,10 @@ class VerticalBlockTestCase(BaseVerticalBlockTest):
)
self.module_system.render(self.vertical, STUDENT_VIEW, self.default_context)
if mark_completed_enabled:
self.assertEqual(
mock_student_view.call_args[0][1]['wrap_xblock_data']['mark-completed-on-view-after-delay'], 9876
)
assert mock_student_view.call_args[0][1]['wrap_xblock_data']['mark-completed-on-view-after-delay'] ==\
9876
else:
self.assertNotIn('wrap_xblock_data', mock_student_view.call_args[0][1])
assert 'wrap_xblock_data' not in mock_student_view.call_args[0][1]
def test_render_studio_view(self):
"""
@@ -246,8 +245,8 @@ class VerticalBlockTestCase(BaseVerticalBlockTest):
'is_unit_page': True
}
html = self.module_system.render(self.vertical, AUTHOR_VIEW, context).content
self.assertNotIn(self.test_html, html)
self.assertNotIn(self.test_problem, html)
assert self.test_html not in html
assert self.test_problem not in html
# Vertical should render reorderable children on the container page
reorderable_items = set()
@@ -256,5 +255,5 @@ class VerticalBlockTestCase(BaseVerticalBlockTest):
'reorderable_items': reorderable_items,
}
html = self.module_system.render(self.vertical, AUTHOR_VIEW, context).content
self.assertIn(self.test_html, html)
self.assertIn(self.test_problem, html)
assert self.test_html in html
assert self.test_problem in html

View File

@@ -21,7 +21,7 @@ import shutil
import unittest
from tempfile import mkdtemp
from uuid import uuid4
import pytest
import ddt
import httpretty
import six
@@ -125,10 +125,7 @@ class VideoBlockTest(unittest.TestCase):
"""Test parsing old-style Youtube ID strings into a dict."""
youtube_str = '0.75:jNCf2gIqpeE,1.00:ZwkTiUPN0mg,1.25:rsq9auxASqI,1.50:kMyNdzVHHgg'
output = VideoBlock._parse_youtube(youtube_str)
self.assertEqual(output, {'0.75': 'jNCf2gIqpeE',
'1.00': 'ZwkTiUPN0mg',
'1.25': 'rsq9auxASqI',
'1.50': 'kMyNdzVHHgg'})
assert output == {'0.75': 'jNCf2gIqpeE', '1.00': 'ZwkTiUPN0mg', '1.25': 'rsq9auxASqI', '1.50': 'kMyNdzVHHgg'}
def test_parse_youtube_one_video(self):
"""
@@ -137,35 +134,23 @@ class VideoBlockTest(unittest.TestCase):
"""
youtube_str = '0.75:jNCf2gIqpeE'
output = VideoBlock._parse_youtube(youtube_str)
self.assertEqual(output, {'0.75': 'jNCf2gIqpeE',
'1.00': '',
'1.25': '',
'1.50': ''})
assert output == {'0.75': 'jNCf2gIqpeE', '1.00': '', '1.25': '', '1.50': ''}
def test_parse_youtube_invalid(self):
"""Ensure that ids that are invalid return an empty dict"""
# invalid id
youtube_str = 'thisisaninvalidid'
output = VideoBlock._parse_youtube(youtube_str)
self.assertEqual(output, {'0.75': '',
'1.00': '',
'1.25': '',
'1.50': ''})
assert output == {'0.75': '', '1.00': '', '1.25': '', '1.50': ''}
# another invalid id
youtube_str = ',::,:,,'
output = VideoBlock._parse_youtube(youtube_str)
self.assertEqual(output, {'0.75': '',
'1.00': '',
'1.25': '',
'1.50': ''})
assert output == {'0.75': '', '1.00': '', '1.25': '', '1.50': ''}
# and another one, partially invalid
youtube_str = '0.75_BAD!!!,1.0:AXdE34_U,1.25:KLHF9K_Y,1.5:VO3SxfeD,'
output = VideoBlock._parse_youtube(youtube_str)
self.assertEqual(output, {'0.75': '',
'1.00': 'AXdE34_U',
'1.25': 'KLHF9K_Y',
'1.50': 'VO3SxfeD'})
assert output == {'0.75': '', '1.00': 'AXdE34_U', '1.25': 'KLHF9K_Y', '1.50': 'VO3SxfeD'}
def test_parse_youtube_key_format(self):
"""
@@ -173,23 +158,14 @@ class VideoBlockTest(unittest.TestCase):
"""
youtube_str = '1.00:p2Q6BrNhdh8'
youtube_str_hack = '1.0:p2Q6BrNhdh8'
self.assertEqual(
VideoBlock._parse_youtube(youtube_str),
VideoBlock._parse_youtube(youtube_str_hack)
)
assert VideoBlock._parse_youtube(youtube_str) == VideoBlock._parse_youtube(youtube_str_hack)
def test_parse_youtube_empty(self):
"""
Some courses have empty youtube attributes, so we should handle
that well.
"""
self.assertEqual(
VideoBlock._parse_youtube(''),
{'0.75': '',
'1.00': '',
'1.25': '',
'1.50': ''}
)
assert VideoBlock._parse_youtube('') == {'0.75': '', '1.00': '', '1.25': '', '1.50': ''}
class VideoBlockTestBase(unittest.TestCase):
@@ -213,9 +189,9 @@ class VideoBlockTestBase(unittest.TestCase):
for attr in ['tag', 'attrib', 'text', 'tail']:
expected_attr = getattr(expected, attr)
actual_attr = getattr(xml, attr)
self.assertEqual(expected_attr, actual_attr)
assert expected_attr == actual_attr
self.assertEqual(get_child_tags(expected), get_child_tags(xml))
assert get_child_tags(expected) == get_child_tags(xml)
for left, right in zip(expected, xml):
self.assertXmlEqual(left, right)
@@ -234,7 +210,7 @@ class TestCreateYoutubeString(VideoBlockTestBase):
self.descriptor.youtube_id_1_25 = '1EeWXzPdhSA'
self.descriptor.youtube_id_1_5 = 'rABDYkeK0x8'
expected = "0.75:izygArpw-Qo,1.00:p2Q6BrNhdh8,1.25:1EeWXzPdhSA,1.50:rABDYkeK0x8"
self.assertEqual(create_youtube_string(self.descriptor), expected)
assert create_youtube_string(self.descriptor) == expected
def test_create_youtube_string_missing(self):
"""
@@ -244,7 +220,7 @@ class TestCreateYoutubeString(VideoBlockTestBase):
self.descriptor.youtube_id_1_0 = 'p2Q6BrNhdh8'
self.descriptor.youtube_id_1_25 = '1EeWXzPdhSA'
expected = "0.75:izygArpw-Qo,1.00:p2Q6BrNhdh8,1.25:1EeWXzPdhSA"
self.assertEqual(create_youtube_string(self.descriptor), expected)
assert create_youtube_string(self.descriptor) == expected
class TestCreateYouTubeUrl(VideoBlockTestBase):
@@ -271,7 +247,7 @@ class VideoBlockImportTestCase(TestCase):
Assert that `video` has the correct attributes. `attrs` is a map of {metadata_field: value}.
"""
for key, value in attrs.items():
self.assertEqual(getattr(video, key), value)
assert getattr(video, key) == value
def test_constructor(self):
sample_xml = '''
@@ -636,13 +612,13 @@ class VideoBlockImportTestCase(TestCase):
"""
def mock_val_import(xml, edx_video_id, resource_fs, static_dir, external_transcripts, course_id):
"""Mock edxval.api.import_from_xml"""
self.assertEqual(xml.tag, 'video_asset')
self.assertEqual(dict(list(xml.items())), {'mock_attr': ''})
self.assertEqual(edx_video_id, 'test_edx_video_id')
self.assertEqual(static_dir, EXPORT_IMPORT_STATIC_DIR)
self.assertIsNotNone(resource_fs)
self.assertEqual(external_transcripts, {u'en': [u'subs_3_yD_cEKoCk.srt.sjson']})
self.assertEqual(course_id, 'test_course_id')
assert xml.tag == 'video_asset'
assert dict(list(xml.items())) == {'mock_attr': ''}
assert edx_video_id == 'test_edx_video_id'
assert static_dir == EXPORT_IMPORT_STATIC_DIR
assert resource_fs is not None
assert external_transcripts == {u'en': [u'subs_3_yD_cEKoCk.srt.sjson']}
assert course_id == 'test_course_id'
return edx_video_id
edx_video_id = 'test_edx_video_id'
@@ -686,7 +662,7 @@ class VideoBlockImportTestCase(TestCase):
<video_asset client_video_id="test_client_video_id" duration="-1"/>
</video>
"""
with self.assertRaises(mock_val_api.ValCannotCreateError):
with pytest.raises(mock_val_api.ValCannotCreateError):
VideoBlock.from_xml(xml_data, module_system, id_generator=Mock())
@@ -811,7 +787,7 @@ class VideoExportTestCase(VideoBlockTestBase):
xml = self.descriptor.definition_to_xml(self.file_system)
# Check that download_video field is also set to default (False) in xml for backward compatibility
expected = '<video url_name="SampleProblem"/>\n'
self.assertEqual(expected, etree.tostring(xml, pretty_print=True).decode('utf-8'))
assert expected == etree.tostring(xml, pretty_print=True).decode('utf-8')
@patch('xmodule.video_module.video_module.edxval_api', None)
def test_export_to_xml_with_transcripts_as_none(self):
@@ -821,7 +797,7 @@ class VideoExportTestCase(VideoBlockTestBase):
self.descriptor.transcripts = None
xml = self.descriptor.definition_to_xml(self.file_system)
expected = b'<video url_name="SampleProblem"/>\n'
self.assertEqual(expected, etree.tostring(xml, pretty_print=True))
assert expected == etree.tostring(xml, pretty_print=True)
@patch('xmodule.video_module.video_module.edxval_api', None)
def test_export_to_xml_invalid_characters_in_attributes(self):
@@ -831,7 +807,7 @@ class VideoExportTestCase(VideoBlockTestBase):
"""
self.descriptor.display_name = 'Display\x1eName'
xml = self.descriptor.definition_to_xml(self.file_system)
self.assertEqual(xml.get('display_name'), 'DisplayName')
assert xml.get('display_name') == 'DisplayName'
@patch('xmodule.video_module.video_module.edxval_api', None)
def test_export_to_xml_unicode_characters(self):
@@ -840,7 +816,7 @@ class VideoExportTestCase(VideoBlockTestBase):
"""
self.descriptor.display_name = u'这是文'
xml = self.descriptor.definition_to_xml(self.file_system)
self.assertEqual(xml.get('display_name'), u'\u8fd9\u662f\u6587')
assert xml.get('display_name') == u'这是文'
@ddt.ddt
@@ -889,7 +865,7 @@ class VideoBlockStudentViewDataTestCase(unittest.TestCase):
descriptor = instantiate_descriptor(**field_data)
descriptor.runtime.course_id = MagicMock()
student_view_data = descriptor.student_view_data()
self.assertEqual(student_view_data, expected_student_view_data)
assert student_view_data == expected_student_view_data
@patch('xmodule.video_module.video_module.HLSPlaybackEnabledFlag.feature_enabled', Mock(return_value=True))
@patch('xmodule.video_module.transcripts_utils.get_available_transcript_languages', Mock(return_value=['es']))
@@ -987,10 +963,7 @@ class VideoBlockIndexingTestCase(unittest.TestCase):
</video>
'''
descriptor = instantiate_descriptor(data=xml_data)
self.assertEqual(descriptor.index_dictionary(), {
"content": {"display_name": "Test Video"},
"content_type": "Video"
})
assert descriptor.index_dictionary() == {'content': {'display_name': 'Test Video'}, 'content_type': 'Video'}
@httpretty.activate
def test_video_with_youtube_subs_index_dictionary(self):
@@ -1022,13 +995,8 @@ class VideoBlockIndexingTestCase(unittest.TestCase):
descriptor = instantiate_descriptor(data=xml_data_sub)
subs = download_youtube_subs(yt_subs_id, descriptor, settings)
save_subs_to_store(json.loads(subs), yt_subs_id, descriptor)
self.assertEqual(descriptor.index_dictionary(), {
"content": {
"display_name": "Test Video",
"transcript_en": YOUTUBE_SUBTITLES
},
"content_type": "Video"
})
assert descriptor.index_dictionary() ==\
{'content': {'display_name': 'Test Video', 'transcript_en': YOUTUBE_SUBTITLES}, 'content_type': 'Video'}
@httpretty.activate
def test_video_with_subs_and_transcript_index_dictionary(self):
@@ -1063,14 +1031,10 @@ class VideoBlockIndexingTestCase(unittest.TestCase):
subs = download_youtube_subs(yt_subs_id, descriptor, settings)
save_subs_to_store(json.loads(subs), yt_subs_id, descriptor)
save_to_store(SRT_FILEDATA, "subs_grmtran1.srt", 'text/srt', descriptor.location)
self.assertEqual(descriptor.index_dictionary(), {
"content": {
"display_name": "Test Video",
"transcript_en": YOUTUBE_SUBTITLES,
"transcript_ge": "sprechen sie deutsch? Ja, ich spreche Deutsch",
},
"content_type": "Video"
})
assert descriptor.index_dictionary() ==\
{'content': {'display_name': 'Test Video', 'transcript_en': YOUTUBE_SUBTITLES,
'transcript_ge': 'sprechen sie deutsch? Ja, ich spreche Deutsch'},
'content_type': 'Video'}
def test_video_with_multiple_transcripts_index_dictionary(self):
"""
@@ -1096,14 +1060,10 @@ class VideoBlockIndexingTestCase(unittest.TestCase):
descriptor = instantiate_descriptor(data=xml_data_transcripts)
save_to_store(SRT_FILEDATA, "subs_grmtran1.srt", 'text/srt', descriptor.location)
save_to_store(CRO_SRT_FILEDATA, "subs_croatian1.srt", 'text/srt', descriptor.location)
self.assertEqual(descriptor.index_dictionary(), {
"content": {
"display_name": "Test Video",
"transcript_ge": "sprechen sie deutsch? Ja, ich spreche Deutsch",
"transcript_hr": "Dobar dan! Kako ste danas?"
},
"content_type": "Video"
})
assert descriptor.index_dictionary() ==\
{'content': {'display_name': 'Test Video',
'transcript_ge': 'sprechen sie deutsch? Ja, ich spreche Deutsch',
'transcript_hr': 'Dobar dan! Kako ste danas?'}, 'content_type': 'Video'}
def test_video_with_multiple_transcripts_translation_retrieval(self):
"""
@@ -1128,7 +1088,7 @@ class VideoBlockIndexingTestCase(unittest.TestCase):
descriptor = instantiate_descriptor(data=xml_data_transcripts)
translations = descriptor.available_translations(descriptor.get_transcripts_info())
self.assertEqual(sorted(translations), sorted(['hr', 'ge']))
assert sorted(translations) == sorted(['hr', 'ge'])
def test_video_with_no_transcripts_translation_retrieval(self):
"""
@@ -1138,13 +1098,13 @@ class VideoBlockIndexingTestCase(unittest.TestCase):
"""
descriptor = instantiate_descriptor(data=None)
translations_with_fallback = descriptor.available_translations(descriptor.get_transcripts_info())
self.assertEqual(translations_with_fallback, ['en'])
assert translations_with_fallback == ['en']
with patch.dict(settings.FEATURES, FALLBACK_TO_ENGLISH_TRANSCRIPTS=False):
# Some organizations don't have English transcripts for all videos
# This feature makes it configurable
translations_no_fallback = descriptor.available_translations(descriptor.get_transcripts_info())
self.assertEqual(translations_no_fallback, [])
assert translations_no_fallback == []
@override_settings(ALL_LANGUAGES=ALL_LANGUAGES)
def test_video_with_language_do_not_have_transcripts_translation(self):
@@ -1168,7 +1128,7 @@ class VideoBlockIndexingTestCase(unittest.TestCase):
'''
descriptor = instantiate_descriptor(data=xml_data_transcripts)
translations = descriptor.available_translations(descriptor.get_transcripts_info(), verify_assets=False)
self.assertNotEqual(translations, ['ur'])
assert translations != ['ur']
def assert_validation_message(self, validation, expected_msg):
"""
@@ -1178,12 +1138,11 @@ class VideoBlockIndexingTestCase(unittest.TestCase):
validation (StudioValidation): A validation object.
expected_msg (string): An expected validation message.
"""
self.assertFalse(validation.empty) # Validation contains some warning/message
self.assertTrue(validation.summary)
self.assertEqual(StudioValidationMessage.WARNING, validation.summary.type)
self.assertIn(
expected_msg, validation.summary.text.replace('Urdu, Esperanto', 'Esperanto, Urdu')
)
assert not validation.empty
# Validation contains some warning/message
assert validation.summary
assert StudioValidationMessage.WARNING == validation.summary.type
assert expected_msg in validation.summary.text.replace('Urdu, Esperanto', 'Esperanto, Urdu')
@ddt.data(
(
@@ -1227,4 +1186,4 @@ class VideoBlockIndexingTestCase(unittest.TestCase):
descriptor.transcripts = None
response = descriptor.get_transcripts_info()
expected = {'transcripts': {}, 'sub': ''}
self.assertEqual(expected, response)
assert expected == response

View File

@@ -48,11 +48,11 @@ class WordCloudBlockTest(TestCase):
CourseLocator('org', 'course', 'run', branch='revision'), 'word_cloud', 'block_id'
)
self.assertEqual(block.display_name, 'Favorite Fruits')
self.assertFalse(block.display_student_percents)
self.assertEqual(block.instructions, 'What are your favorite fruits?')
self.assertEqual(block.num_inputs, 3)
self.assertEqual(block.num_top_words, 100)
assert block.display_name == 'Favorite Fruits'
assert not block.display_student_percents
assert block.instructions == 'What are your favorite fruits?'
assert block.num_inputs == 3
assert block.num_top_words == 100
node = etree.Element("unknown_root")
# This will export the olx to a separate file.
@@ -60,7 +60,7 @@ class WordCloudBlockTest(TestCase):
with runtime.export_fs.open(u'word_cloud/block_id.xml') as f:
exported_xml = f.read()
self.assertEqual(exported_xml, original_xml)
assert exported_xml == original_xml
def test_bad_ajax_request(self):
"""
@@ -86,9 +86,9 @@ class WordCloudBlockTest(TestCase):
post_data = MultiDict(('student_words[]', word) for word in ['cat', 'cat', 'dog', 'sun'])
response = json.loads(block.handle_ajax('submit', post_data))
self.assertEqual(response['status'], 'success')
self.assertEqual(response['submitted'], True)
self.assertEqual(response['total_count'], 22)
assert response['status'] == 'success'
assert response['submitted'] is True
assert response['total_count'] == 22
self.assertDictEqual(
response['student_words'],
{'sun': 1, 'dog': 6, 'cat': 12}
@@ -103,7 +103,7 @@ class WordCloudBlockTest(TestCase):
{'text': 'sun', 'size': 1, 'percent': 4.0}]
)
self.assertEqual(100.0, sum(i['percent'] for i in response['top_words']))
assert 100.0 == sum((i['percent'] for i in response['top_words']))
def test_indexibility(self):
"""
@@ -112,13 +112,7 @@ class WordCloudBlockTest(TestCase):
module_system = get_test_system()
block = WordCloudBlock(module_system, DictFieldData(self.raw_field_data), Mock())
self.assertEqual(
block.index_dictionary(),
{
'content_type': 'Word Cloud',
'content': {
'display_name': 'Word Cloud Block',
'instructions': 'Enter some random words that comes to your mind'
}
}
)
assert block.index_dictionary() ==\
{'content_type': 'Word Cloud',
'content': {'display_name': 'Word Cloud Block',
'instructions': 'Enter some random words that comes to your mind'}}

View File

@@ -340,10 +340,7 @@ class TestStudentView(XBlockWrapperTestMixin, TestCase):
"""
Assert that both student_view and get_html render the same.
"""
self.assertEqual(
descriptor._xmodule.get_html(),
descriptor.render(STUDENT_VIEW).content
)
assert descriptor._xmodule.get_html() == descriptor.render(STUDENT_VIEW).content
class TestStudioView(XBlockWrapperTestMixin, TestCase):
@@ -367,7 +364,7 @@ class TestStudioView(XBlockWrapperTestMixin, TestCase):
"""
html = descriptor.get_html()
rendered_content = descriptor.render(STUDIO_VIEW).content
self.assertEqual(html, rendered_content)
assert html == rendered_content
@ddt.ddt
@@ -392,8 +389,8 @@ class TestXModuleHandler(TestCase):
def test_xmodule_handler_return_value(self):
response = self.module.xmodule_handler(self.request)
self.assertIsInstance(response, webob.Response)
self.assertEqual(response.body.decode('utf-8'), '{}')
assert isinstance(response, webob.Response)
assert response.body.decode('utf-8') == '{}'
@ddt.data(
u'{"test_key": "test_value"}',
@@ -407,8 +404,8 @@ class TestXModuleHandler(TestCase):
self.module.handle_ajax = Mock(return_value=response_data)
response = self.module.xmodule_handler(self.request)
self.assertIsInstance(response, webob.Response)
self.assertEqual(response.body.decode('utf-8'), '{"test_key": "test_value"}')
assert isinstance(response, webob.Response)
assert response.body.decode('utf-8') == '{"test_key": "test_value"}'
class TestXmlExport(XBlockWrapperTestMixin, TestCase):
@@ -430,8 +427,8 @@ class TestXmlExport(XBlockWrapperTestMixin, TestCase):
xmodule_node = etree.fromstring(descriptor.export_to_xml(xmodule_api_fs))
self.assertEqual(list(xmodule_api_fs.walk()), list(xblock_api_fs.walk()))
self.assertEqual(etree.tostring(xmodule_node), etree.tostring(xblock_node))
assert list(xmodule_api_fs.walk()) == list(xblock_api_fs.walk())
assert etree.tostring(xmodule_node) == etree.tostring(xblock_node)
class TestPublicView(XBlockWrapperTestMixin, TestCase):
@@ -453,12 +450,6 @@ class TestPublicView(XBlockWrapperTestMixin, TestCase):
Assert that public_view contains correct message.
"""
if descriptor.display_name:
self.assertIn(
descriptor.display_name,
descriptor.render(PUBLIC_VIEW).content
)
assert descriptor.display_name in descriptor.render(PUBLIC_VIEW).content
else:
self.assertIn(
"This content is only accessible",
descriptor.render(PUBLIC_VIEW).content
)
assert 'This content is only accessible' in descriptor.render(PUBLIC_VIEW).content

View File

@@ -131,8 +131,8 @@ class InheritingFieldDataTest(unittest.TestCase):
Test that the Blocks with nothing set with return the fields' defaults.
"""
block = self.get_a_block()
self.assertEqual(block.inherited, "the default")
self.assertEqual(block.not_inherited, "nothing")
assert block.inherited == 'the default'
assert block.not_inherited == 'nothing'
def test_set_value(self):
"""
@@ -141,8 +141,8 @@ class InheritingFieldDataTest(unittest.TestCase):
block = self.get_a_block()
block.inherited = "Changed!"
block.not_inherited = "New Value!"
self.assertEqual(block.inherited, "Changed!")
self.assertEqual(block.not_inherited, "New Value!")
assert block.inherited == 'Changed!'
assert block.not_inherited == 'New Value!'
def test_inherited(self):
"""
@@ -150,11 +150,11 @@ class InheritingFieldDataTest(unittest.TestCase):
"""
parent_block = self.get_a_block(usage_id=self.get_usage_id("course", "parent"))
parent_block.inherited = "Changed!"
self.assertEqual(parent_block.inherited, "Changed!")
assert parent_block.inherited == 'Changed!'
child = self.get_a_block(usage_id=self.get_usage_id("vertical", "child"))
child.parent = parent_block.location
self.assertEqual(child.inherited, "Changed!")
assert child.inherited == 'Changed!'
def test_inherited_across_generations(self):
"""
@@ -162,12 +162,12 @@ class InheritingFieldDataTest(unittest.TestCase):
"""
parent = self.get_a_block(usage_id=self.get_usage_id("course", "parent"))
parent.inherited = "Changed!"
self.assertEqual(parent.inherited, "Changed!")
assert parent.inherited == 'Changed!'
for child_num in range(10):
usage_id = self.get_usage_id("vertical", "child_{}".format(child_num))
child = self.get_a_block(usage_id=usage_id)
child.parent = parent.location
self.assertEqual(child.inherited, "Changed!")
assert child.inherited == 'Changed!'
def test_not_inherited(self):
"""
@@ -175,11 +175,11 @@ class InheritingFieldDataTest(unittest.TestCase):
"""
parent = self.get_a_block(usage_id=self.get_usage_id("course", "parent"))
parent.not_inherited = "Changed!"
self.assertEqual(parent.not_inherited, "Changed!")
assert parent.not_inherited == 'Changed!'
child = self.get_a_block(usage_id=self.get_usage_id("vertical", "child"))
child.parent = parent.location
self.assertEqual(child.not_inherited, "nothing")
assert child.not_inherited == 'nothing'
def test_non_defaults_inherited_across_lib(self):
"""
@@ -192,7 +192,7 @@ class InheritingFieldDataTest(unittest.TestCase):
fields=dict(inherited="changed!"),
defaults=dict(inherited="parent's default"),
)
self.assertEqual(parent_block.inherited, "changed!")
assert parent_block.inherited == 'changed!'
child = self.get_block_using_split_kvs(
block_type="problem",
@@ -201,7 +201,7 @@ class InheritingFieldDataTest(unittest.TestCase):
defaults={},
)
child.parent = parent_block.location
self.assertEqual(child.inherited, "changed!")
assert child.inherited == 'changed!'
def test_defaults_not_inherited_across_lib(self):
"""
@@ -214,7 +214,7 @@ class InheritingFieldDataTest(unittest.TestCase):
fields=dict(inherited="changed!"),
defaults=dict(inherited="parent's default"),
)
self.assertEqual(parent_block.inherited, "changed!")
assert parent_block.inherited == 'changed!'
child = self.get_block_using_split_kvs(
block_type="library_content",
@@ -223,7 +223,7 @@ class InheritingFieldDataTest(unittest.TestCase):
defaults=dict(inherited="child's default"),
)
child.parent = parent_block.location
self.assertEqual(child.inherited, "child's default")
assert child.inherited == "child's default"
class EditableMetadataFieldsTest(unittest.TestCase):
@@ -232,7 +232,7 @@ class EditableMetadataFieldsTest(unittest.TestCase):
editable_fields = self.get_xml_editable_fields(DictFieldData({}))
# Tests that the xblock fields (currently tags and name) get filtered out.
# Also tests that xml_attributes is filtered out of XmlDescriptor.
self.assertEqual(1, len(editable_fields), editable_fields)
assert 1 == len(editable_fields), editable_fields
self.assert_field_values(
editable_fields, 'display_name', XModuleMixin.display_name,
explicitly_set=False, value=None, default_value=None
@@ -249,7 +249,7 @@ class EditableMetadataFieldsTest(unittest.TestCase):
def test_integer_field(self):
descriptor = self.get_descriptor(DictFieldData({'max_attempts': '7'}))
editable_fields = descriptor.editable_metadata_fields
self.assertEqual(8, len(editable_fields))
assert 8 == len(editable_fields)
self.assert_field_values(
editable_fields, 'max_attempts', TestFields.max_attempts,
explicitly_set=True, value=7, default_value=1000, type='Integer',
@@ -355,17 +355,17 @@ class EditableMetadataFieldsTest(unittest.TestCase):
type='Generic', options=[]): # lint-amnesty, pylint: disable=redefined-builtin
test_field = editable_fields[name]
self.assertEqual(field.name, test_field['field_name'])
self.assertEqual(field.display_name, test_field['display_name'])
self.assertEqual(field.help, test_field['help'])
assert field.name == test_field['field_name']
assert field.display_name == test_field['display_name']
assert field.help == test_field['help']
self.assertEqual(field.to_json(value), test_field['value'])
self.assertEqual(field.to_json(default_value), test_field['default_value'])
assert field.to_json(value) == test_field['value']
assert field.to_json(default_value) == test_field['default_value']
self.assertEqual(options, test_field['options'])
self.assertEqual(type, test_field['type'])
assert options == test_field['options']
assert type == test_field['type']
self.assertEqual(explicitly_set, test_field['explicitly_set'])
assert explicitly_set == test_field['explicitly_set']
class TestSerialize(unittest.TestCase):