def setUp(self): super(ProgramPageBase, self).setUp() self.set_programs_api_configuration(is_enabled=True) self.programs = ProgramFactory.create_batch(3) self.username = None
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 actual_programs = get_programs(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. self.assertEqual( set(program['uuid'] for program in actual_programs), set(program['uuid'] for program in all_programs.values()) ) self.assertFalse(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']) self.assertEqual(program, all_programs[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_completed_programs(self, mock_completed_course_runs, mock_get_programs): """Verify that completed programs are correctly identified.""" data = ProgramFactory.create_batch(3) mock_get_programs.return_value = data program_uuids = [] course_run_keys = [] for program in data: program_uuids.append(program['uuid']) for course in program['courses']: for course_run in course['course_runs']: course_run_keys.append(course_run['key']) # Verify that no programs are complete. meter = ProgramProgressMeter(self.user) self.assertEqual(meter.completed_programs, []) # Complete all programs. self._create_enrollments(*course_run_keys) mock_completed_course_runs.return_value = [ {'course_run_id': course_run_key, 'type': MODES.verified} for course_run_key in course_run_keys ] # Verify that all programs are complete. meter = ProgramProgressMeter(self.user) self.assertEqual(meter.completed_programs, program_uuids)
def setUp(self): super(ProgramPageBase, self).setUp() self.set_programs_api_configuration(is_enabled=True) self.programs = ProgramFactory.create_batch(3) self.username = None
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_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_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 actual_programs = get_programs(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. self.assertEqual( set(program['uuid'] for program in actual_programs), set(program['uuid'] for program in all_programs.values()) ) self.assertFalse(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']) self.assertEqual(program, all_programs[key])
def test_completed_programs(self, mock_completed_course_runs, mock_get_programs): """Verify that completed programs are correctly identified.""" data = ProgramFactory.create_batch(3) mock_get_programs.return_value = data program_uuids = [] course_run_keys = [] for program in data: program_uuids.append(program['uuid']) for course in program['courses']: for course_run in course['course_runs']: course_run_keys.append(course_run['key']) # Verify that no programs are complete. meter = ProgramProgressMeter(self.site, self.user) self.assertEqual(meter.completed_programs, []) # Complete all programs. self._create_enrollments(*course_run_keys) mock_completed_course_runs.return_value = [ {'course_run_id': course_run_key, 'type': MODES.verified} for course_run_key in course_run_keys ] # Verify that all programs are complete. meter = ProgramProgressMeter(self.site, self.user) self.assertEqual(meter.completed_programs, program_uuids)
def test_get_programs_by_types(self, mock_get_edx_api_data): programs = ProgramFactory.create_batch(2) mock_get_edx_api_data.return_value = programs data = get_programs(types=self.types) self.assert_contract(mock_get_edx_api_data.call_args, types=self.types) self.assertEqual(data, programs)
def test_get_programs_by_types(self, mock_get_edx_api_data): programs = ProgramFactory.create_batch(2) mock_get_edx_api_data.return_value = programs data = get_programs(types=self.types) self.assert_contract(mock_get_edx_api_data.call_args, types=self.types) self.assertEqual(data, programs)
def test_get_many(self, mock_warning): 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. self.assertEqual(get_programs(), []) mock_warning.assert_called_once_with('Program UUIDs are not cached.') mock_warning.reset_mock() # Cache UUIDs for all 3 programs. cache.set(PROGRAM_UUIDS_CACHE_KEY, [program['uuid'] for program in programs], None) actual_programs = get_programs() # The 2 cached programs should be returned while a warning 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_warning.assert_called_with( 'Details for program {uuid} are not cached.'.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() # 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])
def setUp(self): super(TestCachePrograms, self).setUp() self.catalog_integration = self.create_catalog_integration() self.list_url = self.catalog_integration.get_internal_api_url().rstrip('/') + '/programs/' self.detail_tpl = self.list_url.rstrip('/') + '/{uuid}/' self.programs = ProgramFactory.create_batch(3) self.uuids = [program['uuid'] for program in self.programs]
def test_get_programs_with_status_filtering(self, mock_get_edx_api_data): """ The function should request active and retired programs when the Waffle switch is enabled. """ programs = ProgramFactory.create_batch(3) mock_get_edx_api_data.return_value = programs Switch.objects.get_or_create(name='display_retired_programs_on_learner_dashboard', defaults={'active': True}) data = get_programs() expected_querystring = { 'exclude_utm': 1, 'status': ('active', 'retired',) } self.assert_contract(mock_get_edx_api_data.call_args, expected_querystring=expected_querystring) self.assertEqual(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(ProgramPageBase, self).setUp() self.set_programs_api_configuration(is_enabled=True) self.programs = ProgramFactory.create_batch(3) self.credit_pathways = CreditPathwayFactory.create_batch(3) for pathway in self.credit_pathways: self.programs += pathway['programs'] # add some of the previously created programs to some pathways self.credit_pathways[0]['programs'].extend([self.programs[0], self.programs[1]]) self.credit_pathways[1]['programs'].append(self.programs[0]) self.username = None
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 setUp(self): super(TestCachePrograms, self).setUp() 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.programs = ProgramFactory.create_batch(3) self.uuids = [program['uuid'] for program in self.programs]
def setUp(self): super(TestCachePrograms, self).setUp() 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.programs = ProgramFactory.create_batch(3) self.uuids = [program['uuid'] for program in self.programs]
def test_get_programs_with_type(self, mock_get_program_types, mock_get_programs): """Verify get_programs_with_type returns the expected list of programs.""" programs_with_program_type = [] programs = ProgramFactory.create_batch(2) program_types = [] for program in programs: program_type = ProgramTypeFactory(name=program['type']) program_types.append(program_type) program_with_type = copy.deepcopy(program) program_with_type['type'] = program_type programs_with_program_type.append(program_with_type) mock_get_programs.return_value = programs mock_get_program_types.return_value = program_types actual = get_programs_with_type(self.site) self.assertEqual(actual, programs_with_program_type)
def test_get_programs_with_type(self, mock_get_program_types, mock_get_programs): """Verify get_programs_with_type returns the expected list of programs.""" programs_with_program_type = [] programs = ProgramFactory.create_batch(2) program_types = [] for program in programs: program_type = ProgramTypeFactory(name=program['type']) program_types.append(program_type) program_with_type = copy.deepcopy(program) program_with_type['type'] = program_type programs_with_program_type.append(program_with_type) mock_get_programs.return_value = programs mock_get_program_types.return_value = program_types actual = get_programs_with_type(self.site) self.assertEqual(actual, programs_with_program_type)
def test_get_programs_with_status_filtering(self, mock_get_edx_api_data): """ The function should request active and retired programs when the Waffle switch is enabled. """ programs = ProgramFactory.create_batch(3) mock_get_edx_api_data.return_value = programs Switch.objects.get_or_create( name='display_retired_programs_on_learner_dashboard', defaults={'active': True}) data = get_programs() expected_querystring = { 'exclude_utm': 1, 'status': ( 'active', 'retired', ) } self.assert_contract(mock_get_edx_api_data.call_args, expected_querystring=expected_querystring) self.assertEqual(data, programs)
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])
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. self.assertEqual(get_programs(self.site), []) mock_warning.assert_called_once_with('Failed to get program UUIDs from the cache.') 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(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( '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(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])