def test_get_value_for_org_2(self): """ Test that get_value_for_org returns correct value for any given key. """ test_org = test_config['course_org_filter'] with with_site_configuration_context(configuration=test_config): # Make sure if ORG is not present in site configuration then microsite configuration is used instead self.assertEqual( configuration_helpers.get_value_for_org( "TestSiteX", "email_from_address"), "*****@*****.**") # Make sure 'default' is returned if org is present but key is not self.assertEqual( configuration_helpers.get_value_for_org( test_org, "email_from_address"), None) # Make sure if ORG is not present in site configuration then microsite configuration is used instead self.assertEqual( configuration_helpers.get_value_for_org( "LogistrationX", "email_from_address"), "*****@*****.**") # This test must come after the above test with with_site_configuration_context(configuration={ "course_org_filter": "TestSiteX", "university": "Test" }): # Make sure site configuration gets preference over microsite configuration self.assertEqual( configuration_helpers.get_value_for_org( "TestSiteX", "university"), "Test")
def test_get_value_for_org_2(self): """ Test that get_value_for_org returns correct value for any given key. """ test_org = test_config['course_org_filter'] with with_site_configuration_context(configuration=test_config): # Make sure if ORG is not present in site configuration then microsite configuration is used instead self.assertEqual( configuration_helpers.get_value_for_org("TestSiteX", "email_from_address"), "*****@*****.**" ) # Make sure 'default' is returned if org is present but key is not self.assertEqual( configuration_helpers.get_value_for_org(test_org, "email_from_address"), None ) # Make sure if ORG is not present in site configuration then microsite configuration is used instead self.assertEqual( configuration_helpers.get_value_for_org("LogistrationX", "email_from_address"), "*****@*****.**" ) # This test must come after the above test with with_site_configuration_context(configuration={"course_org_filter": "TestSiteX", "university": "Test"}): # Make sure site configuration gets preference over microsite configuration self.assertEqual( configuration_helpers.get_value_for_org("TestSiteX", "university"), "Test" )
def test_render_page(self): """ Test render page with three cases: 1. User not logged 2. User logged but not enrolled 3. User logged and enrolled 4. Test only staff filter """ uname = 'test_student' email = '*****@*****.**' password = '******' url = reverse('directmessage_view', kwargs={'course_id': self.course.id}) test_student = UserFactory(username=uname, password=password, email=email) # Create the student # Student without login client = Client() response = client.get(url) self.assertEqual(response.status_code, 302) # Redirect to login # Student logged but not enrolled client.login(username=uname, password=password) response = client.get(url) self.assertEqual(response.status_code, 404) # Show error 404 # Student logged and enrolled CourseEnrollmentFactory(user=test_student, course_id=self.course.id) response = client.get(url) self.assertEqual(response.status_code, 200) # Correct render page # Test only staff filter with with_site_configuration_context( configuration={'EOL_DIRECTMESSAGE_ONLY_STAFF': False}): response = client.get(url) content = response.content # Show no-staff users self.assertIn('new-chat-filter filter-no-staff', content.decode('utf-8')) with with_site_configuration_context( configuration={'EOL_DIRECTMESSAGE_ONLY_STAFF': True}): response = client.get(url) content = response.content # Don't show no-staff users self.assertNotIn('new-chat-filter filter-no-staff', content.decode('utf-8'))
def test_get_value_for_org(self): """ Test that get_value_for_org returns correct value for any given key. """ test_org = test_config['course_org_filter'] with with_site_configuration_context(configuration=test_config): self.assertEqual( configuration_helpers.get_value_for_org(test_org, "university"), test_config['university'] ) self.assertEqual( configuration_helpers.get_value_for_org(test_org, "css_overrides_file"), test_config['css_overrides_file'] ) self.assertItemsEqual( configuration_helpers.get_value_for_org(test_org, "REGISTRATION_EXTRA_FIELDS"), test_config['REGISTRATION_EXTRA_FIELDS'] ) # Test default value of key is not present in configuration self.assertEqual( configuration_helpers.get_value_for_org(test_org, "non_existent_key"), None ) self.assertEqual( configuration_helpers.get_value_for_org(test_org, "non_existent_key", "default for non existent"), "default for non existent" ) self.assertEqual( configuration_helpers.get_value_for_org("missing_org", "university", "default for non existent"), "default for non existent" )
def test_third_party_auth_hint( self, method, tpa_hint, next_url, expected_url, running_pipeline, mock_running_pipeline, ): mock_running_pipeline.return_value = running_pipeline def validate_login(): """ Assert that get_next_url_for_login_page returns as expected. """ if method == 'GET': req = self.request.get(settings.LOGIN_URL + "?next={url}".format(url=next_url)) elif method == 'POST': req = self.request.post(settings.LOGIN_URL, {'next': next_url}) req.META["HTTP_ACCEPT"] = "text/html" self._add_session(req) next_page = get_next_url_for_login_page(req) self.assertEqual(next_page, expected_url) with override_settings(FEATURES=dict(settings.FEATURES, THIRD_PARTY_AUTH_HINT=tpa_hint)): validate_login() with with_site_configuration_context(configuration=dict( THIRD_PARTY_AUTH_HINT=tpa_hint)): validate_login()
def test_linked_in_url_with_cert_name_override(self, cert_mode, expected_cert_name): config = LinkedInAddToProfileConfiguration( company_identifier='0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9', enabled=True ) expected_url = ( 'http://www.linkedin.com/profile/add' '?_ed=0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9&' 'pfCertificationName={platform_name}+{expected_cert_name}&' 'pfCertificationUrl=http%3A%2F%2Fs3.edx%2Fcert&' 'source=o' ).format( expected_cert_name=expected_cert_name, platform_name=quote(settings.PLATFORM_NAME.encode('utf-8')) ) with with_site_configuration_context(configuration=self.SITE_CONFIGURATION): actual_url = config.add_to_profile_url( self.COURSE_KEY, self.COURSE_NAME, cert_mode, self.CERT_URL ) self.assertEqual(actual_url, expected_url)
def test_info_title(self, site_config, expected_title, expected_subtitle): """ Test the info page on a course with all the multiple display options depeding on the current site configuration """ url = reverse('info', args=(six.text_type(self.course.id), )) with with_site_configuration_context(configuration=site_config): response = self.client.get(url) content = pq(response.content) self.assertEqual( expected_title, content('.page-title').contents()[0].strip(), ) if expected_subtitle is None: self.assertEqual( [], content('.page-subtitle'), ) else: self.assertEqual( expected_subtitle, content('.page-subtitle').contents()[0].strip(), )
def test_get_many_with_missing(self, mock_cache, mock_warning, mock_info): programs = ProgramFactory.create_batch(3) all_programs = { PROGRAM_CACHE_KEY_TPL.format(uuid=program['uuid']): program for program in programs } partial_programs = { PROGRAM_CACHE_KEY_TPL.format(uuid=program['uuid']): program for program in programs[:2] } def fake_get_many(keys): if len(keys) == 1: return {PROGRAM_CACHE_KEY_TPL.format(uuid=programs[-1]['uuid']): programs[-1]} else: return partial_programs mock_cache.get.return_value = [program['uuid'] for program in programs] mock_cache.get_many.side_effect = fake_get_many with with_site_configuration_context(domain=self.site.name, configuration={'COURSE_CATALOG_API_URL': 'foo'}): actual_programs = get_programs(site=self.site) # All 3 cached programs should be returned. An info message should be # logged about the one that was initially missing, but the code should # be able to stitch together all the details. assert {program['uuid'] for program in actual_programs} ==\ {program['uuid'] for program in all_programs.values()} assert not mock_warning.called mock_info.assert_called_with('Failed to get details for 1 programs. Retrying.') for program in actual_programs: key = PROGRAM_CACHE_KEY_TPL.format(uuid=program['uuid']) assert program == all_programs[key]
def test_footer_language_selector_is_enabled(self, base_config, site_config, expected): """ Verify that the footer language selector config is correct. """ with patch.dict('django.conf.settings.FEATURES', base_config): with with_site_configuration_context(configuration=site_config): assert language_api.footer_language_selector_is_enabled() == expected
def test_donate_button_with_enabled_site_configuration( self, enable_donation_config, enable_donation_site_config): # Enable the enrollment success message and donations self._configure_message_timeout(10000) # DonationConfiguration has low precedence if 'ENABLE_DONATIONS' is enable in SiteConfiguration DonationConfiguration(enabled=enable_donation_config).save() CourseModeFactory.create(mode_slug="audit", course_id=self.course.id, min_price=0) self.enrollment.mode = "audit" self.enrollment.save() self.client.login(username=self.student.username, password=self.PASSWORD) with with_site_configuration_context( configuration={ 'ENABLE_DONATIONS': enable_donation_site_config }): response = self.client.get(reverse("dashboard")) if enable_donation_site_config: self.assertContains(response, "donate-container") else: self.assertNotContains(response, "donate-container")
def test_linked_in_url_with_cert_name_override(self, cert_mode, expected_cert_name): config = LinkedInAddToProfileConfigurationFactory() # We can switch to this once edx-platform reaches Python 3.8 # expected_url = ( # 'https://www.linkedin.com/profile/add?startTask=CERTIFICATION_NAME&' # 'name={platform}+{cert_name}&certUrl={cert_url}&' # 'organizationId={company_identifier}' # ).format( # platform=quote(settings.PLATFORM_NAME.encode('utf-8')), # cert_name=expected_cert_name, # cert_url=quote(self.CERT_URL, safe=''), # company_identifier=config.company_identifier, # ) with with_site_configuration_context( configuration=self.SITE_CONFIGURATION): actual_url = config.add_to_profile_url(self.COURSE_NAME, cert_mode, self.CERT_URL) # We can switch to this instead of the assertIn once edx-platform reaches Python 3.8 # There was a problem with dict ordering in the add_to_profile_url function that will go away then. # self.assertEqual(actual_url, expected_url) assert 'https://www.linkedin.com/profile/add?startTask=CERTIFICATION_NAME' in actual_url assert f'&name={quote(settings.PLATFORM_NAME.encode("utf-8"))}+{expected_cert_name}' in actual_url assert '&certUrl={cert_url}'.format( cert_url=quote(self.CERT_URL, safe='')) in actual_url assert '&organizationId={org_id}'.format( org_id=config.company_identifier) in actual_url
def test_info_title(self, site_config, expected_title, expected_subtitle): """ Test the info page on a course with all the multiple display options depeding on the current site configuration """ url = reverse('info', args=(unicode(self.course.id),)) with with_site_configuration_context(configuration=site_config): response = self.client.get(url) content = pq(response.content) self.assertEqual( expected_title, content('.page-title').contents()[0].strip(), ) if expected_subtitle is None: self.assertEqual( [], content('.page-subtitle'), ) else: self.assertEqual( expected_subtitle, content('.page-subtitle').contents()[0].strip(), )
def test_footer_language_selector_is_enabled(self, base_config, site_config, expected): """ Verify that the footer language selector config is correct. """ with patch.dict('django.conf.settings.FEATURES', base_config): with with_site_configuration_context(configuration=site_config): self.assertEqual(language_api.footer_language_selector_is_enabled(), expected)
def test_get_value_for_org(self): """ Test that get_value_for_org returns correct value for any given key. """ test_org = test_config['course_org_filter'] with with_site_configuration_context(configuration=test_config): self.assertEqual( configuration_helpers.get_value_for_org( test_org, "university"), test_config['university']) self.assertEqual( configuration_helpers.get_value_for_org( test_org, "css_overrides_file"), test_config['css_overrides_file']) six.assertCountEqual( self, configuration_helpers.get_value_for_org( test_org, "REGISTRATION_EXTRA_FIELDS"), test_config['REGISTRATION_EXTRA_FIELDS']) # Test default value of key is not present in configuration self.assertEqual( configuration_helpers.get_value_for_org( test_org, "non_existent_key"), None) self.assertEqual( configuration_helpers.get_value_for_org( test_org, "non_existent_key", "default for non existent"), "default for non existent") self.assertEqual( configuration_helpers.get_value_for_org( "missing_org", "university", "default for non existent"), "default for non existent")
def test_is_site_configuration_enabled(self): """ Test that is_site_configuration_enabled returns True when configuration is enabled. """ with with_site_configuration_context(configuration=test_config): assert configuration_helpers.is_site_configuration_enabled() # Test without a Site Configuration assert not configuration_helpers.is_site_configuration_enabled()
def test_is_site_configuration_enabled(self): """ Test that is_site_configuration_enabled returns True when configuration is enabled. """ with with_site_configuration_context(configuration=test_config): self.assertTrue(configuration_helpers.is_site_configuration_enabled()) # Test without a Site Configuration self.assertFalse(configuration_helpers.is_site_configuration_enabled())
def test_get_all_orgs(self): """ Test that get_all_orgs returns organizations defined in site configuration """ test_orgs = [test_config['course_org_filter']] with with_site_configuration_context(configuration=test_config): self.assertCountEqual( list(configuration_helpers.get_all_orgs()), test_orgs, )
def test_get_all_orgs(self): """ Test that get_all_orgs returns organizations defined in both site configuration and microsite configuration. """ test_orgs = [test_config['course_org_filter'], "LogistrationX", "TestSiteX"] with with_site_configuration_context(configuration=test_config): self.assertItemsEqual( list(configuration_helpers.get_all_orgs()), test_orgs, )
def test_get_all_orgs(self): """ Test that get_all_orgs returns correct values. """ test_orgs = [test_config['course_org_filter']] with with_site_configuration_context(configuration=test_config): self.assertItemsEqual( list(configuration_helpers.get_all_orgs()), test_orgs, )
def test_custom_redirect_url(self, redirect, expected_url): """ Test custom redirect after login """ configuration_values = {"DEFAULT_REDIRECT_AFTER_LOGIN": redirect} req = self.request.get(settings.LOGIN_URL) req.META["HTTP_ACCEPT"] = "text/html" with with_site_configuration_context(configuration=configuration_values): next_page = get_next_url_for_login_page(req) assert next_page == expected_url
def test_get_value_for_org_2(self): """ Test that get_value_for_org returns correct value for any given key. """ test_org = test_config['course_org_filter'] with with_site_configuration_context(configuration=test_config): # Make sure if ORG is not present in site configuration then default is used instead assert configuration_helpers.get_value_for_org( 'TestSiteX', 'email_from_address') is None # Make sure 'default' is returned if org is present but key is not assert configuration_helpers.get_value_for_org( test_org, 'email_from_address') is None
def test_about_with_site_configuration_and_html(self): """ Test the about view with html in the header. """ test_header = u"<i>Very Unique Test Header</i>" test_content = u"<i>Very Unique Test Content</i>" test_header_key = u'static_template_about_header' test_content_key = u'static_template_about_content' response = None 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)
def test_about_with_site_configuration(self): """ Test the about view with the header and content set in SiteConfiguration. """ test_header = u"Very Unique Test Header" test_content = u"Very Unique Test Content" test_header_key = u'static_template_about_header' test_content_key = u'static_template_about_content' response = None 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.assertContains(response, test_header) self.assertContains(response, test_content)
def test_third_party_auth_hint(self, tpa_hint, next_url, expected_url, running_pipeline, mock_running_pipeline): mock_running_pipeline.return_value = running_pipeline def validate_login(): req = self.request.get(settings.LOGIN_URL + "?next={url}".format(url=next_url)) req.META["HTTP_ACCEPT"] = "text/html" # pylint: disable=no-member self._add_session(req) next_page = get_next_url_for_login_page(req) self.assertEqual(next_page, expected_url) with override_settings(FEATURES=dict(settings.FEATURES, THIRD_PARTY_AUTH_HINT=tpa_hint)): validate_login() with with_site_configuration_context(configuration=dict(THIRD_PARTY_AUTH_HINT=tpa_hint)): validate_login()
def test_third_party_auth_hint(self, tpa_hint, next_url, expected_url, running_pipeline, mock_running_pipeline): mock_running_pipeline.return_value = running_pipeline def validate_login(): req = self.request.get(reverse("login") + "?next={url}".format(url=next_url)) req.META["HTTP_ACCEPT"] = "text/html" # pylint: disable=no-member self._add_session(req) next_page = get_next_url_for_login_page(req) self.assertEqual(next_page, expected_url) with override_settings(FEATURES=dict(settings.FEATURES, THIRD_PARTY_AUTH_HINT=tpa_hint)): validate_login() with with_site_configuration_context(configuration=dict(THIRD_PARTY_AUTH_HINT=tpa_hint)): validate_login()
def test_get_current_site_configuration_values(self): """ Test get_current_site_configuration_values helper function """ site_values = configuration_helpers.get_current_site_configuration_values( ) self.assertTrue(isinstance(site_values, dict)) # without any site configuration it should return empty dict self.assertEqual(site_values, {}) with with_site_configuration_context(configuration=test_config): site_values = configuration_helpers.get_current_site_configuration_values( ) self.assertEqual(site_values, test_config)
def test_show_empty_dashboard_message(self): """ Verify that when the EMPTY_DASHBOARD_MESSAGE feature is set, its text is displayed in an empty courses list. """ empty_dashboard_message = "Check out our lovely <i>free</i> courses!" response = self.client.get(reverse('dashboard')) self.assertIn('You are not enrolled in any courses yet.', response.content) self.assertNotIn(empty_dashboard_message, response.content) with with_site_configuration_context(configuration={ "EMPTY_DASHBOARD_MESSAGE": empty_dashboard_message, }): response = self.client.get(reverse('dashboard')) self.assertIn('You are not enrolled in any courses yet.', response.content) self.assertIn(empty_dashboard_message, response.content)
def test_show_empty_dashboard_message(self): """ Verify that when the EMPTY_DASHBOARD_MESSAGE feature is set, its text is displayed in an empty courses list. """ empty_dashboard_message = "Check out our lovely <i>free</i> courses!" response = self.client.get(reverse('dashboard')) self.assertContains(response, 'You are not enrolled in any courses yet.') self.assertNotContains(response, empty_dashboard_message) with with_site_configuration_context(configuration={ "EMPTY_DASHBOARD_MESSAGE": empty_dashboard_message, }): response = self.client.get(reverse('dashboard')) self.assertContains(response, 'You are not enrolled in any courses yet.') self.assertContains(response, empty_dashboard_message)
def test_get_only_staff_filter(self): """ Test get only staff filter with staff user and student. Test Priority: 1. Staff user: always 'False' 2. Student user: Models > Site Configurations > Default value ('False') """ # Test staff_user always return False only_staff_filter = views._get_only_staff_filter( self.staff_user, self.course) self.assertEqual(only_staff_filter, False) # Test student. By default (without any configuration) return False only_staff_filter = views._get_only_staff_filter( self.main_student, self.course) self.assertEqual(only_staff_filter, False) # Test with configurations # Test student with site configuration (only_staff) test_config = { 'EOL_DIRECTMESSAGE_ONLY_STAFF': True, } with with_site_configuration_context(configuration=test_config): only_staff_filter = views._get_only_staff_filter( self.main_student, self.course) self.assertEqual(only_staff_filter, True) # Test student with site and course configuration (in models) course_filter = EolMessageFilter.objects.create( course_id=self.course.id, only_staff=False, ) only_staff_filter = views._get_only_staff_filter( self.main_student, self.course) self.assertEqual(only_staff_filter, False) course_filter.only_staff = True course_filter.save() only_staff_filter = views._get_only_staff_filter( self.main_student, self.course) self.assertEqual(only_staff_filter, True) only_staff_filter = views._get_only_staff_filter( self.staff_user, self.course) self.assertEqual(only_staff_filter, False)
def test_donate_button_with_enabled_site_configuration(self, enable_donation_config, enable_donation_site_config): # Enable the enrollment success message and donations self._configure_message_timeout(10000) # DonationConfiguration has low precedence if 'ENABLE_DONATIONS' is enable in SiteConfiguration DonationConfiguration(enabled=enable_donation_config).save() CourseModeFactory.create(mode_slug="audit", course_id=self.course.id, min_price=0) self.enrollment.mode = "audit" self.enrollment.save() self.client.login(username=self.student.username, password=self.PASSWORD) with with_site_configuration_context(configuration={'ENABLE_DONATIONS': enable_donation_site_config}): response = self.client.get(reverse("dashboard")) if enable_donation_site_config: self.assertContains(response, "donate-container") else: self.assertNotContains(response, "donate-container")
def lms_link_for_certificate_web_view_test(self): """ Tests get_lms_link_for_certificate_web_view. """ course_key = CourseLocator('mitX', '101', 'test') dummy_user = ModuleStoreEnum.UserID.test mode = 'professional' self.assertEqual( utils.get_lms_link_for_certificate_web_view(course_key, mode), "//localhost:8000/certificates/course/{course_key}?preview={mode}". format(course_key=course_key, mode=mode)) with with_site_configuration_context(configuration={ "course_org_filter": "mitX", "LMS_BASE": "dummyhost:8000" }): self.assertEqual( utils.get_lms_link_for_certificate_web_view(course_key, mode), "//dummyhost:8000/certificates/course/{course_key}?preview={mode}" .format(course_key=course_key, mode=mode))
def test_linked_in_url_with_cert_name_override(self, cert_mode, expected_cert_name): config = LinkedInAddToProfileConfiguration( company_identifier='0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9', enabled=True) expected_url = ( 'http://www.linkedin.com/profile/add' '?_ed=0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9&' 'pfCertificationName={platform_name}+{expected_cert_name}&' 'pfCertificationUrl=http%3A%2F%2Fs3.edx%2Fcert&' 'source=o').format(expected_cert_name=expected_cert_name, platform_name=quote( settings.PLATFORM_NAME.encode('utf-8'))) with with_site_configuration_context( configuration=self.SITE_CONFIGURATION): actual_url = config.add_to_profile_url(self.COURSE_KEY, self.COURSE_NAME, cert_mode, self.CERT_URL) self.assertEqual(actual_url, expected_url)
def test_get_value_for_org(self): """ Test that get_value_for_org returns correct value for any given key. """ test_org = test_config['course_org_filter'] with with_site_configuration_context(configuration=test_config): assert configuration_helpers.get_value_for_org( test_org, 'university') == test_config['university'] assert configuration_helpers.get_value_for_org(test_org, 'css_overrides_file') ==\ test_config['css_overrides_file'] self.assertCountEqual( configuration_helpers.get_value_for_org( test_org, "REGISTRATION_EXTRA_FIELDS"), test_config['REGISTRATION_EXTRA_FIELDS']) # Test default value of key is not present in configuration assert configuration_helpers.get_value_for_org( test_org, 'non_existent_key') is None assert configuration_helpers.get_value_for_org(test_org, 'non_existent_key', 'default for non existent') ==\ 'default for non existent' assert configuration_helpers.get_value_for_org('missing_org', 'university', 'default for non existent') ==\ 'default for non existent'
def lms_link_for_certificate_web_view_test(self): """ Tests get_lms_link_for_certificate_web_view. """ course_key = SlashSeparatedCourseKey('mitX', '101', 'test') dummy_user = ModuleStoreEnum.UserID.test mode = 'professional' self.assertEquals( utils.get_lms_link_for_certificate_web_view(dummy_user, course_key, mode), "//localhost:8000/certificates/user/{user_id}/course/{course_key}?preview={mode}".format( user_id=dummy_user, course_key=course_key, mode=mode ) ) with with_site_configuration_context(configuration={"course_org_filter": "mitX", "LMS_BASE": "dummyhost:8000"}): self.assertEquals( utils.get_lms_link_for_certificate_web_view(dummy_user, course_key, mode), "//dummyhost:8000/certificates/user/{user_id}/course/{course_key}?preview={mode}".format( user_id=dummy_user, course_key=course_key, mode=mode ) )
def test_get_many(self, mock_warning, mock_info): programs = ProgramFactory.create_batch(3) # Cache details for 2 of 3 programs. partial_programs = { PROGRAM_CACHE_KEY_TPL.format(uuid=program['uuid']): program for program in programs[:2] } cache.set_many(partial_programs, None) # When called before UUIDs are cached, the function should return an # empty list and log a warning. with with_site_configuration_context( domain=self.site.name, configuration={'COURSE_CATALOG_API_URL': 'foo'}): self.assertEqual(get_programs(site=self.site), []) mock_warning.assert_called_once_with( u'Failed to get program UUIDs from the cache for site {}.'. format(self.site.domain)) mock_warning.reset_mock() # Cache UUIDs for all 3 programs. cache.set( SITE_PROGRAM_UUIDS_CACHE_KEY_TPL.format(domain=self.site.domain), [program['uuid'] for program in programs], None) actual_programs = get_programs(site=self.site) # The 2 cached programs should be returned while info and warning # messages should be logged for the missing one. self.assertEqual( set(program['uuid'] for program in actual_programs), set(program['uuid'] for program in partial_programs.values())) mock_info.assert_called_with( 'Failed to get details for 1 programs. Retrying.') mock_warning.assert_called_with( u'Failed to get details for program {uuid} from the cache.'.format( uuid=programs[2]['uuid'])) mock_warning.reset_mock() # We can't use a set comparison here because these values are dictionaries # and aren't hashable. We've already verified that all programs came out # of the cache above, so all we need to do here is verify the accuracy of # the data itself. for program in actual_programs: key = PROGRAM_CACHE_KEY_TPL.format(uuid=program['uuid']) self.assertEqual(program, partial_programs[key]) # Cache details for all 3 programs. all_programs = { PROGRAM_CACHE_KEY_TPL.format(uuid=program['uuid']): program for program in programs } cache.set_many(all_programs, None) actual_programs = get_programs(site=self.site) # All 3 programs should be returned. self.assertEqual( set(program['uuid'] for program in actual_programs), set(program['uuid'] for program in all_programs.values())) self.assertFalse(mock_warning.called) for program in actual_programs: key = PROGRAM_CACHE_KEY_TPL.format(uuid=program['uuid']) self.assertEqual(program, all_programs[key])