From a6b219a9e9e49e9a405460a0de06aa93866e717d Mon Sep 17 00:00:00 2001
From: Nimisha Asthagiri <nasthagiri@edx.org>
Date: Sat, 28 Sep 2019 18:22:27 -0400
Subject: [PATCH] Python-3: assertIn(..response.content) -> assertContains

---
 .../views/tests/test_certificates.py          |   3 +-
 .../views/tests/test_course_index.py          |   6 +-
 .../contentstore/views/tests/test_library.py  |   4 +-
 lms/djangoapps/branding/tests/test_page.py    |  10 +-
 lms/djangoapps/bulk_email/tests/test_email.py |   2 +-
 .../bulk_email/tests/test_signals.py          |   2 +-
 .../bulk_enroll/tests/test_views.py           |   3 +-
 .../course_wiki/tests/test_middleware.py      |   4 +-
 .../courseware/tests/test_password_reset.py   |   2 +-
 lms/djangoapps/courseware/tests/test_views.py |  31 +++--
 lms/djangoapps/edxnotes/tests.py              |   6 +-
 lms/djangoapps/instructor/tests/test_api.py   |  28 ++--
 .../instructor/tests/test_ecommerce.py        | 123 ++++++++++--------
 lms/djangoapps/instructor/tests/test_email.py |   6 +-
 .../instructor/tests/test_proctoring.py       |   2 +-
 .../tests/views/test_instructor_dashboard.py  |  46 +++----
 .../shoppingcart/tests/test_views.py          |  14 +-
 .../static_template_view/tests/test_views.py  |   8 +-
 lms/djangoapps/teams/tests/test_views.py      |   6 +-
 .../verify_student/tests/test_views.py        |  22 ++--
 .../djangoapps/credit/tests/test_views.py     |   3 +-
 .../accounts/tests/test_settings_views.py     |   4 +-
 .../announcements/tests/test_announcements.py |   6 +-
 .../tests/test_course_expiration.py           |   4 +-
 .../tests/views/test_course_home.py           |   6 +-
 .../tests/views/test_course_outline.py        |  10 +-
 .../tests/views/test_learner_profile.py       |   4 +-
 27 files changed, 188 insertions(+), 177 deletions(-)

diff --git a/cms/djangoapps/contentstore/views/tests/test_certificates.py b/cms/djangoapps/contentstore/views/tests/test_certificates.py
index 1aeb1c9b2fd..bdd4fe24fe0 100644
--- a/cms/djangoapps/contentstore/views/tests/test_certificates.py
+++ b/cms/djangoapps/contentstore/views/tests/test_certificates.py
@@ -349,8 +349,7 @@ class CertificatesListHandlerTestCase(
             self._url(),
             data=CERTIFICATE_JSON
         )
-        self.assertEqual(response.status_code, 403)
-        self.assertIn("error", response.content)
+        self.assertContains(response, "error", status_code=403)
 
     def test_audit_course_mode_is_skipped(self):
         """
diff --git a/cms/djangoapps/contentstore/views/tests/test_course_index.py b/cms/djangoapps/contentstore/views/tests/test_course_index.py
index e9af42c8226..8849fbd1cdf 100644
--- a/cms/djangoapps/contentstore/views/tests/test_course_index.py
+++ b/cms/djangoapps/contentstore/views/tests/test_course_index.py
@@ -311,7 +311,7 @@ class TestCourseIndex(CourseTestCase):
         self.assertEqual(response.status_code, 200)
 
         # Assert that 'display_course_number' is being set to "" (as display_coursenumber was None).
-        self.assertIn('display_course_number: ""', response.content)
+        self.assertContains(response, 'display_course_number: ""')
 
 
 @ddt.ddt
@@ -648,7 +648,7 @@ class TestCourseReIndex(CourseTestCase):
         response = self.client.get(index_url, {}, HTTP_ACCEPT='application/json')
 
         # A course with the default release date should display as "Unscheduled"
-        self.assertIn(self.SUCCESSFUL_RESPONSE, response.content)
+        self.assertContains(response, self.SUCCESSFUL_RESPONSE)
         self.assertEqual(response.status_code, 200)
 
         response = self.client.post(index_url, {}, HTTP_ACCEPT='application/json')
@@ -677,7 +677,7 @@ class TestCourseReIndex(CourseTestCase):
         response = self.client.get(index_url, {}, CONTENT_TYPE='')
 
         # A course with the default release date should display as "Unscheduled"
-        self.assertIn(self.SUCCESSFUL_RESPONSE, response.content)
+        self.assertContains(response, self.SUCCESSFUL_RESPONSE)
         self.assertEqual(response.status_code, 200)
 
     @mock.patch('xmodule.html_module.HtmlBlock.index_dictionary')
diff --git a/cms/djangoapps/contentstore/views/tests/test_library.py b/cms/djangoapps/contentstore/views/tests/test_library.py
index e658410f70d..bf485f6394e 100644
--- a/cms/djangoapps/contentstore/views/tests/test_library.py
+++ b/cms/djangoapps/contentstore/views/tests/test_library.py
@@ -257,8 +257,8 @@ class UnitTestLibraries(CourseTestCase):
 
         response = self.client.get(make_url_for_lib(lib.location.library_key))
         self.assertEqual(response.status_code, 200)
-        self.assertIn("<html", response.content)
-        self.assertIn(lib.display_name.encode('utf-8'), response.content)
+        self.assertContains(response, "<html")
+        self.assertContains(response, lib.display_name)
 
     @ddt.data('library-v1:Nonexistent+library', 'course-v1:Org+Course', 'course-v1:Org+Course+Run', 'invalid')
     def test_invalid_keys(self, key_str):
diff --git a/lms/djangoapps/branding/tests/test_page.py b/lms/djangoapps/branding/tests/test_page.py
index 3b8bed715ce..2b5812388fc 100644
--- a/lms/djangoapps/branding/tests/test_page.py
+++ b/lms/djangoapps/branding/tests/test_page.py
@@ -213,7 +213,7 @@ class IndexPageCourseCardsSortingTests(ModuleStoreTestCase):
         self.assertNotIn('<aside aria-label="Refine Your Search" class="search-facets phone-menu">', response.content)
 
         # make sure we have the special css class on the section
-        self.assertIn('<div class="courses no-course-discovery"', response.content)
+        self.assertContains(response, '<div class="courses no-course-discovery"')
 
     @patch('student.views.management.render_to_response', RENDER_MOCK)
     @patch('lms.djangoapps.courseware.views.views.render_to_response', RENDER_MOCK)
@@ -226,16 +226,16 @@ class IndexPageCourseCardsSortingTests(ModuleStoreTestCase):
         response = self.client.get('/')
         self.assertEqual(response.status_code, 200)
         # assert that the course discovery UI is not present
-        self.assertIn('Search for a course', response.content)
+        self.assertContains(response, 'Search for a course')
 
         # check the /courses view
         response = self.client.get(reverse('courses'))
         self.assertEqual(response.status_code, 200)
 
         # assert that the course discovery UI is present
-        self.assertIn('Search for a course', response.content)
-        self.assertIn('<aside aria-label="Refine Your Search" class="search-facets phone-menu">', response.content)
-        self.assertIn('<div class="courses"', response.content)
+        self.assertContains(response, 'Search for a course')
+        self.assertContains(response, '<aside aria-label="Refine Your Search" class="search-facets phone-menu">')
+        self.assertContains(response, '<div class="courses"')
 
     @patch('student.views.management.render_to_response', RENDER_MOCK)
     @patch('lms.djangoapps.courseware.views.views.render_to_response', RENDER_MOCK)
diff --git a/lms/djangoapps/bulk_email/tests/test_email.py b/lms/djangoapps/bulk_email/tests/test_email.py
index a6b526dbfd3..070fda2f403 100644
--- a/lms/djangoapps/bulk_email/tests/test_email.py
+++ b/lms/djangoapps/bulk_email/tests/test_email.py
@@ -100,7 +100,7 @@ class EmailSendFromDashboardTestCase(SharedModuleStoreTestCase):
         response = self.client.get(url)
         email_section = '<div class="vert-left send-email" id="section-send-email">'
         # If this fails, it is likely because bulk_email.api.is_bulk_email_feature_enabled is set to False
-        self.assertIn(email_section, response.content)
+        self.assertContains(response, email_section)
 
     @classmethod
     def setUpClass(cls):
diff --git a/lms/djangoapps/bulk_email/tests/test_signals.py b/lms/djangoapps/bulk_email/tests/test_signals.py
index d61c1fc906d..2af4bff861b 100644
--- a/lms/djangoapps/bulk_email/tests/test_signals.py
+++ b/lms/djangoapps/bulk_email/tests/test_signals.py
@@ -60,7 +60,7 @@ class TestOptoutCourseEmailsBySignal(ModuleStoreTestCase):
         email_section = '<div class="vert-left send-email" id="section-send-email">'
 
         # If this fails, it is likely because BulkEmailFlag.is_enabled() is set to False
-        self.assertIn(email_section, response.content)
+        self.assertContains(response, email_section)
 
         test_email = {
             'action': 'Send email',
diff --git a/lms/djangoapps/bulk_enroll/tests/test_views.py b/lms/djangoapps/bulk_enroll/tests/test_views.py
index d55dd81353c..fb9c942f59c 100644
--- a/lms/djangoapps/bulk_enroll/tests/test_views.py
+++ b/lms/djangoapps/bulk_enroll/tests/test_views.py
@@ -383,8 +383,7 @@ class BulkEnrollmentTest(ModuleStoreTestCase, LoginEnrollmentTestCase, APITestCa
             'cohorts': 'cohort1',
             'courses': self.course_key
         })
-        self.assertEqual(response.status_code, 400)
-        self.assertIn('Cohorts can only be used for enrollments.', response.content.decode('utf-8'))
+        self.assertContains(response, 'Cohorts can only be used for enrollments.', status_code=400)
 
     def test_add_to_valid_cohort(self):
         config_course_cohorts(self.course, is_cohorted=True, manual_cohorts=["cohort1", "cohort2"])
diff --git a/lms/djangoapps/course_wiki/tests/test_middleware.py b/lms/djangoapps/course_wiki/tests/test_middleware.py
index 687987e3a15..3aaa256061a 100644
--- a/lms/djangoapps/course_wiki/tests/test_middleware.py
+++ b/lms/djangoapps/course_wiki/tests/test_middleware.py
@@ -32,5 +32,5 @@ class TestWikiAccessMiddleware(ModuleStoreTestCase):
     def test_url_tranform(self):
         """Test that the correct prefix ('/courses/<course_id>') is added to the urls in the wiki."""
         response = self.client.get('/courses/edx/math101/2014/wiki/math101/')
-        self.assertIn('/courses/edx/math101/2014/wiki/math101/_edit/', response.content)
-        self.assertIn('/courses/edx/math101/2014/wiki/math101/_settings/', response.content)
+        self.assertContains(response, '/courses/edx/math101/2014/wiki/math101/_edit/')
+        self.assertContains(response, '/courses/edx/math101/2014/wiki/math101/_settings/')
diff --git a/lms/djangoapps/courseware/tests/test_password_reset.py b/lms/djangoapps/courseware/tests/test_password_reset.py
index e603c862692..c9f3db74014 100644
--- a/lms/djangoapps/courseware/tests/test_password_reset.py
+++ b/lms/djangoapps/courseware/tests/test_password_reset.py
@@ -51,7 +51,7 @@ class TestPasswordReset(LoginEnrollmentTestCase):
         """
         self.assertEqual(response.status_code, 200)
         self.assertEqual(response.context_data['validlink'], valid_link)
-        self.assertIn(error_message, response.content)
+        self.assertContains(response, error_message)
 
     @override_settings(AUTH_PASSWORD_VALIDATORS=[
         create_validator_config('util.password_policy_validators.MinimumLengthValidator', {'min_length': 6})
diff --git a/lms/djangoapps/courseware/tests/test_views.py b/lms/djangoapps/courseware/tests/test_views.py
index d12c217c793..9ba3af18fea 100644
--- a/lms/djangoapps/courseware/tests/test_views.py
+++ b/lms/djangoapps/courseware/tests/test_views.py
@@ -480,7 +480,7 @@ class ViewsTestCase(ModuleStoreTestCase):
         shoppingcart.models.PaidCourseRegistration.add_to_order(cart, course.id)
         response = self.client.get(reverse('about_course', args=[six.text_type(course.id)]))
         self.assertEqual(response.status_code, 200)
-        self.assertIn(in_cart_span, response.content)
+        self.assertContains(response, in_cart_span)
 
     def assert_enrollment_link_present(self, is_anonymous):
         """
@@ -729,8 +729,8 @@ class ViewsTestCase(ModuleStoreTestCase):
                 response_content = HTMLParser().unescape(response.content)
                 expected_time = datetime.now() + timedelta(hours=hour_diff)
                 expected_tz = expected_time.strftime('%Z')
-                self.assertIn(expected_tz, response_content)
-                self.assertIn(str(expected_time), response_content)
+                self.assertContains(response, expected_tz)
+                self.assertContains(response, str(expected_time))
 
     def _email_opt_in_checkbox(self, response, org_name_string=None):
         """Check if the email opt-in checkbox appears in the response content."""
@@ -749,7 +749,7 @@ class ViewsTestCase(ModuleStoreTestCase):
         response = self.client.get(url)
         # This is a static page, so just assert that it is returned correctly
         self.assertEqual(response.status_code, 200)
-        self.assertIn('Financial Assistance Application', response.content)
+        self.assertContains(response, 'Financial Assistance Application')
 
     @ddt.data(([CourseMode.AUDIT, CourseMode.VERIFIED], CourseMode.AUDIT, True, YESTERDAY),
               ([CourseMode.AUDIT, CourseMode.VERIFIED], CourseMode.VERIFIED, True, None),
@@ -837,7 +837,7 @@ class ViewsTestCase(ModuleStoreTestCase):
         response = self.client.get(url)
         self.assertEqual(response.status_code, 200)
 
-        self.assertIn(str(course), response.content)
+        self.assertContains(response, str(course))
 
     def _submit_financial_assistance_form(self, data):
         """Submit a financial assistance request."""
@@ -2644,7 +2644,7 @@ class TestIndexViewCompleteOnView(ModuleStoreTestCase, CompletionWaffleTestMixin
         self.assertTrue(self.client.login(username=self.user.username, password='test'))
 
         response = self.client.get(self.section_1_url)
-        self.assertIn('data-mark-completed-on-view-after-delay', response.content)
+        self.assertContains(response, 'data-mark-completed-on-view-after-delay')
         self.assertEqual(response.content.count("data-mark-completed-on-view-after-delay"), 2)
 
         request = self.request_factory.post(
@@ -2662,7 +2662,7 @@ class TestIndexViewCompleteOnView(ModuleStoreTestCase, CompletionWaffleTestMixin
         self.assertEqual(json.loads(response.content.decode('utf-8')), {'result': "ok"})
 
         response = self.client.get(self.section_1_url)
-        self.assertIn('data-mark-completed-on-view-after-delay', response.content)
+        self.assertContains(response, 'data-mark-completed-on-view-after-delay')
         self.assertEqual(response.content.count("data-mark-completed-on-view-after-delay"), 1)
 
         request = self.request_factory.post(
@@ -2735,7 +2735,7 @@ class TestIndexViewWithVerticalPositions(ModuleStoreTestCase):
         """
         Asserts that the expected position and the position in the response are the same
         """
-        self.assertIn('data-position="{}"'.format(expected_position), response.content)
+        self.assertContains(response, 'data-position="{}"'.format(expected_position))
 
     @ddt.data(("-1", 1), ("0", 1), ("-0", 1), ("2", 2), ("5", 1))
     @ddt.unpack
@@ -2799,7 +2799,7 @@ class TestIndexViewWithGating(ModuleStoreTestCase, MilestonesTestCaseMixin):
             )
         )
         self.assertEqual(response.status_code, 200)
-        self.assertIn("Content Locked", response.content)
+        self.assertContains(response, "Content Locked")
 
 
 class TestIndexViewWithCourseDurationLimits(ModuleStoreTestCase):
@@ -2885,8 +2885,7 @@ class TestRenderXBlock(RenderXBlockTestMixin, ModuleStoreTestCase, CompletionWaf
         Test XBlockRendering with invalid usage key
         """
         response = self.get_response(usage_key='some_invalid_usage_key')
-        self.assertEqual(response.status_code, 404)
-        self.assertIn('Page not found', response.content)
+        self.assertContains(response, 'Page not found', status_code=404)
 
     def get_response(self, usage_key, url_encoded_params=None):
         """
@@ -2906,7 +2905,7 @@ class TestRenderXBlock(RenderXBlockTestMixin, ModuleStoreTestCase, CompletionWaf
 
         response = self.get_response(usage_key=self.html_block.location)
         self.assertEqual(response.status_code, 200)
-        self.assertIn('data-enable-completion-on-view-service="false"', response.content)
+        self.assertContains(response, 'data-enable-completion-on-view-service="false"')
         self.assertNotIn('data-mark-completed-on-view-after-delay', response.content)
 
     def test_render_xblock_with_completion_service_enabled(self):
@@ -2920,8 +2919,8 @@ class TestRenderXBlock(RenderXBlockTestMixin, ModuleStoreTestCase, CompletionWaf
 
         response = self.get_response(usage_key=self.html_block.location)
         self.assertEqual(response.status_code, 200)
-        self.assertIn('data-enable-completion-on-view-service="true"', response.content)
-        self.assertIn('data-mark-completed-on-view-after-delay', response.content)
+        self.assertContains(response, 'data-enable-completion-on-view-service="true"')
+        self.assertContains(response, 'data-mark-completed-on-view-after-delay')
 
         request = RequestFactoryNoCsrf().post(
             '/',
@@ -2940,12 +2939,12 @@ class TestRenderXBlock(RenderXBlockTestMixin, ModuleStoreTestCase, CompletionWaf
 
         response = self.get_response(usage_key=self.html_block.location)
         self.assertEqual(response.status_code, 200)
-        self.assertIn('data-enable-completion-on-view-service="false"', response.content)
+        self.assertContains(response, 'data-enable-completion-on-view-service="false"')
         self.assertNotIn('data-mark-completed-on-view-after-delay', response.content)
 
         response = self.get_response(usage_key=self.problem_block.location)
         self.assertEqual(response.status_code, 200)
-        self.assertIn('data-enable-completion-on-view-service="false"', response.content)
+        self.assertContains(response, 'data-enable-completion-on-view-service="false"')
         self.assertNotIn('data-mark-completed-on-view-after-delay', response.content)
 
 
diff --git a/lms/djangoapps/edxnotes/tests.py b/lms/djangoapps/edxnotes/tests.py
index 44a45fbfcb1..bfaebe81d77 100644
--- a/lms/djangoapps/edxnotes/tests.py
+++ b/lms/djangoapps/edxnotes/tests.py
@@ -1081,8 +1081,7 @@ class EdxNotesViewsTest(ModuleStoreTestCase):
         mock_search.side_effect = EdxNotesServiceUnavailable
         enable_edxnotes_for_the_course(self.course, self.user.id)
         response = self.client.get(self.notes_url, {"text": "test"})
-        self.assertEqual(response.status_code, 500)
-        self.assertIn("error", response.content)
+        self.assertContains(response, "error", status_code=500)
 
     @patch.dict("django.conf.settings.FEATURES", {"ENABLE_EDXNOTES": True})
     @patch("edxnotes.views.get_notes", autospec=True)
@@ -1094,8 +1093,7 @@ class EdxNotesViewsTest(ModuleStoreTestCase):
         mock_search.side_effect = EdxNotesParseError
         enable_edxnotes_for_the_course(self.course, self.user.id)
         response = self.client.get(self.notes_url, {"text": "test"})
-        self.assertEqual(response.status_code, 500)
-        self.assertIn("error", response.content)
+        self.assertContains(response, "error", status_code=500)
 
     @patch.dict("django.conf.settings.FEATURES", {"ENABLE_EDXNOTES": True})
     def test_get_id_token(self):
diff --git a/lms/djangoapps/instructor/tests/test_api.py b/lms/djangoapps/instructor/tests/test_api.py
index 40b5759ca4e..3c1b9f7f5e6 100644
--- a/lms/djangoapps/instructor/tests/test_api.py
+++ b/lms/djangoapps/instructor/tests/test_api.py
@@ -2684,22 +2684,23 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
 
         # Now re_validate the same active invoice number and expect an Bad request
         response = self.assert_request_status_code(400, url, method="POST", data=data)
-        self.assertIn("This invoice is already active.", response.content.decode('utf-8'))
+        self.assertContains(response, "This invoice is already active.", status_code=400)
 
         test_data_2 = {'invoice_number': self.sale_invoice_1.id}
         response = self.assert_request_status_code(400, url, method="POST", data=test_data_2)
-        self.assertIn("Missing required event_type parameter", response.content.decode('utf-8'))
+        self.assertContains(response, "Missing required event_type parameter", status_code=400)
 
         test_data_3 = {'event_type': "re_validate"}
         response = self.assert_request_status_code(400, url, method="POST", data=test_data_3)
-        self.assertIn("Missing required invoice_number parameter", response.content.decode('utf-8'))
+        self.assertContains(response, "Missing required invoice_number parameter", status_code=400)
 
         # submitting invalid invoice number
         data['invoice_number'] = 'testing'
         response = self.assert_request_status_code(400, url, method="POST", data=data)
-        self.assertIn(
+        self.assertContains(
+            response,
             u"invoice_number must be an integer, {value} provided".format(value=data['invoice_number']),
-            response.content.decode('utf-8')
+            status_code=400,
         )
 
     def test_get_sale_order_records_features_csv(self):
@@ -2991,8 +2992,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
             submit_task_function.side_effect = error
             response = self.client.post(url, {})
 
-        self.assertEqual(response.status_code, 400)
-        self.assertIn(already_running_status, response.content.decode('utf-8'))
+        self.assertContains(response, already_running_status, status_code=400)
 
     def test_get_students_features(self):
         """
@@ -3070,8 +3070,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
             error = AlreadyRunningError(already_running_status)
             submit_task_function.side_effect = error
             response = self.client.post(url, {})
-        self.assertEqual(response.status_code, 400)
-        self.assertIn(already_running_status, response.content.decode('utf-8'))
+        self.assertContains(response, already_running_status, status_code=400)
 
     def test_get_student_exam_results(self):
         """
@@ -3093,8 +3092,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
             error = AlreadyRunningError(already_running_status)
             submit_task_function.side_effect = error
             response = self.client.post(url, {})
-            self.assertEqual(response.status_code, 400)
-            self.assertIn(already_running_status, response.content.decode('utf-8'))
+            self.assertContains(response, already_running_status, status_code=400)
 
     def test_access_course_finance_admin_with_invalid_course_key(self):
         """
@@ -3408,8 +3406,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
             mock.side_effect = AlreadyRunningError(already_running_status)
             response = self.client.post(url, {})
 
-        self.assertEqual(response.status_code, 400)
-        self.assertIn(already_running_status, response.content.decode('utf-8'))
+        self.assertContains(response, already_running_status, status_code=400)
 
     def test_get_ora2_responses_success(self):
         url = reverse('export_ora2_data', kwargs={'course_id': text_type(self.course.id)})
@@ -3429,8 +3426,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
             mock_submit_ora2_task.side_effect = AlreadyRunningError(already_running_status)
             response = self.client.post(url, {})
 
-        self.assertEqual(response.status_code, 400)
-        self.assertIn(already_running_status, response.content.decode('utf-8'))
+        self.assertContains(response, already_running_status, status_code=400)
 
     def test_get_student_progress_url(self):
         """ Test that progress_url is in the successful response. """
@@ -5176,7 +5172,7 @@ class TestCourseRegistrationCodes(SharedModuleStoreTestCase):
 
         response = self.client.post(generate_code_url, data, **{'HTTP_HOST': 'localhost'})
         self.assertEqual(response.status_code, 400, response.content.decode('utf-8'))
-        self.assertIn('Could not parse amount as', response.content.decode('utf-8'))
+        self.assertContains(response, 'Could not parse amount as', status_code=400)
 
     def test_get_historical_coupon_codes(self):
         """
diff --git a/lms/djangoapps/instructor/tests/test_ecommerce.py b/lms/djangoapps/instructor/tests/test_ecommerce.py
index 8e8c30c1513..d9290caf430 100644
--- a/lms/djangoapps/instructor/tests/test_ecommerce.py
+++ b/lms/djangoapps/instructor/tests/test_ecommerce.py
@@ -52,9 +52,9 @@ class TestECommerceDashboardViews(SiteMixin, SharedModuleStoreTestCase):
         Test Pass E-commerce Tab is in the Instructor Dashboard
         """
         response = self.client.get(self.url)
-        self.assertIn(self.ecommerce_link, response.content)
+        self.assertContains(response, self.ecommerce_link)
         # Coupons should show up for White Label sites with priced honor modes.
-        self.assertIn('Coupon Code List', response.content)
+        self.assertContains(response, 'Coupon Code List')
 
     def test_reports_section_under_e_commerce_tab(self):
         """
@@ -63,8 +63,8 @@ class TestECommerceDashboardViews(SiteMixin, SharedModuleStoreTestCase):
         self.use_site(site=self.site_other)
         self.client.login(username=self.instructor.username, password="test")
         response = self.client.get(self.url)
-        self.assertIn(self.ecommerce_link, response.content)
-        self.assertIn('Create Enrollment Report', response.content)
+        self.assertContains(response, self.ecommerce_link)
+        self.assertContains(response, 'Create Enrollment Report')
 
     def test_reports_section_not_under_e_commerce_tab(self):
         """
@@ -72,17 +72,17 @@ class TestECommerceDashboardViews(SiteMixin, SharedModuleStoreTestCase):
         value
         """
         response = self.client.get(self.url)
-        self.assertIn(self.ecommerce_link, response.content)
+        self.assertContains(response, self.ecommerce_link)
         self.assertNotIn('Create Enrollment Report', response.content)
 
     def test_user_has_finance_admin_rights_in_e_commerce_tab(self):
         response = self.client.get(self.url)
-        self.assertIn(self.ecommerce_link, response.content)
+        self.assertContains(response, self.ecommerce_link)
 
         # Order/Invoice sales csv button text should render in e-commerce page
-        self.assertIn('Total Credit Card Purchases', response.content)
-        self.assertIn('Download All Credit Card Purchases', response.content)
-        self.assertIn('Download All Invoices', response.content)
+        self.assertContains(response, 'Total Credit Card Purchases')
+        self.assertContains(response, 'Download All Credit Card Purchases')
+        self.assertContains(response, 'Download All Invoices')
 
         # removing the course finance_admin role of login user
         CourseFinanceAdminRole(self.course.id).remove_users(self.instructor)
@@ -98,13 +98,13 @@ class TestECommerceDashboardViews(SiteMixin, SharedModuleStoreTestCase):
         the instructor dashboard
         """
         response = self.client.get(self.url)
-        self.assertIn(self.ecommerce_link, response.content)
+        self.assertContains(response, self.ecommerce_link)
 
         # Total amount html should render in e-commerce page, total amount will be 0
         course_honor_mode = CourseMode.mode_for_course(self.course.id, 'honor')
 
         price = course_honor_mode.min_price
-        self.assertIn('Course price per seat: <span>$' + str(price) + '</span>', response.content)
+        self.assertContains(response, 'Course price per seat: <span>$' + str(price) + '</span>')
         self.assertNotIn('+ Set Price</a></span>', response.content)
 
         # removing the course finance_admin role of login user
@@ -130,13 +130,13 @@ class TestECommerceDashboardViews(SiteMixin, SharedModuleStoreTestCase):
         set_course_price_url = reverse('set_course_mode_price', kwargs={'course_id': text_type(self.course.id)})
         data = {'course_price': price, 'currency': 'usd'}
         response = self.client.post(set_course_price_url, data)
-        self.assertIn('CourseMode price updated successfully', response.content)
+        self.assertContains(response, 'CourseMode price updated successfully')
 
         # Course A updated total amount should be visible in e-commerce page if the user is finance admin
         url = reverse('instructor_dashboard', kwargs={'course_id': text_type(self.course.id)})
         response = self.client.get(url)
 
-        self.assertIn('Course price per seat: <span>$' + str(price) + '</span>', response.content)
+        self.assertContains(response, 'Course price per seat: <span>$' + str(price) + '</span>')
 
     def test_user_admin_set_course_price(self):
         """
@@ -148,20 +148,21 @@ class TestECommerceDashboardViews(SiteMixin, SharedModuleStoreTestCase):
 
         # Value Error course price should be a numeric value
         response = self.client.post(set_course_price_url, data)
-        self.assertIn("Please Enter the numeric value for the course price", response.content)
+        self.assertContains(response, "Please Enter the numeric value for the course price", status_code=400)
 
         # validation check passes and course price is successfully added
         data['course_price'] = 100
         response = self.client.post(set_course_price_url, data)
-        self.assertIn("CourseMode price updated successfully", response.content)
+        self.assertContains(response, "CourseMode price updated successfully")
 
         course_honor_mode = CourseMode.objects.get(mode_slug='honor')
         course_honor_mode.delete()
         # Course Mode not exist with mode slug honor
         response = self.client.post(set_course_price_url, data)
-        self.assertIn(
+        self.assertContains(
+            response,
             u"CourseMode with the mode slug({mode_slug}) DoesNotExist".format(mode_slug='honor'),
-            response.content
+            status_code=400,
         )
 
     def test_add_coupon(self):
@@ -180,9 +181,9 @@ class TestECommerceDashboardViews(SiteMixin, SharedModuleStoreTestCase):
             )
         }
         response = self.client.post(add_coupon_url, data)
-        self.assertIn(
+        self.assertContains(
+            response,
             u"coupon with the coupon code ({code}) added successfully".format(code=data['code']),
-            response.content
         )
 
         #now add the coupon with the wrong value in the expiration_date
@@ -193,18 +194,26 @@ class TestECommerceDashboardViews(SiteMixin, SharedModuleStoreTestCase):
             'expiration_date': expiration_date.strftime('"%d/%m/%Y')
         }
         response = self.client.post(add_coupon_url, data)
-        self.assertIn("Please enter the date in this format i-e month/day/year", response.content)
+        self.assertContains(
+            response,
+            "Please enter the date in this format i-e month/day/year",
+            status_code=400,
+        )
 
         data = {
             'code': 'A2314', 'course_id': text_type(self.course.id),
             'description': 'asdsasda', 'created_by': self.instructor, 'discount': 99
         }
         response = self.client.post(add_coupon_url, data)
-        self.assertIn(u"coupon with the coupon code ({code}) already exist".format(code='A2314'), response.content)
+        self.assertContains(
+            response,
+            u"coupon with the coupon code ({code}) already exist".format(code='A2314'),
+            status_code=400,
+        )
 
         response = self.client.post(self.url)
-        self.assertIn('<td>ADSADASDSAD</td>', response.content)
-        self.assertIn('<td>A2314</td>', response.content)
+        self.assertContains(response, '<td>ADSADASDSAD</td>')
+        self.assertContains(response, '<td>A2314</td>')
         self.assertNotIn('<td>111</td>', response.content)
 
         data = {
@@ -212,11 +221,15 @@ class TestECommerceDashboardViews(SiteMixin, SharedModuleStoreTestCase):
             'description': 'asdsasda', 'created_by': self.instructor, 'discount': 199
         }
         response = self.client.post(add_coupon_url, data)
-        self.assertIn("Please Enter the Coupon Discount Value Less than or Equal to 100", response.content)
+        self.assertContains(
+            response,
+            "Please Enter the Coupon Discount Value Less than or Equal to 100",
+            status_code=400,
+        )
 
         data['discount'] = '25%'
         response = self.client.post(add_coupon_url, data=data)
-        self.assertIn('Please Enter the Integer Value for Coupon Discount', response.content)
+        self.assertContains(response, 'Please Enter the Integer Value for Coupon Discount', status_code=400)
 
         course_registration = CourseRegistrationCode(
             code='Vs23Ws4j', course_id=text_type(self.course.id), created_by=self.instructor,
@@ -227,7 +240,7 @@ class TestECommerceDashboardViews(SiteMixin, SharedModuleStoreTestCase):
         data['code'] = 'Vs23Ws4j'
         response = self.client.post(add_coupon_url, data)
         msg = u"The code ({code}) that you have tried to define is already in use as a registration code"
-        self.assertIn(msg.format(code=data['code']), response.content)
+        self.assertContains(response, msg.format(code=data['code']), status_code=400)
 
     def test_delete_coupon(self):
         """
@@ -241,33 +254,35 @@ class TestECommerceDashboardViews(SiteMixin, SharedModuleStoreTestCase):
         coupon.save()
 
         response = self.client.post(self.url)
-        self.assertIn('<td>AS452</td>', response.content)
+        self.assertContains(response, '<td>AS452</td>')
 
         # URL for remove_coupon
         delete_coupon_url = reverse('remove_coupon', kwargs={'course_id': text_type(self.course.id)})
         response = self.client.post(delete_coupon_url, {'id': coupon.id})
-        self.assertIn(
+        self.assertContains(
+            response,
             u'coupon with the coupon id ({coupon_id}) updated successfully'.format(coupon_id=coupon.id),
-            response.content
         )
 
         coupon.is_active = False
         coupon.save()
 
         response = self.client.post(delete_coupon_url, {'id': coupon.id})
-        self.assertIn(
+        self.assertContains(
+            response,
             u'coupon with the coupon id ({coupon_id}) is already inactive'.format(coupon_id=coupon.id),
-            response.content
+            status_code=400,
         )
 
         response = self.client.post(delete_coupon_url, {'id': 24454})
-        self.assertIn(
+        self.assertContains(
+            response,
             u'coupon with the coupon id ({coupon_id}) DoesNotExist'.format(coupon_id=24454),
-            response.content
+            status_code=400,
         )
 
         response = self.client.post(delete_coupon_url, {'id': ''})
-        self.assertIn('coupon id is None', response.content)
+        self.assertContains(response, 'coupon id is None', status_code=400)
 
     def test_get_coupon_info(self):
         """
@@ -282,28 +297,30 @@ class TestECommerceDashboardViews(SiteMixin, SharedModuleStoreTestCase):
         # URL for edit_coupon_info
         edit_url = reverse('get_coupon_info', kwargs={'course_id': text_type(self.course.id)})
         response = self.client.post(edit_url, {'id': coupon.id})
-        self.assertIn(
+        self.assertContains(
+            response,
             u'coupon with the coupon id ({coupon_id}) updated successfully'.format(coupon_id=coupon.id),
-            response.content
         )
-        self.assertIn(coupon.display_expiry_date, response.content)
+        self.assertContains(response, coupon.display_expiry_date)
 
         response = self.client.post(edit_url, {'id': 444444})
-        self.assertIn(
+        self.assertContains(
+            response,
             u'coupon with the coupon id ({coupon_id}) DoesNotExist'.format(coupon_id=444444),
-            response.content
+            status_code=400,
         )
 
         response = self.client.post(edit_url, {'id': ''})
-        self.assertIn('coupon id not found"', response.content)
+        self.assertContains(response, 'coupon id not found"', status_code=400)
 
         coupon.is_active = False
         coupon.save()
 
         response = self.client.post(edit_url, {'id': coupon.id})
-        self.assertIn(
+        self.assertContains(
+            response,
             u"coupon with the coupon id ({coupon_id}) is already inactive".format(coupon_id=coupon.id),
-            response.content
+            status_code=400,
         )
 
     def test_update_coupon(self):
@@ -316,7 +333,7 @@ class TestECommerceDashboardViews(SiteMixin, SharedModuleStoreTestCase):
         )
         coupon.save()
         response = self.client.post(self.url)
-        self.assertIn('<td>AS452</td>', response.content)
+        self.assertContains(response, '<td>AS452</td>')
         data = {
             'coupon_id': coupon.id, 'code': 'AS452', 'discount': '10', 'description': 'updated_description',
             'course_id': text_type(coupon.course_id)
@@ -330,15 +347,19 @@ class TestECommerceDashboardViews(SiteMixin, SharedModuleStoreTestCase):
         )
 
         response = self.client.post(self.url)
-        self.assertIn('<td>updated_description</td>', response.content)
+        self.assertContains(response, '<td>updated_description</td>')
 
         data['coupon_id'] = 1000  # Coupon Not Exist with this ID
         response = self.client.post(update_coupon_url, data=data)
-        self.assertIn(u'coupon with the coupon id ({coupon_id}) DoesNotExist'.format(coupon_id=1000), response.content)
+        self.assertContains(
+            response,
+            u'coupon with the coupon id ({coupon_id}) DoesNotExist'.format(coupon_id=1000),
+            status_code=400,
+        )
 
         data['coupon_id'] = ''  # Coupon id is not provided
         response = self.client.post(update_coupon_url, data=data)
-        self.assertIn('coupon id not found', response.content)
+        self.assertContains(response, 'coupon id not found', status_code=400)
 
     def test_verified_course(self):
         """Verify the e-commerce panel shows up for verified courses as well, without Coupons """
@@ -353,7 +374,7 @@ class TestECommerceDashboardViews(SiteMixin, SharedModuleStoreTestCase):
 
         # Get the response value, ensure the Coupon section is not included.
         response = self.client.get(self.url)
-        self.assertIn(self.ecommerce_link, response.content)
+        self.assertContains(response, self.ecommerce_link)
         # Coupons should show up for White Label sites with priced honor modes.
         self.assertNotIn('Coupons List', response.content)
 
@@ -366,7 +387,7 @@ class TestECommerceDashboardViews(SiteMixin, SharedModuleStoreTestCase):
         CourseMode.objects.filter(course_id=self.course.id).update(sku='test_sku')
 
         response = self.client.get(self.url)
-        self.assertIn(self.ecommerce_link, response.content)
+        self.assertContains(response, self.ecommerce_link)
         self.assertNotIn('Coupon Code List', response.content)
 
     def test_enrollment_codes_section_not_under_e_commerce_tab(self):
@@ -378,7 +399,7 @@ class TestECommerceDashboardViews(SiteMixin, SharedModuleStoreTestCase):
         CourseMode.objects.filter(course_id=self.course.id).update(sku='test_sku')
 
         response = self.client.get(self.url)
-        self.assertIn(self.ecommerce_link, response.content)
+        self.assertContains(response, self.ecommerce_link)
         self.assertNotIn('<h3 class="hd hd-3">Enrollment Codes</h3>', response.content)
 
     def test_enrollment_codes_section_visible_for_non_ecommerce_course(self):
@@ -387,5 +408,5 @@ class TestECommerceDashboardViews(SiteMixin, SharedModuleStoreTestCase):
         e-commerce course
         """
         response = self.client.get(self.url)
-        self.assertIn(self.ecommerce_link, response.content)
-        self.assertIn('<h3 class="hd hd-3">Enrollment Codes</h3>', response.content)
+        self.assertContains(response, self.ecommerce_link)
+        self.assertContains(response, '<h3 class="hd hd-3">Enrollment Codes</h3>')
diff --git a/lms/djangoapps/instructor/tests/test_email.py b/lms/djangoapps/instructor/tests/test_email.py
index 7835b5b9635..66553c516dc 100644
--- a/lms/djangoapps/instructor/tests/test_email.py
+++ b/lms/djangoapps/instructor/tests/test_email.py
@@ -55,10 +55,10 @@ class TestNewInstructorDashboardEmailViewMongoBacked(SharedModuleStoreTestCase):
         self.assertTrue(is_bulk_email_feature_enabled(self.course.id))
         # Assert that the URL for the email view is in the response
         response = self.client.get(self.url)
-        self.assertIn(self.email_link, response.content)
+        self.assertContains(response, self.email_link)
 
         send_to_label = '<div class="send_to_list">Send to:</div>'
-        self.assertIn(send_to_label, response.content)
+        self.assertContains(response, send_to_label)
         self.assertEqual(response.status_code, 200)
 
     # The course is Mongo-backed but the flag is disabled (should not work)
@@ -94,7 +94,7 @@ class TestNewInstructorDashboardEmailViewMongoBacked(SharedModuleStoreTestCase):
         self.assertTrue(is_bulk_email_feature_enabled(self.course.id))
         # Assert that the URL for the email view is in the response
         response = self.client.get(self.url)
-        self.assertIn(self.email_link, response.content)
+        self.assertContains(response, self.email_link)
 
     # Flag is disabled, but course is authorized
     def test_course_authorized_feature_off(self):
diff --git a/lms/djangoapps/instructor/tests/test_proctoring.py b/lms/djangoapps/instructor/tests/test_proctoring.py
index aa6fa9cfcfa..a4fcc4811b7 100644
--- a/lms/djangoapps/instructor/tests/test_proctoring.py
+++ b/lms/djangoapps/instructor/tests/test_proctoring.py
@@ -148,7 +148,7 @@ class TestProctoringDashboardViews(SharedModuleStoreTestCase):
                 backend='test',
             )
             response = self.client.get(self.url)
-            self.assertIn('Review Dashboard', response.content)
+            self.assertContains(response, 'Review Dashboard')
 
     def _assert_proctoring_tab_available(self, available):
         """
diff --git a/lms/djangoapps/instructor/tests/views/test_instructor_dashboard.py b/lms/djangoapps/instructor/tests/views/test_instructor_dashboard.py
index 229bf43300f..f4980f7e075 100644
--- a/lms/djangoapps/instructor/tests/views/test_instructor_dashboard.py
+++ b/lms/djangoapps/instructor/tests/views/test_instructor_dashboard.py
@@ -180,8 +180,8 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase, XssT
         )
 
         response = self.client.get(url)
-        self.assertIn('<option value="role1">role1</option>', response.content)
-        self.assertIn('<option value="role2">role2</option>', response.content)
+        self.assertContains(response, '<option value="role1">role1</option>')
+        self.assertContains(response, '<option value="role2">role2</option>')
 
     def test_membership_default_role(self):
         """
@@ -197,9 +197,9 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase, XssT
         )
 
         response = self.client.get(url)
-        self.assertIn('<option value="Learner">Learner</option>', response.content)
-        self.assertIn('<option value="Support">Support</option>', response.content)
-        self.assertIn('<option value="Partner">Partner</option>', response.content)
+        self.assertContains(response, '<option value="Learner">Learner</option>')
+        self.assertContains(response, '<option value="Support">Support</option>')
+        self.assertContains(response, '<option value="Partner">Partner</option>')
 
     def test_student_admin_staff_instructor(self):
         """
@@ -208,15 +208,15 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase, XssT
         """
         # Original (instructor) user can see both specific grades, and course-wide grade adjustment tools
         response = self.client.get(self.url)
-        self.assertIn('<h4 class="hd hd-4">Adjust all enrolled learners', response.content)
-        self.assertIn('<h4 class="hd hd-4">View a specific learner&#39;s grades and progress', response.content)
+        self.assertContains(response, '<h4 class="hd hd-4">Adjust all enrolled learners')
+        self.assertContains(response, '<h4 class="hd hd-4">View a specific learner&#39;s grades and progress')
 
         # But staff user can only see specific grades
         staff = StaffFactory(course_key=self.course.id)
         self.client.login(username=staff.username, password="test")
         response = self.client.get(self.url)
         self.assertNotIn('<h4 class="hd hd-4">Adjust all enrolled learners', response.content)
-        self.assertIn('<h4 class="hd hd-4">View a specific learner&#39;s grades and progress', response.content)
+        self.assertContains(response, '<h4 class="hd hd-4">View a specific learner&#39;s grades and progress')
 
     @patch(
         'lms.djangoapps.instructor.views.instructor_dashboard.settings.WRITABLE_GRADEBOOK_URL',
@@ -231,8 +231,8 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase, XssT
             response = self.client.get(self.url)
 
         expected_gradebook_url = 'http://gradebook.local.edx.org/{}'.format(self.course.id)
-        self.assertIn(expected_gradebook_url, response.content)
-        self.assertIn('View Gradebook', response.content)
+        self.assertContains(response, expected_gradebook_url)
+        self.assertContains(response, 'View Gradebook')
 
     GRADEBOOK_LEARNER_COUNT_MESSAGE = (
         'Note: This feature is available only to courses with a small number ' +
@@ -250,7 +250,7 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase, XssT
             self.GRADEBOOK_LEARNER_COUNT_MESSAGE,
             response.content
         )
-        self.assertIn('View Gradebook', response.content)
+        self.assertContains(response, 'View Gradebook')
 
     @patch(
         'lms.djangoapps.instructor.views.instructor_dashboard.settings.WRITABLE_GRADEBOOK_URL',
@@ -269,7 +269,7 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase, XssT
             TestInstructorDashboard.GRADEBOOK_LEARNER_COUNT_MESSAGE,
             response.content
         )
-        self.assertIn('View Gradebook', response.content)
+        self.assertContains(response, 'View Gradebook')
 
     def test_default_currency_in_the_html_response(self):
         """
@@ -278,7 +278,7 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase, XssT
         CourseFinanceAdminRole(self.course.id).add_users(self.instructor)
         total_amount = PaidCourseRegistration.get_total_amount_of_purchased_item(self.course.id)
         response = self.client.get(self.url)
-        self.assertIn('${amount}'.format(amount=total_amount), response.content)
+        self.assertContains(response, '${amount}'.format(amount=total_amount))
 
     def test_course_name_xss(self):
         """Test that the instructor dashboard correctly escapes course names
@@ -295,7 +295,7 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase, XssT
         CourseFinanceAdminRole(self.course.id).add_users(self.instructor)
         total_amount = PaidCourseRegistration.get_total_amount_of_purchased_item(self.course.id)
         response = self.client.get(self.url)
-        self.assertIn('{currency}{amount}'.format(currency='Rs', amount=total_amount), response.content)
+        self.assertContains(response, '{currency}{amount}'.format(currency='Rs', amount=total_amount))
 
     @patch.dict(settings.FEATURES, {'DISPLAY_ANALYTICS_ENROLLMENTS': False})
     @override_settings(ANALYTICS_DASHBOARD_URL='')
@@ -316,11 +316,11 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase, XssT
         response = self.client.get(self.url)
 
         # enrollment information visible
-        self.assertIn('<h4 class="hd hd-4">Enrollment Information</h4>', response.content)
-        self.assertIn('<th scope="row">Verified</th>', response.content)
-        self.assertIn('<th scope="row">Audit</th>', response.content)
-        self.assertIn('<th scope="row">Honor</th>', response.content)
-        self.assertIn('<th scope="row">Professional</th>', response.content)
+        self.assertContains(response, '<h4 class="hd hd-4">Enrollment Information</h4>')
+        self.assertContains(response, '<th scope="row">Verified</th>')
+        self.assertContains(response, '<th scope="row">Audit</th>')
+        self.assertContains(response, '<th scope="row">Honor</th>')
+        self.assertContains(response, '<th scope="row">Professional</th>')
 
         # dashboard link hidden
         self.assertNotIn(self.get_dashboard_enrollment_message(), response.content.decode(response.charset))
@@ -376,7 +376,7 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase, XssT
         """
         response = self.client.get(self.url)
         analytics_section = '<li class="nav-item"><button type="button" class="btn-link instructor_analytics" data-section="instructor_analytics">Analytics</button></li>'  # pylint: disable=line-too-long
-        self.assertIn(analytics_section, response.content)
+        self.assertContains(response, analytics_section)
 
         # link to dashboard shown
         expected_message = self.get_dashboard_analytics_message()
@@ -408,7 +408,7 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase, XssT
         bulk_purchase_total = CourseRegCodeItem.get_total_amount_of_purchased_item(self.course.id)
         total_amount = single_purchase_total + bulk_purchase_total
         response = self.client.get(self.url)
-        self.assertIn('{currency}{amount}'.format(currency='$', amount=total_amount), response.content)
+        self.assertContains(response, '{currency}{amount}'.format(currency='$', amount=total_amount))
 
     @ddt.data(
         (True, True, True),
@@ -439,7 +439,7 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase, XssT
         Verify that grade cutoffs are displayed in the correct order.
         """
         response = self.client.get(self.url)
-        self.assertIn('D: 0.5, C: 0.57, B: 0.63, A: 0.75', response.content)
+        self.assertContains(response, 'D: 0.5, C: 0.57, B: 0.63, A: 0.75')
 
     @patch('lms.djangoapps.instructor.views.gradebook_api.MAX_STUDENTS_PER_PAGE_GRADE_BOOK', 2)
     def test_calculate_page_info(self):
@@ -483,7 +483,7 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase, XssT
 
         ItemFactory.create(parent_location=self.course.location, category="openassessment")
         response = self.client.get(self.url)
-        self.assertIn(ora_section, response.content)
+        self.assertContains(response, ora_section)
 
     def test_open_response_assessment_page_orphan(self):
         """
diff --git a/lms/djangoapps/shoppingcart/tests/test_views.py b/lms/djangoapps/shoppingcart/tests/test_views.py
index db448838ce5..7d8e246a7c0 100644
--- a/lms/djangoapps/shoppingcart/tests/test_views.py
+++ b/lms/djangoapps/shoppingcart/tests/test_views.py
@@ -1847,28 +1847,28 @@ class RegistrationCodeRedemptionCourseEnrollment(SharedModuleStoreTestCase):
         response = self.client.get(redeem_url)
         self.assertEquals(response.status_code, 200)
         # check button text
-        self.assertIn('Activate Course Enrollment', response.content)
+        self.assertContains(response, 'Activate Course Enrollment')
 
         #now activate the user by enrolling him/her to the course
         response = self.client.post(redeem_url)
         self.assertEquals(response.status_code, 200)
-        self.assertIn('View Dashboard', response.content)
+        self.assertContains(response, 'View Dashboard')
 
         #now check that the registration code has already been redeemed and user is already registered in the course
         RegistrationCodeRedemption.objects.filter(registration_code__code=registration_code)
         response = self.client.get(redeem_url)
         self.assertEquals(len(RegistrationCodeRedemption.objects.filter(registration_code__code=registration_code)), 1)
-        self.assertIn("You&#39;ve clicked a link for an enrollment code that has already been used.", response.content)
+        self.assertContains(response, "You&#39;ve clicked a link for an enrollment code that has already been used.")
 
         #now check that the registration code has already been redeemed
         response = self.client.post(redeem_url)
-        self.assertIn("You&#39;ve clicked a link for an enrollment code that has already been used.", response.content)
+        self.assertContains(response, "You&#39;ve clicked a link for an enrollment code that has already been used.")
 
         #now check the response of the dashboard page
         dashboard_url = reverse('dashboard')
         response = self.client.get(dashboard_url)
         self.assertEquals(response.status_code, 200)
-        self.assertIn(self.course.display_name.encode('utf-8'), response.content)
+        self.assertContains(response, self.course.display_name.encode('utf-8'))
 
 
 @ddt.ddt
@@ -2176,7 +2176,7 @@ class CSVReportViewsTest(SharedModuleStoreTestCase):
                                                                     'requested_report': report_type})
         self.assertEqual(response['Content-Type'], 'text/csv')
         report = initialize_report(report_type, start_date, end_date)
-        self.assertIn(",".join(report.header()), response.content)
+        self.assertContains(response, ",".join(report.header()))
         self.assertIn(
             ",1,purchased,1,40.00,40.00,usd,Registration for Course: Robot Super Course,",
             response.content
@@ -2197,7 +2197,7 @@ class CSVReportViewsTest(SharedModuleStoreTestCase):
                                                                     'requested_report': report_type})
         self.assertEqual(response['Content-Type'], 'text/csv')
         report = initialize_report(report_type, start_date, end_date, start_letter, end_letter)
-        self.assertIn(",".join(report.header()), response.content)
+        self.assertContains(response, ",".join(report.header()))
 
 
 class UtilFnsTest(TestCase):
diff --git a/lms/djangoapps/static_template_view/tests/test_views.py b/lms/djangoapps/static_template_view/tests/test_views.py
index 33a0a81c120..4bfb85d443d 100644
--- a/lms/djangoapps/static_template_view/tests/test_views.py
+++ b/lms/djangoapps/static_template_view/tests/test_views.py
@@ -45,8 +45,8 @@ class MarketingSiteViewTests(TestCase):
         configuration = {test_header_key: test_header, test_content_key: test_content}
         with with_site_configuration_context(configuration=configuration):
             response = self.client.get(reverse("about"))
-        self.assertIn(test_header.encode('utf-8'), response.content)
-        self.assertIn(test_content.encode('utf-8'), response.content)
+        self.assertContains(response, test_header)
+        self.assertContains(response, test_content)
 
     def test_about_with_site_configuration_and_html(self):
         """
@@ -60,8 +60,8 @@ class MarketingSiteViewTests(TestCase):
         configuration = {test_header_key: test_header, test_content_key: test_content}
         with with_site_configuration_context(configuration=configuration):
             response = self.client.get(reverse("about"))
-        self.assertIn(test_header.encode('utf-8'), response.content)
-        self.assertIn(test_content.encode('utf-8'), response.content)
+        self.assertContains(response, test_header)
+        self.assertContains(response, test_content)
 
     def test_404(self):
         """
diff --git a/lms/djangoapps/teams/tests/test_views.py b/lms/djangoapps/teams/tests/test_views.py
index 0e65314ba5c..eb5ddb4a221 100644
--- a/lms/djangoapps/teams/tests/test_views.py
+++ b/lms/djangoapps/teams/tests/test_views.py
@@ -180,17 +180,17 @@ class TestDashboard(SharedModuleStoreTestCase):
         # Check that initially list of user teams in course one is empty
         course_one_teams_url = reverse('teams_dashboard', args=[self.course.id])
         response = self.client.get(course_one_teams_url)
-        self.assertIn('"teams": {"count": 0', response.content)  # pylint: disable=unicode-format-string
+        self.assertContains(response, '"teams": {"count": 0')  # pylint: disable=unicode-format-string
         # Add user to a course one team
         course_one_team.add_user(self.user)
 
         # Check that list of user teams in course one is not empty, it is one now
         response = self.client.get(course_one_teams_url)
-        self.assertIn('"teams": {"count": 1', response.content)  # pylint: disable=unicode-format-string
+        self.assertContains(response, '"teams": {"count": 1')  # pylint: disable=unicode-format-string
         # Check that list of user teams in course two is still empty
         course_two_teams_url = reverse('teams_dashboard', args=[course_two.id])
         response = self.client.get(course_two_teams_url)
-        self.assertIn('"teams": {"count": 0', response.content)  # pylint: disable=unicode-format-string
+        self.assertContains(response, '"teams": {"count": 0')  # pylint: disable=unicode-format-string
 
 
 class TeamAPITestCase(APITestCase, SharedModuleStoreTestCase):
diff --git a/lms/djangoapps/verify_student/tests/test_views.py b/lms/djangoapps/verify_student/tests/test_views.py
index 98b4b1f4dda..4c2d5818bcf 100644
--- a/lms/djangoapps/verify_student/tests/test_views.py
+++ b/lms/djangoapps/verify_student/tests/test_views.py
@@ -1340,7 +1340,7 @@ class TestCreateOrderView(ModuleStoreTestCase):
     @patch.dict(settings.FEATURES, {'AUTOMATIC_VERIFY_STUDENT_IDENTITY_FOR_TESTING': True})
     def test_invalid_amount(self):
         response = self._create_order('1.a', self.course_id, expect_status_code=400)
-        self.assertIn('Selected price is not valid number.', response.content.decode('utf-8'))
+        self.assertContains(response, 'Selected price is not valid number.', status_code=400)
 
     @patch.dict(settings.FEATURES, {'AUTOMATIC_VERIFY_STUDENT_IDENTITY_FOR_TESTING': True})
     def test_invalid_mode(self):
@@ -1348,7 +1348,11 @@ class TestCreateOrderView(ModuleStoreTestCase):
         course_id = 'Fake/999/Test_Course'
         CourseFactory.create(org='Fake', number='999', display_name='Test Course')
         response = self._create_order('50', course_id, expect_status_code=400)
-        self.assertIn('This course doesn\'t support paid certificates', response.content.decode('utf-8'))
+        self.assertContains(
+            response,
+            'This course doesn\'t support paid certificates',
+            status_code=400,
+        )
 
     @patch.dict(settings.FEATURES, {'AUTOMATIC_VERIFY_STUDENT_IDENTITY_FOR_TESTING': True})
     def test_create_order_fail_with_get(self):
@@ -1672,8 +1676,7 @@ class TestPhotoVerificationResultsCallback(ModuleStoreTestCase):
             HTTP_AUTHORIZATION='test BBBBBBBBBBBBBBBBBBBB: testing',
             HTTP_DATE='testdate'
         )
-        self.assertIn('Invalid JSON', response.content.decode('utf-8'))
-        self.assertEqual(response.status_code, 400)
+        self.assertContains(response, 'Invalid JSON', status_code=400)
 
     def test_invalid_dict(self):
         """
@@ -1687,8 +1690,7 @@ class TestPhotoVerificationResultsCallback(ModuleStoreTestCase):
             HTTP_AUTHORIZATION='test BBBBBBBBBBBBBBBBBBBB:testing',
             HTTP_DATE='testdate'
         )
-        self.assertIn('JSON should be dict', response.content.decode('utf-8'))
-        self.assertEqual(response.status_code, 400)
+        self.assertContains(response, 'JSON should be dict', status_code=400)
 
     @patch(
         'lms.djangoapps.verify_student.ssencrypt.has_valid_signature',
@@ -1712,8 +1714,7 @@ class TestPhotoVerificationResultsCallback(ModuleStoreTestCase):
             HTTP_AUTHORIZATION='test testing:testing',
             HTTP_DATE='testdate'
         )
-        self.assertIn('Access key invalid', response.content.decode('utf-8'))
-        self.assertEqual(response.status_code, 400)
+        self.assertContains(response, 'Access key invalid', status_code=400)
 
     @patch(
         'lms.djangoapps.verify_student.ssencrypt.has_valid_signature',
@@ -1737,8 +1738,7 @@ class TestPhotoVerificationResultsCallback(ModuleStoreTestCase):
             HTTP_AUTHORIZATION='test BBBBBBBBBBBBBBBBBBBB:testing',
             HTTP_DATE='testdate'
         )
-        self.assertIn('edX ID Invalid-Id not found', response.content.decode('utf-8'))
-        self.assertEqual(response.status_code, 400)
+        self.assertContains(response, 'edX ID Invalid-Id not found', status_code=400)
 
     @patch(
         'lms.djangoapps.verify_student.ssencrypt.has_valid_signature',
@@ -1896,7 +1896,7 @@ class TestPhotoVerificationResultsCallback(ModuleStoreTestCase):
             HTTP_AUTHORIZATION='test BBBBBBBBBBBBBBBBBBBB:testing',
             HTTP_DATE='testdate'
         )
-        self.assertIn('Result Unknown not understood', response.content.decode('utf-8'))
+        self.assertContains(response, 'Result Unknown not understood', status_code=400)
 
 
 class TestReverifyView(TestCase):
diff --git a/openedx/core/djangoapps/credit/tests/test_views.py b/openedx/core/djangoapps/credit/tests/test_views.py
index b226918e169..1b3c928f6c3 100644
--- a/openedx/core/djangoapps/credit/tests/test_views.py
+++ b/openedx/core/djangoapps/credit/tests/test_views.py
@@ -160,8 +160,7 @@ class CreditCourseViewSetTests(AuthMixin, UserMixin, TestCase):
 
         # POSTs without a CSRF token should fail.
         response = client.post(self.path, data=json.dumps(data), content_type=JSON)
-        self.assertEqual(response.status_code, 403)
-        self.assertIn('CSRF', response.content)
+        self.assertContains(response, 'CSRF', status_code=403)
 
         # Retrieve a CSRF token
         response = client.get('/')
diff --git a/openedx/core/djangoapps/user_api/accounts/tests/test_settings_views.py b/openedx/core/djangoapps/user_api/accounts/tests/test_settings_views.py
index 6ff1edf5a80..7923fd5118e 100644
--- a/openedx/core/djangoapps/user_api/accounts/tests/test_settings_views.py
+++ b/openedx/core/djangoapps/user_api/accounts/tests/test_settings_views.py
@@ -163,7 +163,7 @@ class AccountSettingsViewTest(ThirdPartyAuthTestMixin, SiteMixin, ProgramsApiCon
         response = self.client.get(path=view_path)
 
         for attribute in self.FIELDS:
-            self.assertIn(attribute, response.content)
+            self.assertContains(response, attribute)
 
     def test_header_with_programs_listing_enabled(self):
         """
@@ -256,7 +256,7 @@ class AccountSettingsViewTest(ThirdPartyAuthTestMixin, SiteMixin, ProgramsApiCon
             # Test with waffle flag active and site setting disabled, does not redirect
             response = self.client.get(path=old_url_path)
             for attribute in self.FIELDS:
-                self.assertIn(attribute, response.content)
+                self.assertContains(response, attribute)
 
             # Test with waffle flag active and site setting enabled, redirects to microfrontend
             site_domain = 'othersite.example.com'
diff --git a/openedx/features/announcements/tests/test_announcements.py b/openedx/features/announcements/tests/test_announcements.py
index 686485993f3..99cf50f0ae1 100644
--- a/openedx/features/announcements/tests/test_announcements.py
+++ b/openedx/features/announcements/tests/test_announcements.py
@@ -60,7 +60,7 @@ class TestGlobalAnnouncements(TestCase):
     def test_feature_flag_enabled(self):
         """Ensures that enabling the flag, enables the feature"""
         response = self.client.get('/dashboard')
-        self.assertIn('AnnouncementsView', response.content)
+        self.assertContains(response, 'AnnouncementsView')
 
     def test_pagination(self):
         url = reverse("announcements:page", kwargs={"page": 1})
@@ -79,7 +79,7 @@ class TestGlobalAnnouncements(TestCase):
         """
         url = reverse("announcements:page", kwargs={"page": 1})
         response = self.client.get(url)
-        self.assertIn("Active Announcement", response.content)
+        self.assertContains(response, "Active Announcement")
 
     def test_inactive(self):
         """
@@ -95,4 +95,4 @@ class TestGlobalAnnouncements(TestCase):
         """
         url = reverse("announcements:page", kwargs={"page": 1})
         response = self.client.get(url)
-        self.assertIn("<strong>Formatted Announcement</strong>", response.content)
+        self.assertContains(response, "<strong>Formatted Announcement</strong>")
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 153e98e3898..82d996ceced 100644
--- a/openedx/features/course_duration_limits/tests/test_course_expiration.py
+++ b/openedx/features/course_duration_limits/tests/test_course_expiration.py
@@ -219,7 +219,7 @@ class CourseExpirationTestCase(ModuleStoreTestCase):
         six.assertCountEqual(self, 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)
+            self.assertContains(response, banner_text)
         else:
             self.assertNotIn(banner_text, response.content)
 
@@ -319,7 +319,7 @@ class CourseExpirationTestCase(ModuleStoreTestCase):
         self.assertEqual(response.status_code, 200)
         six.assertCountEqual(self, response.redirect_chain, [])
         banner_text = 'This learner does not have access to this course. Their access expired on'
-        self.assertIn(banner_text, response.content)
+        self.assertContains(response, banner_text)
 
     @mock.patch("openedx.features.course_duration_limits.access.get_course_run_details")
     @ddt.data(
diff --git a/openedx/features/course_experience/tests/views/test_course_home.py b/openedx/features/course_experience/tests/views/test_course_home.py
index 95a6aaeb970..a14f4d0a909 100644
--- a/openedx/features/course_experience/tests/views/test_course_home.py
+++ b/openedx/features/course_experience/tests/views/test_course_home.py
@@ -966,10 +966,10 @@ class CourseHomeFragmentViewTests(ModuleStoreTestCase):
 
     def assert_upgrade_message_displayed(self):
         response = self.client.get(self.url)
-        self.assertIn('section-upgrade', response.content)
+        self.assertContains(response, 'section-upgrade')
         url = EcommerceService().get_checkout_page_url(self.verified_mode.sku)
-        self.assertIn('<a class="btn-brand btn-upgrade"', response.content)
-        self.assertIn(url, response.content)
+        self.assertContains(response, '<a class="btn-brand btn-upgrade"')
+        self.assertContains(response, url)
         self.assertIn(
             u"Upgrade (<span class='price'>${price}</span>)".format(price=self.verified_mode.min_price),
             response.content.decode(response.charset)
diff --git a/openedx/features/course_experience/tests/views/test_course_outline.py b/openedx/features/course_experience/tests/views/test_course_outline.py
index bcc2030fc9d..92054bb50eb 100644
--- a/openedx/features/course_experience/tests/views/test_course_outline.py
+++ b/openedx/features/course_experience/tests/views/test_course_outline.py
@@ -126,16 +126,16 @@ class TestCourseOutlinePage(SharedModuleStoreTestCase):
 
             self.assertTrue(course.children)
             for chapter in course.children:
-                self.assertIn(chapter.display_name, response_content)
+                self.assertContains(response, chapter.display_name)
                 self.assertTrue(chapter.children)
                 for sequential in chapter.children:
-                    self.assertIn(sequential.display_name, response_content)
+                    self.assertContains(response, sequential.display_name)
                     if sequential.graded:
-                        self.assertIn(sequential.due.strftime(u'%Y-%m-%d %H:%M:%S'), response_content)
-                        self.assertIn(sequential.format, response_content)
+                        self.assertContains(response, sequential.due.strftime(u'%Y-%m-%d %H:%M:%S'))
+                        self.assertContains(response, sequential.format)
                     self.assertTrue(sequential.children)
                     for vertical in sequential.children:
-                        self.assertIn(vertical.display_name, response_content)
+                        self.assertContains(response, vertical.display_name)
 
 
 class TestCourseOutlinePageWithPrerequisites(SharedModuleStoreTestCase, MilestonesTestCaseMixin):
diff --git a/openedx/features/learner_profile/tests/views/test_learner_profile.py b/openedx/features/learner_profile/tests/views/test_learner_profile.py
index 919f8d99aef..f1a8ce37fb2 100644
--- a/openedx/features/learner_profile/tests/views/test_learner_profile.py
+++ b/openedx/features/learner_profile/tests/views/test_learner_profile.py
@@ -115,7 +115,7 @@ class LearnerProfileViewTest(SiteMixin, UrlResetMixin, ModuleStoreTestCase):
         response = self.client.get(path=profile_path)
 
         for attribute in self.CONTEXT_DATA:
-            self.assertIn(attribute, response.content)
+            self.assertContains(response, attribute)
 
     def test_redirect_view(self):
         with override_waffle_flag(REDIRECT_TO_PROFILE_MICROFRONTEND, active=True):
@@ -124,7 +124,7 @@ class LearnerProfileViewTest(SiteMixin, UrlResetMixin, ModuleStoreTestCase):
             # Test with waffle flag active and site setting disabled, does not redirect
             response = self.client.get(path=profile_path)
             for attribute in self.CONTEXT_DATA:
-                self.assertIn(attribute, response.content)
+                self.assertContains(response, attribute)
 
             # Test with waffle flag active and site setting enabled, redirects to microfrontend
             site_domain = 'othersite.example.com'
-- 
GitLab