def test_handle(self, commit, mock_task, mock_get_programs): """ Verify that relevant tasks are only enqueued when the commit option is passed. """ data = [ factories.Program(courses=[ factories.Course(course_runs=[ factories.CourseRun(key=self.course_run_key), ]), ]), ] mock_get_programs.return_value = data GeneratedCertificateFactory( user=self.alice, course_id=self.course_run_key, mode=MODES.verified, status=CertificateStatuses.downloadable, ) GeneratedCertificateFactory( user=self.bob, course_id=self.alternate_course_run_key, mode=MODES.verified, status=CertificateStatuses.downloadable, ) call_command('backpopulate_program_credentials', commit=commit) if commit: mock_task.assert_called_once_with(self.alice.username) else: mock_task.assert_not_called()
def test_get_programs_data(self, _mock_cache, mock_get_catalog_data): # pylint: disable=unused-argument programs = [] program_types = [] programs_data = [] for index in range(3): # Creating the Programs and their corresponding program types. type_name = "type_name_{postfix}".format(postfix=index) program = factories.Program(type=type_name) program_type = factories.ProgramType(name=type_name) # Maintaining the programs, program types and program data(program+logo_image) lists. programs.append(program) program_types.append(program_type) programs_data.append(copy.deepcopy(program)) # Adding the logo image in program data. programs_data[-1]['logo_image'] = program_type["logo_image"] with mock.patch("openedx.core.djangoapps.catalog.utils.get_programs") as patched_get_programs: with mock.patch("openedx.core.djangoapps.catalog.utils.get_program_types") as patched_get_program_types: # Mocked the "get_programs" and "get_program_types" patched_get_programs.return_value = programs patched_get_program_types.return_value = program_types programs_data = utils.get_programs_data() self.assertEqual(programs_data, programs)
def test_handle_mode_slugs(self, mock_task, mock_get_programs): """ Verify that course run types are taken into account when identifying qualifying course run certificates. """ data = [ factories.Program(courses=[ factories.Course(course_runs=[ factories.CourseRun(key=self.course_run_key, type='honor'), ]), ]), ] mock_get_programs.return_value = data GeneratedCertificateFactory( user=self.alice, course_id=self.course_run_key, mode=MODES.honor, status=CertificateStatuses.downloadable, ) GeneratedCertificateFactory( user=self.bob, course_id=self.course_run_key, mode=MODES.verified, status=CertificateStatuses.downloadable, ) call_command('backpopulate_program_credentials', commit=True) mock_task.assert_called_once_with(self.alice.username)
def test_handle_username_dedup(self, mock_task, mock_get_programs): """ Verify that only one task is enqueued for a user with multiple eligible course run certificates. """ data = [ factories.Program(courses=[ factories.Course(course_runs=[ factories.CourseRun(key=self.course_run_key), factories.CourseRun(key=self.alternate_course_run_key), ]), ]), ] mock_get_programs.return_value = data GeneratedCertificateFactory( user=self.alice, course_id=self.course_run_key, mode=MODES.verified, status=CertificateStatuses.downloadable, ) GeneratedCertificateFactory( user=self.alice, course_id=self.alternate_course_run_key, mode=MODES.verified, status=CertificateStatuses.downloadable, ) call_command('backpopulate_program_credentials', commit=True) mock_task.assert_called_once_with(self.alice.username)
def test_get_programs_by_type(self, _mock_cache, mock_get_catalog_data): programs = [factories.Program() for __ in range(2)] mock_get_catalog_data.return_value = programs data = utils.get_programs(self.user, type=self.type) self.assert_contract(mock_get_catalog_data.call_args, type=self.type) self.assertEqual(data, programs)
def test_get_one_program(self, _mock_cache, mock_get_catalog_data): program = factories.Program() mock_get_catalog_data.return_value = program data = utils.get_programs(self.user, uuid=self.uuid) self.assert_contract(mock_get_catalog_data.call_args, program_uuid=self.uuid) self.assertEqual(data, program)
def setUp(self): super(ProgramPageBase, self).setUp() self.set_programs_api_configuration(is_enabled=True) self.programs = [catalog_factories.Program() for __ in range(3)] self.course_run = catalog_factories.CourseRun(key=self.course_id) self.stub_catalog_api()
def test_get_program_for_certificates(self): """Verify programs data can be retrieved and parsed correctly for certificates.""" programs = [ catalog_factories.Program(uuid=self.primary_uuid), catalog_factories.Program(uuid=self.alternate_uuid) ] program_credentials_data = self._expected_program_credentials_data() with mock.patch( "openedx.core.djangoapps.credentials.utils.get_programs" ) as patched_get_programs: patched_get_programs.return_value = programs actual = get_programs_for_credentials(self.user, program_credentials_data) self.assertEqual(len(actual), 2) self.assertEqual(actual, programs)
def test_get_programs_credentials(self): """ Verify that the program credentials data required for display can be retrieved. """ # create credentials and program configuration self.create_credentials_config() # Mocking the API responses from programs and credentials primary_uuid, alternate_uuid = str(uuid.uuid4()), str(uuid.uuid4()) credentials_api_response = { "next": None, "results": [ factories.UserCredential( username='******', credential=factories.ProgramCredential( program_uuid=primary_uuid)), factories.UserCredential( username='******', credential=factories.ProgramCredential( program_uuid=alternate_uuid)) ] } self.mock_credentials_api(self.user, data=credentials_api_response, reset_url=False) programs = [ catalog_factories.Program(uuid=primary_uuid), catalog_factories.Program(uuid=alternate_uuid) ] with mock.patch( "openedx.core.djangoapps.credentials.utils.get_programs" ) as mock_get_programs: mock_get_programs.return_value = programs actual = get_programs_credentials(self.user) expected = self.expected_credentials_display_data(programs) # Checking result is as expected self.assertEqual(len(actual), 2) self.assertEqual(actual, expected)
class TestMungeCatalogProgram(TestCase): """Tests covering querystring stripping.""" catalog_program = factories.Program() def test_munge_catalog_program(self): munged = utils.munge_catalog_program(self.catalog_program) expected = { 'id': self.catalog_program['uuid'], 'name': self.catalog_program['title'], 'subtitle': self.catalog_program['subtitle'], 'category': self.catalog_program['type'], 'marketing_slug': self.catalog_program['marketing_slug'], 'organizations': [{ 'display_name': organization['name'], 'key': organization['key'] } for organization in self.catalog_program['authoring_organizations']], 'course_codes': [{ 'display_name': course['title'], 'key': course['key'], 'organization': { 'display_name': course['owners'][0]['name'], 'key': course['owners'][0]['key'] }, 'run_modes': [{ 'course_key': run['key'], 'run_key': CourseKey.from_string(run['key']).run, 'mode_slug': 'verified' } for run in course['course_runs']], } for course in self.catalog_program['courses']], 'banner_image_urls': { 'w1440h480': self.catalog_program['banner_image']['large']['url'], 'w726h242': self.catalog_program['banner_image']['medium']['url'], 'w435h145': self.catalog_program['banner_image']['small']['url'], 'w348h116': self.catalog_program['banner_image']['x-small']['url'], }, } self.assertEqual(munged, expected)
def test_get_programs_anonymous_user(self, _mock_cache, mock_get_catalog_data): programs = [factories.Program() for __ in range(3)] mock_get_catalog_data.return_value = programs anonymous_user = AnonymousUserFactory() # The user is an Anonymous user but the Catalog Service User has not been created yet. data = utils.get_programs(anonymous_user) # This should not return programs. self.assertEqual(data, []) UserFactory(username='******') # After creating the service user above, data = utils.get_programs(anonymous_user) # the programs should be returned successfully. self.assertEqual(data, programs)
def test_handle_enqueue_failure(self, mock_log, mock_task, mock_get_programs): """Verify that failure to enqueue a task doesn't halt execution.""" def side_effect(username): """Simulate failure to enqueue a task.""" if username == self.alice.username: raise Exception mock_task.side_effect = side_effect data = [ factories.Program(courses=[ factories.Course(course_runs=[ factories.CourseRun(key=self.course_run_key), ]), ]), ] mock_get_programs.return_value = data GeneratedCertificateFactory( user=self.alice, course_id=self.course_run_key, mode=MODES.verified, status=CertificateStatuses.downloadable, ) GeneratedCertificateFactory( user=self.bob, course_id=self.course_run_key, mode=MODES.verified, status=CertificateStatuses.downloadable, ) call_command('backpopulate_program_credentials', commit=True) self.assertTrue(mock_log.called) calls = [mock.call(self.alice.username), mock.call(self.bob.username)] mock_task.assert_has_calls(calls, any_order=True)
def test_get_completed_programs(self, mock_get_completed_courses): """ Verify that completed programs are found, using the cache when possible. """ data = [ factories.Program(), ] self._mock_programs_api(data) munged_program = munge_catalog_program(data[0]) course_codes = munged_program['course_codes'] mock_get_completed_courses.return_value = [{ 'course_id': run_mode['course_key'], 'mode': run_mode['mode_slug'] } for run_mode in course_codes[0]['run_modes']] for _ in range(2): result = tasks.get_completed_programs(self.user) self.assertEqual(result[0], munged_program['id']) # Verify that only one request to the catalog was made (i.e., the cache was hit). self._assert_num_requests(1)
def test_handle_passing_status(self, mock_task, mock_get_programs): """ Verify that only course run certificates with a passing status are selected. """ data = [ factories.Program(courses=[ factories.Course(course_runs=[ factories.CourseRun(key=self.course_run_key), ]), ]), ] mock_get_programs.return_value = data passing_status = CertificateStatuses.downloadable failing_status = CertificateStatuses.notpassing self.assertIn(passing_status, CertificateStatuses.PASSED_STATUSES) self.assertNotIn(failing_status, CertificateStatuses.PASSED_STATUSES) GeneratedCertificateFactory( user=self.alice, course_id=self.course_run_key, mode=MODES.verified, status=passing_status, ) GeneratedCertificateFactory( user=self.bob, course_id=self.course_run_key, mode=MODES.verified, status=failing_status, ) call_command('backpopulate_program_credentials', commit=True) mock_task.assert_called_once_with(self.alice.username)
class BackpopulateProgramCredentialsTests(CatalogIntegrationMixin, CredentialsApiConfigMixin, TestCase): """Tests for the backpopulate_program_credentials management command.""" course_run_key, alternate_course_run_key = ( factories.generate_course_run_key() for __ in range(2)) def setUp(self): super(BackpopulateProgramCredentialsTests, self).setUp() self.alice = UserFactory() self.bob = UserFactory() # Disable certification to prevent the task from being triggered when # setting up test data (i.e., certificates with a passing status), thereby # skewing mock call counts. self.create_credentials_config(enable_learner_issuance=False) self.catalog_integration = self.create_catalog_integration() self.service_user = UserFactory( username=self.catalog_integration.service_username) @ddt.data(True, False) def test_handle(self, commit, mock_task, mock_get_programs): """ Verify that relevant tasks are only enqueued when the commit option is passed. """ data = [ factories.Program(courses=[ factories.Course(course_runs=[ factories.CourseRun(key=self.course_run_key), ]), ]), ] mock_get_programs.return_value = data GeneratedCertificateFactory( user=self.alice, course_id=self.course_run_key, mode=MODES.verified, status=CertificateStatuses.downloadable, ) GeneratedCertificateFactory( user=self.bob, course_id=self.alternate_course_run_key, mode=MODES.verified, status=CertificateStatuses.downloadable, ) call_command('backpopulate_program_credentials', commit=commit) if commit: mock_task.assert_called_once_with(self.alice.username) else: mock_task.assert_not_called() @ddt.data( [ factories.Program(courses=[ factories.Course(course_runs=[ factories.CourseRun(key=course_run_key), ]), ]), factories.Program(courses=[ factories.Course(course_runs=[ factories.CourseRun(key=alternate_course_run_key), ]), ]), ], [ factories.Program(courses=[ factories.Course(course_runs=[ factories.CourseRun(key=course_run_key), ]), factories.Course(course_runs=[ factories.CourseRun(key=alternate_course_run_key), ]), ]), ], [ factories.Program(courses=[ factories.Course(course_runs=[ factories.CourseRun(key=course_run_key), factories.CourseRun(key=alternate_course_run_key), ]), ]), ], ) def test_handle_flatten(self, data, mock_task, mock_get_programs): """Verify that program structures are flattened correctly.""" mock_get_programs.return_value = data GeneratedCertificateFactory( user=self.alice, course_id=self.course_run_key, mode=MODES.verified, status=CertificateStatuses.downloadable, ) GeneratedCertificateFactory( user=self.bob, course_id=self.alternate_course_run_key, mode=MODES.verified, status=CertificateStatuses.downloadable, ) call_command('backpopulate_program_credentials', commit=True) calls = [mock.call(self.alice.username), mock.call(self.bob.username)] mock_task.assert_has_calls(calls, any_order=True) def test_handle_username_dedup(self, mock_task, mock_get_programs): """ Verify that only one task is enqueued for a user with multiple eligible course run certificates. """ data = [ factories.Program(courses=[ factories.Course(course_runs=[ factories.CourseRun(key=self.course_run_key), factories.CourseRun(key=self.alternate_course_run_key), ]), ]), ] mock_get_programs.return_value = data GeneratedCertificateFactory( user=self.alice, course_id=self.course_run_key, mode=MODES.verified, status=CertificateStatuses.downloadable, ) GeneratedCertificateFactory( user=self.alice, course_id=self.alternate_course_run_key, mode=MODES.verified, status=CertificateStatuses.downloadable, ) call_command('backpopulate_program_credentials', commit=True) mock_task.assert_called_once_with(self.alice.username) def test_handle_mode_slugs(self, mock_task, mock_get_programs): """ Verify that course run types are taken into account when identifying qualifying course run certificates. """ data = [ factories.Program(courses=[ factories.Course(course_runs=[ factories.CourseRun(key=self.course_run_key, type='honor'), ]), ]), ] mock_get_programs.return_value = data GeneratedCertificateFactory( user=self.alice, course_id=self.course_run_key, mode=MODES.honor, status=CertificateStatuses.downloadable, ) GeneratedCertificateFactory( user=self.bob, course_id=self.course_run_key, mode=MODES.verified, status=CertificateStatuses.downloadable, ) call_command('backpopulate_program_credentials', commit=True) mock_task.assert_called_once_with(self.alice.username) def test_handle_passing_status(self, mock_task, mock_get_programs): """ Verify that only course run certificates with a passing status are selected. """ data = [ factories.Program(courses=[ factories.Course(course_runs=[ factories.CourseRun(key=self.course_run_key), ]), ]), ] mock_get_programs.return_value = data passing_status = CertificateStatuses.downloadable failing_status = CertificateStatuses.notpassing self.assertIn(passing_status, CertificateStatuses.PASSED_STATUSES) self.assertNotIn(failing_status, CertificateStatuses.PASSED_STATUSES) GeneratedCertificateFactory( user=self.alice, course_id=self.course_run_key, mode=MODES.verified, status=passing_status, ) GeneratedCertificateFactory( user=self.bob, course_id=self.course_run_key, mode=MODES.verified, status=failing_status, ) call_command('backpopulate_program_credentials', commit=True) mock_task.assert_called_once_with(self.alice.username) @mock.patch(COMMAND_MODULE + '.logger.exception') def test_handle_enqueue_failure(self, mock_log, mock_task, mock_get_programs): """Verify that failure to enqueue a task doesn't halt execution.""" def side_effect(username): """Simulate failure to enqueue a task.""" if username == self.alice.username: raise Exception mock_task.side_effect = side_effect data = [ factories.Program(courses=[ factories.Course(course_runs=[ factories.CourseRun(key=self.course_run_key), ]), ]), ] mock_get_programs.return_value = data GeneratedCertificateFactory( user=self.alice, course_id=self.course_run_key, mode=MODES.verified, status=CertificateStatuses.downloadable, ) GeneratedCertificateFactory( user=self.bob, course_id=self.course_run_key, mode=MODES.verified, status=CertificateStatuses.downloadable, ) call_command('backpopulate_program_credentials', commit=True) self.assertTrue(mock_log.called) calls = [mock.call(self.alice.username), mock.call(self.bob.username)] mock_task.assert_has_calls(calls, any_order=True)