def test_get_many(self, mock_warning, mock_info): pathways = PathwayFactory.create_batch(3) # Cache details for 2 of 3 programs. partial_pathways = { PATHWAY_CACHE_KEY_TPL.format(id=pathway['id']): pathway for pathway in pathways[:2] } cache.set_many(partial_pathways, None) # When called before pathways are cached, the function should return an # empty list and log a warning. assert get_pathways(self.site) == [] mock_warning.assert_called_once_with( 'Failed to get credit pathway ids from the cache.') mock_warning.reset_mock() # Cache all 3 pathways cache.set( SITE_PATHWAY_IDS_CACHE_KEY_TPL.format(domain=self.site.domain), [pathway['id'] for pathway in pathways], None) actual_pathways = get_pathways(self.site) # The 2 cached pathways should be returned while info and warning # messages should be logged for the missing one. assert {pathway['id'] for pathway in actual_pathways} ==\ {pathway['id'] for pathway in partial_pathways.values()} mock_info.assert_called_with( 'Failed to get details for 1 pathways. Retrying.') mock_warning.assert_called_with( 'Failed to get details for credit pathway {id} from the cache.'. format(id=pathways[2]['id'])) 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 pathways came out # of the cache above, so all we need to do here is verify the accuracy of # the data itself. for pathway in actual_pathways: key = PATHWAY_CACHE_KEY_TPL.format(id=pathway['id']) assert pathway == partial_pathways[key] # Cache details for all 3 pathways. all_pathways = { PATHWAY_CACHE_KEY_TPL.format(id=pathway['id']): pathway for pathway in pathways } cache.set_many(all_pathways, None) actual_pathways = get_pathways(self.site) # All 3 pathways should be returned. assert {pathway['id'] for pathway in actual_pathways} ==\ {pathway['id'] for pathway in all_pathways.values()} assert not mock_warning.called for pathway in actual_pathways: key = PATHWAY_CACHE_KEY_TPL.format(id=pathway['id']) assert pathway == all_pathways[key]
def setUp(self): super(TestCachePrograms, self).setUp() httpretty.httpretty.reset() self.catalog_integration = self.create_catalog_integration() self.site_domain = 'testsite.com' self.site = self.set_up_site( self.site_domain, { 'COURSE_CATALOG_API_URL': self.catalog_integration.get_internal_api_url().rstrip('/') } ) self.list_url = self.catalog_integration.get_internal_api_url().rstrip('/') + '/programs/' self.detail_tpl = self.list_url.rstrip('/') + '/{uuid}/' self.pathway_url = self.catalog_integration.get_internal_api_url().rstrip('/') + '/pathways/' self.programs = ProgramFactory.create_batch(3) self.pathways = PathwayFactory.create_batch(3) self.child_program = ProgramFactory.create() self.programs[0]['curricula'][0]['programs'].append(self.child_program) self.programs.append(self.child_program) self.programs[0]['authoring_organizations'] = OrganizationFactory.create_batch(2) for pathway in self.pathways: self.programs += pathway['programs'] self.uuids = [program['uuid'] for program in self.programs] # add some of the previously created programs to some pathways self.pathways[0]['programs'].extend([self.programs[0], self.programs[1]]) self.pathways[1]['programs'].append(self.programs[0])
def test_get_many_with_missing(self, mock_cache, mock_warning, mock_info): pathways = PathwayFactory.create_batch(3) all_pathways = { PATHWAY_CACHE_KEY_TPL.format(id=pathway['id']): pathway for pathway in pathways } partial_pathways = { PATHWAY_CACHE_KEY_TPL.format(id=pathway['id']): pathway for pathway in pathways[:2] } def fake_get_many(keys): if len(keys) == 1: return {PATHWAY_CACHE_KEY_TPL.format(id=pathways[-1]['id']): pathways[-1]} else: return partial_pathways mock_cache.get.return_value = [pathway['id'] for pathway in pathways] mock_cache.get_many.side_effect = fake_get_many actual_pathways = get_pathways(self.site) # All 3 cached pathways 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. self.assertEqual( set(pathway['id'] for pathway in actual_pathways), set(pathway['id'] for pathway in all_pathways.values()) ) self.assertFalse(mock_warning.called) mock_info.assert_called_with('Failed to get details for 1 pathways. Retrying.') for pathway in actual_pathways: key = PATHWAY_CACHE_KEY_TPL.format(id=pathway['id']) self.assertEqual(pathway, all_pathways[key])
def setUp(self): super(TestCachePrograms, self).setUp() httpretty.httpretty.reset() self.catalog_integration = self.create_catalog_integration() self.site_domain = 'testsite.com' self.set_up_site( self.site_domain, { 'COURSE_CATALOG_API_URL': self.catalog_integration.get_internal_api_url().rstrip('/') } ) self.list_url = self.catalog_integration.get_internal_api_url().rstrip('/') + '/programs/' self.detail_tpl = self.list_url.rstrip('/') + '/{uuid}/' self.pathway_url = self.catalog_integration.get_internal_api_url().rstrip('/') + '/pathways/' self.programs = ProgramFactory.create_batch(3) self.pathways = PathwayFactory.create_batch(3) for pathway in self.pathways: self.programs += pathway['programs'] self.uuids = [program['uuid'] for program in self.programs] # add some of the previously created programs to some pathways self.pathways[0]['programs'].extend([self.programs[0], self.programs[1]]) self.pathways[1]['programs'].append(self.programs[0])
def test_pathways_multiple_pages(self): """ Verify that the command properly caches credit pathways when multiple pages are returned from its endpoint """ UserFactory(username=self.catalog_integration.service_username) new_pathways = PathwayFactory.create_batch(40) for new_pathway in new_pathways: new_pathway['programs'] = [] pathways = self.pathways + new_pathways programs = { PROGRAM_CACHE_KEY_TPL.format(uuid=program['uuid']): program for program in self.programs } self.mock_list() for uuid in self.uuids: program = programs[PROGRAM_CACHE_KEY_TPL.format(uuid=uuid)] self.mock_detail(uuid, program) # mock 3 pages of credit pathways, starting at the last self.mock_pathways(pathways[40:], page_number=3, final=True) self.mock_pathways(pathways[20:40], page_number=2, final=False) self.mock_pathways(pathways[:20], page_number=1, final=False) call_command('cache_programs') pathways_dict = { PATHWAY_CACHE_KEY_TPL.format(id=pathway['id']): pathway for pathway in pathways } pathway_keys = list(pathways_dict.keys()) cached_pathway_keys = cache.get(SITE_PATHWAY_IDS_CACHE_KEY_TPL.format(domain=self.site_domain)) self.assertEqual( set(cached_pathway_keys), set(pathway_keys) ) cached_pathways = cache.get_many(pathway_keys) self.assertEqual( set(cached_pathways), set(pathways_dict) ) # We can't use a set comparison here because these values are dictionaries # and aren't hashable. We've already verified that all pathways came out # of the cache above, so all we need to do here is verify the accuracy of # the data itself. for key, pathway in cached_pathways.items(): # cached pathways store just program uuids instead of the full programs, transform before comparing pathways_dict[key]['program_uuids'] = [program['uuid'] for program in pathways_dict[key]['programs']] del pathways_dict[key]['programs'] self.assertEqual(pathway, pathways_dict[key])
def setUpClass(cls): super().setUpClass() modulestore_course = ModuleStoreCourseFactory() course_run = CourseRunFactory(key=str(modulestore_course.id)) # lint-amnesty, pylint: disable=no-member course = CourseFactory(course_runs=[course_run]) cls.program_data = ProgramFactory(uuid=cls.program_uuid, courses=[course]) cls.pathway_data = PathwayFactory() cls.program_data['pathway_ids'] = [cls.pathway_data['id']] cls.pathway_data['program_uuids'] = [cls.program_data['uuid']] del cls.pathway_data['programs'] # lint-amnesty, pylint: disable=unsupported-delete-operation
def setUpClass(cls): super(TestProgramDetails, cls).setUpClass() modulestore_course = ModuleStoreCourseFactory() course_run = CourseRunFactory(key=six.text_type(modulestore_course.id)) course = CourseFactory(course_runs=[course_run]) cls.program_data = ProgramFactory(uuid=cls.program_uuid, courses=[course]) cls.pathway_data = PathwayFactory() cls.program_data['pathway_ids'] = [cls.pathway_data['id']] cls.pathway_data['program_uuids'] = [cls.program_data['uuid']] del cls.pathway_data['programs']
def setUp(self): super(ProgramPageBase, self).setUp() self.set_programs_api_configuration(is_enabled=True) self.programs = ProgramFactory.create_batch(3) self.pathways = PathwayFactory.create_batch(3) for pathway in self.pathways: self.programs += pathway['programs'] # add some of the previously created programs to some pathways self.pathways[0]['programs'].extend([self.programs[0], self.programs[1]]) self.pathways[1]['programs'].append(self.programs[0]) self.username = None
def setUp(self): super().setUp() self.set_programs_api_configuration(is_enabled=True) self.programs = ProgramFactory.create_batch(3) self.pathways = PathwayFactory.create_batch(3) for pathway in self.pathways: self.programs += pathway['programs'] # add some of the previously created programs to some pathways self.pathways[0]['programs'].extend([self.programs[0], self.programs[1]]) self.pathways[1]['programs'].append(self.programs[0]) self.username = None
def test_get_one(self, mock_warning, _mock_info): expected_pathway = PathwayFactory() expected_id = expected_pathway['id'] self.assertEqual(get_pathways(self.site, pathway_id=expected_id), None) mock_warning.assert_called_once_with( u'Failed to get details for credit pathway {id} from the cache.'. format(id=expected_id)) mock_warning.reset_mock() cache.set(PATHWAY_CACHE_KEY_TPL.format(id=expected_id), expected_pathway, None) actual_pathway = get_pathways(self.site, pathway_id=expected_id) self.assertEqual(actual_pathway, expected_pathway) self.assertFalse(mock_warning.called)
def setUp(self): super(ProgramPageBase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.set_programs_api_configuration(is_enabled=True) self.programs = ProgramFactory.create_batch(3) self.pathways = PathwayFactory.create_batch(3) for pathway in self.pathways: self.programs += pathway['programs'] # add some of the previously created programs to some pathways self.pathways[0]['programs'].extend( [self.programs[0], self.programs[1]]) self.pathways[1]['programs'].append(self.programs[0]) self.username = None
def test_get_one(self, mock_warning, _mock_info): expected_pathway = PathwayFactory() expected_id = expected_pathway['id'] assert get_pathways(self.site, pathway_id=expected_id) is None mock_warning.assert_called_once_with( f'Failed to get details for credit pathway {expected_id} from the cache.' ) mock_warning.reset_mock() cache.set(PATHWAY_CACHE_KEY_TPL.format(id=expected_id), expected_pathway, None) actual_pathway = get_pathways(self.site, pathway_id=expected_id) assert actual_pathway == expected_pathway assert not mock_warning.called
def test_get_many(self, mock_warning, mock_info): pathways = PathwayFactory.create_batch(3) # Cache details for 2 of 3 programs. partial_pathways = { PATHWAY_CACHE_KEY_TPL.format(id=pathway['id']): pathway for pathway in pathways[:2] } cache.set_many(partial_pathways, None) # When called before pathways are cached, the function should return an # empty list and log a warning. self.assertEqual(get_pathways(self.site), []) mock_warning.assert_called_once_with('Failed to get credit pathway ids from the cache.') mock_warning.reset_mock() # Cache all 3 pathways cache.set( SITE_PATHWAY_IDS_CACHE_KEY_TPL.format(domain=self.site.domain), [pathway['id'] for pathway in pathways], None ) actual_pathways = get_pathways(self.site) # The 2 cached pathways should be returned while info and warning # messages should be logged for the missing one. self.assertEqual( set(pathway['id'] for pathway in actual_pathways), set(pathway['id'] for pathway in partial_pathways.values()) ) mock_info.assert_called_with('Failed to get details for 1 pathways. Retrying.') mock_warning.assert_called_with( 'Failed to get details for credit pathway {id} from the cache.'.format(id=pathways[2]['id']) ) 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 pathways came out # of the cache above, so all we need to do here is verify the accuracy of # the data itself. for pathway in actual_pathways: key = PATHWAY_CACHE_KEY_TPL.format(id=pathway['id']) self.assertEqual(pathway, partial_pathways[key]) # Cache details for all 3 pathways. all_pathways = { PATHWAY_CACHE_KEY_TPL.format(id=pathway['id']): pathway for pathway in pathways } cache.set_many(all_pathways, None) actual_pathways = get_pathways(self.site) # All 3 pathways should be returned. self.assertEqual( set(pathway['id'] for pathway in actual_pathways), set(pathway['id'] for pathway in all_pathways.values()) ) self.assertFalse(mock_warning.called) for pathway in actual_pathways: key = PATHWAY_CACHE_KEY_TPL.format(id=pathway['id']) self.assertEqual(pathway, all_pathways[key])