From 1951d2eab8e34d896a656ea3c2eca410743813fc Mon Sep 17 00:00:00 2001 From: Nimisha Asthagiri Date: Mon, 19 Aug 2019 11:42:36 -0400 Subject: [PATCH 01/20] Fix byte encoding of Grades hashes --- lms/djangoapps/grades/models.py | 2 +- lms/djangoapps/grades/transformer.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lms/djangoapps/grades/models.py b/lms/djangoapps/grades/models.py index a287f4d314..a0e398976d 100644 --- a/lms/djangoapps/grades/models.py +++ b/lms/djangoapps/grades/models.py @@ -79,7 +79,7 @@ class BlockRecordList(object): supported by adding a label indicated which algorithm was used, e.g., "sha256$j0NDRmSPa5bfid2pAcUXaxCm2Dlh3TwayItZstwyeqQ=". """ - return b64encode(sha1(self.json_value).digest()) + return b64encode(sha1(self.json_value.encode('utf-8')).digest()) @lazy def json_value(self): diff --git a/lms/djangoapps/grades/transformer.py b/lms/djangoapps/grades/transformer.py index a959e583f5..7470c8ac91 100644 --- a/lms/djangoapps/grades/transformer.py +++ b/lms/djangoapps/grades/transformer.py @@ -93,7 +93,7 @@ class GradesTransformer(BlockStructureTransformer): separators=(',', ':'), # Remove spaces from separators for more compact representation sort_keys=True, ) - return b64encode(sha1(ordered_policy).digest()) + return b64encode(sha1(ordered_policy.encode('utf-8')).digest()) @classmethod def _collect_explicit_graded(cls, block_structure): From b97db5aa86cb840378c8538d40ba6a473168dbcf Mon Sep 17 00:00:00 2001 From: Nimisha Asthagiri Date: Mon, 19 Aug 2019 11:51:05 -0400 Subject: [PATCH 02/20] Fix encode before calling md4 hash in common/djangoapps/util/memcache.py --- common/djangoapps/util/memcache.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/djangoapps/util/memcache.py b/common/djangoapps/util/memcache.py index bca18d51d8..a09d62f440 100644 --- a/common/djangoapps/util/memcache.py +++ b/common/djangoapps/util/memcache.py @@ -17,7 +17,7 @@ def fasthash(string): Hashes `string` into a string representation of a 128-bit digest. """ md4 = hashlib.new("md4") - md4.update(string) + md4.update(string.encode('utf-8')) return md4.hexdigest() From 95a4e9ba3cb56658a28dde4b97bbc4964c81bb8d Mon Sep 17 00:00:00 2001 From: David Ormsbee Date: Mon, 19 Aug 2019 12:16:39 -0400 Subject: [PATCH 03/20] Fix BlockTransformer Py3 issues (#21376) Django's reverse can handle Unicode for arguments. --- cms/lib/xblock/runtime.py | 2 +- common/lib/xmodule/xmodule/modulestore/mongo/base.py | 2 +- lms/djangoapps/lms_xblock/runtime.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cms/lib/xblock/runtime.py b/cms/lib/xblock/runtime.py index 9b7f300632..016717fbe2 100644 --- a/cms/lib/xblock/runtime.py +++ b/cms/lib/xblock/runtime.py @@ -17,7 +17,7 @@ def handler_url(block, handler_name, suffix='', query='', thirdparty=False): raise NotImplementedError("edX Studio doesn't support third-party xblock handler urls") url = reverse('component_handler', kwargs={ - 'usage_key_string': six.text_type(block.scope_ids.usage_id).encode('utf-8'), + 'usage_key_string': six.text_type(block.scope_ids.usage_id), 'handler': handler_name, 'suffix': suffix, }).rstrip('/') diff --git a/common/lib/xmodule/xmodule/modulestore/mongo/base.py b/common/lib/xmodule/xmodule/modulestore/mongo/base.py index 26c6181b24..bd3c5b5264 100644 --- a/common/lib/xmodule/xmodule/modulestore/mongo/base.py +++ b/common/lib/xmodule/xmodule/modulestore/mongo/base.py @@ -859,7 +859,7 @@ class MongoModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase, Mongo course_key = self.fill_in_run(course_key) parent_cache = self._get_parent_cache(self.get_branch_setting()) - while to_process and depth is None or depth >= 0: + while to_process and (depth is None or depth >= 0): children = [] for item in to_process: self._clean_item_data(item) diff --git a/lms/djangoapps/lms_xblock/runtime.py b/lms/djangoapps/lms_xblock/runtime.py index 483733073a..8b9d68e65c 100644 --- a/lms/djangoapps/lms_xblock/runtime.py +++ b/lms/djangoapps/lms_xblock/runtime.py @@ -51,7 +51,7 @@ def handler_url(block, handler_name, suffix='', query='', thirdparty=False): url = reverse(view_name, kwargs={ 'course_id': six.text_type(block.location.course_key), - 'usage_id': quote_slashes(six.text_type(block.scope_ids.usage_id).encode('utf-8')), + 'usage_id': quote_slashes(six.text_type(block.scope_ids.usage_id)), 'handler': handler_name, 'suffix': suffix, }) From f17f9d386223eba1e4f6ca6d034a58cf62fe76d5 Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Mon, 19 Aug 2019 12:43:09 -0400 Subject: [PATCH 04/20] All of the fall 2012 courses have been imported by now. --- common/lib/xmodule/xmodule/modulestore/xml.py | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/common/lib/xmodule/xmodule/modulestore/xml.py b/common/lib/xmodule/xmodule/modulestore/xml.py index 371280c866..fc31eda63a 100644 --- a/common/lib/xmodule/xmodule/modulestore/xml.py +++ b/common/lib/xmodule/xmodule/modulestore/xml.py @@ -11,7 +11,6 @@ import sys from collections import defaultdict from contextlib import contextmanager from importlib import import_module -from io import BytesIO import six from fs.osfs import OSFS @@ -49,16 +48,6 @@ etree.set_default_parser(edx_xml_parser) log = logging.getLogger(__name__) -# VS[compat] -# TODO (cpennington): Remove this once all fall 2012 courses have been imported -# into the cms from xml -def clean_out_mako_templating(xml_string): - orig_xml = xml_string - xml_string = xml_string.replace('%include', 'include') - xml_string = re.sub(r"(?m)^\s*%.*$", '', xml_string) - return xml_string - - class ImportSystem(XMLParsingSystem, MakoDescriptorSystem): def __init__(self, xmlstore, course_id, course_dir, error_tracker, @@ -171,10 +160,6 @@ class ImportSystem(XMLParsingSystem, MakoDescriptorSystem): xml_data.set('url_name', url_name) try: - # VS[compat] - # TODO (cpennington): Remove this once all fall 2012 courses - # have been imported into the cms from xml - xml = clean_out_mako_templating(xml) xml_data = etree.fromstring(xml) make_name_unique(xml_data) @@ -451,10 +436,6 @@ class XMLModuleStore(ModuleStoreReadBase): log.debug('========> Starting courselike import from %s', course_dir) with open(self.data_dir / course_dir / self.parent_xml) as course_file: - # VS[compat] - # TODO (cpennington): Remove this once all fall 2012 courses have - # been imported into the cms from xml - course_file = BytesIO(clean_out_mako_templating(course_file.read())) course_data = etree.parse(course_file, parser=edx_xml_parser).getroot() From d564af8301d1be6d08a0929f7120c32cac35f492 Mon Sep 17 00:00:00 2001 From: Nimisha Asthagiri Date: Mon, 19 Aug 2019 14:26:48 -0400 Subject: [PATCH 05/20] Fix for decode errors in bulk_email.tests.test_course_optout.py --- common/djangoapps/track/views/__init__.py | 2 +- lms/djangoapps/bulk_email/tests/test_course_optout.py | 2 +- lms/djangoapps/instructor/views/instructor_dashboard.py | 2 +- lms/djangoapps/instructor_task/api.py | 2 +- lms/djangoapps/instructor_task/api_helper.py | 2 +- lms/templates/experiments/user_metadata.html | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/common/djangoapps/track/views/__init__.py b/common/djangoapps/track/views/__init__.py index 6b0bd06357..d36a3d8eca 100644 --- a/common/djangoapps/track/views/__init__.py +++ b/common/djangoapps/track/views/__init__.py @@ -121,7 +121,7 @@ def server_track(request, event_type, event, page=None): "event_source": "server", "event_type": event_type, "event": event, - "agent": _get_request_header(request, 'HTTP_USER_AGENT').decode('latin1'), + "agent": _get_request_header(request, 'HTTP_USER_AGENT').encode().decode('latin1'), "page": page, "time": datetime.datetime.utcnow().replace(tzinfo=pytz.utc), "host": _get_request_header(request, 'SERVER_NAME'), diff --git a/lms/djangoapps/bulk_email/tests/test_course_optout.py b/lms/djangoapps/bulk_email/tests/test_course_optout.py index 225ae65cac..8407889567 100644 --- a/lms/djangoapps/bulk_email/tests/test_course_optout.py +++ b/lms/djangoapps/bulk_email/tests/test_course_optout.py @@ -57,7 +57,7 @@ class TestOptoutCourseEmails(ModuleStoreTestCase): response = self.client.get(url) email_section = '
' # If this fails, it is likely because BulkEmailFlag.is_enabled() is set to False - self.assertIn(email_section, response.content) + self.assertIn(email_section, response.content.decode('utf-8')) def test_optout_course(self): """ diff --git a/lms/djangoapps/instructor/views/instructor_dashboard.py b/lms/djangoapps/instructor/views/instructor_dashboard.py index 2fb8489fe0..0c596b73bf 100644 --- a/lms/djangoapps/instructor/views/instructor_dashboard.py +++ b/lms/djangoapps/instructor/views/instructor_dashboard.py @@ -739,7 +739,7 @@ def _section_send_email(course, access): usage_id_serializer=lambda usage_id: quote_slashes(six.text_type(usage_id)), # Generate a new request_token here at random, because this module isn't connected to any other # xblock rendering. - request_token=uuid.uuid1().get_hex() + request_token=uuid.uuid1().hex ) cohorts = [] if is_course_cohorted(course_key): diff --git a/lms/djangoapps/instructor_task/api.py b/lms/djangoapps/instructor_task/api.py index b587aa4a1a..52c06bb68a 100644 --- a/lms/djangoapps/instructor_task/api.py +++ b/lms/djangoapps/instructor_task/api.py @@ -320,7 +320,7 @@ def submit_bulk_course_email(request, course_key, email_id): task_input = {'email_id': email_id, 'to_option': targets} task_key_stub = str(email_id) # create the key value by using MD5 hash: - task_key = hashlib.md5(task_key_stub).hexdigest() + task_key = hashlib.md5(task_key_stub.encode('utf-8')).hexdigest() return submit_task(request, task_type, task_class, course_key, task_input, task_key) diff --git a/lms/djangoapps/instructor_task/api_helper.py b/lms/djangoapps/instructor_task/api_helper.py index 77dba670be..10afaef641 100644 --- a/lms/djangoapps/instructor_task/api_helper.py +++ b/lms/djangoapps/instructor_task/api_helper.py @@ -140,7 +140,7 @@ def _get_xmodule_instance_args(request, task_id): request_info = {'username': request.user.username, 'user_id': request.user.id, 'ip': request.META['REMOTE_ADDR'], - 'agent': request.META.get('HTTP_USER_AGENT', '').decode('latin1'), + 'agent': request.META.get('HTTP_USER_AGENT', '').encode().decode('latin1'), 'host': request.META['SERVER_NAME'], } diff --git a/lms/templates/experiments/user_metadata.html b/lms/templates/experiments/user_metadata.html index 00a1a3daa4..d4b0ba0963 100644 --- a/lms/templates/experiments/user_metadata.html +++ b/lms/templates/experiments/user_metadata.html @@ -59,7 +59,7 @@ if course_key: } if not course_id: - user_metadata['course_id'] = unicode(course_key) + user_metadata['course_id'] = six.text_type(course_key) elif isinstance(course_key, six.string_types): user_metadata['course_id'] = course_key From e64c61160edced875edcdc894c72665641a8f157 Mon Sep 17 00:00:00 2001 From: "Dave St.Germain" Date: Mon, 19 Aug 2019 14:54:03 -0400 Subject: [PATCH 06/20] Iterating dictionaries --- common/lib/xmodule/xmodule/modulestore/django.py | 2 +- lms/templates/shoppingcart/cybersource_form.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/common/lib/xmodule/xmodule/modulestore/django.py b/common/lib/xmodule/xmodule/modulestore/django.py index 4c1bd60185..6988e649b4 100644 --- a/common/lib/xmodule/xmodule/modulestore/django.py +++ b/common/lib/xmodule/xmodule/modulestore/django.py @@ -425,7 +425,7 @@ def _get_modulestore_branch_setting(): # compare hostname against the regex expressions set of mappings which will tell us which branch to use if mappings: - for key in mappings.iterkeys(): + for key in mappings: if re.match(key, hostname): return mappings[key] if branch is None: diff --git a/lms/templates/shoppingcart/cybersource_form.html b/lms/templates/shoppingcart/cybersource_form.html index c42de3354f..6c34a37a0f 100644 --- a/lms/templates/shoppingcart/cybersource_form.html +++ b/lms/templates/shoppingcart/cybersource_form.html @@ -1,6 +1,6 @@ <%! from django.utils.translation import ugettext as _ %>
- % for pk, pv in params.iteritems(): + % for pk, pv in params.items(): % endfor From 5ba4152cb69c3c967913f52eae4add0419f01be9 Mon Sep 17 00:00:00 2001 From: "Dave St.Germain" Date: Mon, 19 Aug 2019 15:02:09 -0400 Subject: [PATCH 07/20] Upgrade edx-val for python3 compatibility --- requirements/edx/base.txt | 2 +- requirements/edx/development.txt | 2 +- requirements/edx/testing.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt index 3c3a3b3f05..25e165e3be 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -121,7 +121,7 @@ git+https://github.com/mitodl/edx-sga.git@3828ba9e413080a81b907a3381e5ffa05e063f edx-submissions==2.1.1 edx-user-state-client==1.1.1 edx-when==0.3 -edxval==1.1.25 +edxval==1.1.26 elasticsearch==1.9.0 # via edx-search enum34==1.1.6 event-tracking==0.2.9 diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt index 2c458aee6f..5004735747 100644 --- a/requirements/edx/development.txt +++ b/requirements/edx/development.txt @@ -147,7 +147,7 @@ edx-sphinx-theme==1.5.0 edx-submissions==2.1.1 edx-user-state-client==1.1.1 edx-when==0.3 -edxval==1.1.25 +edxval==1.1.26 elasticsearch==1.9.0 entrypoints==0.3 enum34==1.1.6 diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt index 7b6e9897a0..243a08f6be 100644 --- a/requirements/edx/testing.txt +++ b/requirements/edx/testing.txt @@ -142,7 +142,7 @@ git+https://github.com/mitodl/edx-sga.git@3828ba9e413080a81b907a3381e5ffa05e063f edx-submissions==2.1.1 edx-user-state-client==1.1.1 edx-when==0.3 -edxval==1.1.25 +edxval==1.1.26 elasticsearch==1.9.0 entrypoints==0.3 # via flake8 enum34==1.1.6 From 9d8db8e4cab03863873ebf598ededa4459f2e002 Mon Sep 17 00:00:00 2001 From: "Dave St.Germain" Date: Mon, 19 Aug 2019 15:10:56 -0400 Subject: [PATCH 08/20] Convert to utf-8 before JSON decoding --- cms/djangoapps/contentstore/views/assets.py | 2 +- cms/djangoapps/contentstore/views/certificates.py | 2 +- common/djangoapps/util/json_request.py | 2 +- lms/djangoapps/ccx/views.py | 2 +- lms/djangoapps/courseware/views/views.py | 2 +- lms/djangoapps/edxnotes/views.py | 2 +- openedx/core/djangoapps/lang_pref/views.py | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cms/djangoapps/contentstore/views/assets.py b/cms/djangoapps/contentstore/views/assets.py index 8a8780f41a..c914063283 100644 --- a/cms/djangoapps/contentstore/views/assets.py +++ b/cms/djangoapps/contentstore/views/assets.py @@ -538,7 +538,7 @@ def _update_asset(request, course_key, asset_key): # update existing asset try: - modified_asset = json.loads(request.body) + modified_asset = json.loads(request.body.decode('utf8')) except ValueError: return HttpResponseBadRequest() contentstore().set_attr(asset_key, 'locked', modified_asset['locked']) diff --git a/cms/djangoapps/contentstore/views/certificates.py b/cms/djangoapps/contentstore/views/certificates.py index a47af6ec8f..69a208c8b9 100644 --- a/cms/djangoapps/contentstore/views/certificates.py +++ b/cms/djangoapps/contentstore/views/certificates.py @@ -349,7 +349,7 @@ def certificate_activation_handler(request, course_key_string): msg = _(u'PermissionDenied: Failed in authenticating {user}').format(user=request.user) return JsonResponse({"error": msg}, status=403) - data = json.loads(request.body) + data = json.loads(request.body.decode('utf8')) is_active = data.get('is_active', False) certificates = CertificateManager.get_certificates(course) diff --git a/common/djangoapps/util/json_request.py b/common/djangoapps/util/json_request.py index a5badd3bb7..2b001ed9e3 100644 --- a/common/djangoapps/util/json_request.py +++ b/common/djangoapps/util/json_request.py @@ -46,7 +46,7 @@ def expect_json(view_function): # e.g. 'charset', so we can't do a direct string compare if "application/json" in request.META.get('CONTENT_TYPE', '') and request.body: try: - request.json = json.loads(request.body) + request.json = json.loads(request.body.decode('utf8')) except ValueError: return JsonResponseBadRequest({"error": "Invalid JSON"}) else: diff --git a/lms/djangoapps/ccx/views.py b/lms/djangoapps/ccx/views.py index b9144839ec..c7b3e17885 100644 --- a/lms/djangoapps/ccx/views.py +++ b/lms/djangoapps/ccx/views.py @@ -313,7 +313,7 @@ def save_ccx(request, course, ccx=None): return earliest, ccx_ids_to_delete graded = {} - earliest, ccx_ids_to_delete = override_fields(course, json.loads(request.body), graded, []) + earliest, ccx_ids_to_delete = override_fields(course, json.loads(request.body.decode('utf8')), graded, []) bulk_delete_ccx_override_fields(ccx, ccx_ids_to_delete) if earliest: override_field_for_ccx(ccx, course, 'start', earliest) diff --git a/lms/djangoapps/courseware/views/views.py b/lms/djangoapps/courseware/views/views.py index 43898fa28c..c6fe2f06d8 100644 --- a/lms/djangoapps/courseware/views/views.py +++ b/lms/djangoapps/courseware/views/views.py @@ -1633,7 +1633,7 @@ def financial_assistance(_request): def financial_assistance_request(request): """Submit a request for financial assistance to Zendesk.""" try: - data = json.loads(request.body) + data = json.loads(request.body.decode('utf8')) # Simple sanity check that the session belongs to the user # submitting an FA request username = data['username'] diff --git a/lms/djangoapps/edxnotes/views.py b/lms/djangoapps/edxnotes/views.py index 0704af26b9..6833f19be4 100644 --- a/lms/djangoapps/edxnotes/views.py +++ b/lms/djangoapps/edxnotes/views.py @@ -205,7 +205,7 @@ def edxnotes_visibility(request, course_id): raise Http404 try: - visibility = json.loads(request.body)["visibility"] + visibility = json.loads(request.body.decode('utf8'))["visibility"] course_module.edxnotes_visibility = visibility course_module.save() return JsonResponse(status=200) diff --git a/openedx/core/djangoapps/lang_pref/views.py b/openedx/core/djangoapps/lang_pref/views.py index 95127e9103..d1196d48e5 100644 --- a/openedx/core/djangoapps/lang_pref/views.py +++ b/openedx/core/djangoapps/lang_pref/views.py @@ -22,7 +22,7 @@ def update_session_language(request): """ response = HttpResponse(200) if request.method == 'PATCH': - data = json.loads(request.body) + data = json.loads(request.body.decode('utf8')) language = data.get(LANGUAGE_KEY, settings.LANGUAGE_CODE) if request.session.get(LANGUAGE_SESSION_KEY, None) != language: request.session[LANGUAGE_SESSION_KEY] = six.text_type(language) From eccfeef94bbd548d5a7246eff756af9d6787488f Mon Sep 17 00:00:00 2001 From: "Dave St.Germain" Date: Mon, 19 Aug 2019 15:13:37 -0400 Subject: [PATCH 09/20] Convert from utf8 --- lms/djangoapps/instructor/views/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lms/djangoapps/instructor/views/api.py b/lms/djangoapps/instructor/views/api.py index ac12af8673..f44015e93b 100644 --- a/lms/djangoapps/instructor/views/api.py +++ b/lms/djangoapps/instructor/views/api.py @@ -3273,7 +3273,7 @@ def parse_request_data(request): :return: dict object containing parsed json data. """ try: - data = json.loads(request.body or '{}') + data = json.loads(request.body.decode('utf8') or u'{}') except ValueError: raise ValueError(_('The record is not in the correct format. Please add a valid username or email address.')) From aaf7ddd3f3339640ca022f099888468b89edfda0 Mon Sep 17 00:00:00 2001 From: "Dave St.Germain" Date: Mon, 19 Aug 2019 16:08:38 -0400 Subject: [PATCH 10/20] Correctly encode and decode --- common/lib/xmodule/xmodule/course_metadata_utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common/lib/xmodule/xmodule/course_metadata_utils.py b/common/lib/xmodule/xmodule/course_metadata_utils.py index faa43f37b3..c862356513 100644 --- a/common/lib/xmodule/xmodule/course_metadata_utils.py +++ b/common/lib/xmodule/xmodule/course_metadata_utils.py @@ -66,8 +66,9 @@ def clean_course_key(course_key, padding_char): padding_char (str): Character used for padding at end of the encoded string. The standard value for this is '='. """ + encoded = b32encode(six.text_type(course_key).encode('utf8')).decode('utf8') return "course_{}".format( - b32encode(six.text_type(course_key)).replace('=', padding_char) + encoded.replace('=', padding_char) ) From 521cdbe309b34be4bfe90d143e8a3f8e912c2b52 Mon Sep 17 00:00:00 2001 From: "Dave St.Germain" Date: Mon, 19 Aug 2019 16:16:31 -0400 Subject: [PATCH 11/20] Response content is bytes --- .../instructor/tests/test_spoc_gradebook.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lms/djangoapps/instructor/tests/test_spoc_gradebook.py b/lms/djangoapps/instructor/tests/test_spoc_gradebook.py index b1a88db803..eaa8c91271 100644 --- a/lms/djangoapps/instructor/tests/test_spoc_gradebook.py +++ b/lms/djangoapps/instructor/tests/test_spoc_gradebook.py @@ -98,17 +98,17 @@ class TestDefaultGradingPolicy(TestGradebook): def test_default_policy(self): # Default >= 50% passes, so Users 5-10 should be passing for Homework 1 [6] # One use at the top of the page [1] - self.assertEquals(7, self.response.content.count('grade_Pass')) + self.assertEquals(7, self.response.content.count(b'grade_Pass')) # Users 1-5 attempted Homework 1 (and get Fs) [4] # Users 1-10 attempted any homework (and get Fs) [10] # Users 4-10 scored enough to not get rounded to 0 for the class (and get Fs) [7] # One use at top of the page [1] - self.assertEquals(22, self.response.content.count('grade_F')) + self.assertEquals(22, self.response.content.count(b'grade_F')) # All other grades are None [29 categories * 11 users - 27 non-empty grades = 292] # One use at the top of the page [1] - self.assertEquals(293, self.response.content.count('grade_None')) + self.assertEquals(293, self.response.content.count(b'grade_None')) class TestLetterCutoffPolicy(TestGradebook): @@ -145,29 +145,29 @@ class TestLetterCutoffPolicy(TestGradebook): # Users 9-10 have >= 90% on Homeworks [2] # Users 9-10 have >= 90% on the class [2] # One use at the top of the page [1] - self.assertEquals(5, self.response.content.count('grade_A')) + self.assertEquals(5, self.response.content.count(b'grade_A')) # User 8 has 80 <= Homeworks < 90 [1] # User 8 has 80 <= class < 90 [1] # One use at the top of the page [1] - self.assertEquals(3, self.response.content.count('grade_B')) + self.assertEquals(3, self.response.content.count(b'grade_B')) # User 7 has 70 <= Homeworks < 80 [1] # User 7 has 70 <= class < 80 [1] # One use at the top of the page [1] - self.assertEquals(3, self.response.content.count('grade_C')) + self.assertEquals(3, self.response.content.count(b'grade_C')) # User 6 has 60 <= Homeworks < 70 [1] # User 6 has 60 <= class < 70 [1] # One use at the top of the page [1] - self.assertEquals(3, self.response.content.count('grade_C')) + self.assertEquals(3, self.response.content.count(b'grade_C')) # Users 1-5 have 60% > grades > 0 on Homeworks [5] # Users 1-5 have 60% > grades > 0 on the class [5] # One use at top of the page [1] - self.assertEquals(11, self.response.content.count('grade_F')) + self.assertEquals(11, self.response.content.count(b'grade_F')) # User 0 has 0 on Homeworks [1] # User 0 has 0 on the class [1] # One use at the top of the page [1] - self.assertEquals(3, self.response.content.count('grade_None')) + self.assertEquals(3, self.response.content.count(b'grade_None')) From 8e725c9eee9567311dda918378a1929b2376cb12 Mon Sep 17 00:00:00 2001 From: "Dave St.Germain" Date: Mon, 19 Aug 2019 16:21:28 -0400 Subject: [PATCH 12/20] Prevent comparison to None --- .../discussion/django_comment_client/utils.py | 2 +- .../instructor/tests/test_spoc_gradebook.py | 20 +++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lms/djangoapps/discussion/django_comment_client/utils.py b/lms/djangoapps/discussion/django_comment_client/utils.py index d1083d9f95..158b2ae73c 100644 --- a/lms/djangoapps/discussion/django_comment_client/utils.py +++ b/lms/djangoapps/discussion/django_comment_client/utils.py @@ -906,7 +906,7 @@ def is_comment_too_deep(parent): return ( MAX_COMMENT_DEPTH is not None and ( MAX_COMMENT_DEPTH < 0 or - (parent and parent["depth"] >= MAX_COMMENT_DEPTH) + (parent and (parent["depth"] or 0) >= MAX_COMMENT_DEPTH) ) ) diff --git a/lms/djangoapps/instructor/tests/test_spoc_gradebook.py b/lms/djangoapps/instructor/tests/test_spoc_gradebook.py index eaa8c91271..e335d18569 100644 --- a/lms/djangoapps/instructor/tests/test_spoc_gradebook.py +++ b/lms/djangoapps/instructor/tests/test_spoc_gradebook.py @@ -83,7 +83,7 @@ class TestGradebook(SharedModuleStoreTestCase): args=(text_type(self.course.id),) )) - self.assertEquals(self.response.status_code, 200) + self.assertEqual(self.response.status_code, 200) class TestDefaultGradingPolicy(TestGradebook): @@ -98,17 +98,17 @@ class TestDefaultGradingPolicy(TestGradebook): def test_default_policy(self): # Default >= 50% passes, so Users 5-10 should be passing for Homework 1 [6] # One use at the top of the page [1] - self.assertEquals(7, self.response.content.count(b'grade_Pass')) + self.assertEqual(7, self.response.content.count(b'grade_Pass')) # Users 1-5 attempted Homework 1 (and get Fs) [4] # Users 1-10 attempted any homework (and get Fs) [10] # Users 4-10 scored enough to not get rounded to 0 for the class (and get Fs) [7] # One use at top of the page [1] - self.assertEquals(22, self.response.content.count(b'grade_F')) + self.assertEqual(22, self.response.content.count(b'grade_F')) # All other grades are None [29 categories * 11 users - 27 non-empty grades = 292] # One use at the top of the page [1] - self.assertEquals(293, self.response.content.count(b'grade_None')) + self.assertEqual(293, self.response.content.count(b'grade_None')) class TestLetterCutoffPolicy(TestGradebook): @@ -145,29 +145,29 @@ class TestLetterCutoffPolicy(TestGradebook): # Users 9-10 have >= 90% on Homeworks [2] # Users 9-10 have >= 90% on the class [2] # One use at the top of the page [1] - self.assertEquals(5, self.response.content.count(b'grade_A')) + self.assertEqual(5, self.response.content.count(b'grade_A')) # User 8 has 80 <= Homeworks < 90 [1] # User 8 has 80 <= class < 90 [1] # One use at the top of the page [1] - self.assertEquals(3, self.response.content.count(b'grade_B')) + self.assertEqual(3, self.response.content.count(b'grade_B')) # User 7 has 70 <= Homeworks < 80 [1] # User 7 has 70 <= class < 80 [1] # One use at the top of the page [1] - self.assertEquals(3, self.response.content.count(b'grade_C')) + self.assertEqual(3, self.response.content.count(b'grade_C')) # User 6 has 60 <= Homeworks < 70 [1] # User 6 has 60 <= class < 70 [1] # One use at the top of the page [1] - self.assertEquals(3, self.response.content.count(b'grade_C')) + self.assertEqual(3, self.response.content.count(b'grade_C')) # Users 1-5 have 60% > grades > 0 on Homeworks [5] # Users 1-5 have 60% > grades > 0 on the class [5] # One use at top of the page [1] - self.assertEquals(11, self.response.content.count(b'grade_F')) + self.assertEqual(11, self.response.content.count(b'grade_F')) # User 0 has 0 on Homeworks [1] # User 0 has 0 on the class [1] # One use at the top of the page [1] - self.assertEquals(3, self.response.content.count(b'grade_None')) + self.assertEqual(3, self.response.content.count(b'grade_None')) From a3b52662d11f89a16e03e6908f19c9aa90f206c7 Mon Sep 17 00:00:00 2001 From: "Dave St.Germain" Date: Mon, 19 Aug 2019 16:27:04 -0400 Subject: [PATCH 13/20] Prevent changing dict while iterating --- common/djangoapps/student/tests/factories.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/djangoapps/student/tests/factories.py b/common/djangoapps/student/tests/factories.py index 90d4f30a79..d948e9ec92 100644 --- a/common/djangoapps/student/tests/factories.py +++ b/common/djangoapps/student/tests/factories.py @@ -135,7 +135,7 @@ class CourseEnrollmentFactory(DjangoModelFactory): def _create(cls, model_class, *args, **kwargs): manager = cls._get_manager(model_class) course_kwargs = {} - for key in kwargs.keys(): + for key in list(kwargs): if key.startswith('course__'): course_kwargs[key.split('__')[1]] = kwargs.pop(key) From c51db6c92de36cba90e929a88918b844bd929552 Mon Sep 17 00:00:00 2001 From: "Dave St.Germain" Date: Mon, 19 Aug 2019 16:35:41 -0400 Subject: [PATCH 14/20] Must compare with bytes --- lms/djangoapps/courseware/tests/test_date_summary.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lms/djangoapps/courseware/tests/test_date_summary.py b/lms/djangoapps/courseware/tests/test_date_summary.py index 068f6ac9df..ecb5619153 100644 --- a/lms/djangoapps/courseware/tests/test_date_summary.py +++ b/lms/djangoapps/courseware/tests/test_date_summary.py @@ -61,7 +61,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase): self.client.login(username=user.username, password=TEST_PASSWORD) url = reverse('info', args=(course.id,)) response = self.client.get(url) - self.assertNotIn('date-summary', response.content) + self.assertNotIn(b'date-summary', response.content) def test_course_home_logged_out(self): course = create_course_run() From 7a28bc87590b82faba8f8fdc446d148f46c2b85c Mon Sep 17 00:00:00 2001 From: "Dave St.Germain" Date: Mon, 19 Aug 2019 16:39:09 -0400 Subject: [PATCH 15/20] Response content is bytes --- cms/djangoapps/contentstore/tests/test_course_settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cms/djangoapps/contentstore/tests/test_course_settings.py b/cms/djangoapps/contentstore/tests/test_course_settings.py index d74e971285..e0a7bc5df6 100644 --- a/cms/djangoapps/contentstore/tests/test_course_settings.py +++ b/cms/djangoapps/contentstore/tests/test_course_settings.py @@ -254,7 +254,7 @@ class CourseDetailsViewTest(CourseTestCase, MilestonesTestCaseMixin): resp = self.client.get_html(course_details_url) self.assertEqual( feature_flags[2], - '

' in resp.content + b'

' in resp.content ) @override_settings(MKTG_URLS={'ROOT': 'dummy-root'}) From 3bb7d0f61ace66303d42b1fe0a912e24be474cb2 Mon Sep 17 00:00:00 2001 From: "Dave St.Germain" Date: Mon, 19 Aug 2019 16:42:20 -0400 Subject: [PATCH 16/20] unicode -> text_type --- cms/djangoapps/contentstore/views/item.py | 40 +++++++++++------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/cms/djangoapps/contentstore/views/item.py b/cms/djangoapps/contentstore/views/item.py index 492a36d24d..c54fd6599f 100644 --- a/cms/djangoapps/contentstore/views/item.py +++ b/cms/djangoapps/contentstore/views/item.py @@ -225,7 +225,7 @@ def xblock_handler(request, usage_key_string): request.user, request.json.get('display_name'), ) - return JsonResponse({'locator': unicode(dest_usage_key), 'courseKey': unicode(dest_usage_key.course_key)}) + return JsonResponse({'locator': text_type(dest_usage_key), 'courseKey': text_type(dest_usage_key.course_key)}) else: return _create_item(request) elif request.method == 'PATCH': @@ -323,14 +323,14 @@ def xblock_view_handler(request, usage_key_string, view_name): xblock.runtime.wrappers.append(partial( wrap_xblock, 'StudioRuntime', - usage_id_serializer=unicode, + usage_id_serializer=text_type, request_token=request_token(request), )) xblock.runtime.wrappers_asides.append(partial( wrap_xblock_aside, 'StudioRuntime', - usage_id_serializer=unicode, + usage_id_serializer=text_type, request_token=request_token(request), extra_classes=['wrapper-comp-plugins'] )) @@ -508,7 +508,7 @@ def _save_xblock(user, xblock, data=None, children_strings=None, metadata=None, store.revert_to_published(xblock.location, user.id) # Returning the same sort of result that we do for other save operations. In the future, # we may want to return the full XBlockInfo. - return JsonResponse({'id': unicode(xblock.location)}) + return JsonResponse({'id': text_type(xblock.location)}) old_metadata = own_metadata(xblock) old_content = xblock.get_explicitly_set_fields_by_scope(Scope.content) @@ -615,7 +615,7 @@ def _save_xblock(user, xblock, data=None, children_strings=None, metadata=None, store.update_item(course, user.id) result = { - 'id': unicode(xblock.location), + 'id': text_type(xblock.location), 'data': data, 'metadata': own_metadata(xblock) } @@ -692,7 +692,7 @@ def _create_item(request): ) return JsonResponse( - {'locator': unicode(created_block.location), 'courseKey': unicode(created_block.location.course_key)} + {'locator': text_type(created_block.location), 'courseKey': text_type(created_block.location.course_key)} ) @@ -724,7 +724,7 @@ def is_source_item_in_target_parents(source_item, target_parent): """ target_ancestors = _create_xblock_ancestor_info(target_parent, is_concise=True)['ancestors'] for target_ancestor in target_ancestors: - if unicode(source_item.location) == target_ancestor['id']: + if text_type(source_item.location) == target_ancestor['id']: return True return False @@ -782,15 +782,15 @@ def _move_item(source_usage_key, target_parent_usage_key, user, target_index=Non error = _('You can not move an item directly into content experiment.') elif source_index is None: error = _(u'{source_usage_key} not found in {parent_usage_key}.').format( - source_usage_key=unicode(source_usage_key), - parent_usage_key=unicode(source_parent.location) + source_usage_key=text_type(source_usage_key), + parent_usage_key=text_type(source_parent.location) ) else: try: target_index = int(target_index) if target_index is not None else None if len(target_parent.children) < target_index: error = _(u'You can not move {source_usage_key} at an invalid index ({target_index}).').format( - source_usage_key=unicode(source_usage_key), + source_usage_key=text_type(source_usage_key), target_index=target_index ) except ValueError: @@ -813,15 +813,15 @@ def _move_item(source_usage_key, target_parent_usage_key, user, target_index=Non log.info( u'MOVE: %s moved from %s to %s at %d index', - unicode(source_usage_key), - unicode(source_parent.location), - unicode(target_parent_usage_key), + text_type(source_usage_key), + text_type(source_parent.location), + text_type(target_parent_usage_key), insert_at ) context = { - 'move_source_locator': unicode(source_usage_key), - 'parent_locator': unicode(target_parent_usage_key), + 'move_source_locator': text_type(source_usage_key), + 'parent_locator': text_type(target_parent_usage_key), 'source_index': target_index if target_index is not None else source_index } return JsonResponse(context) @@ -956,7 +956,7 @@ def orphan_handler(request, course_key_string): course_usage_key = CourseKey.from_string(course_key_string) if request.method == 'GET': if has_studio_read_access(request.user, course_usage_key): - return JsonResponse([unicode(item) for item in modulestore().get_orphans(course_usage_key)]) + return JsonResponse([text_type(item) for item in modulestore().get_orphans(course_usage_key)]) else: raise PermissionDenied() if request.method == 'DELETE': @@ -984,7 +984,7 @@ def _delete_orphans(course_usage_key, user_id, commit=False): if branch == ModuleStoreEnum.BranchName.published: revision = ModuleStoreEnum.RevisionOption.published_only store.delete_item(itemloc, user_id, revision=revision) - return [unicode(item) for item in items] + return [text_type(item) for item in items] def _get_xblock(usage_key, user): @@ -1004,7 +1004,7 @@ def _get_xblock(usage_key, user): raise except InvalidLocationError: log.error("Can't find item by location.") - return JsonResponse({"error": "Can't find item by location: " + unicode(usage_key)}, 404) + return JsonResponse({"error": "Can't find item by location: " + text_type(usage_key)}, 404) def _get_module_info(xblock, rewrite_static_links=True, include_ancestor_info=False, include_publishing_info=False): @@ -1056,7 +1056,7 @@ def _get_gating_info(course, xblock): setattr(course, 'gating_prerequisites', gating_api.get_prerequisites(course.id)) info["is_prereq"] = gating_api.is_prerequisite(course.id, xblock.location) info["prereqs"] = [ - p for p in course.gating_prerequisites if unicode(xblock.location) not in p['namespace'] + p for p in course.gating_prerequisites if text_type(xblock.location) not in p['namespace'] ] prereq, prereq_min_score, prereq_min_completion = gating_api.get_required_content( course.id, @@ -1158,7 +1158,7 @@ def create_xblock_info(xblock, data=None, metadata=None, include_ancestor_info=F pct_sign=_('%')) xblock_info = { - 'id': unicode(xblock.location), + 'id': text_type(xblock.location), 'display_name': xblock.display_name_with_default, 'category': xblock.category, 'has_children': xblock.has_children From 3d2617983b3bc17cb254ad8943be9873d1604f95 Mon Sep 17 00:00:00 2001 From: "Dave St.Germain" Date: Mon, 19 Aug 2019 17:00:17 -0400 Subject: [PATCH 17/20] assertItemsEqual() moved to assertCountEqual() --- .../commands/tests/test_migrate_transcripts.py | 4 ++-- .../commands/tests/test_reindex_courses.py | 3 ++- .../commands/tests/test_reindex_library.py | 2 +- .../views/tests/test_course_index.py | 2 +- .../djangoapps/course_modes/tests/test_models.py | 5 +++-- .../terrain/stubs/tests/test_edxnotes.py | 3 ++- .../third_party_auth/api/tests/test_views.py | 6 +++--- .../djangoapps/xblock_django/tests/test_api.py | 13 +++++++------ .../modulestore/tests/test_mixed_modulestore.py | 2 +- .../test_split_modulestore_bulk_operations.py | 13 +++++++------ common/lib/xmodule/xmodule/tests/__init__.py | 2 +- .../xmodule/xmodule/tests/test_capa_module.py | 4 ++-- common/lib/xmodule/xmodule/tests/test_export.py | 3 ++- .../acceptance/tests/lms/test_lms_courseware.py | 3 ++- .../tests/studio/test_studio_container.py | 5 +++-- .../tests/studio/test_studio_outline.py | 3 ++- lms/djangoapps/badges/tests/test_models.py | 2 +- lms/djangoapps/bulk_email/tests/test_email.py | 16 ++++++++-------- lms/djangoapps/ccx/api/v0/tests/test_views.py | 12 ++++++------ lms/djangoapps/certificates/tests/test_api.py | 4 ++-- .../commands/tests/test_dump_course.py | 2 +- lms/djangoapps/courseware/rules.py | 14 +++++++------- .../courseware/tests/test_submitting_problems.py | 4 ++-- .../courseware/tests/test_video_handlers.py | 2 +- .../courseware/tests/test_video_mongo.py | 2 +- .../django_comment_client/tests/test_utils.py | 7 ++++--- lms/djangoapps/edxnotes/tests.py | 15 ++++++++------- .../instructor_task/tests/test_base.py | 5 +++-- lms/djangoapps/shoppingcart/tests/test_models.py | 4 ++-- .../core/djangoapps/catalog/tests/test_utils.py | 2 +- .../commands/tests/test_dump_to_neo4j.py | 4 ++-- .../djangoapps/enrollments/tests/test_views.py | 4 ++-- .../lang_pref/tests/test_middleware.py | 3 ++- .../core/djangoapps/programs/tests/test_utils.py | 2 +- .../commands/tests/test_send_upgrade_reminder.py | 3 ++- .../site_configuration/tests/test_helpers.py | 11 ++++++----- .../djangoapps/theming/tests/test_commands.py | 7 ++++--- .../djangoapps/theming/tests/test_helpers.py | 5 +++-- .../accounts/tests/test_retirement_views.py | 7 ++++--- .../user_api/accounts/tests/test_views.py | 3 ++- .../core/djangoapps/user_api/tests/test_views.py | 8 ++++---- openedx/core/lib/api/test_utils.py | 3 ++- .../tests/test_course_expiration.py | 10 +++++----- pavelib/paver_tests/test_assets.py | 9 +++++---- 44 files changed, 132 insertions(+), 111 deletions(-) diff --git a/cms/djangoapps/contentstore/management/commands/tests/test_migrate_transcripts.py b/cms/djangoapps/contentstore/management/commands/tests/test_migrate_transcripts.py index fb701fd815..d4a2693237 100644 --- a/cms/djangoapps/contentstore/management/commands/tests/test_migrate_transcripts.py +++ b/cms/djangoapps/contentstore/management/commands/tests/test_migrate_transcripts.py @@ -187,7 +187,7 @@ class TestMigrateTranscripts(ModuleStoreTestCase): Test migrating transcripts """ translations = self.video_descriptor.available_translations(self.video_descriptor.get_transcripts_info()) - self.assertItemsEqual(translations, ['hr', 'ge']) + six.assertCountEqual(translations, ['hr', 'ge']) self.assertFalse(api.is_transcript_available(self.video_descriptor.edx_video_id, 'hr')) self.assertFalse(api.is_transcript_available(self.video_descriptor.edx_video_id, 'ge')) @@ -202,7 +202,7 @@ class TestMigrateTranscripts(ModuleStoreTestCase): Test migrating transcripts multiple times """ translations = self.video_descriptor.available_translations(self.video_descriptor.get_transcripts_info()) - self.assertItemsEqual(translations, ['hr', 'ge']) + six.assertCountEqual(translations, ['hr', 'ge']) self.assertFalse(api.is_transcript_available(self.video_descriptor.edx_video_id, 'hr')) self.assertFalse(api.is_transcript_available(self.video_descriptor.edx_video_id, 'ge')) diff --git a/cms/djangoapps/contentstore/management/commands/tests/test_reindex_courses.py b/cms/djangoapps/contentstore/management/commands/tests/test_reindex_courses.py index 35d8725116..a1a446a285 100644 --- a/cms/djangoapps/contentstore/management/commands/tests/test_reindex_courses.py +++ b/cms/djangoapps/contentstore/management/commands/tests/test_reindex_courses.py @@ -3,6 +3,7 @@ from __future__ import absolute_import import ddt import mock +import six from django.core.management import CommandError, call_command from six import text_type @@ -104,7 +105,7 @@ class TestReindexCourse(ModuleStoreTestCase): patched_yes_no.assert_called_once_with(ReindexCommand.CONFIRMATION_PROMPT, default='no') expected_calls = self._build_calls(self.first_course, self.second_course) - self.assertItemsEqual(patched_index.mock_calls, expected_calls) + six.assertCountEqual(patched_index.mock_calls, expected_calls) def test_given_all_key_prompts_and_reindexes_all_courses_cancelled(self): """ Test that does not reindex anything when --all key is given and cancelled """ diff --git a/cms/djangoapps/contentstore/management/commands/tests/test_reindex_library.py b/cms/djangoapps/contentstore/management/commands/tests/test_reindex_library.py index 5104cf0185..9150441d6d 100644 --- a/cms/djangoapps/contentstore/management/commands/tests/test_reindex_library.py +++ b/cms/djangoapps/contentstore/management/commands/tests/test_reindex_library.py @@ -104,7 +104,7 @@ class TestReindexLibrary(ModuleStoreTestCase): patched_yes_no.assert_called_once_with(ReindexCommand.CONFIRMATION_PROMPT, default='no') expected_calls = self._build_calls(self.first_lib, self.second_lib) - self.assertItemsEqual(patched_index.mock_calls, expected_calls) + six.assertCountEqual(patched_index.mock_calls, expected_calls) def test_given_all_key_prompts_and_reindexes_all_libraries_cancelled(self): """ Test that does not reindex anything when --all key is given and cancelled """ diff --git a/cms/djangoapps/contentstore/views/tests/test_course_index.py b/cms/djangoapps/contentstore/views/tests/test_course_index.py index b22fc2d0fa..c6f10aab31 100644 --- a/cms/djangoapps/contentstore/views/tests/test_course_index.py +++ b/cms/djangoapps/contentstore/views/tests/test_course_index.py @@ -554,7 +554,7 @@ class TestCourseOutline(CourseTestCase): [component for component in advanced_modules if component in deprecated_block_types] ) - self.assertItemsEqual(info['blocks'], expected_blocks) + six.assertCountEqual(info['blocks'], expected_blocks) self.assertEqual( info['advance_settings_url'], reverse_course_url('advanced_settings_handler', course_id) diff --git a/common/djangoapps/course_modes/tests/test_models.py b/common/djangoapps/course_modes/tests/test_models.py index 7dbc967b33..411cfcb5a0 100644 --- a/common/djangoapps/course_modes/tests/test_models.py +++ b/common/djangoapps/course_modes/tests/test_models.py @@ -10,6 +10,7 @@ import itertools from datetime import timedelta import ddt +import six from django.core.exceptions import ValidationError from django.test import TestCase, override_settings from django.utils.timezone import now @@ -399,11 +400,11 @@ class CourseModeModelTest(TestCase): # Check the selectable modes, which should exclude credit selectable_modes = CourseMode.modes_for_course_dict(self.course_key) - self.assertItemsEqual(list(selectable_modes.keys()), expected_selectable_modes) + six.assertCountEqual(list(selectable_modes.keys()), expected_selectable_modes) # When we get all unexpired modes, we should see credit as well all_modes = CourseMode.modes_for_course_dict(self.course_key, only_selectable=False) - self.assertItemsEqual(list(all_modes.keys()), available_modes) + six.assertCountEqual(list(all_modes.keys()), available_modes) def _enrollment_display_modes_dicts(self, dict_type): """ diff --git a/common/djangoapps/terrain/stubs/tests/test_edxnotes.py b/common/djangoapps/terrain/stubs/tests/test_edxnotes.py index 32e1e66d22..39c175db82 100644 --- a/common/djangoapps/terrain/stubs/tests/test_edxnotes.py +++ b/common/djangoapps/terrain/stubs/tests/test_edxnotes.py @@ -9,6 +9,7 @@ from uuid import uuid4 import ddt import requests +import six import six.moves.urllib.parse # pylint: disable=import-error from six.moves import range @@ -192,7 +193,7 @@ class StubEdxNotesServiceTest(unittest.TestCase): updated_note = self._get_notes()[0] self.assertEqual("new test text", updated_note["text"]) self.assertEqual(note["id"], updated_note["id"]) - self.assertItemsEqual(note, updated_note) + six.assertCountEqual(note, updated_note) response = requests.get(self._get_url("api/v1/annotations/does_not_exist")) self.assertEqual(response.status_code, 404) diff --git a/common/djangoapps/third_party_auth/api/tests/test_views.py b/common/djangoapps/third_party_auth/api/tests/test_views.py index 95786a50dc..0a2d8d3503 100644 --- a/common/djangoapps/third_party_auth/api/tests/test_views.py +++ b/common/djangoapps/third_party_auth/api/tests/test_views.py @@ -133,7 +133,7 @@ class UserViewsMixin(object): self.assertEqual(response.status_code, expect_result) if expect_result == 200: self.assertIn("active", response.data) - self.assertItemsEqual(response.data["active"], self.expected_active(target_user)) + six.assertCountEqual(response.data["active"], self.expected_active(target_user)) @ddt.data( # A server with a valid API key can query any user's list of providers @@ -149,7 +149,7 @@ class UserViewsMixin(object): self.assertEqual(response.status_code, expect_result) if expect_result == 200: self.assertIn("active", response.data) - self.assertItemsEqual(response.data["active"], self.expected_active(target_user)) + six.assertCountEqual(response.data["active"], self.expected_active(target_user)) @ddt.data( (True, ALICE_USERNAME, 200, True), @@ -352,7 +352,7 @@ class UserMappingViewAPITests(TpaAPITestCase): if expect_code == 200: for item in ['results', 'count', 'num_pages']: self.assertIn(item, response.data) - self.assertItemsEqual(response.data['results'], expect_result) + six.assertCountEqual(response.data['results'], expect_result) @unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms') diff --git a/common/djangoapps/xblock_django/tests/test_api.py b/common/djangoapps/xblock_django/tests/test_api.py index a98617f806..8ee2fae998 100644 --- a/common/djangoapps/xblock_django/tests/test_api.py +++ b/common/djangoapps/xblock_django/tests/test_api.py @@ -3,6 +3,7 @@ Tests related to XBlock support API. """ from __future__ import absolute_import +import six from openedx.core.djangolib.testing.utils import CacheIsolationTestCase from xblock_django.api import authorable_xblocks, deprecated_xblocks, disabled_xblocks from xblock_django.models import XBlockConfiguration, XBlockStudioConfiguration, XBlockStudioConfigurationFlag @@ -45,23 +46,23 @@ class XBlockSupportTestCase(CacheIsolationTestCase): """ Tests the deprecated_xblocks method """ deprecated_xblock_names = [block.name for block in deprecated_xblocks()] - self.assertItemsEqual(["poll", "survey"], deprecated_xblock_names) + six.assertCountEqual(["poll", "survey"], deprecated_xblock_names) XBlockConfiguration(name="poll", enabled=True, deprecated=False).save() deprecated_xblock_names = [block.name for block in deprecated_xblocks()] - self.assertItemsEqual(["survey"], deprecated_xblock_names) + six.assertCountEqual(["survey"], deprecated_xblock_names) def test_disabled_blocks(self): """ Tests the disabled_xblocks method """ disabled_xblock_names = [block.name for block in disabled_xblocks()] - self.assertItemsEqual(["survey"], disabled_xblock_names) + six.assertCountEqual(["survey"], disabled_xblock_names) XBlockConfiguration(name="poll", enabled=False, deprecated=True).save() disabled_xblock_names = [block.name for block in disabled_xblocks()] - self.assertItemsEqual(["survey", "poll"], disabled_xblock_names) + six.assertCountEqual(["survey", "poll"], disabled_xblock_names) def test_authorable_blocks_empty_model(self): """ @@ -79,7 +80,7 @@ class XBlockSupportTestCase(CacheIsolationTestCase): Tests authorable_xblocks when name is not specified. """ authorable_xblock_names = [block.name for block in authorable_xblocks()] - self.assertItemsEqual(["done", "problem", "problem", "html"], authorable_xblock_names) + six.assertCountEqual(["done", "problem", "problem", "html"], authorable_xblock_names) # Note that "survey" is disabled in XBlockConfiguration, but it is still returned by # authorable_xblocks because it is marked as enabled and unsupported in XBlockStudioConfiguration. @@ -87,7 +88,7 @@ class XBlockSupportTestCase(CacheIsolationTestCase): # is a whitelist and uses a combination of xblock type and template (and in addition has a global feature flag), # it is expected that Studio code will need to filter by both disabled_xblocks and authorable_xblocks. authorable_xblock_names = [block.name for block in authorable_xblocks(allow_unsupported=True)] - self.assertItemsEqual( + six.assertCountEqual( ["survey", "done", "problem", "problem", "problem", "html", "split_module"], authorable_xblock_names ) diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py b/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py index 4029ed57a7..1e68037a72 100644 --- a/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py +++ b/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py @@ -1836,7 +1836,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup): with check_mongo_calls(max_find, max_send): found_orphans = self.store.get_orphans(self.course_locations[self.MONGO_COURSEID].course_key) - self.assertItemsEqual(found_orphans, orphan_locations) + six.assertCountEqual(found_orphans, orphan_locations) @ddt.data(ModuleStoreEnum.Type.mongo) def test_get_non_orphan_parents(self, default_ms): diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_split_modulestore_bulk_operations.py b/common/lib/xmodule/xmodule/modulestore/tests/test_split_modulestore_bulk_operations.py index c95b9fa7c9..452aeb4cdc 100644 --- a/common/lib/xmodule/xmodule/modulestore/tests/test_split_modulestore_bulk_operations.py +++ b/common/lib/xmodule/xmodule/modulestore/tests/test_split_modulestore_bulk_operations.py @@ -8,6 +8,7 @@ import copy import unittest import ddt +import six from bson.objectid import ObjectId from mock import MagicMock, Mock, call from opaque_keys.edx.locator import CourseLocator @@ -169,7 +170,7 @@ class TestBulkWriteMixinClosed(TestBulkWriteMixin): self.bulk.update_structure(self.course_key.replace(branch='b'), other_structure) self.assertConnCalls() self.bulk._end_bulk_operation(self.course_key) - self.assertItemsEqual( + six.assertCountEqual( [ call.insert_structure(self.structure, self.course_key), call.insert_structure(other_structure, self.course_key) @@ -205,7 +206,7 @@ class TestBulkWriteMixinClosed(TestBulkWriteMixin): self.bulk.update_definition(self.course_key.replace(branch='b'), other_definition) self.bulk.insert_course_index(self.course_key, {'versions': {'a': self.definition['_id'], 'b': other_definition['_id']}}) self.bulk._end_bulk_operation(self.course_key) - self.assertItemsEqual( + six.assertCountEqual( [ call.insert_definition(self.definition, self.course_key), call.insert_definition(other_definition, self.course_key), @@ -236,7 +237,7 @@ class TestBulkWriteMixinClosed(TestBulkWriteMixin): self.bulk.update_definition(self.course_key.replace(branch='b'), other_definition) self.assertConnCalls() self.bulk._end_bulk_operation(self.course_key) - self.assertItemsEqual( + six.assertCountEqual( [ call.insert_definition(self.definition, self.course_key), call.insert_definition(other_definition, self.course_key) @@ -272,7 +273,7 @@ class TestBulkWriteMixinClosed(TestBulkWriteMixin): self.bulk.update_structure(self.course_key.replace(branch='b'), other_structure) self.bulk.insert_course_index(self.course_key, {'versions': {'a': self.structure['_id'], 'b': other_structure['_id']}}) self.bulk._end_bulk_operation(self.course_key) - self.assertItemsEqual( + six.assertCountEqual( [ call.insert_structure(self.structure, self.course_key), call.insert_structure(other_structure, self.course_key), @@ -392,7 +393,7 @@ class TestBulkWriteMixinFindMethods(TestBulkWriteMixin): expected = matching + db_indexes self.conn.find_matching_course_indexes.return_value = db_indexes result = self.bulk.find_matching_course_indexes(branch, search_targets) - self.assertItemsEqual(result, expected) + six.assertCountEqual(result, expected) for item in unmatching: self.assertNotIn(item, result) @@ -580,7 +581,7 @@ class TestBulkWriteMixinFindMethods(TestBulkWriteMixin): self.conn.find_ancestor_structures.return_value = db_match + db_unmatch results = self.bulk.find_ancestor_structures(original_version, block_id) self.conn.find_ancestor_structures.assert_called_once_with(original_version, block_id) - self.assertItemsEqual(active_match + db_match, results) + six.assertCountEqual(active_match + db_match, results) @ddt.ddt diff --git a/common/lib/xmodule/xmodule/tests/__init__.py b/common/lib/xmodule/xmodule/tests/__init__.py index a1c8322616..d568473ee1 100644 --- a/common/lib/xmodule/xmodule/tests/__init__.py +++ b/common/lib/xmodule/xmodule/tests/__init__.py @@ -395,7 +395,7 @@ class CourseComparisonTest(TestCase): } # Split Mongo and Old-Mongo disagree about what the block_id of courses is, so skip those in # this comparison - self.assertItemsEqual( + six.assertCountEqual( [map_key(item.location) for item in expected_items if item.scope_ids.block_type != 'course'], [key for key in actual_item_map.keys() if key[0] != 'course'], ) diff --git a/common/lib/xmodule/xmodule/tests/test_capa_module.py b/common/lib/xmodule/xmodule/tests/test_capa_module.py index c695d7b6ab..01ca6047b0 100644 --- a/common/lib/xmodule/xmodule/tests/test_capa_module.py +++ b/common/lib/xmodule/xmodule/tests/test_capa_module.py @@ -863,7 +863,7 @@ class ProblemBlockTest(unittest.TestCase): self.assertEqual(xqueue_interface._http_post.call_count, 1) _, kwargs = xqueue_interface._http_post.call_args # pylint: disable=unpacking-non-sequence - self.assertItemsEqual(fpaths, list(kwargs['files'].keys())) + six.assertCountEqual(fpaths, list(kwargs['files'].keys())) for fpath, fileobj in six.iteritems(kwargs['files']): self.assertEqual(fpath, fileobj.name) @@ -896,7 +896,7 @@ class ProblemBlockTest(unittest.TestCase): self.assertEqual(xqueue_interface._http_post.call_count, 1) _, kwargs = xqueue_interface._http_post.call_args # pylint: disable=unpacking-non-sequence - self.assertItemsEqual(fnames, list(kwargs['files'].keys())) + six.assertCountEqual(fnames, list(kwargs['files'].keys())) for fpath, fileobj in six.iteritems(kwargs['files']): self.assertEqual(fpath, fileobj.name) diff --git a/common/lib/xmodule/xmodule/tests/test_export.py b/common/lib/xmodule/xmodule/tests/test_export.py index f5b774d156..9373d91c6d 100644 --- a/common/lib/xmodule/xmodule/tests/test_export.py +++ b/common/lib/xmodule/xmodule/tests/test_export.py @@ -14,6 +14,7 @@ import ddt import lxml.etree import mock import pytz +import six from django.utils.translation import ugettext_lazy from fs.osfs import OSFS from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator @@ -136,7 +137,7 @@ class RoundTripTestCase(unittest.TestCase): course_id = initial_course.id print("Checking key equality") - self.assertItemsEqual( + six.assertCountEqual( list(initial_import.modules[course_id].keys()), list(second_import.modules[course_id].keys()) ) diff --git a/common/test/acceptance/tests/lms/test_lms_courseware.py b/common/test/acceptance/tests/lms/test_lms_courseware.py index e9433db9f7..270ed527da 100644 --- a/common/test/acceptance/tests/lms/test_lms_courseware.py +++ b/common/test/acceptance/tests/lms/test_lms_courseware.py @@ -9,6 +9,7 @@ import json from datetime import datetime, timedelta import ddt +import six from six.moves import range from openedx.core.lib.tests import attr @@ -939,4 +940,4 @@ class WordCloudTests(UniqueCourseTest): self.assertTrue(self.courseware_page.is_word_cloud_rendered) self.courseware_page.input_word_cloud('test_wordcloud') self.courseware_page.save_word_cloud() - self.assertItemsEqual(expected_data, self.courseware_page.word_cloud_answer_list) + six.assertCountEqual(expected_data, self.courseware_page.word_cloud_answer_list) diff --git a/common/test/acceptance/tests/studio/test_studio_container.py b/common/test/acceptance/tests/studio/test_studio_container.py index c914d786c2..74728aa7ab 100644 --- a/common/test/acceptance/tests/studio/test_studio_container.py +++ b/common/test/acceptance/tests/studio/test_studio_container.py @@ -8,6 +8,7 @@ from __future__ import absolute_import import datetime import ddt +import six from common.test.acceptance.fixtures.course import XBlockFixtureDesc from common.test.acceptance.pages.lms.courseware import CoursewarePage @@ -297,13 +298,13 @@ class BaseGroupConfigurationsTest(ContainerBase): """ Check that the expected partition scheme is selected. """ - self.assertItemsEqual(expected_scheme, visibility_editor.selected_partition_scheme) + six.assertCountEqual(expected_scheme, visibility_editor.selected_partition_scheme) def verify_selected_groups(self, visibility_editor, expected_groups): """ Check the expected partition groups. """ - self.assertItemsEqual(expected_groups, [group.text for group in visibility_editor.selected_groups]) + six.assertCountEqual(expected_groups, [group.text for group in visibility_editor.selected_groups]) def select_and_verify_saved(self, component, partition_label, groups=[]): """ diff --git a/common/test/acceptance/tests/studio/test_studio_outline.py b/common/test/acceptance/tests/studio/test_studio_outline.py index 50395828a0..a7d7c96c67 100644 --- a/common/test/acceptance/tests/studio/test_studio_outline.py +++ b/common/test/acceptance/tests/studio/test_studio_outline.py @@ -6,6 +6,7 @@ from __future__ import absolute_import import itertools import json +import six from datetime import datetime, timedelta from unittest import skip @@ -1713,7 +1714,7 @@ class DeprecationWarningMessageTest(CourseOutlineTest): self.assertEqual(self.course_outline_page.components_visible, components_present) if components_present: self.assertEqual(self.course_outline_page.components_list_heading, self.COMPONENT_LIST_HEADING) - self.assertItemsEqual(self.course_outline_page.components_display_names, components_display_name_list) + six.assertCountEqual(self.course_outline_page.components_display_names, components_display_name_list) def test_no_deprecation_warning_message_present(self): """ diff --git a/lms/djangoapps/badges/tests/test_models.py b/lms/djangoapps/badges/tests/test_models.py index 844e28292e..dc54e1a771 100644 --- a/lms/djangoapps/badges/tests/test_models.py +++ b/lms/djangoapps/badges/tests/test_models.py @@ -248,7 +248,7 @@ class BadgeAssertionTest(ModuleStoreTestCase): Verify that grabbing all assertions for a user behaves as expected. This function uses object IDs because for some reason Jenkins trips up - on its assertItemsEqual check here despite the items being equal. + on its six.assertCountEqual check here despite the items being equal. """ user = UserFactory() assertions = [BadgeAssertionFactory.create(user=user).id for _i in range(3)] diff --git a/lms/djangoapps/bulk_email/tests/test_email.py b/lms/djangoapps/bulk_email/tests/test_email.py index 7ba38669e5..cbf5ab678e 100644 --- a/lms/djangoapps/bulk_email/tests/test_email.py +++ b/lms/djangoapps/bulk_email/tests/test_email.py @@ -290,7 +290,7 @@ class TestEmailSendFromDashboardMockedHtmlToText(EmailSendFromDashboardTestCase) # the 1 is for the instructor in this test and others self.assertEquals(len(mail.outbox), 1 + len(self.staff)) - self.assertItemsEqual( + six.assertCountEqual( [e.to[0] for e in mail.outbox], [self.instructor.email] + [s.email for s in self.staff] ) @@ -311,7 +311,7 @@ class TestEmailSendFromDashboardMockedHtmlToText(EmailSendFromDashboardTestCase) response = self.client.post(self.send_mail_url, test_email) self.assertEquals(json.loads(response.content.decode('utf-8')), self.success_content) - self.assertItemsEqual( + six.assertCountEqual( [e.to[0] for e in mail.outbox], [s.email for s in self.students] ) @@ -352,7 +352,7 @@ class TestEmailSendFromDashboardMockedHtmlToText(EmailSendFromDashboardTestCase) response = self.client.post(self.send_mail_url, test_email) self.assertEquals(json.loads(response.content.decode('utf-8')), self.success_content) - self.assertItemsEqual( + six.assertCountEqual( [e.to[0] for e in mail.outbox], [s.email for s in self.students] ) @@ -410,7 +410,7 @@ class TestEmailSendFromDashboardMockedHtmlToText(EmailSendFromDashboardTestCase) # the 1 is for the instructor self.assertEquals(len(mail.outbox), 1 + len(self.staff) + len(self.students)) - self.assertItemsEqual( + six.assertCountEqual( [e.to[0] for e in mail.outbox], [self.instructor.email] + [s.email for s in self.staff] + [s.email for s in self.students] ) @@ -467,7 +467,7 @@ class TestEmailSendFromDashboardMockedHtmlToText(EmailSendFromDashboardTestCase) self.assertEquals(json.loads(response.content.decode('utf-8')), self.success_content) self.assertEquals(len(mail.outbox), 1 + len(self.staff) + len(self.students)) - self.assertItemsEqual( + six.assertCountEqual( [e.to[0] for e in mail.outbox], [self.instructor.email] + [s.email for s in self.staff] + [s.email for s in self.students] ) @@ -494,7 +494,7 @@ class TestEmailSendFromDashboardMockedHtmlToText(EmailSendFromDashboardTestCase) self.assertEquals(len(mail.outbox), 1 + len(self.staff) + len(self.students)) - self.assertItemsEqual( + six.assertCountEqual( [e.to[0] for e in mail.outbox], [self.instructor.email] + [s.email for s in self.staff] + [s.email for s in self.students] ) @@ -595,7 +595,7 @@ class TestEmailSendFromDashboardMockedHtmlToText(EmailSendFromDashboardTestCase) [s.email for s in self.staff] + [s.email for s in self.students] + [s.email for s in added_users if s not in optouts]) - self.assertItemsEqual(outbox_contents, should_send_contents) + six.assertCountEqual(outbox_contents, should_send_contents) @skipIf(os.environ.get("TRAVIS") == 'true', "Skip this test in Travis CI.") @@ -623,7 +623,7 @@ class TestEmailSendFromDashboard(EmailSendFromDashboardTestCase): self.assertEquals(json.loads(response.content.decode('utf-8')), self.success_content) self.assertEquals(len(mail.outbox), 1 + len(self.staff) + len(self.students)) - self.assertItemsEqual( + six.assertCountEqual( [e.to[0] for e in mail.outbox], [self.instructor.email] + [s.email for s in self.staff] + [s.email for s in self.students] ) diff --git a/lms/djangoapps/ccx/api/v0/tests/test_views.py b/lms/djangoapps/ccx/api/v0/tests/test_views.py index 1e29fb6e56..799914c05b 100644 --- a/lms/djangoapps/ccx/api/v0/tests/test_views.py +++ b/lms/djangoapps/ccx/api/v0/tests/test_views.py @@ -1105,7 +1105,7 @@ class CcxDetailTest(CcxRestApiTest): ) self.assertEqual(resp.data.get('coach_email'), self.ccx.coach.email) # pylint: disable=no-member self.assertEqual(resp.data.get('master_course_id'), six.text_type(self.ccx.course_id)) - self.assertItemsEqual(resp.data.get('course_modules'), self.master_course_chapters) + six.assertCountEqual(resp.data.get('course_modules'), self.master_course_chapters) @ddt.data(*AUTH_ATTRS) def test_delete_detail(self, auth_attr): @@ -1332,19 +1332,19 @@ class CcxDetailTest(CcxRestApiTest): resp = self.client.patch(self.detail_url, data, format='json', HTTP_AUTHORIZATION=getattr(self, auth_attr)) self.assertEqual(resp.status_code, status.HTTP_204_NO_CONTENT) ccx_from_db = CustomCourseForEdX.objects.get(id=self.ccx.id) - self.assertItemsEqual(ccx_from_db.structure, data['course_modules']) + six.assertCountEqual(ccx_from_db.structure, data['course_modules']) data = {'course_modules': []} resp = self.client.patch(self.detail_url, data, format='json', HTTP_AUTHORIZATION=getattr(self, auth_attr)) self.assertEqual(resp.status_code, status.HTTP_204_NO_CONTENT) ccx_from_db = CustomCourseForEdX.objects.get(id=self.ccx.id) - self.assertItemsEqual(ccx_from_db.structure, []) + six.assertCountEqual(ccx_from_db.structure, []) data = {'course_modules': self.master_course_chapters} resp = self.client.patch(self.detail_url, data, format='json', HTTP_AUTHORIZATION=getattr(self, auth_attr)) self.assertEqual(resp.status_code, status.HTTP_204_NO_CONTENT) ccx_from_db = CustomCourseForEdX.objects.get(id=self.ccx.id) - self.assertItemsEqual(ccx_from_db.structure, self.master_course_chapters) + six.assertCountEqual(ccx_from_db.structure, self.master_course_chapters) data = {'course_modules': None} resp = self.client.patch(self.detail_url, data, format='json', HTTP_AUTHORIZATION=getattr(self, auth_attr)) @@ -1357,7 +1357,7 @@ class CcxDetailTest(CcxRestApiTest): resp = self.client.patch(self.detail_url, data, format='json', HTTP_AUTHORIZATION=getattr(self, auth_attr)) self.assertEqual(resp.status_code, status.HTTP_204_NO_CONTENT) ccx_from_db = CustomCourseForEdX.objects.get(id=self.ccx.id) - self.assertItemsEqual(ccx_from_db.structure, chapters) + six.assertCountEqual(ccx_from_db.structure, chapters) @ddt.data( ('auth', True), @@ -1381,7 +1381,7 @@ class CcxDetailTest(CcxRestApiTest): else: self.assertEqual(resp.status_code, status.HTTP_204_NO_CONTENT) ccx_from_db = CustomCourseForEdX.objects.get(id=self.ccx.id) - self.assertItemsEqual(ccx_from_db.structure, chapters) + six.assertCountEqual(ccx_from_db.structure, chapters) @ddt.data( ('auth', True), diff --git a/lms/djangoapps/certificates/tests/test_api.py b/lms/djangoapps/certificates/tests/test_api.py index 69a6ad9c76..08c0e02404 100644 --- a/lms/djangoapps/certificates/tests/test_api.py +++ b/lms/djangoapps/certificates/tests/test_api.py @@ -762,7 +762,7 @@ class CertificatesBrandingTest(TestCase): data = certs_api.get_certificate_header_context(is_secure=True) # Make sure there are not unexpected keys in dict returned by 'get_certificate_header_context' - self.assertItemsEqual( + six.assertCountEqual( list(data.keys()), ['logo_src', 'logo_url'] ) @@ -787,7 +787,7 @@ class CertificatesBrandingTest(TestCase): data = certs_api.get_certificate_footer_context() # Make sure there are not unexpected keys in dict returned by 'get_certificate_footer_context' - self.assertItemsEqual( + six.assertCountEqual( list(data.keys()), ['company_about_url', 'company_privacy_url', 'company_tos_url'] ) diff --git a/lms/djangoapps/courseware/management/commands/tests/test_dump_course.py b/lms/djangoapps/courseware/management/commands/tests/test_dump_course.py index a968c300a4..2e7f6f98df 100644 --- a/lms/djangoapps/courseware/management/commands/tests/test_dump_course.py +++ b/lms/djangoapps/courseware/management/commands/tests/test_dump_course.py @@ -135,7 +135,7 @@ class CommandsTestBase(SharedModuleStoreTestCase): self.assertEqual(dump[video_id]['category'], 'video') video_metadata = dump[video_id]['metadata'] video_metadata.pop('edx_video_id', None) - self.assertItemsEqual( + six.assertCountEqual( list(video_metadata.keys()), ['youtube_id_0_75', 'youtube_id_1_0', 'youtube_id_1_25', 'youtube_id_1_5'] ) diff --git a/lms/djangoapps/courseware/rules.py b/lms/djangoapps/courseware/rules.py index 7c01087c16..84815516bf 100644 --- a/lms/djangoapps/courseware/rules.py +++ b/lms/djangoapps/courseware/rules.py @@ -68,13 +68,13 @@ class StaffAccessExperiment(laboratory.Experiment): def publish(self, result): if not result.match: - - LOG.warning( - u"StaffAccessExperiment: control=%r, candidate=%r\n%s", - result.control, - result.candidates[0], - "".join(traceback.format_stack(limit=10)) - ) + pass + # LOG.warning( + # u"StaffAccessExperiment: control=%r, candidate=%r\n%s", + # result.control, + # result.candidates[0], + # "".join(traceback.format_stack(limit=10)) + # ) class HasStaffAccessToContent(Rule): diff --git a/lms/djangoapps/courseware/tests/test_submitting_problems.py b/lms/djangoapps/courseware/tests/test_submitting_problems.py index 788d673135..01a0913e83 100644 --- a/lms/djangoapps/courseware/tests/test_submitting_problems.py +++ b/lms/djangoapps/courseware/tests/test_submitting_problems.py @@ -803,8 +803,8 @@ class ProblemWithUploadedFilesTest(TestSubmittingProblems): self.assertEqual(name, "post") self.assertEqual(len(args), 1) self.assertTrue(args[0].endswith("/submit/")) - self.assertItemsEqual(list(kwargs.keys()), ["files", "data", "timeout"]) - self.assertItemsEqual(list(kwargs['files'].keys()), filenames.split()) + six.assertCountEqual(list(kwargs.keys()), ["files", "data", "timeout"]) + six.assertCountEqual(list(kwargs['files'].keys()), filenames.split()) class TestPythonGradedResponse(TestSubmittingProblems): diff --git a/lms/djangoapps/courseware/tests/test_video_handlers.py b/lms/djangoapps/courseware/tests/test_video_handlers.py index a1894ef465..f4eca8b882 100644 --- a/lms/djangoapps/courseware/tests/test_video_handlers.py +++ b/lms/djangoapps/courseware/tests/test_video_handlers.py @@ -366,7 +366,7 @@ class TestTranscriptAvailableTranslationsDispatch(TestVideo): # Make request to available translations dispatch. request = Request.blank('/available_translations') response = self.item.transcript(request=request, dispatch='available_translations') - self.assertItemsEqual(json.loads(response.body), result) + six.assertCountEqual(json.loads(response.body.decode('utf8')), result) @patch('xmodule.video_module.transcripts_utils.edxval_api.get_available_transcript_languages') def test_val_available_translations_feature_disabled(self, mock_get_available_transcript_languages): diff --git a/lms/djangoapps/courseware/tests/test_video_mongo.py b/lms/djangoapps/courseware/tests/test_video_mongo.py index 8f23b9c500..7a13ad13aa 100644 --- a/lms/djangoapps/courseware/tests/test_video_mongo.py +++ b/lms/djangoapps/courseware/tests/test_video_mongo.py @@ -1576,7 +1576,7 @@ class TestVideoBlockStudentViewJson(BaseTestVideoXBlock, CacheIsolationTestCase) self.video.transcripts = transcripts self.video.sub = english_sub student_view_response = self.get_result() - self.assertItemsEqual(list(student_view_response['transcripts'].keys()), expected_transcripts) + six.assertCountEqual(list(student_view_response['transcripts'].keys()), expected_transcripts) @ddt.ddt diff --git a/lms/djangoapps/discussion/django_comment_client/tests/test_utils.py b/lms/djangoapps/discussion/django_comment_client/tests/test_utils.py index 22ea5ade1f..89eebfadff 100644 --- a/lms/djangoapps/discussion/django_comment_client/tests/test_utils.py +++ b/lms/djangoapps/discussion/django_comment_client/tests/test_utils.py @@ -7,6 +7,7 @@ import json import ddt import mock +import six from django.test import RequestFactory, TestCase from django.urls import reverse from edx_django_utils.cache import RequestCache @@ -1019,7 +1020,7 @@ class CategoryMapTestCase(CategoryMapTestMixin, ModuleStoreTestCase): "Topic B": {"id": "Topic_B"}, "Topic C": {"id": "Topic_C"} } - self.assertItemsEqual( + six.assertCountEqual( utils.get_discussion_categories_ids(self.course, self.user), ["Topic_A", "Topic_B", "Topic_C"] ) @@ -1031,7 +1032,7 @@ class CategoryMapTestCase(CategoryMapTestMixin, ModuleStoreTestCase): self.create_discussion("Chapter 2 / Section 1 / Subsection 1", "Discussion") self.create_discussion("Chapter 2 / Section 1 / Subsection 2", "Discussion") self.create_discussion("Chapter 3 / Section 1", "Discussion") - self.assertItemsEqual( + six.assertCountEqual( utils.get_discussion_categories_ids(self.course, self.user), ["discussion1", "discussion2", "discussion3", "discussion4", "discussion5", "discussion6"] ) @@ -1045,7 +1046,7 @@ class CategoryMapTestCase(CategoryMapTestMixin, ModuleStoreTestCase): self.create_discussion("Chapter 1", "Discussion 1") self.create_discussion("Chapter 2", "Discussion") self.create_discussion("Chapter 2 / Section 1 / Subsection 1", "Discussion") - self.assertItemsEqual( + six.assertCountEqual( utils.get_discussion_categories_ids(self.course, self.user), ["Topic_A", "Topic_B", "Topic_C", "discussion1", "discussion2", "discussion3"] ) diff --git a/lms/djangoapps/edxnotes/tests.py b/lms/djangoapps/edxnotes/tests.py index 5e83d1ef2e..666b133875 100644 --- a/lms/djangoapps/edxnotes/tests.py +++ b/lms/djangoapps/edxnotes/tests.py @@ -10,6 +10,7 @@ from unittest import skipUnless import ddt import jwt +import six from six import text_type from six.moves.urllib.parse import urlparse, parse_qs # pylint: disable=import-error from django.conf import settings @@ -334,7 +335,7 @@ class EdxNotesHelpersTest(ModuleStoreTestCase): } ) - self.assertItemsEqual( + six.assertCountEqual( { "count": 2, "current_page": 1, @@ -440,7 +441,7 @@ class EdxNotesHelpersTest(ModuleStoreTestCase): ] }) - self.assertItemsEqual( + six.assertCountEqual( { "count": 2, "current_page": 1, @@ -524,7 +525,7 @@ class EdxNotesHelpersTest(ModuleStoreTestCase): Tests no results. """ mock_get.return_value.content = json.dumps(NOTES_API_EMPTY_RESPONSE) - self.assertItemsEqual( + six.assertCountEqual( NOTES_VIEW_EMPTY_RESPONSE, helpers.get_notes(self.request, self.course) ) @@ -571,7 +572,7 @@ class EdxNotesHelpersTest(ModuleStoreTestCase): }, ] - self.assertItemsEqual( + six.assertCountEqual( [{ u"quote": u"quote text", u"text": u"text", @@ -617,7 +618,7 @@ class EdxNotesHelpersTest(ModuleStoreTestCase): ] self.html_module_2.visible_to_staff_only = True self.store.update_item(self.html_module_2, self.user.id) - self.assertItemsEqual( + six.assertCountEqual( [{ u"quote": u"quote text", u"text": u"text", @@ -660,7 +661,7 @@ class EdxNotesHelpersTest(ModuleStoreTestCase): u"updated": datetime(2014, 11, 19, 8, 5, 16, 00000).isoformat(), }] - self.assertItemsEqual( + six.assertCountEqual( [], helpers.preprocess_collection(self.user, self.course, initial_collection) ) @@ -684,7 +685,7 @@ class EdxNotesHelpersTest(ModuleStoreTestCase): }, ] - self.assertItemsEqual( + six.assertCountEqual( [ { diff --git a/lms/djangoapps/instructor_task/tests/test_base.py b/lms/djangoapps/instructor_task/tests/test_base.py index 70a5eb3538..bf7f3c9f9e 100644 --- a/lms/djangoapps/instructor_task/tests/test_base.py +++ b/lms/djangoapps/instructor_task/tests/test_base.py @@ -8,6 +8,7 @@ import json # pylint: disable=attribute-defined-outside-init import os import shutil +import six from tempfile import mkdtemp from uuid import uuid4 @@ -369,8 +370,8 @@ class TestReportMixin(object): self.assertEqual(csv_rows, expected_rows) self.assertEqual(numeric_csv_rows, numeric_expected_rows) else: - self.assertItemsEqual(csv_rows, expected_rows) - self.assertItemsEqual(numeric_csv_rows, numeric_expected_rows) + six.assertCountEqual(csv_rows, expected_rows) + six.assertCountEqual(numeric_csv_rows, numeric_expected_rows) @staticmethod def _extract_and_round_numeric_items(dictionary): diff --git a/lms/djangoapps/shoppingcart/tests/test_models.py b/lms/djangoapps/shoppingcart/tests/test_models.py index f685861c46..ce28306048 100644 --- a/lms/djangoapps/shoppingcart/tests/test_models.py +++ b/lms/djangoapps/shoppingcart/tests/test_models.py @@ -1376,12 +1376,12 @@ class InvoiceHistoryTest(TestCase): def _assert_history_items(self, expected_items): """Check line item info in the latest history record. """ items = self._latest_history()['items'] - self.assertItemsEqual(items, expected_items) + six.assertCountEqual(items, expected_items) def _assert_history_transactions(self, expected_transactions): """Check transactions (payments/refunds) in the latest history record. """ transactions = self._latest_history()['transactions'] - self.assertItemsEqual(transactions, expected_transactions) + six.assertCountEqual(transactions, expected_transactions) def _latest_history(self): """Retrieve the snapshot from the latest history record. """ diff --git a/openedx/core/djangoapps/catalog/tests/test_utils.py b/openedx/core/djangoapps/catalog/tests/test_utils.py index 49e6e3b1c1..7b4c193fc5 100644 --- a/openedx/core/djangoapps/catalog/tests/test_utils.py +++ b/openedx/core/djangoapps/catalog/tests/test_utils.py @@ -842,7 +842,7 @@ class TestGetProgramsByType(CacheIsolationTestCase): def test_get_masters_programs(self): expected_programs = [self.masters_program_1, self.masters_program_2] - self.assertItemsEqual(expected_programs, get_programs_by_type(self.site, 'masters')) + six.assertCountEqual(expected_programs, get_programs_by_type(self.site, 'masters')) def test_get_bachelors_programs(self): expected_programs = [self.bachelors_program] diff --git a/openedx/core/djangoapps/coursegraph/management/commands/tests/test_dump_to_neo4j.py b/openedx/core/djangoapps/coursegraph/management/commands/tests/test_dump_to_neo4j.py index 5156428876..eb16965389 100644 --- a/openedx/core/djangoapps/coursegraph/management/commands/tests/test_dump_to_neo4j.py +++ b/openedx/core/djangoapps/coursegraph/management/commands/tests/test_dump_to_neo4j.py @@ -422,7 +422,7 @@ class TestModuleStoreSerializer(TestDumpToNeo4jCommandBase): # 2 nodes and no relationships from the second self.assertEqual(len(mock_graph.nodes), 11) - self.assertItemsEqual(submitted, self.course_strings) + six.assertCountEqual(submitted, self.course_strings) @mock.patch('openedx.core.djangoapps.coursegraph.tasks.NodeSelector') @mock.patch('openedx.core.djangoapps.coursegraph.tasks.authenticate_and_create_graph') @@ -445,7 +445,7 @@ class TestModuleStoreSerializer(TestDumpToNeo4jCommandBase): number_rollbacks=2, ) - self.assertItemsEqual(submitted, self.course_strings) + six.assertCountEqual(submitted, self.course_strings) @mock.patch('openedx.core.djangoapps.coursegraph.tasks.NodeSelector') @mock.patch('openedx.core.djangoapps.coursegraph.tasks.authenticate_and_create_graph') diff --git a/openedx/core/djangoapps/enrollments/tests/test_views.py b/openedx/core/djangoapps/enrollments/tests/test_views.py index ce7e2b66ac..29ccb72586 100644 --- a/openedx/core/djangoapps/enrollments/tests/test_views.py +++ b/openedx/core/djangoapps/enrollments/tests/test_views.py @@ -363,7 +363,7 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase, Ente response = self.client.get(reverse('courseenrollments'), {'user': self.user.username}, **kwargs) self.assertEqual(response.status_code, status.HTTP_200_OK) data = json.loads(response.content.decode('utf-8')) - self.assertItemsEqual( + six.assertCountEqual( [(datum['course_details']['course_id'], datum['course_details']['course_name']) for datum in data], [(six.text_type(course.id), course.display_name_with_default) for course in courses] ) @@ -1680,4 +1680,4 @@ class CourseEnrollmentsApiListTest(APITestCase, ModuleStoreTestCase): content = self._assert_list_of_enrollments(query_params, status.HTTP_200_OK) results = content['results'] - self.assertItemsEqual(results, expected_results) + six.assertCountEqual(results, expected_results) diff --git a/openedx/core/djangoapps/lang_pref/tests/test_middleware.py b/openedx/core/djangoapps/lang_pref/tests/test_middleware.py index 372691e422..950e17d6e0 100644 --- a/openedx/core/djangoapps/lang_pref/tests/test_middleware.py +++ b/openedx/core/djangoapps/lang_pref/tests/test_middleware.py @@ -8,6 +8,7 @@ import itertools import ddt import mock +import six from django.conf import settings from django.contrib.sessions.middleware import SessionMiddleware from django.http import HttpResponse @@ -149,7 +150,7 @@ class TestUserPreferenceMiddleware(CacheIsolationTestCase): accept_lang_out = parse_accept_lang_header(accept_lang_out) if accept_lang_out and accept_lang_result: - self.assertItemsEqual(accept_lang_result, accept_lang_out) + six.assertCountEqual(accept_lang_result, accept_lang_out) else: self.assertEqual(accept_lang_result, accept_lang_out) diff --git a/openedx/core/djangoapps/programs/tests/test_utils.py b/openedx/core/djangoapps/programs/tests/test_utils.py index a755ef79ed..10e99e10ca 100644 --- a/openedx/core/djangoapps/programs/tests/test_utils.py +++ b/openedx/core/djangoapps/programs/tests/test_utils.py @@ -674,7 +674,7 @@ class TestProgramProgressMeter(TestCase): self._create_certificates(unknown['key'], status='unknown') meter = ProgramProgressMeter(self.site, self.user) - self.assertItemsEqual( + six.assertCountEqual( meter.completed_course_runs, [ {'course_run_id': downloadable['key'], 'type': CourseMode.VERIFIED}, diff --git a/openedx/core/djangoapps/schedules/management/commands/tests/test_send_upgrade_reminder.py b/openedx/core/djangoapps/schedules/management/commands/tests/test_send_upgrade_reminder.py index 4174f67129..9fa317cf0a 100644 --- a/openedx/core/djangoapps/schedules/management/commands/tests/test_send_upgrade_reminder.py +++ b/openedx/core/djangoapps/schedules/management/commands/tests/test_send_upgrade_reminder.py @@ -7,6 +7,7 @@ import logging from unittest import skipUnless import ddt +import six from django.conf import settings from edx_ace import Message from edx_ace.utils.date import serialize @@ -86,7 +87,7 @@ class TestUpgradeReminder(ScheduleSendEmailTestMixin, CacheIsolationTestCase): messages = [Message.from_string(m) for m in sent_messages] self.assertEqual(len(messages), 1) message = messages[0] - self.assertItemsEqual( + six.assertCountEqual( message.context['course_ids'], [str(schedules[i].enrollment.course.id) for i in (1, 2, 4)] ) diff --git a/openedx/core/djangoapps/site_configuration/tests/test_helpers.py b/openedx/core/djangoapps/site_configuration/tests/test_helpers.py index beb04a85cf..5cc7c7375a 100644 --- a/openedx/core/djangoapps/site_configuration/tests/test_helpers.py +++ b/openedx/core/djangoapps/site_configuration/tests/test_helpers.py @@ -3,6 +3,7 @@ Tests for helper function provided by site_configuration app. """ from __future__ import absolute_import +import six from django.test import TestCase from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers @@ -81,7 +82,7 @@ class TestHelpers(TestCase): Test that get_dict returns correct value for any given key. """ # Make sure entry is saved and retrieved correctly - self.assertItemsEqual( + six.assertCountEqual( configuration_helpers.get_dict("REGISTRATION_EXTRA_FIELDS"), test_config['REGISTRATION_EXTRA_FIELDS'], ) @@ -91,7 +92,7 @@ class TestHelpers(TestCase): expected.update(test_config['REGISTRATION_EXTRA_FIELDS']) # Test that the default value is returned if the value for the given key is not found in the configuration - self.assertItemsEqual( + six.assertCountEqual( configuration_helpers.get_dict("REGISTRATION_EXTRA_FIELDS", default), expected, ) @@ -134,7 +135,7 @@ class TestHelpers(TestCase): test_config['css_overrides_file'] ) - self.assertItemsEqual( + six.assertCountEqual( configuration_helpers.get_value_for_org(test_org, "REGISTRATION_EXTRA_FIELDS"), test_config['REGISTRATION_EXTRA_FIELDS'] ) @@ -177,7 +178,7 @@ class TestHelpers(TestCase): """ test_orgs = [test_config['course_org_filter']] with with_site_configuration_context(configuration=test_config): - self.assertItemsEqual( + six.assertCountEqual( list(configuration_helpers.get_all_orgs()), test_orgs, ) @@ -185,7 +186,7 @@ class TestHelpers(TestCase): @with_site_configuration(configuration=test_config_multi_org) def test_get_current_site_orgs(self): test_orgs = test_config_multi_org['course_org_filter'] - self.assertItemsEqual( + six.assertCountEqual( list(configuration_helpers.get_current_site_orgs()), test_orgs ) diff --git a/openedx/core/djangoapps/theming/tests/test_commands.py b/openedx/core/djangoapps/theming/tests/test_commands.py index 7b4563c0bb..d5f1d40eb6 100644 --- a/openedx/core/djangoapps/theming/tests/test_commands.py +++ b/openedx/core/djangoapps/theming/tests/test_commands.py @@ -3,6 +3,7 @@ Tests for Management commands of comprehensive theming. """ from __future__ import absolute_import +import six from django.core.management import CommandError, call_command from django.test import TestCase @@ -44,12 +45,12 @@ class TestUpdateAssets(TestCase): """ # make sure compile_sass picks all themes when called with 'themes=all' option parsed_args = Command.parse_arguments(themes=["all"]) - self.assertItemsEqual(parsed_args[2], get_themes()) + six.assertCountEqual(parsed_args[2], get_themes()) # make sure compile_sass picks no themes when called with 'themes=no' option parsed_args = Command.parse_arguments(themes=["no"]) - self.assertItemsEqual(parsed_args[2], []) + six.assertCountEqual(parsed_args[2], []) # make sure compile_sass picks only specified themes parsed_args = Command.parse_arguments(themes=["test-theme"]) - self.assertItemsEqual(parsed_args[2], [theme for theme in get_themes() if theme.theme_dir_name == "test-theme"]) + six.assertCountEqual(parsed_args[2], [theme for theme in get_themes() if theme.theme_dir_name == "test-theme"]) diff --git a/openedx/core/djangoapps/theming/tests/test_helpers.py b/openedx/core/djangoapps/theming/tests/test_helpers.py index bb920ff1cb..8ffcceb14f 100644 --- a/openedx/core/djangoapps/theming/tests/test_helpers.py +++ b/openedx/core/djangoapps/theming/tests/test_helpers.py @@ -3,6 +3,7 @@ Test helpers for Comprehensive Theming. """ from __future__ import absolute_import +import six from django.conf import settings from django.test import TestCase, override_settings from edx_django_utils.cache import RequestCache @@ -38,7 +39,7 @@ class TestHelpers(TestCase): Theme('test-theme', 'test-theme', get_theme_base_dir('test-theme'), settings.PROJECT_ROOT), ] actual_themes = get_themes() - self.assertItemsEqual(expected_themes, actual_themes) + six.assertCountEqual(expected_themes, actual_themes) @override_settings(COMPREHENSIVE_THEME_DIRS=[settings.TEST_THEME.dirname()]) def test_get_themes_2(self): @@ -49,7 +50,7 @@ class TestHelpers(TestCase): Theme('test-theme', 'test-theme', get_theme_base_dir('test-theme'), settings.PROJECT_ROOT), ] actual_themes = get_themes() - self.assertItemsEqual(expected_themes, actual_themes) + six.assertCountEqual(expected_themes, actual_themes) def test_get_value_returns_override(self): """ diff --git a/openedx/core/djangoapps/user_api/accounts/tests/test_retirement_views.py b/openedx/core/djangoapps/user_api/accounts/tests/test_retirement_views.py index 0d3bfb6075..762f99c577 100644 --- a/openedx/core/djangoapps/user_api/accounts/tests/test_retirement_views.py +++ b/openedx/core/djangoapps/user_api/accounts/tests/test_retirement_views.py @@ -11,6 +11,7 @@ import unittest import ddt import mock import pytz +import six from consent.models import DataSharingConsent from django.conf import settings from django.contrib.auth.models import User @@ -565,7 +566,7 @@ class TestPartnerReportingList(ModuleStoreTestCase): for returned_user in returned_users: returned_user['orgs'].sort() - self.assertCountEqual(returned_users, expected_users) + six.assertCountEqual(returned_users, expected_users) def test_success(self): """ @@ -661,7 +662,7 @@ class TestAccountRetirementList(RetirementTestCase): del retirement['created'] del retirement['modified'] - self.assertItemsEqual(response_data, expected_data) + six.assertCountEqual(response_data, expected_data) def test_empty(self): """ @@ -834,7 +835,7 @@ class TestAccountRetirementsByStatusAndDate(RetirementTestCase): except KeyError: pass - self.assertItemsEqual(response_data, expected_data) + six.assertCountEqual(response_data, expected_data) def test_empty(self): """ diff --git a/openedx/core/djangoapps/user_api/accounts/tests/test_views.py b/openedx/core/djangoapps/user_api/accounts/tests/test_views.py index 6b24bd66b8..9270d97df8 100644 --- a/openedx/core/djangoapps/user_api/accounts/tests/test_views.py +++ b/openedx/core/djangoapps/user_api/accounts/tests/test_views.py @@ -12,6 +12,7 @@ from copy import deepcopy import ddt import mock import pytz +import six from django.conf import settings from django.core.urlresolvers import reverse from django.test.testcases import TransactionTestCase @@ -790,7 +791,7 @@ class TestAccountsAPI(CacheIsolationTestCase, UserAPITestCase): # than django model id. for proficiencies in ([{"code": "en"}, {"code": "fr"}, {"code": "es"}], [{"code": "fr"}], [{"code": "aa"}], []): response = self.send_patch(client, {"language_proficiencies": proficiencies}) - self.assertItemsEqual(response.data["language_proficiencies"], proficiencies) + six.assertCountEqual(response.data["language_proficiencies"], proficiencies) @ddt.data( ( diff --git a/openedx/core/djangoapps/user_api/tests/test_views.py b/openedx/core/djangoapps/user_api/tests/test_views.py index 05cc1d7854..40633ceaca 100644 --- a/openedx/core/djangoapps/user_api/tests/test_views.py +++ b/openedx/core/djangoapps/user_api/tests/test_views.py @@ -19,7 +19,7 @@ from django.test.utils import override_settings from django.urls import reverse from opaque_keys.edx.keys import CourseKey from pytz import UTC, common_timezones_set -from six import text_type +from six import text_type, assertCountEqual from six.moves import range from social_django.models import Partial, UserSocialAuth @@ -93,8 +93,8 @@ class UserAPITestCase(ApiTestCase): def assertUserIsValid(self, user): """Assert that the given user result is valid""" - self.assertItemsEqual(list(user.keys()), ["email", "id", "name", "username", "preferences", "url"]) - self.assertItemsEqual( + assertCountEqual(list(user.keys()), ["email", "id", "name", "username", "preferences", "url"]) + assertCountEqual( list(user["preferences"].items()), [(pref.key, pref.value) for pref in self.prefs if pref.user.id == user["id"]] ) @@ -104,7 +104,7 @@ class UserAPITestCase(ApiTestCase): """ Assert that the given preference is acknowledged by the system """ - self.assertItemsEqual(list(pref.keys()), ["user", "key", "value", "url"]) + assertCountEqual(list(pref.keys()), ["user", "key", "value", "url"]) self.assertSelfReferential(pref) self.assertUserIsValid(pref["user"]) diff --git a/openedx/core/lib/api/test_utils.py b/openedx/core/lib/api/test_utils.py index 70e8ebaad4..83333e4a65 100644 --- a/openedx/core/lib/api/test_utils.py +++ b/openedx/core/lib/api/test_utils.py @@ -5,6 +5,7 @@ from __future__ import absolute_import import base64 import json import re +import six from django.test import TestCase from django.test.utils import override_settings @@ -49,7 +50,7 @@ class ApiTestCase(TestCase): allow_header = resp.get("Allow") self.assertIsNotNone(allow_header) allowed_methods = re.split('[^A-Z]+', allow_header) - self.assertItemsEqual(allowed_methods, expected_methods) + six.assertCountEqual(allowed_methods, expected_methods) def assertSelfReferential(self, obj): """Assert that accessing the "url" entry in the given object returns the same object""" diff --git a/openedx/features/course_duration_limits/tests/test_course_expiration.py b/openedx/features/course_duration_limits/tests/test_course_expiration.py index 07c06c23f7..1b93b9dbeb 100644 --- a/openedx/features/course_duration_limits/tests/test_course_expiration.py +++ b/openedx/features/course_duration_limits/tests/test_course_expiration.py @@ -216,7 +216,7 @@ class CourseExpirationTestCase(ModuleStoreTestCase): course_home_url = reverse('openedx.course_experience.course_home', args=[six.text_type(self.course.id)]) response = self.client.get(course_home_url, follow=True) self.assertEqual(response.status_code, 200) - self.assertItemsEqual(response.redirect_chain, []) + six.assertCountEqual(response.redirect_chain, []) banner_text = 'You lose all access to this course, including your progress,' if show_expiration_banner: self.assertIn(banner_text, response.content) @@ -281,7 +281,7 @@ class CourseExpirationTestCase(ModuleStoreTestCase): course_home_url = reverse('openedx.course_experience.course_home', args=[six.text_type(self.course.id)]) response = self.client.get(course_home_url, follow=True) self.assertEqual(response.status_code, 200) - self.assertItemsEqual(response.redirect_chain, []) + self.six.assertCountEqual(response.redirect_chain, []) banner_text = 'You lose all access to this course, including your progress,' self.assertNotIn(banner_text, response.content) @@ -317,7 +317,7 @@ class CourseExpirationTestCase(ModuleStoreTestCase): course_home_url = reverse('openedx.course_experience.course_home', args=[six.text_type(self.course.id)]) response = self.client.get(course_home_url, follow=True) self.assertEqual(response.status_code, 200) - self.assertItemsEqual(response.redirect_chain, []) + self.six.assertCountEqual(response.redirect_chain, []) banner_text = 'This learner does not have access to this course. Their access expired on' self.assertIn(banner_text, response.content) @@ -368,7 +368,7 @@ class CourseExpirationTestCase(ModuleStoreTestCase): course_home_url = reverse('openedx.course_experience.course_home', args=[six.text_type(self.course.id)]) response = self.client.get(course_home_url, follow=True) self.assertEqual(response.status_code, 200) - self.assertItemsEqual(response.redirect_chain, []) + self.six.assertCountEqual(response.redirect_chain, []) banner_text = 'This learner does not have access to this course. Their access expired on' self.assertNotIn(banner_text, response.content) @@ -417,6 +417,6 @@ class CourseExpirationTestCase(ModuleStoreTestCase): course_home_url = reverse('openedx.course_experience.course_home', args=[six.text_type(self.course.id)]) response = self.client.get(course_home_url, follow=True) self.assertEqual(response.status_code, 200) - self.assertItemsEqual(response.redirect_chain, []) + self.six.assertCountEqual(response.redirect_chain, []) banner_text = 'This learner does not have access to this course. Their access expired on' self.assertNotIn(banner_text, response.content) diff --git a/pavelib/paver_tests/test_assets.py b/pavelib/paver_tests/test_assets.py index bff9a83969..d69d9a5f06 100644 --- a/pavelib/paver_tests/test_assets.py +++ b/pavelib/paver_tests/test_assets.py @@ -7,6 +7,7 @@ from unittest import TestCase import ddt import paver.tasks +import six from mock import patch from paver.easy import call_task, path from watchdog.observers import Observer @@ -78,7 +79,7 @@ class TestPaverAssetTasks(PaverTestCase): u'rtlcss cms/static/css/bootstrap/studio-main.css cms/static/css/bootstrap/studio-main-rtl.css' ) - self.assertItemsEqual(self.task_messages, expected_messages) + six.assertCountEqual(self.task_messages, expected_messages) @ddt.ddt @@ -195,7 +196,7 @@ class TestPaverThemeAssetTasks(PaverTestCase): u'rtlcss cms/static/css/bootstrap/studio-main.css cms/static/css/bootstrap/studio-main-rtl.css' ) - self.assertItemsEqual(self.task_messages, expected_messages) + self.six.assertCountEqual(self.task_messages, expected_messages) class TestPaverWatchAssetTasks(TestCase): @@ -245,7 +246,7 @@ class TestPaverWatchAssetTasks(TestCase): self.assertIsInstance(sass_watcher_args[0], Observer) self.assertIsInstance(sass_watcher_args[1], list) - self.assertItemsEqual(sass_watcher_args[1], self.expected_sass_directories) + self.six.assertCountEqual(sass_watcher_args[1], self.expected_sass_directories) def test_watch_theme_assets(self): """ @@ -275,7 +276,7 @@ class TestPaverWatchAssetTasks(TestCase): sass_watcher_args = mock_register.call_args_list[0][0] self.assertIsInstance(sass_watcher_args[0], Observer) self.assertIsInstance(sass_watcher_args[1], list) - self.assertItemsEqual(sass_watcher_args[1], self.expected_sass_directories) + self.six.assertCountEqual(sass_watcher_args[1], self.expected_sass_directories) @ddt.ddt From 73a146fbbed29e005414a8a9fec0f5a8af8c8fae Mon Sep 17 00:00:00 2001 From: Feanil Patel Date: Tue, 20 Aug 2019 15:31:20 -0400 Subject: [PATCH 18/20] Revert "assertItemsEqual() moved to assertCountEqual()" This reverts commit 3d2617983b3bc17cb254ad8943be9873d1604f95. The change was not quite right because the method six provides needs to have `self` be passed in as well. See the docs here: https://six.readthedocs.io/#unittest-assertions Reverting for now and we can fix it in smaller chunks later. --- .../commands/tests/test_migrate_transcripts.py | 4 ++-- .../commands/tests/test_reindex_courses.py | 3 +-- .../commands/tests/test_reindex_library.py | 2 +- .../views/tests/test_course_index.py | 2 +- .../djangoapps/course_modes/tests/test_models.py | 5 ++--- .../terrain/stubs/tests/test_edxnotes.py | 3 +-- .../third_party_auth/api/tests/test_views.py | 6 +++--- .../djangoapps/xblock_django/tests/test_api.py | 13 ++++++------- .../modulestore/tests/test_mixed_modulestore.py | 2 +- .../test_split_modulestore_bulk_operations.py | 13 ++++++------- common/lib/xmodule/xmodule/tests/__init__.py | 2 +- .../xmodule/xmodule/tests/test_capa_module.py | 4 ++-- common/lib/xmodule/xmodule/tests/test_export.py | 3 +-- .../acceptance/tests/lms/test_lms_courseware.py | 3 +-- .../tests/studio/test_studio_container.py | 5 ++--- .../tests/studio/test_studio_outline.py | 3 +-- lms/djangoapps/badges/tests/test_models.py | 2 +- lms/djangoapps/bulk_email/tests/test_email.py | 16 ++++++++-------- lms/djangoapps/ccx/api/v0/tests/test_views.py | 12 ++++++------ lms/djangoapps/certificates/tests/test_api.py | 4 ++-- .../commands/tests/test_dump_course.py | 2 +- lms/djangoapps/courseware/rules.py | 14 +++++++------- .../courseware/tests/test_submitting_problems.py | 4 ++-- .../courseware/tests/test_video_handlers.py | 2 +- .../courseware/tests/test_video_mongo.py | 2 +- .../django_comment_client/tests/test_utils.py | 7 +++---- lms/djangoapps/edxnotes/tests.py | 15 +++++++-------- .../instructor_task/tests/test_base.py | 5 ++--- lms/djangoapps/shoppingcart/tests/test_models.py | 4 ++-- .../core/djangoapps/catalog/tests/test_utils.py | 2 +- .../commands/tests/test_dump_to_neo4j.py | 4 ++-- .../djangoapps/enrollments/tests/test_views.py | 4 ++-- .../lang_pref/tests/test_middleware.py | 3 +-- .../core/djangoapps/programs/tests/test_utils.py | 2 +- .../commands/tests/test_send_upgrade_reminder.py | 3 +-- .../site_configuration/tests/test_helpers.py | 11 +++++------ .../djangoapps/theming/tests/test_commands.py | 7 +++---- .../djangoapps/theming/tests/test_helpers.py | 5 ++--- .../accounts/tests/test_retirement_views.py | 7 +++---- .../user_api/accounts/tests/test_views.py | 3 +-- .../core/djangoapps/user_api/tests/test_views.py | 8 ++++---- openedx/core/lib/api/test_utils.py | 3 +-- .../tests/test_course_expiration.py | 10 +++++----- pavelib/paver_tests/test_assets.py | 9 ++++----- 44 files changed, 111 insertions(+), 132 deletions(-) diff --git a/cms/djangoapps/contentstore/management/commands/tests/test_migrate_transcripts.py b/cms/djangoapps/contentstore/management/commands/tests/test_migrate_transcripts.py index d4a2693237..fb701fd815 100644 --- a/cms/djangoapps/contentstore/management/commands/tests/test_migrate_transcripts.py +++ b/cms/djangoapps/contentstore/management/commands/tests/test_migrate_transcripts.py @@ -187,7 +187,7 @@ class TestMigrateTranscripts(ModuleStoreTestCase): Test migrating transcripts """ translations = self.video_descriptor.available_translations(self.video_descriptor.get_transcripts_info()) - six.assertCountEqual(translations, ['hr', 'ge']) + self.assertItemsEqual(translations, ['hr', 'ge']) self.assertFalse(api.is_transcript_available(self.video_descriptor.edx_video_id, 'hr')) self.assertFalse(api.is_transcript_available(self.video_descriptor.edx_video_id, 'ge')) @@ -202,7 +202,7 @@ class TestMigrateTranscripts(ModuleStoreTestCase): Test migrating transcripts multiple times """ translations = self.video_descriptor.available_translations(self.video_descriptor.get_transcripts_info()) - six.assertCountEqual(translations, ['hr', 'ge']) + self.assertItemsEqual(translations, ['hr', 'ge']) self.assertFalse(api.is_transcript_available(self.video_descriptor.edx_video_id, 'hr')) self.assertFalse(api.is_transcript_available(self.video_descriptor.edx_video_id, 'ge')) diff --git a/cms/djangoapps/contentstore/management/commands/tests/test_reindex_courses.py b/cms/djangoapps/contentstore/management/commands/tests/test_reindex_courses.py index a1a446a285..35d8725116 100644 --- a/cms/djangoapps/contentstore/management/commands/tests/test_reindex_courses.py +++ b/cms/djangoapps/contentstore/management/commands/tests/test_reindex_courses.py @@ -3,7 +3,6 @@ from __future__ import absolute_import import ddt import mock -import six from django.core.management import CommandError, call_command from six import text_type @@ -105,7 +104,7 @@ class TestReindexCourse(ModuleStoreTestCase): patched_yes_no.assert_called_once_with(ReindexCommand.CONFIRMATION_PROMPT, default='no') expected_calls = self._build_calls(self.first_course, self.second_course) - six.assertCountEqual(patched_index.mock_calls, expected_calls) + self.assertItemsEqual(patched_index.mock_calls, expected_calls) def test_given_all_key_prompts_and_reindexes_all_courses_cancelled(self): """ Test that does not reindex anything when --all key is given and cancelled """ diff --git a/cms/djangoapps/contentstore/management/commands/tests/test_reindex_library.py b/cms/djangoapps/contentstore/management/commands/tests/test_reindex_library.py index 9150441d6d..5104cf0185 100644 --- a/cms/djangoapps/contentstore/management/commands/tests/test_reindex_library.py +++ b/cms/djangoapps/contentstore/management/commands/tests/test_reindex_library.py @@ -104,7 +104,7 @@ class TestReindexLibrary(ModuleStoreTestCase): patched_yes_no.assert_called_once_with(ReindexCommand.CONFIRMATION_PROMPT, default='no') expected_calls = self._build_calls(self.first_lib, self.second_lib) - six.assertCountEqual(patched_index.mock_calls, expected_calls) + self.assertItemsEqual(patched_index.mock_calls, expected_calls) def test_given_all_key_prompts_and_reindexes_all_libraries_cancelled(self): """ Test that does not reindex anything when --all key is given and cancelled """ diff --git a/cms/djangoapps/contentstore/views/tests/test_course_index.py b/cms/djangoapps/contentstore/views/tests/test_course_index.py index c6f10aab31..b22fc2d0fa 100644 --- a/cms/djangoapps/contentstore/views/tests/test_course_index.py +++ b/cms/djangoapps/contentstore/views/tests/test_course_index.py @@ -554,7 +554,7 @@ class TestCourseOutline(CourseTestCase): [component for component in advanced_modules if component in deprecated_block_types] ) - six.assertCountEqual(info['blocks'], expected_blocks) + self.assertItemsEqual(info['blocks'], expected_blocks) self.assertEqual( info['advance_settings_url'], reverse_course_url('advanced_settings_handler', course_id) diff --git a/common/djangoapps/course_modes/tests/test_models.py b/common/djangoapps/course_modes/tests/test_models.py index 411cfcb5a0..7dbc967b33 100644 --- a/common/djangoapps/course_modes/tests/test_models.py +++ b/common/djangoapps/course_modes/tests/test_models.py @@ -10,7 +10,6 @@ import itertools from datetime import timedelta import ddt -import six from django.core.exceptions import ValidationError from django.test import TestCase, override_settings from django.utils.timezone import now @@ -400,11 +399,11 @@ class CourseModeModelTest(TestCase): # Check the selectable modes, which should exclude credit selectable_modes = CourseMode.modes_for_course_dict(self.course_key) - six.assertCountEqual(list(selectable_modes.keys()), expected_selectable_modes) + self.assertItemsEqual(list(selectable_modes.keys()), expected_selectable_modes) # When we get all unexpired modes, we should see credit as well all_modes = CourseMode.modes_for_course_dict(self.course_key, only_selectable=False) - six.assertCountEqual(list(all_modes.keys()), available_modes) + self.assertItemsEqual(list(all_modes.keys()), available_modes) def _enrollment_display_modes_dicts(self, dict_type): """ diff --git a/common/djangoapps/terrain/stubs/tests/test_edxnotes.py b/common/djangoapps/terrain/stubs/tests/test_edxnotes.py index 39c175db82..32e1e66d22 100644 --- a/common/djangoapps/terrain/stubs/tests/test_edxnotes.py +++ b/common/djangoapps/terrain/stubs/tests/test_edxnotes.py @@ -9,7 +9,6 @@ from uuid import uuid4 import ddt import requests -import six import six.moves.urllib.parse # pylint: disable=import-error from six.moves import range @@ -193,7 +192,7 @@ class StubEdxNotesServiceTest(unittest.TestCase): updated_note = self._get_notes()[0] self.assertEqual("new test text", updated_note["text"]) self.assertEqual(note["id"], updated_note["id"]) - six.assertCountEqual(note, updated_note) + self.assertItemsEqual(note, updated_note) response = requests.get(self._get_url("api/v1/annotations/does_not_exist")) self.assertEqual(response.status_code, 404) diff --git a/common/djangoapps/third_party_auth/api/tests/test_views.py b/common/djangoapps/third_party_auth/api/tests/test_views.py index 0a2d8d3503..95786a50dc 100644 --- a/common/djangoapps/third_party_auth/api/tests/test_views.py +++ b/common/djangoapps/third_party_auth/api/tests/test_views.py @@ -133,7 +133,7 @@ class UserViewsMixin(object): self.assertEqual(response.status_code, expect_result) if expect_result == 200: self.assertIn("active", response.data) - six.assertCountEqual(response.data["active"], self.expected_active(target_user)) + self.assertItemsEqual(response.data["active"], self.expected_active(target_user)) @ddt.data( # A server with a valid API key can query any user's list of providers @@ -149,7 +149,7 @@ class UserViewsMixin(object): self.assertEqual(response.status_code, expect_result) if expect_result == 200: self.assertIn("active", response.data) - six.assertCountEqual(response.data["active"], self.expected_active(target_user)) + self.assertItemsEqual(response.data["active"], self.expected_active(target_user)) @ddt.data( (True, ALICE_USERNAME, 200, True), @@ -352,7 +352,7 @@ class UserMappingViewAPITests(TpaAPITestCase): if expect_code == 200: for item in ['results', 'count', 'num_pages']: self.assertIn(item, response.data) - six.assertCountEqual(response.data['results'], expect_result) + self.assertItemsEqual(response.data['results'], expect_result) @unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms') diff --git a/common/djangoapps/xblock_django/tests/test_api.py b/common/djangoapps/xblock_django/tests/test_api.py index 8ee2fae998..a98617f806 100644 --- a/common/djangoapps/xblock_django/tests/test_api.py +++ b/common/djangoapps/xblock_django/tests/test_api.py @@ -3,7 +3,6 @@ Tests related to XBlock support API. """ from __future__ import absolute_import -import six from openedx.core.djangolib.testing.utils import CacheIsolationTestCase from xblock_django.api import authorable_xblocks, deprecated_xblocks, disabled_xblocks from xblock_django.models import XBlockConfiguration, XBlockStudioConfiguration, XBlockStudioConfigurationFlag @@ -46,23 +45,23 @@ class XBlockSupportTestCase(CacheIsolationTestCase): """ Tests the deprecated_xblocks method """ deprecated_xblock_names = [block.name for block in deprecated_xblocks()] - six.assertCountEqual(["poll", "survey"], deprecated_xblock_names) + self.assertItemsEqual(["poll", "survey"], deprecated_xblock_names) XBlockConfiguration(name="poll", enabled=True, deprecated=False).save() deprecated_xblock_names = [block.name for block in deprecated_xblocks()] - six.assertCountEqual(["survey"], deprecated_xblock_names) + self.assertItemsEqual(["survey"], deprecated_xblock_names) def test_disabled_blocks(self): """ Tests the disabled_xblocks method """ disabled_xblock_names = [block.name for block in disabled_xblocks()] - six.assertCountEqual(["survey"], disabled_xblock_names) + self.assertItemsEqual(["survey"], disabled_xblock_names) XBlockConfiguration(name="poll", enabled=False, deprecated=True).save() disabled_xblock_names = [block.name for block in disabled_xblocks()] - six.assertCountEqual(["survey", "poll"], disabled_xblock_names) + self.assertItemsEqual(["survey", "poll"], disabled_xblock_names) def test_authorable_blocks_empty_model(self): """ @@ -80,7 +79,7 @@ class XBlockSupportTestCase(CacheIsolationTestCase): Tests authorable_xblocks when name is not specified. """ authorable_xblock_names = [block.name for block in authorable_xblocks()] - six.assertCountEqual(["done", "problem", "problem", "html"], authorable_xblock_names) + self.assertItemsEqual(["done", "problem", "problem", "html"], authorable_xblock_names) # Note that "survey" is disabled in XBlockConfiguration, but it is still returned by # authorable_xblocks because it is marked as enabled and unsupported in XBlockStudioConfiguration. @@ -88,7 +87,7 @@ class XBlockSupportTestCase(CacheIsolationTestCase): # is a whitelist and uses a combination of xblock type and template (and in addition has a global feature flag), # it is expected that Studio code will need to filter by both disabled_xblocks and authorable_xblocks. authorable_xblock_names = [block.name for block in authorable_xblocks(allow_unsupported=True)] - six.assertCountEqual( + self.assertItemsEqual( ["survey", "done", "problem", "problem", "problem", "html", "split_module"], authorable_xblock_names ) diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py b/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py index 1e68037a72..4029ed57a7 100644 --- a/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py +++ b/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py @@ -1836,7 +1836,7 @@ class TestMixedModuleStore(CommonMixedModuleStoreSetup): with check_mongo_calls(max_find, max_send): found_orphans = self.store.get_orphans(self.course_locations[self.MONGO_COURSEID].course_key) - six.assertCountEqual(found_orphans, orphan_locations) + self.assertItemsEqual(found_orphans, orphan_locations) @ddt.data(ModuleStoreEnum.Type.mongo) def test_get_non_orphan_parents(self, default_ms): diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_split_modulestore_bulk_operations.py b/common/lib/xmodule/xmodule/modulestore/tests/test_split_modulestore_bulk_operations.py index 452aeb4cdc..c95b9fa7c9 100644 --- a/common/lib/xmodule/xmodule/modulestore/tests/test_split_modulestore_bulk_operations.py +++ b/common/lib/xmodule/xmodule/modulestore/tests/test_split_modulestore_bulk_operations.py @@ -8,7 +8,6 @@ import copy import unittest import ddt -import six from bson.objectid import ObjectId from mock import MagicMock, Mock, call from opaque_keys.edx.locator import CourseLocator @@ -170,7 +169,7 @@ class TestBulkWriteMixinClosed(TestBulkWriteMixin): self.bulk.update_structure(self.course_key.replace(branch='b'), other_structure) self.assertConnCalls() self.bulk._end_bulk_operation(self.course_key) - six.assertCountEqual( + self.assertItemsEqual( [ call.insert_structure(self.structure, self.course_key), call.insert_structure(other_structure, self.course_key) @@ -206,7 +205,7 @@ class TestBulkWriteMixinClosed(TestBulkWriteMixin): self.bulk.update_definition(self.course_key.replace(branch='b'), other_definition) self.bulk.insert_course_index(self.course_key, {'versions': {'a': self.definition['_id'], 'b': other_definition['_id']}}) self.bulk._end_bulk_operation(self.course_key) - six.assertCountEqual( + self.assertItemsEqual( [ call.insert_definition(self.definition, self.course_key), call.insert_definition(other_definition, self.course_key), @@ -237,7 +236,7 @@ class TestBulkWriteMixinClosed(TestBulkWriteMixin): self.bulk.update_definition(self.course_key.replace(branch='b'), other_definition) self.assertConnCalls() self.bulk._end_bulk_operation(self.course_key) - six.assertCountEqual( + self.assertItemsEqual( [ call.insert_definition(self.definition, self.course_key), call.insert_definition(other_definition, self.course_key) @@ -273,7 +272,7 @@ class TestBulkWriteMixinClosed(TestBulkWriteMixin): self.bulk.update_structure(self.course_key.replace(branch='b'), other_structure) self.bulk.insert_course_index(self.course_key, {'versions': {'a': self.structure['_id'], 'b': other_structure['_id']}}) self.bulk._end_bulk_operation(self.course_key) - six.assertCountEqual( + self.assertItemsEqual( [ call.insert_structure(self.structure, self.course_key), call.insert_structure(other_structure, self.course_key), @@ -393,7 +392,7 @@ class TestBulkWriteMixinFindMethods(TestBulkWriteMixin): expected = matching + db_indexes self.conn.find_matching_course_indexes.return_value = db_indexes result = self.bulk.find_matching_course_indexes(branch, search_targets) - six.assertCountEqual(result, expected) + self.assertItemsEqual(result, expected) for item in unmatching: self.assertNotIn(item, result) @@ -581,7 +580,7 @@ class TestBulkWriteMixinFindMethods(TestBulkWriteMixin): self.conn.find_ancestor_structures.return_value = db_match + db_unmatch results = self.bulk.find_ancestor_structures(original_version, block_id) self.conn.find_ancestor_structures.assert_called_once_with(original_version, block_id) - six.assertCountEqual(active_match + db_match, results) + self.assertItemsEqual(active_match + db_match, results) @ddt.ddt diff --git a/common/lib/xmodule/xmodule/tests/__init__.py b/common/lib/xmodule/xmodule/tests/__init__.py index d568473ee1..a1c8322616 100644 --- a/common/lib/xmodule/xmodule/tests/__init__.py +++ b/common/lib/xmodule/xmodule/tests/__init__.py @@ -395,7 +395,7 @@ class CourseComparisonTest(TestCase): } # Split Mongo and Old-Mongo disagree about what the block_id of courses is, so skip those in # this comparison - six.assertCountEqual( + self.assertItemsEqual( [map_key(item.location) for item in expected_items if item.scope_ids.block_type != 'course'], [key for key in actual_item_map.keys() if key[0] != 'course'], ) diff --git a/common/lib/xmodule/xmodule/tests/test_capa_module.py b/common/lib/xmodule/xmodule/tests/test_capa_module.py index 01ca6047b0..c695d7b6ab 100644 --- a/common/lib/xmodule/xmodule/tests/test_capa_module.py +++ b/common/lib/xmodule/xmodule/tests/test_capa_module.py @@ -863,7 +863,7 @@ class ProblemBlockTest(unittest.TestCase): self.assertEqual(xqueue_interface._http_post.call_count, 1) _, kwargs = xqueue_interface._http_post.call_args # pylint: disable=unpacking-non-sequence - six.assertCountEqual(fpaths, list(kwargs['files'].keys())) + self.assertItemsEqual(fpaths, list(kwargs['files'].keys())) for fpath, fileobj in six.iteritems(kwargs['files']): self.assertEqual(fpath, fileobj.name) @@ -896,7 +896,7 @@ class ProblemBlockTest(unittest.TestCase): self.assertEqual(xqueue_interface._http_post.call_count, 1) _, kwargs = xqueue_interface._http_post.call_args # pylint: disable=unpacking-non-sequence - six.assertCountEqual(fnames, list(kwargs['files'].keys())) + self.assertItemsEqual(fnames, list(kwargs['files'].keys())) for fpath, fileobj in six.iteritems(kwargs['files']): self.assertEqual(fpath, fileobj.name) diff --git a/common/lib/xmodule/xmodule/tests/test_export.py b/common/lib/xmodule/xmodule/tests/test_export.py index 9373d91c6d..f5b774d156 100644 --- a/common/lib/xmodule/xmodule/tests/test_export.py +++ b/common/lib/xmodule/xmodule/tests/test_export.py @@ -14,7 +14,6 @@ import ddt import lxml.etree import mock import pytz -import six from django.utils.translation import ugettext_lazy from fs.osfs import OSFS from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator @@ -137,7 +136,7 @@ class RoundTripTestCase(unittest.TestCase): course_id = initial_course.id print("Checking key equality") - six.assertCountEqual( + self.assertItemsEqual( list(initial_import.modules[course_id].keys()), list(second_import.modules[course_id].keys()) ) diff --git a/common/test/acceptance/tests/lms/test_lms_courseware.py b/common/test/acceptance/tests/lms/test_lms_courseware.py index 270ed527da..e9433db9f7 100644 --- a/common/test/acceptance/tests/lms/test_lms_courseware.py +++ b/common/test/acceptance/tests/lms/test_lms_courseware.py @@ -9,7 +9,6 @@ import json from datetime import datetime, timedelta import ddt -import six from six.moves import range from openedx.core.lib.tests import attr @@ -940,4 +939,4 @@ class WordCloudTests(UniqueCourseTest): self.assertTrue(self.courseware_page.is_word_cloud_rendered) self.courseware_page.input_word_cloud('test_wordcloud') self.courseware_page.save_word_cloud() - six.assertCountEqual(expected_data, self.courseware_page.word_cloud_answer_list) + self.assertItemsEqual(expected_data, self.courseware_page.word_cloud_answer_list) diff --git a/common/test/acceptance/tests/studio/test_studio_container.py b/common/test/acceptance/tests/studio/test_studio_container.py index 74728aa7ab..c914d786c2 100644 --- a/common/test/acceptance/tests/studio/test_studio_container.py +++ b/common/test/acceptance/tests/studio/test_studio_container.py @@ -8,7 +8,6 @@ from __future__ import absolute_import import datetime import ddt -import six from common.test.acceptance.fixtures.course import XBlockFixtureDesc from common.test.acceptance.pages.lms.courseware import CoursewarePage @@ -298,13 +297,13 @@ class BaseGroupConfigurationsTest(ContainerBase): """ Check that the expected partition scheme is selected. """ - six.assertCountEqual(expected_scheme, visibility_editor.selected_partition_scheme) + self.assertItemsEqual(expected_scheme, visibility_editor.selected_partition_scheme) def verify_selected_groups(self, visibility_editor, expected_groups): """ Check the expected partition groups. """ - six.assertCountEqual(expected_groups, [group.text for group in visibility_editor.selected_groups]) + self.assertItemsEqual(expected_groups, [group.text for group in visibility_editor.selected_groups]) def select_and_verify_saved(self, component, partition_label, groups=[]): """ diff --git a/common/test/acceptance/tests/studio/test_studio_outline.py b/common/test/acceptance/tests/studio/test_studio_outline.py index a7d7c96c67..50395828a0 100644 --- a/common/test/acceptance/tests/studio/test_studio_outline.py +++ b/common/test/acceptance/tests/studio/test_studio_outline.py @@ -6,7 +6,6 @@ from __future__ import absolute_import import itertools import json -import six from datetime import datetime, timedelta from unittest import skip @@ -1714,7 +1713,7 @@ class DeprecationWarningMessageTest(CourseOutlineTest): self.assertEqual(self.course_outline_page.components_visible, components_present) if components_present: self.assertEqual(self.course_outline_page.components_list_heading, self.COMPONENT_LIST_HEADING) - six.assertCountEqual(self.course_outline_page.components_display_names, components_display_name_list) + self.assertItemsEqual(self.course_outline_page.components_display_names, components_display_name_list) def test_no_deprecation_warning_message_present(self): """ diff --git a/lms/djangoapps/badges/tests/test_models.py b/lms/djangoapps/badges/tests/test_models.py index dc54e1a771..844e28292e 100644 --- a/lms/djangoapps/badges/tests/test_models.py +++ b/lms/djangoapps/badges/tests/test_models.py @@ -248,7 +248,7 @@ class BadgeAssertionTest(ModuleStoreTestCase): Verify that grabbing all assertions for a user behaves as expected. This function uses object IDs because for some reason Jenkins trips up - on its six.assertCountEqual check here despite the items being equal. + on its assertItemsEqual check here despite the items being equal. """ user = UserFactory() assertions = [BadgeAssertionFactory.create(user=user).id for _i in range(3)] diff --git a/lms/djangoapps/bulk_email/tests/test_email.py b/lms/djangoapps/bulk_email/tests/test_email.py index cbf5ab678e..7ba38669e5 100644 --- a/lms/djangoapps/bulk_email/tests/test_email.py +++ b/lms/djangoapps/bulk_email/tests/test_email.py @@ -290,7 +290,7 @@ class TestEmailSendFromDashboardMockedHtmlToText(EmailSendFromDashboardTestCase) # the 1 is for the instructor in this test and others self.assertEquals(len(mail.outbox), 1 + len(self.staff)) - six.assertCountEqual( + self.assertItemsEqual( [e.to[0] for e in mail.outbox], [self.instructor.email] + [s.email for s in self.staff] ) @@ -311,7 +311,7 @@ class TestEmailSendFromDashboardMockedHtmlToText(EmailSendFromDashboardTestCase) response = self.client.post(self.send_mail_url, test_email) self.assertEquals(json.loads(response.content.decode('utf-8')), self.success_content) - six.assertCountEqual( + self.assertItemsEqual( [e.to[0] for e in mail.outbox], [s.email for s in self.students] ) @@ -352,7 +352,7 @@ class TestEmailSendFromDashboardMockedHtmlToText(EmailSendFromDashboardTestCase) response = self.client.post(self.send_mail_url, test_email) self.assertEquals(json.loads(response.content.decode('utf-8')), self.success_content) - six.assertCountEqual( + self.assertItemsEqual( [e.to[0] for e in mail.outbox], [s.email for s in self.students] ) @@ -410,7 +410,7 @@ class TestEmailSendFromDashboardMockedHtmlToText(EmailSendFromDashboardTestCase) # the 1 is for the instructor self.assertEquals(len(mail.outbox), 1 + len(self.staff) + len(self.students)) - six.assertCountEqual( + self.assertItemsEqual( [e.to[0] for e in mail.outbox], [self.instructor.email] + [s.email for s in self.staff] + [s.email for s in self.students] ) @@ -467,7 +467,7 @@ class TestEmailSendFromDashboardMockedHtmlToText(EmailSendFromDashboardTestCase) self.assertEquals(json.loads(response.content.decode('utf-8')), self.success_content) self.assertEquals(len(mail.outbox), 1 + len(self.staff) + len(self.students)) - six.assertCountEqual( + self.assertItemsEqual( [e.to[0] for e in mail.outbox], [self.instructor.email] + [s.email for s in self.staff] + [s.email for s in self.students] ) @@ -494,7 +494,7 @@ class TestEmailSendFromDashboardMockedHtmlToText(EmailSendFromDashboardTestCase) self.assertEquals(len(mail.outbox), 1 + len(self.staff) + len(self.students)) - six.assertCountEqual( + self.assertItemsEqual( [e.to[0] for e in mail.outbox], [self.instructor.email] + [s.email for s in self.staff] + [s.email for s in self.students] ) @@ -595,7 +595,7 @@ class TestEmailSendFromDashboardMockedHtmlToText(EmailSendFromDashboardTestCase) [s.email for s in self.staff] + [s.email for s in self.students] + [s.email for s in added_users if s not in optouts]) - six.assertCountEqual(outbox_contents, should_send_contents) + self.assertItemsEqual(outbox_contents, should_send_contents) @skipIf(os.environ.get("TRAVIS") == 'true', "Skip this test in Travis CI.") @@ -623,7 +623,7 @@ class TestEmailSendFromDashboard(EmailSendFromDashboardTestCase): self.assertEquals(json.loads(response.content.decode('utf-8')), self.success_content) self.assertEquals(len(mail.outbox), 1 + len(self.staff) + len(self.students)) - six.assertCountEqual( + self.assertItemsEqual( [e.to[0] for e in mail.outbox], [self.instructor.email] + [s.email for s in self.staff] + [s.email for s in self.students] ) diff --git a/lms/djangoapps/ccx/api/v0/tests/test_views.py b/lms/djangoapps/ccx/api/v0/tests/test_views.py index 799914c05b..1e29fb6e56 100644 --- a/lms/djangoapps/ccx/api/v0/tests/test_views.py +++ b/lms/djangoapps/ccx/api/v0/tests/test_views.py @@ -1105,7 +1105,7 @@ class CcxDetailTest(CcxRestApiTest): ) self.assertEqual(resp.data.get('coach_email'), self.ccx.coach.email) # pylint: disable=no-member self.assertEqual(resp.data.get('master_course_id'), six.text_type(self.ccx.course_id)) - six.assertCountEqual(resp.data.get('course_modules'), self.master_course_chapters) + self.assertItemsEqual(resp.data.get('course_modules'), self.master_course_chapters) @ddt.data(*AUTH_ATTRS) def test_delete_detail(self, auth_attr): @@ -1332,19 +1332,19 @@ class CcxDetailTest(CcxRestApiTest): resp = self.client.patch(self.detail_url, data, format='json', HTTP_AUTHORIZATION=getattr(self, auth_attr)) self.assertEqual(resp.status_code, status.HTTP_204_NO_CONTENT) ccx_from_db = CustomCourseForEdX.objects.get(id=self.ccx.id) - six.assertCountEqual(ccx_from_db.structure, data['course_modules']) + self.assertItemsEqual(ccx_from_db.structure, data['course_modules']) data = {'course_modules': []} resp = self.client.patch(self.detail_url, data, format='json', HTTP_AUTHORIZATION=getattr(self, auth_attr)) self.assertEqual(resp.status_code, status.HTTP_204_NO_CONTENT) ccx_from_db = CustomCourseForEdX.objects.get(id=self.ccx.id) - six.assertCountEqual(ccx_from_db.structure, []) + self.assertItemsEqual(ccx_from_db.structure, []) data = {'course_modules': self.master_course_chapters} resp = self.client.patch(self.detail_url, data, format='json', HTTP_AUTHORIZATION=getattr(self, auth_attr)) self.assertEqual(resp.status_code, status.HTTP_204_NO_CONTENT) ccx_from_db = CustomCourseForEdX.objects.get(id=self.ccx.id) - six.assertCountEqual(ccx_from_db.structure, self.master_course_chapters) + self.assertItemsEqual(ccx_from_db.structure, self.master_course_chapters) data = {'course_modules': None} resp = self.client.patch(self.detail_url, data, format='json', HTTP_AUTHORIZATION=getattr(self, auth_attr)) @@ -1357,7 +1357,7 @@ class CcxDetailTest(CcxRestApiTest): resp = self.client.patch(self.detail_url, data, format='json', HTTP_AUTHORIZATION=getattr(self, auth_attr)) self.assertEqual(resp.status_code, status.HTTP_204_NO_CONTENT) ccx_from_db = CustomCourseForEdX.objects.get(id=self.ccx.id) - six.assertCountEqual(ccx_from_db.structure, chapters) + self.assertItemsEqual(ccx_from_db.structure, chapters) @ddt.data( ('auth', True), @@ -1381,7 +1381,7 @@ class CcxDetailTest(CcxRestApiTest): else: self.assertEqual(resp.status_code, status.HTTP_204_NO_CONTENT) ccx_from_db = CustomCourseForEdX.objects.get(id=self.ccx.id) - six.assertCountEqual(ccx_from_db.structure, chapters) + self.assertItemsEqual(ccx_from_db.structure, chapters) @ddt.data( ('auth', True), diff --git a/lms/djangoapps/certificates/tests/test_api.py b/lms/djangoapps/certificates/tests/test_api.py index 08c0e02404..69a6ad9c76 100644 --- a/lms/djangoapps/certificates/tests/test_api.py +++ b/lms/djangoapps/certificates/tests/test_api.py @@ -762,7 +762,7 @@ class CertificatesBrandingTest(TestCase): data = certs_api.get_certificate_header_context(is_secure=True) # Make sure there are not unexpected keys in dict returned by 'get_certificate_header_context' - six.assertCountEqual( + self.assertItemsEqual( list(data.keys()), ['logo_src', 'logo_url'] ) @@ -787,7 +787,7 @@ class CertificatesBrandingTest(TestCase): data = certs_api.get_certificate_footer_context() # Make sure there are not unexpected keys in dict returned by 'get_certificate_footer_context' - six.assertCountEqual( + self.assertItemsEqual( list(data.keys()), ['company_about_url', 'company_privacy_url', 'company_tos_url'] ) diff --git a/lms/djangoapps/courseware/management/commands/tests/test_dump_course.py b/lms/djangoapps/courseware/management/commands/tests/test_dump_course.py index 2e7f6f98df..a968c300a4 100644 --- a/lms/djangoapps/courseware/management/commands/tests/test_dump_course.py +++ b/lms/djangoapps/courseware/management/commands/tests/test_dump_course.py @@ -135,7 +135,7 @@ class CommandsTestBase(SharedModuleStoreTestCase): self.assertEqual(dump[video_id]['category'], 'video') video_metadata = dump[video_id]['metadata'] video_metadata.pop('edx_video_id', None) - six.assertCountEqual( + self.assertItemsEqual( list(video_metadata.keys()), ['youtube_id_0_75', 'youtube_id_1_0', 'youtube_id_1_25', 'youtube_id_1_5'] ) diff --git a/lms/djangoapps/courseware/rules.py b/lms/djangoapps/courseware/rules.py index 84815516bf..7c01087c16 100644 --- a/lms/djangoapps/courseware/rules.py +++ b/lms/djangoapps/courseware/rules.py @@ -68,13 +68,13 @@ class StaffAccessExperiment(laboratory.Experiment): def publish(self, result): if not result.match: - pass - # LOG.warning( - # u"StaffAccessExperiment: control=%r, candidate=%r\n%s", - # result.control, - # result.candidates[0], - # "".join(traceback.format_stack(limit=10)) - # ) + + LOG.warning( + u"StaffAccessExperiment: control=%r, candidate=%r\n%s", + result.control, + result.candidates[0], + "".join(traceback.format_stack(limit=10)) + ) class HasStaffAccessToContent(Rule): diff --git a/lms/djangoapps/courseware/tests/test_submitting_problems.py b/lms/djangoapps/courseware/tests/test_submitting_problems.py index 01a0913e83..788d673135 100644 --- a/lms/djangoapps/courseware/tests/test_submitting_problems.py +++ b/lms/djangoapps/courseware/tests/test_submitting_problems.py @@ -803,8 +803,8 @@ class ProblemWithUploadedFilesTest(TestSubmittingProblems): self.assertEqual(name, "post") self.assertEqual(len(args), 1) self.assertTrue(args[0].endswith("/submit/")) - six.assertCountEqual(list(kwargs.keys()), ["files", "data", "timeout"]) - six.assertCountEqual(list(kwargs['files'].keys()), filenames.split()) + self.assertItemsEqual(list(kwargs.keys()), ["files", "data", "timeout"]) + self.assertItemsEqual(list(kwargs['files'].keys()), filenames.split()) class TestPythonGradedResponse(TestSubmittingProblems): diff --git a/lms/djangoapps/courseware/tests/test_video_handlers.py b/lms/djangoapps/courseware/tests/test_video_handlers.py index f4eca8b882..a1894ef465 100644 --- a/lms/djangoapps/courseware/tests/test_video_handlers.py +++ b/lms/djangoapps/courseware/tests/test_video_handlers.py @@ -366,7 +366,7 @@ class TestTranscriptAvailableTranslationsDispatch(TestVideo): # Make request to available translations dispatch. request = Request.blank('/available_translations') response = self.item.transcript(request=request, dispatch='available_translations') - six.assertCountEqual(json.loads(response.body.decode('utf8')), result) + self.assertItemsEqual(json.loads(response.body), result) @patch('xmodule.video_module.transcripts_utils.edxval_api.get_available_transcript_languages') def test_val_available_translations_feature_disabled(self, mock_get_available_transcript_languages): diff --git a/lms/djangoapps/courseware/tests/test_video_mongo.py b/lms/djangoapps/courseware/tests/test_video_mongo.py index 7a13ad13aa..8f23b9c500 100644 --- a/lms/djangoapps/courseware/tests/test_video_mongo.py +++ b/lms/djangoapps/courseware/tests/test_video_mongo.py @@ -1576,7 +1576,7 @@ class TestVideoBlockStudentViewJson(BaseTestVideoXBlock, CacheIsolationTestCase) self.video.transcripts = transcripts self.video.sub = english_sub student_view_response = self.get_result() - six.assertCountEqual(list(student_view_response['transcripts'].keys()), expected_transcripts) + self.assertItemsEqual(list(student_view_response['transcripts'].keys()), expected_transcripts) @ddt.ddt diff --git a/lms/djangoapps/discussion/django_comment_client/tests/test_utils.py b/lms/djangoapps/discussion/django_comment_client/tests/test_utils.py index 89eebfadff..22ea5ade1f 100644 --- a/lms/djangoapps/discussion/django_comment_client/tests/test_utils.py +++ b/lms/djangoapps/discussion/django_comment_client/tests/test_utils.py @@ -7,7 +7,6 @@ import json import ddt import mock -import six from django.test import RequestFactory, TestCase from django.urls import reverse from edx_django_utils.cache import RequestCache @@ -1020,7 +1019,7 @@ class CategoryMapTestCase(CategoryMapTestMixin, ModuleStoreTestCase): "Topic B": {"id": "Topic_B"}, "Topic C": {"id": "Topic_C"} } - six.assertCountEqual( + self.assertItemsEqual( utils.get_discussion_categories_ids(self.course, self.user), ["Topic_A", "Topic_B", "Topic_C"] ) @@ -1032,7 +1031,7 @@ class CategoryMapTestCase(CategoryMapTestMixin, ModuleStoreTestCase): self.create_discussion("Chapter 2 / Section 1 / Subsection 1", "Discussion") self.create_discussion("Chapter 2 / Section 1 / Subsection 2", "Discussion") self.create_discussion("Chapter 3 / Section 1", "Discussion") - six.assertCountEqual( + self.assertItemsEqual( utils.get_discussion_categories_ids(self.course, self.user), ["discussion1", "discussion2", "discussion3", "discussion4", "discussion5", "discussion6"] ) @@ -1046,7 +1045,7 @@ class CategoryMapTestCase(CategoryMapTestMixin, ModuleStoreTestCase): self.create_discussion("Chapter 1", "Discussion 1") self.create_discussion("Chapter 2", "Discussion") self.create_discussion("Chapter 2 / Section 1 / Subsection 1", "Discussion") - six.assertCountEqual( + self.assertItemsEqual( utils.get_discussion_categories_ids(self.course, self.user), ["Topic_A", "Topic_B", "Topic_C", "discussion1", "discussion2", "discussion3"] ) diff --git a/lms/djangoapps/edxnotes/tests.py b/lms/djangoapps/edxnotes/tests.py index 666b133875..5e83d1ef2e 100644 --- a/lms/djangoapps/edxnotes/tests.py +++ b/lms/djangoapps/edxnotes/tests.py @@ -10,7 +10,6 @@ from unittest import skipUnless import ddt import jwt -import six from six import text_type from six.moves.urllib.parse import urlparse, parse_qs # pylint: disable=import-error from django.conf import settings @@ -335,7 +334,7 @@ class EdxNotesHelpersTest(ModuleStoreTestCase): } ) - six.assertCountEqual( + self.assertItemsEqual( { "count": 2, "current_page": 1, @@ -441,7 +440,7 @@ class EdxNotesHelpersTest(ModuleStoreTestCase): ] }) - six.assertCountEqual( + self.assertItemsEqual( { "count": 2, "current_page": 1, @@ -525,7 +524,7 @@ class EdxNotesHelpersTest(ModuleStoreTestCase): Tests no results. """ mock_get.return_value.content = json.dumps(NOTES_API_EMPTY_RESPONSE) - six.assertCountEqual( + self.assertItemsEqual( NOTES_VIEW_EMPTY_RESPONSE, helpers.get_notes(self.request, self.course) ) @@ -572,7 +571,7 @@ class EdxNotesHelpersTest(ModuleStoreTestCase): }, ] - six.assertCountEqual( + self.assertItemsEqual( [{ u"quote": u"quote text", u"text": u"text", @@ -618,7 +617,7 @@ class EdxNotesHelpersTest(ModuleStoreTestCase): ] self.html_module_2.visible_to_staff_only = True self.store.update_item(self.html_module_2, self.user.id) - six.assertCountEqual( + self.assertItemsEqual( [{ u"quote": u"quote text", u"text": u"text", @@ -661,7 +660,7 @@ class EdxNotesHelpersTest(ModuleStoreTestCase): u"updated": datetime(2014, 11, 19, 8, 5, 16, 00000).isoformat(), }] - six.assertCountEqual( + self.assertItemsEqual( [], helpers.preprocess_collection(self.user, self.course, initial_collection) ) @@ -685,7 +684,7 @@ class EdxNotesHelpersTest(ModuleStoreTestCase): }, ] - six.assertCountEqual( + self.assertItemsEqual( [ { diff --git a/lms/djangoapps/instructor_task/tests/test_base.py b/lms/djangoapps/instructor_task/tests/test_base.py index bf7f3c9f9e..70a5eb3538 100644 --- a/lms/djangoapps/instructor_task/tests/test_base.py +++ b/lms/djangoapps/instructor_task/tests/test_base.py @@ -8,7 +8,6 @@ import json # pylint: disable=attribute-defined-outside-init import os import shutil -import six from tempfile import mkdtemp from uuid import uuid4 @@ -370,8 +369,8 @@ class TestReportMixin(object): self.assertEqual(csv_rows, expected_rows) self.assertEqual(numeric_csv_rows, numeric_expected_rows) else: - six.assertCountEqual(csv_rows, expected_rows) - six.assertCountEqual(numeric_csv_rows, numeric_expected_rows) + self.assertItemsEqual(csv_rows, expected_rows) + self.assertItemsEqual(numeric_csv_rows, numeric_expected_rows) @staticmethod def _extract_and_round_numeric_items(dictionary): diff --git a/lms/djangoapps/shoppingcart/tests/test_models.py b/lms/djangoapps/shoppingcart/tests/test_models.py index ce28306048..f685861c46 100644 --- a/lms/djangoapps/shoppingcart/tests/test_models.py +++ b/lms/djangoapps/shoppingcart/tests/test_models.py @@ -1376,12 +1376,12 @@ class InvoiceHistoryTest(TestCase): def _assert_history_items(self, expected_items): """Check line item info in the latest history record. """ items = self._latest_history()['items'] - six.assertCountEqual(items, expected_items) + self.assertItemsEqual(items, expected_items) def _assert_history_transactions(self, expected_transactions): """Check transactions (payments/refunds) in the latest history record. """ transactions = self._latest_history()['transactions'] - six.assertCountEqual(transactions, expected_transactions) + self.assertItemsEqual(transactions, expected_transactions) def _latest_history(self): """Retrieve the snapshot from the latest history record. """ diff --git a/openedx/core/djangoapps/catalog/tests/test_utils.py b/openedx/core/djangoapps/catalog/tests/test_utils.py index 7b4c193fc5..49e6e3b1c1 100644 --- a/openedx/core/djangoapps/catalog/tests/test_utils.py +++ b/openedx/core/djangoapps/catalog/tests/test_utils.py @@ -842,7 +842,7 @@ class TestGetProgramsByType(CacheIsolationTestCase): def test_get_masters_programs(self): expected_programs = [self.masters_program_1, self.masters_program_2] - six.assertCountEqual(expected_programs, get_programs_by_type(self.site, 'masters')) + self.assertItemsEqual(expected_programs, get_programs_by_type(self.site, 'masters')) def test_get_bachelors_programs(self): expected_programs = [self.bachelors_program] diff --git a/openedx/core/djangoapps/coursegraph/management/commands/tests/test_dump_to_neo4j.py b/openedx/core/djangoapps/coursegraph/management/commands/tests/test_dump_to_neo4j.py index eb16965389..5156428876 100644 --- a/openedx/core/djangoapps/coursegraph/management/commands/tests/test_dump_to_neo4j.py +++ b/openedx/core/djangoapps/coursegraph/management/commands/tests/test_dump_to_neo4j.py @@ -422,7 +422,7 @@ class TestModuleStoreSerializer(TestDumpToNeo4jCommandBase): # 2 nodes and no relationships from the second self.assertEqual(len(mock_graph.nodes), 11) - six.assertCountEqual(submitted, self.course_strings) + self.assertItemsEqual(submitted, self.course_strings) @mock.patch('openedx.core.djangoapps.coursegraph.tasks.NodeSelector') @mock.patch('openedx.core.djangoapps.coursegraph.tasks.authenticate_and_create_graph') @@ -445,7 +445,7 @@ class TestModuleStoreSerializer(TestDumpToNeo4jCommandBase): number_rollbacks=2, ) - six.assertCountEqual(submitted, self.course_strings) + self.assertItemsEqual(submitted, self.course_strings) @mock.patch('openedx.core.djangoapps.coursegraph.tasks.NodeSelector') @mock.patch('openedx.core.djangoapps.coursegraph.tasks.authenticate_and_create_graph') diff --git a/openedx/core/djangoapps/enrollments/tests/test_views.py b/openedx/core/djangoapps/enrollments/tests/test_views.py index 29ccb72586..ce7e2b66ac 100644 --- a/openedx/core/djangoapps/enrollments/tests/test_views.py +++ b/openedx/core/djangoapps/enrollments/tests/test_views.py @@ -363,7 +363,7 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase, Ente response = self.client.get(reverse('courseenrollments'), {'user': self.user.username}, **kwargs) self.assertEqual(response.status_code, status.HTTP_200_OK) data = json.loads(response.content.decode('utf-8')) - six.assertCountEqual( + self.assertItemsEqual( [(datum['course_details']['course_id'], datum['course_details']['course_name']) for datum in data], [(six.text_type(course.id), course.display_name_with_default) for course in courses] ) @@ -1680,4 +1680,4 @@ class CourseEnrollmentsApiListTest(APITestCase, ModuleStoreTestCase): content = self._assert_list_of_enrollments(query_params, status.HTTP_200_OK) results = content['results'] - six.assertCountEqual(results, expected_results) + self.assertItemsEqual(results, expected_results) diff --git a/openedx/core/djangoapps/lang_pref/tests/test_middleware.py b/openedx/core/djangoapps/lang_pref/tests/test_middleware.py index 950e17d6e0..372691e422 100644 --- a/openedx/core/djangoapps/lang_pref/tests/test_middleware.py +++ b/openedx/core/djangoapps/lang_pref/tests/test_middleware.py @@ -8,7 +8,6 @@ import itertools import ddt import mock -import six from django.conf import settings from django.contrib.sessions.middleware import SessionMiddleware from django.http import HttpResponse @@ -150,7 +149,7 @@ class TestUserPreferenceMiddleware(CacheIsolationTestCase): accept_lang_out = parse_accept_lang_header(accept_lang_out) if accept_lang_out and accept_lang_result: - six.assertCountEqual(accept_lang_result, accept_lang_out) + self.assertItemsEqual(accept_lang_result, accept_lang_out) else: self.assertEqual(accept_lang_result, accept_lang_out) diff --git a/openedx/core/djangoapps/programs/tests/test_utils.py b/openedx/core/djangoapps/programs/tests/test_utils.py index 10e99e10ca..a755ef79ed 100644 --- a/openedx/core/djangoapps/programs/tests/test_utils.py +++ b/openedx/core/djangoapps/programs/tests/test_utils.py @@ -674,7 +674,7 @@ class TestProgramProgressMeter(TestCase): self._create_certificates(unknown['key'], status='unknown') meter = ProgramProgressMeter(self.site, self.user) - six.assertCountEqual( + self.assertItemsEqual( meter.completed_course_runs, [ {'course_run_id': downloadable['key'], 'type': CourseMode.VERIFIED}, diff --git a/openedx/core/djangoapps/schedules/management/commands/tests/test_send_upgrade_reminder.py b/openedx/core/djangoapps/schedules/management/commands/tests/test_send_upgrade_reminder.py index 9fa317cf0a..4174f67129 100644 --- a/openedx/core/djangoapps/schedules/management/commands/tests/test_send_upgrade_reminder.py +++ b/openedx/core/djangoapps/schedules/management/commands/tests/test_send_upgrade_reminder.py @@ -7,7 +7,6 @@ import logging from unittest import skipUnless import ddt -import six from django.conf import settings from edx_ace import Message from edx_ace.utils.date import serialize @@ -87,7 +86,7 @@ class TestUpgradeReminder(ScheduleSendEmailTestMixin, CacheIsolationTestCase): messages = [Message.from_string(m) for m in sent_messages] self.assertEqual(len(messages), 1) message = messages[0] - six.assertCountEqual( + self.assertItemsEqual( message.context['course_ids'], [str(schedules[i].enrollment.course.id) for i in (1, 2, 4)] ) diff --git a/openedx/core/djangoapps/site_configuration/tests/test_helpers.py b/openedx/core/djangoapps/site_configuration/tests/test_helpers.py index 5cc7c7375a..beb04a85cf 100644 --- a/openedx/core/djangoapps/site_configuration/tests/test_helpers.py +++ b/openedx/core/djangoapps/site_configuration/tests/test_helpers.py @@ -3,7 +3,6 @@ Tests for helper function provided by site_configuration app. """ from __future__ import absolute_import -import six from django.test import TestCase from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers @@ -82,7 +81,7 @@ class TestHelpers(TestCase): Test that get_dict returns correct value for any given key. """ # Make sure entry is saved and retrieved correctly - six.assertCountEqual( + self.assertItemsEqual( configuration_helpers.get_dict("REGISTRATION_EXTRA_FIELDS"), test_config['REGISTRATION_EXTRA_FIELDS'], ) @@ -92,7 +91,7 @@ class TestHelpers(TestCase): expected.update(test_config['REGISTRATION_EXTRA_FIELDS']) # Test that the default value is returned if the value for the given key is not found in the configuration - six.assertCountEqual( + self.assertItemsEqual( configuration_helpers.get_dict("REGISTRATION_EXTRA_FIELDS", default), expected, ) @@ -135,7 +134,7 @@ class TestHelpers(TestCase): test_config['css_overrides_file'] ) - six.assertCountEqual( + self.assertItemsEqual( configuration_helpers.get_value_for_org(test_org, "REGISTRATION_EXTRA_FIELDS"), test_config['REGISTRATION_EXTRA_FIELDS'] ) @@ -178,7 +177,7 @@ class TestHelpers(TestCase): """ test_orgs = [test_config['course_org_filter']] with with_site_configuration_context(configuration=test_config): - six.assertCountEqual( + self.assertItemsEqual( list(configuration_helpers.get_all_orgs()), test_orgs, ) @@ -186,7 +185,7 @@ class TestHelpers(TestCase): @with_site_configuration(configuration=test_config_multi_org) def test_get_current_site_orgs(self): test_orgs = test_config_multi_org['course_org_filter'] - six.assertCountEqual( + self.assertItemsEqual( list(configuration_helpers.get_current_site_orgs()), test_orgs ) diff --git a/openedx/core/djangoapps/theming/tests/test_commands.py b/openedx/core/djangoapps/theming/tests/test_commands.py index d5f1d40eb6..7b4563c0bb 100644 --- a/openedx/core/djangoapps/theming/tests/test_commands.py +++ b/openedx/core/djangoapps/theming/tests/test_commands.py @@ -3,7 +3,6 @@ Tests for Management commands of comprehensive theming. """ from __future__ import absolute_import -import six from django.core.management import CommandError, call_command from django.test import TestCase @@ -45,12 +44,12 @@ class TestUpdateAssets(TestCase): """ # make sure compile_sass picks all themes when called with 'themes=all' option parsed_args = Command.parse_arguments(themes=["all"]) - six.assertCountEqual(parsed_args[2], get_themes()) + self.assertItemsEqual(parsed_args[2], get_themes()) # make sure compile_sass picks no themes when called with 'themes=no' option parsed_args = Command.parse_arguments(themes=["no"]) - six.assertCountEqual(parsed_args[2], []) + self.assertItemsEqual(parsed_args[2], []) # make sure compile_sass picks only specified themes parsed_args = Command.parse_arguments(themes=["test-theme"]) - six.assertCountEqual(parsed_args[2], [theme for theme in get_themes() if theme.theme_dir_name == "test-theme"]) + self.assertItemsEqual(parsed_args[2], [theme for theme in get_themes() if theme.theme_dir_name == "test-theme"]) diff --git a/openedx/core/djangoapps/theming/tests/test_helpers.py b/openedx/core/djangoapps/theming/tests/test_helpers.py index 8ffcceb14f..bb920ff1cb 100644 --- a/openedx/core/djangoapps/theming/tests/test_helpers.py +++ b/openedx/core/djangoapps/theming/tests/test_helpers.py @@ -3,7 +3,6 @@ Test helpers for Comprehensive Theming. """ from __future__ import absolute_import -import six from django.conf import settings from django.test import TestCase, override_settings from edx_django_utils.cache import RequestCache @@ -39,7 +38,7 @@ class TestHelpers(TestCase): Theme('test-theme', 'test-theme', get_theme_base_dir('test-theme'), settings.PROJECT_ROOT), ] actual_themes = get_themes() - six.assertCountEqual(expected_themes, actual_themes) + self.assertItemsEqual(expected_themes, actual_themes) @override_settings(COMPREHENSIVE_THEME_DIRS=[settings.TEST_THEME.dirname()]) def test_get_themes_2(self): @@ -50,7 +49,7 @@ class TestHelpers(TestCase): Theme('test-theme', 'test-theme', get_theme_base_dir('test-theme'), settings.PROJECT_ROOT), ] actual_themes = get_themes() - six.assertCountEqual(expected_themes, actual_themes) + self.assertItemsEqual(expected_themes, actual_themes) def test_get_value_returns_override(self): """ diff --git a/openedx/core/djangoapps/user_api/accounts/tests/test_retirement_views.py b/openedx/core/djangoapps/user_api/accounts/tests/test_retirement_views.py index 762f99c577..0d3bfb6075 100644 --- a/openedx/core/djangoapps/user_api/accounts/tests/test_retirement_views.py +++ b/openedx/core/djangoapps/user_api/accounts/tests/test_retirement_views.py @@ -11,7 +11,6 @@ import unittest import ddt import mock import pytz -import six from consent.models import DataSharingConsent from django.conf import settings from django.contrib.auth.models import User @@ -566,7 +565,7 @@ class TestPartnerReportingList(ModuleStoreTestCase): for returned_user in returned_users: returned_user['orgs'].sort() - six.assertCountEqual(returned_users, expected_users) + self.assertCountEqual(returned_users, expected_users) def test_success(self): """ @@ -662,7 +661,7 @@ class TestAccountRetirementList(RetirementTestCase): del retirement['created'] del retirement['modified'] - six.assertCountEqual(response_data, expected_data) + self.assertItemsEqual(response_data, expected_data) def test_empty(self): """ @@ -835,7 +834,7 @@ class TestAccountRetirementsByStatusAndDate(RetirementTestCase): except KeyError: pass - six.assertCountEqual(response_data, expected_data) + self.assertItemsEqual(response_data, expected_data) def test_empty(self): """ diff --git a/openedx/core/djangoapps/user_api/accounts/tests/test_views.py b/openedx/core/djangoapps/user_api/accounts/tests/test_views.py index 9270d97df8..6b24bd66b8 100644 --- a/openedx/core/djangoapps/user_api/accounts/tests/test_views.py +++ b/openedx/core/djangoapps/user_api/accounts/tests/test_views.py @@ -12,7 +12,6 @@ from copy import deepcopy import ddt import mock import pytz -import six from django.conf import settings from django.core.urlresolvers import reverse from django.test.testcases import TransactionTestCase @@ -791,7 +790,7 @@ class TestAccountsAPI(CacheIsolationTestCase, UserAPITestCase): # than django model id. for proficiencies in ([{"code": "en"}, {"code": "fr"}, {"code": "es"}], [{"code": "fr"}], [{"code": "aa"}], []): response = self.send_patch(client, {"language_proficiencies": proficiencies}) - six.assertCountEqual(response.data["language_proficiencies"], proficiencies) + self.assertItemsEqual(response.data["language_proficiencies"], proficiencies) @ddt.data( ( diff --git a/openedx/core/djangoapps/user_api/tests/test_views.py b/openedx/core/djangoapps/user_api/tests/test_views.py index 40633ceaca..05cc1d7854 100644 --- a/openedx/core/djangoapps/user_api/tests/test_views.py +++ b/openedx/core/djangoapps/user_api/tests/test_views.py @@ -19,7 +19,7 @@ from django.test.utils import override_settings from django.urls import reverse from opaque_keys.edx.keys import CourseKey from pytz import UTC, common_timezones_set -from six import text_type, assertCountEqual +from six import text_type from six.moves import range from social_django.models import Partial, UserSocialAuth @@ -93,8 +93,8 @@ class UserAPITestCase(ApiTestCase): def assertUserIsValid(self, user): """Assert that the given user result is valid""" - assertCountEqual(list(user.keys()), ["email", "id", "name", "username", "preferences", "url"]) - assertCountEqual( + self.assertItemsEqual(list(user.keys()), ["email", "id", "name", "username", "preferences", "url"]) + self.assertItemsEqual( list(user["preferences"].items()), [(pref.key, pref.value) for pref in self.prefs if pref.user.id == user["id"]] ) @@ -104,7 +104,7 @@ class UserAPITestCase(ApiTestCase): """ Assert that the given preference is acknowledged by the system """ - assertCountEqual(list(pref.keys()), ["user", "key", "value", "url"]) + self.assertItemsEqual(list(pref.keys()), ["user", "key", "value", "url"]) self.assertSelfReferential(pref) self.assertUserIsValid(pref["user"]) diff --git a/openedx/core/lib/api/test_utils.py b/openedx/core/lib/api/test_utils.py index 83333e4a65..70e8ebaad4 100644 --- a/openedx/core/lib/api/test_utils.py +++ b/openedx/core/lib/api/test_utils.py @@ -5,7 +5,6 @@ from __future__ import absolute_import import base64 import json import re -import six from django.test import TestCase from django.test.utils import override_settings @@ -50,7 +49,7 @@ class ApiTestCase(TestCase): allow_header = resp.get("Allow") self.assertIsNotNone(allow_header) allowed_methods = re.split('[^A-Z]+', allow_header) - six.assertCountEqual(allowed_methods, expected_methods) + self.assertItemsEqual(allowed_methods, expected_methods) def assertSelfReferential(self, obj): """Assert that accessing the "url" entry in the given object returns the same object""" diff --git a/openedx/features/course_duration_limits/tests/test_course_expiration.py b/openedx/features/course_duration_limits/tests/test_course_expiration.py index 1b93b9dbeb..07c06c23f7 100644 --- a/openedx/features/course_duration_limits/tests/test_course_expiration.py +++ b/openedx/features/course_duration_limits/tests/test_course_expiration.py @@ -216,7 +216,7 @@ class CourseExpirationTestCase(ModuleStoreTestCase): course_home_url = reverse('openedx.course_experience.course_home', args=[six.text_type(self.course.id)]) response = self.client.get(course_home_url, follow=True) self.assertEqual(response.status_code, 200) - six.assertCountEqual(response.redirect_chain, []) + self.assertItemsEqual(response.redirect_chain, []) banner_text = 'You lose all access to this course, including your progress,' if show_expiration_banner: self.assertIn(banner_text, response.content) @@ -281,7 +281,7 @@ class CourseExpirationTestCase(ModuleStoreTestCase): course_home_url = reverse('openedx.course_experience.course_home', args=[six.text_type(self.course.id)]) response = self.client.get(course_home_url, follow=True) self.assertEqual(response.status_code, 200) - self.six.assertCountEqual(response.redirect_chain, []) + self.assertItemsEqual(response.redirect_chain, []) banner_text = 'You lose all access to this course, including your progress,' self.assertNotIn(banner_text, response.content) @@ -317,7 +317,7 @@ class CourseExpirationTestCase(ModuleStoreTestCase): course_home_url = reverse('openedx.course_experience.course_home', args=[six.text_type(self.course.id)]) response = self.client.get(course_home_url, follow=True) self.assertEqual(response.status_code, 200) - self.six.assertCountEqual(response.redirect_chain, []) + self.assertItemsEqual(response.redirect_chain, []) banner_text = 'This learner does not have access to this course. Their access expired on' self.assertIn(banner_text, response.content) @@ -368,7 +368,7 @@ class CourseExpirationTestCase(ModuleStoreTestCase): course_home_url = reverse('openedx.course_experience.course_home', args=[six.text_type(self.course.id)]) response = self.client.get(course_home_url, follow=True) self.assertEqual(response.status_code, 200) - self.six.assertCountEqual(response.redirect_chain, []) + self.assertItemsEqual(response.redirect_chain, []) banner_text = 'This learner does not have access to this course. Their access expired on' self.assertNotIn(banner_text, response.content) @@ -417,6 +417,6 @@ class CourseExpirationTestCase(ModuleStoreTestCase): course_home_url = reverse('openedx.course_experience.course_home', args=[six.text_type(self.course.id)]) response = self.client.get(course_home_url, follow=True) self.assertEqual(response.status_code, 200) - self.six.assertCountEqual(response.redirect_chain, []) + self.assertItemsEqual(response.redirect_chain, []) banner_text = 'This learner does not have access to this course. Their access expired on' self.assertNotIn(banner_text, response.content) diff --git a/pavelib/paver_tests/test_assets.py b/pavelib/paver_tests/test_assets.py index d69d9a5f06..bff9a83969 100644 --- a/pavelib/paver_tests/test_assets.py +++ b/pavelib/paver_tests/test_assets.py @@ -7,7 +7,6 @@ from unittest import TestCase import ddt import paver.tasks -import six from mock import patch from paver.easy import call_task, path from watchdog.observers import Observer @@ -79,7 +78,7 @@ class TestPaverAssetTasks(PaverTestCase): u'rtlcss cms/static/css/bootstrap/studio-main.css cms/static/css/bootstrap/studio-main-rtl.css' ) - six.assertCountEqual(self.task_messages, expected_messages) + self.assertItemsEqual(self.task_messages, expected_messages) @ddt.ddt @@ -196,7 +195,7 @@ class TestPaverThemeAssetTasks(PaverTestCase): u'rtlcss cms/static/css/bootstrap/studio-main.css cms/static/css/bootstrap/studio-main-rtl.css' ) - self.six.assertCountEqual(self.task_messages, expected_messages) + self.assertItemsEqual(self.task_messages, expected_messages) class TestPaverWatchAssetTasks(TestCase): @@ -246,7 +245,7 @@ class TestPaverWatchAssetTasks(TestCase): self.assertIsInstance(sass_watcher_args[0], Observer) self.assertIsInstance(sass_watcher_args[1], list) - self.six.assertCountEqual(sass_watcher_args[1], self.expected_sass_directories) + self.assertItemsEqual(sass_watcher_args[1], self.expected_sass_directories) def test_watch_theme_assets(self): """ @@ -276,7 +275,7 @@ class TestPaverWatchAssetTasks(TestCase): sass_watcher_args = mock_register.call_args_list[0][0] self.assertIsInstance(sass_watcher_args[0], Observer) self.assertIsInstance(sass_watcher_args[1], list) - self.six.assertCountEqual(sass_watcher_args[1], self.expected_sass_directories) + self.assertItemsEqual(sass_watcher_args[1], self.expected_sass_directories) @ddt.ddt From fde27196f9996c4816b89cc3f5da896a9ce201f2 Mon Sep 17 00:00:00 2001 From: Feanil Patel Date: Tue, 20 Aug 2019 18:02:30 -0400 Subject: [PATCH 19/20] Fix quality issues. --- common/lib/xmodule/xmodule/modulestore/xml.py | 2 -- lms/templates/shoppingcart/cybersource_form.html | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/common/lib/xmodule/xmodule/modulestore/xml.py b/common/lib/xmodule/xmodule/modulestore/xml.py index fc31eda63a..cf595b685c 100644 --- a/common/lib/xmodule/xmodule/modulestore/xml.py +++ b/common/lib/xmodule/xmodule/modulestore/xml.py @@ -435,8 +435,6 @@ class XMLModuleStore(ModuleStoreReadBase): """ log.debug('========> Starting courselike import from %s', course_dir) with open(self.data_dir / course_dir / self.parent_xml) as course_file: - - course_data = etree.parse(course_file, parser=edx_xml_parser).getroot() org = course_data.get('org') diff --git a/lms/templates/shoppingcart/cybersource_form.html b/lms/templates/shoppingcart/cybersource_form.html index 6c34a37a0f..ee9e6858a6 100644 --- a/lms/templates/shoppingcart/cybersource_form.html +++ b/lms/templates/shoppingcart/cybersource_form.html @@ -1,3 +1,4 @@ +<%page expression_filter="h"/> <%! from django.utils.translation import ugettext as _ %> % for pk, pv in params.items(): From 3c33f6c30fe53487d02a58c35f7f87342612c083 Mon Sep 17 00:00:00 2001 From: Feanil Patel Date: Wed, 21 Aug 2019 07:44:06 -0400 Subject: [PATCH 20/20] Fix another quality issue. --- cms/djangoapps/contentstore/views/item.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cms/djangoapps/contentstore/views/item.py b/cms/djangoapps/contentstore/views/item.py index c54fd6599f..7209219aca 100644 --- a/cms/djangoapps/contentstore/views/item.py +++ b/cms/djangoapps/contentstore/views/item.py @@ -225,7 +225,10 @@ def xblock_handler(request, usage_key_string): request.user, request.json.get('display_name'), ) - return JsonResponse({'locator': text_type(dest_usage_key), 'courseKey': text_type(dest_usage_key.course_key)}) + return JsonResponse({ + 'locator': text_type(dest_usage_key), + 'courseKey': text_type(dest_usage_key.course_key) + }) else: return _create_item(request) elif request.method == 'PATCH':