def setUp(self): super(AwardProgramCertificatesTestCase, self).setUp() self.create_credentials_config() self.student = UserFactory.create(username='******') self.catalog_integration = self.create_catalog_integration() ClientFactory.create(name='credentials') UserFactory.create(username=settings.CREDENTIALS_SERVICE_USERNAME) # pylint: disable=no-member
def setUp(self): super(AwardProgramCertificatesTestCase, self).setUp() self.create_programs_config() self.create_credentials_config() self.student = UserFactory.create(username="******") ClientFactory.create(name="programs") ClientFactory.create(name="credentials") UserFactory.create(username=settings.CREDENTIALS_SERVICE_USERNAME) # pylint: disable=no-member
def test_get_api_client(self, mock_get_id_token): """ Ensure the function is making the right API calls based on inputs """ student = UserFactory() ClientFactory.create(name="programs") api_config = self.create_programs_config(internal_service_url="http://foo", api_version_number=99) mock_get_id_token.return_value = "test-token" api_client = tasks.get_api_client(api_config, student) self.assertEqual(mock_get_id_token.call_args[0], (student, "programs")) self.assertEqual(api_client._store["base_url"], "http://foo/api/v99/") # pylint: disable=protected-access self.assertEqual(api_client._store["session"].auth.token, "test-token") # pylint: disable=protected-access
def test_get_api_client(self, mock_build_token): """ Ensure the function is making the right API calls based on inputs """ student = UserFactory() ClientFactory.create(name='credentials') api_config = self.create_credentials_config() mock_build_token.return_value = 'test-token' api_client = tasks.get_api_client(api_config, student) expected = CREDENTIALS_INTERNAL_SERVICE_URL.strip('/') + '/api/v2/' self.assertEqual(api_client._store['base_url'], expected) # pylint: disable=protected-access self.assertEqual(api_client._store['session'].auth.token, 'test-token') # pylint: disable=protected-access
def test_get_api_client(self, mock_build_token): """ Ensure the function is making the right API calls based on inputs """ student = UserFactory() ClientFactory.create(name='credentials') api_config = self.create_credentials_config( internal_service_url='http://foo' ) mock_build_token.return_value = 'test-token' api_client = tasks.get_api_client(api_config, student) self.assertEqual(api_client._store['base_url'], 'http://foo/api/v2/') # pylint: disable=protected-access self.assertEqual(api_client._store['session'].auth.token, 'test-token') # pylint: disable=protected-access
def setUp(self): super(TestProgramProgressMeter, self).setUp() self.user = UserFactory() self.create_programs_config() ClientFactory(name=ProgramsApiConfig.OAUTH2_CLIENT_NAME, client_type=CONFIDENTIAL)
def setUp(self): super(TestIdTokenGeneration, self).setUp() self.oauth2_client = ClientFactory(name=self.client_name, client_type=CONFIDENTIAL) self.user = UserFactory.build() self.user.save()
def test_get_api_client(self, mock_get_id_token): """ Ensure the function is making the right API calls based on inputs """ student = UserFactory() ClientFactory.create(name='programs') api_config = self.create_programs_config( internal_service_url='http://foo', api_version_number=99, ) mock_get_id_token.return_value = 'test-token' api_client = tasks.get_api_client(api_config, student) self.assertEqual(mock_get_id_token.call_args[0], (student, 'programs')) self.assertEqual(api_client._store['base_url'], 'http://foo/api/v99/') # pylint: disable=protected-access self.assertEqual(api_client._store['session'].auth.token, 'test-token') # pylint: disable=protected-access
def setUp(self): super(TestGetCredentials, self).setUp() ClientFactory(name=CredentialsApiConfig.OAUTH2_CLIENT_NAME, client_type=CONFIDENTIAL) self.credentials_config = self.create_credentials_config(cache_ttl=1) self.user = UserFactory()
def setUpClass(cls): super(TestProgramListing, cls).setUpClass() for name in [ ProgramsApiConfig.OAUTH2_CLIENT_NAME, CredentialsApiConfig.OAUTH2_CLIENT_NAME ]: ClientFactory(name=name, client_type=CONFIDENTIAL) cls.course = CourseFactory() organization = programs_factories.Organization() run_mode = programs_factories.RunMode(course_key=unicode( cls.course.id)) # pylint: disable=no-member course_code = programs_factories.CourseCode(run_modes=[run_mode]) cls.first_program = programs_factories.Program( organizations=[organization], course_codes=[course_code]) cls.second_program = programs_factories.Program( organizations=[organization], course_codes=[course_code]) cls.data = sorted([cls.first_program, cls.second_program], key=cls.program_sort_key) cls.marketing_root = urljoin(settings.MKTG_URLS.get('ROOT'), 'xseries').rstrip('/')
def test_oauth(self): """ Verify the endpoint supports authentication via OAuth 2.0. """ access_token = AccessTokenFactory(user=self.user, client=ClientFactory()).token headers = {'HTTP_AUTHORIZATION': 'Bearer ' + access_token} self.client.logout() response = self.client.get(self.path, **headers) self.assertEqual(response.status_code, 200)
def setUp(self): super(CatalogTest, self).setUp() password = '******' self.user = UserFactory(password=password, is_staff=True) self.client.login(username=self.user.username, password=password) ClientFactory(user=self.user, name='course-discovery', url=MOCK_CATALOG_API_URL_ROOT)
def _create_dop_tokens(self, user=None): """Create dop access token for given user if user provided else for default user.""" if not user: user = User.objects.get(email=self.OLD_EMAIL) client = ClientFactory() access_token = AccessTokenFactory(user=user, client=client) RefreshTokenFactory(user=user, client=client, access_token=access_token)
def setUp(self): super(TestProgramRetrieval, self).setUp() ClientFactory(name=ProgramsApiConfig.OAUTH2_CLIENT_NAME, client_type=CONFIDENTIAL) self.user = UserFactory() cache.clear()
def setUp(self): """ Add a student """ super(TestProgramListing, self).setUp() ClientFactory(name=ProgramsApiConfig.OAUTH2_CLIENT_NAME, client_type=CONFIDENTIAL) self.student = UserFactory() self.create_programs_config(xseries_ad_enabled=True, program_listing_enabled=True)
def setUp(self): super(GetCompletedProgramsTestCase, self).setUp() self.user = UserFactory() self.programs_config = self.create_programs_config(cache_ttl=5) ClientFactory(name=self.programs_config.OAUTH2_CLIENT_NAME, client_type=CONFIDENTIAL) cache.clear()
def test_api_client_not_provided(self): """Verify that an API client doesn't need to be provided.""" ClientFactory(name=CredentialsApiConfig.OAUTH2_CLIENT_NAME, client_type=CONFIDENTIAL) credentials_api_config = self.create_credentials_config() with mock.patch('openedx.core.lib.edx_api_utils.EdxRestApiClient.__init__') as mock_init: get_edx_api_data(credentials_api_config, self.user, 'credentials') self.assertTrue(mock_init.called)
def test_oauth(self): """Verify that the endpoint supports OAuth 2.0.""" access_token = AccessTokenFactory(user=self.user, client=ClientFactory()).token # pylint: disable=no-member self.headers['HTTP_AUTHORIZATION'] = 'Bearer ' + access_token self.client.logout() self._verify_response(200)
def setUp(self): super(TestCredentialsRetrieval, self).setUp() ClientFactory(name=CredentialsApiConfig.OAUTH2_CLIENT_NAME, client_type=CONFIDENTIAL) self.user = UserFactory() self.primary_uuid = str(uuid.uuid4()) self.alternate_uuid = str(uuid.uuid4()) cache.clear()
def setUp(self): super(EdxNotesDecoratorTest, self).setUp() ClientFactory(name="edx-notes") # Using old mongo because of locator comparison issues (see longer # note below in EdxNotesHelpersTest setUp. self.course = CourseFactory(edxnotes=True, default_store=ModuleStoreEnum.Type.mongo) self.user = UserFactory() self.client.login(username=self.user.username, password=UserFactory._DEFAULT_PASSWORD) self.problem = TestProblem(self.course, self.user)
def setUp(self): super(TestProgramListing, self).setUp() ClientFactory(name=ProgramsApiConfig.OAUTH2_CLIENT_NAME, client_type=CONFIDENTIAL) self.staff = UserFactory(is_staff=True) self.client.login(username=self.staff.username, password='******') self.studio_home = reverse('home')
def setUp(self): super(AwardCourseCertificatesTestCase, self).setUp() self.course = CourseOverviewFactory.create( self_paced=True # Any option to allow the certificate to be viewable for the course ) self.student = UserFactory.create(username='******') # Instantiate the Certificate first so that the config doesn't execute issuance self.certificate = GeneratedCertificateFactory.create( user=self.student, mode='verified', course_id=self.course.id, status='downloadable' ) self.create_credentials_config() self.site = SiteFactory() ClientFactory.create(name='credentials') UserFactory.create(username=settings.CREDENTIALS_SERVICE_USERNAME)
def setUp(self): ClientFactory(name="edx-notes") super(EdxNotesViewsTest, self).setUp() self.course = CourseFactory.create(edxnotes=True) self.user = UserFactory.create(username="******", email="*****@*****.**", password="******") CourseEnrollmentFactory.create(user=self.user, course_id=self.course.id) self.client.login(username=self.user.username, password="******") self.notes_page_url = reverse("edxnotes", args=[unicode(self.course.id)]) self.notes_url = reverse("notes", args=[unicode(self.course.id)]) self.get_token_url = reverse("get_token", args=[unicode(self.course.id)]) self.visibility_url = reverse("edxnotes_visibility", args=[unicode(self.course.id)])
def setUp(self): ClientFactory(name="edx-notes") super(EdxNotesViewsTest, self).setUp() self.course = CourseFactory(edxnotes=True) self.user = UserFactory() CourseEnrollmentFactory(user=self.user, course_id=self.course.id) self.client.login(username=self.user.username, password=UserFactory._DEFAULT_PASSWORD) self.notes_page_url = reverse("edxnotes", args=[unicode(self.course.id)]) self.notes_url = reverse("notes", args=[unicode(self.course.id)]) self.get_token_url = reverse("get_token", args=[unicode(self.course.id)]) self.visibility_url = reverse("edxnotes_visibility", args=[unicode(self.course.id)])
def setUp(self): super(BackpopulateProgramCredentialsTests, self).setUp() self.alice = UserFactory() self.bob = UserFactory() self.oauth2_user = UserFactory() self.oauth2_client = ClientFactory(name=ProgramsApiConfig.OAUTH2_CLIENT_NAME, client_type=CONFIDENTIAL) # 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_programs_config(enable_certification=False)
def setUpClass(cls): super(TestProgramDetails, cls).setUpClass() ClientFactory(name=ProgramsApiConfig.OAUTH2_CLIENT_NAME, client_type=CONFIDENTIAL) course = CourseFactory() organization = programs_factories.Organization() run_mode = programs_factories.RunMode(course_key=unicode(course.id)) # pylint: disable=no-member course_code = programs_factories.CourseCode(run_modes=[run_mode]) cls.data = programs_factories.Program(organizations=[organization], course_codes=[course_code])
def test_config_enabled(self, mock_build_token): """ Ensure the endpoint responds with a valid JSON payload when authoring is enabled. """ mock_build_token.return_value = 'test-id-token' ClientFactory(name=ProgramsApiConfig.OAUTH2_CLIENT_NAME, client_type=CONFIDENTIAL) self.create_programs_config() response = self.client.get(self.path) self.assertEqual(response.status_code, 200) payload = json.loads(response.content) self.assertEqual(payload, {'id_token': 'test-id-token'})
def test_reset_password_email(self, body_type, expected_output): """Tests contents of reset password email, and that user is not active""" good_req = self.request_factory.post('/password_reset/', {'email': self.user.email}) good_req.user = self.user good_req.site = Mock(domain='example.com') dop_client = ClientFactory() dop_access_token = AccessTokenFactory(user=self.user, client=dop_client) RefreshTokenFactory(user=self.user, client=dop_client, access_token=dop_access_token) dot_application = dot_factories.ApplicationFactory(user=self.user) dot_access_token = dot_factories.AccessTokenFactory(user=self.user, application=dot_application) dot_factories.RefreshTokenFactory(user=self.user, application=dot_application, access_token=dot_access_token) good_resp = password_reset(good_req) self.assertEquals(good_resp.status_code, 200) self.assertFalse(dop_models.AccessToken.objects.filter(user=self.user).exists()) self.assertFalse(dop_models.RefreshToken.objects.filter(user=self.user).exists()) self.assertFalse(dot_models.AccessToken.objects.filter(user=self.user).exists()) self.assertFalse(dot_models.RefreshToken.objects.filter(user=self.user).exists()) obj = json.loads(good_resp.content.decode('utf-8')) self.assertTrue(obj['success']) self.assertIn('e-mailed you instructions for setting your password', obj['value']) from_email = configuration_helpers.get_value('email_from_address', settings.DEFAULT_FROM_EMAIL) sent_message = mail.outbox[0] bodies = { 'plain_text': sent_message.body, 'html': sent_message.alternatives[0][0], } body = bodies[body_type] self.assertIn("Password reset", sent_message.subject) self.assertIn(expected_output, body) self.assertEquals(sent_message.from_email, from_email) self.assertEquals(len(sent_message.to), 1) self.assertIn(self.user.email, sent_message.to) self.assert_event_emitted( SETTING_CHANGE_INITIATED, user_id=self.user.id, setting=u'password', old=None, new=None, ) # Test that the user is not active self.user = User.objects.get(pk=self.user.pk) self.assertFalse(self.user.is_active) self.assertIn('password_reset_confirm/', body) re.search(r'password_reset_confirm/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/', body).groupdict()
def setUp(self): super(TestProgramDetails, self).setUp() self.details_page = reverse('program_details_view', args=[self.program_id]) self.user = UserFactory() self.client.login(username=self.user.username, password=self.password) ClientFactory(name=ProgramsApiConfig.OAUTH2_CLIENT_NAME, client_type=CONFIDENTIAL) self.organization = factories.Organization() self.run_mode = factories.RunMode(course_key=unicode(self.course.id)) # pylint: disable=no-member self.course_code = factories.CourseCode(run_modes=[self.run_mode]) self.data = factories.Program(organizations=[self.organization], course_codes=[self.course_code])
def test_oauth(self): """ Verify the endpoint supports OAuth, and only allows authorization for staff users. """ user = UserFactory(is_staff=False) oauth_client = ClientFactory.create() access_token = AccessTokenFactory.create(user=user, client=oauth_client).token headers = {'HTTP_AUTHORIZATION': 'Bearer ' + access_token} # Non-staff users should not have access to the API response = self.client.get(self.path, **headers) self.assertEqual(response.status_code, 403) # Staff users should have access to the API user.is_staff = True user.save() response = self.client.get(self.path, **headers) self.assertEqual(response.status_code, 200)
def setUpClass(cls): super(RelatedProgramsTests, cls).setUpClass() cls.user = UserFactory() cls.course = CourseFactory() cls.enrollment = CourseEnrollmentFactory(user=cls.user, course_id=cls.course.id) # pylint: disable=no-member ClientFactory(name=ProgramsApiConfig.OAUTH2_CLIENT_NAME, client_type=CONFIDENTIAL) cls.organization = programs_factories.Organization() run_mode = programs_factories.RunMode(course_key=unicode(cls.course.id)) # pylint: disable=no-member course_code = programs_factories.CourseCode(run_modes=[run_mode]) cls.programs = [ programs_factories.Program( organizations=[cls.organization], course_codes=[course_code] ) for __ in range(2) ]
def test_oauth(self): """ Verify the endpoint supports OAuth, and only allows authorization for staff users. """ user = UserFactory(is_staff=False) oauth_client = ClientFactory.create() access_token = AccessTokenFactory.create(user=user, client=oauth_client).token headers = { 'HTTP_AUTHORIZATION': 'Bearer ' + access_token } # Non-staff users should not have access to the API response = self.client.get(self.path, **headers) self.assertEqual(response.status_code, 403) # Staff users should have access to the API user.is_staff = True user.save() response = self.client.get(self.path, **headers) self.assertEqual(response.status_code, 200)
def setUp(self): """ Setup a dummy course content. """ super(EdxNotesHelpersTest, self).setUp() # There are many tests that are comparing locators as returned from helper methods. When using # the split modulestore, some of those locators have version and branch information, but the # comparison values do not. This needs further investigation in order to enable these tests # with the split modulestore. with self.store.default_store(ModuleStoreEnum.Type.mongo): ClientFactory(name="edx-notes") self.course = CourseFactory.create() self.chapter = ItemFactory.create(category="chapter", parent_location=self.course.location) self.chapter_2 = ItemFactory.create(category="chapter", parent_location=self.course.location) self.sequential = ItemFactory.create(category="sequential", parent_location=self.chapter.location) self.vertical = ItemFactory.create(category="vertical", parent_location=self.sequential.location) self.html_module_1 = ItemFactory.create(category="html", parent_location=self.vertical.location) self.html_module_2 = ItemFactory.create(category="html", parent_location=self.vertical.location) self.vertical_with_container = ItemFactory.create( category='vertical', parent_location=self.sequential.location ) self.child_container = ItemFactory.create( category='split_test', parent_location=self.vertical_with_container.location) self.child_vertical = ItemFactory.create(category='vertical', parent_location=self.child_container.location) self.child_html_module = ItemFactory.create(category="html", parent_location=self.child_vertical.location) # Read again so that children lists are accurate self.course = self.store.get_item(self.course.location) self.chapter = self.store.get_item(self.chapter.location) self.chapter_2 = self.store.get_item(self.chapter_2.location) self.sequential = self.store.get_item(self.sequential.location) self.vertical = self.store.get_item(self.vertical.location) self.vertical_with_container = self.store.get_item(self.vertical_with_container.location) self.child_container = self.store.get_item(self.child_container.location) self.child_vertical = self.store.get_item(self.child_vertical.location) self.child_html_module = self.store.get_item(self.child_html_module.location) self.user = UserFactory() self.client.login(username=self.user.username, password=UserFactory._DEFAULT_PASSWORD) self.request = RequestFactory().request() self.request.user = self.user
def setUp(self): super(TestSupplementProgramData, self).setUp() self.user = UserFactory() self.client.login(username=self.user.username, password=self.password) ClientFactory(name=ProgramsApiConfig.OAUTH2_CLIENT_NAME, client_type=CONFIDENTIAL) self.course = CourseFactory() self.course.start = timezone.now() - datetime.timedelta(days=1) self.course.end = timezone.now() + datetime.timedelta(days=1) self.course = self.update_course(self.course, self.user.id) # pylint: disable=no-member self.organization = factories.Organization() self.run_mode = factories.RunMode(course_key=unicode(self.course.id)) # pylint: disable=no-member self.course_code = factories.CourseCode(run_modes=[self.run_mode]) self.program = factories.Program(organizations=[self.organization], course_codes=[self.course_code])
def test_oauth_csv(self): """ Verify the endpoint supports OAuth, and only allows authorization for staff users. """ cohorts.add_cohort(self.course_key, "DEFAULT", "random") path = reverse('api_cohorts:cohort_users_csv', kwargs={'course_key_string': self.course_str}) user = UserFactory(is_staff=False) oauth_client = ClientFactory.create() access_token = AccessTokenFactory.create(user=user, client=oauth_client).token headers = {'HTTP_AUTHORIZATION': 'Bearer ' + access_token} # Non-staff users should not have access to the API response = self.client.post(path=path, **headers) self.assertEqual(response.status_code, 403) # Staff users should have access to the API user.is_staff = True user.save() response = self.client.post(path=path, **headers) self.assertEqual(response.status_code, 400)
def test_oauth_csv(self): """ Verify the endpoint supports OAuth, and only allows authorization for staff users. """ cohorts.add_cohort(self.course_key, "DEFAULT", "random") path = reverse('api_cohorts:cohort_users_csv', kwargs={'course_key_string': self.course_str}) user = UserFactory(is_staff=False) oauth_client = ClientFactory.create() access_token = AccessTokenFactory.create(user=user, client=oauth_client).token headers = { 'HTTP_AUTHORIZATION': 'Bearer ' + access_token } # Non-staff users should not have access to the API response = self.client.post(path=path, **headers) self.assertEqual(response.status_code, 403) # Staff users should have access to the API user.is_staff = True user.save() response = self.client.post(path=path, **headers) self.assertEqual(response.status_code, 400)
def test_access_token(self): """ Verify the client credentials grant can be used to obtain an access token whose default scopes allow access to the user info endpoint. """ oauth_client = ClientFactory(user=self.user) data = { 'grant_type': 'client_credentials', 'client_id': oauth_client.client_id, 'client_secret': oauth_client.client_secret } response = self.client.post(reverse('oauth2:access_token'), data) self.assertEqual(response.status_code, 200) access_token = json.loads(response.content)['access_token'] expected = AccessToken.objects.filter(client=oauth_client, user=self.user).first().token self.assertEqual(access_token, expected) headers = {'HTTP_AUTHORIZATION': 'Bearer ' + access_token} response = self.client.get(reverse('oauth2:user_info'), **headers) self.assertEqual(response.status_code, 200)
def test_reset_password_email(self, send_email): """ Tests contents of reset password email, and that user is not active """ good_req = self.request_factory.post('/password_reset/', {'email': self.user.email}) good_req.user = self.user dop_client = ClientFactory() dop_access_token = AccessTokenFactory(user=self.user, client=dop_client) RefreshTokenFactory(user=self.user, client=dop_client, access_token=dop_access_token) dot_application = dot_factories.ApplicationFactory(user=self.user) dot_access_token = dot_factories.AccessTokenFactory(user=self.user, application=dot_application) dot_factories.RefreshTokenFactory(user=self.user, application=dot_application, access_token=dot_access_token) good_resp = password_reset(good_req) self.assertEquals(good_resp.status_code, 200) self.assertFalse(dop_models.AccessToken.objects.filter(user=self.user).exists()) self.assertFalse(dop_models.RefreshToken.objects.filter(user=self.user).exists()) self.assertFalse(dot_models.AccessToken.objects.filter(user=self.user).exists()) self.assertFalse(dot_models.RefreshToken.objects.filter(user=self.user).exists()) obj = json.loads(good_resp.content) self.assertEquals(obj, { 'success': True, 'value': "('registration/password_reset_done.html', [])", }) (subject, msg, from_addr, to_addrs) = send_email.call_args[0] self.assertIn("Password reset", subject) self.assertIn("You're receiving this e-mail because you requested a password reset", msg) self.assertEquals(from_addr, configuration_helpers.get_value('email_from_address', settings.DEFAULT_FROM_EMAIL)) self.assertEquals(len(to_addrs), 1) self.assertIn(self.user.email, to_addrs) self.assert_event_emitted( SETTING_CHANGE_INITIATED, user_id=self.user.id, setting=u'password', old=None, new=None, ) #test that the user is not active self.user = User.objects.get(pk=self.user.pk) self.assertFalse(self.user.is_active) re.search(r'password_reset_confirm/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/', msg).groupdict()
class BackpopulateProgramCredentialsTests(ProgramsApiConfigMixin, TestCase): """Tests for the backpopulate_program_credentials management command.""" course_id, alternate_course_id = 'org/course/run', 'org/alternate/run' def setUp(self): super(BackpopulateProgramCredentialsTests, self).setUp() self.alice = UserFactory() self.bob = UserFactory() self.oauth2_user = UserFactory() self.oauth2_client = ClientFactory(name=ProgramsApiConfig.OAUTH2_CLIENT_NAME, client_type=CONFIDENTIAL) # 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_programs_config(enable_certification=False) def _link_oauth2_user(self): """Helper to link user and OAuth2 client.""" self.oauth2_client.user = self.oauth2_user self.oauth2_client.save() # pylint: disable=no-member def _mock_programs_api(self, data): """Helper for mocking out Programs API URLs.""" self.assertTrue(httpretty.is_enabled(), msg='httpretty must be enabled to mock Programs API calls.') url = ProgramsApiConfig.current().internal_api_url.strip('/') + '/programs/' body = json.dumps({'results': data}) httpretty.register_uri(httpretty.GET, url, body=body, content_type='application/json') @ddt.data(True, False) def test_handle(self, commit, mock_task): """Verify that relevant tasks are only enqueued when the commit option is passed.""" data = [ factories.Program( organizations=[factories.Organization()], course_codes=[ factories.CourseCode(run_modes=[ factories.RunMode(course_key=self.course_id), ]), ] ), ] self._mock_programs_api(data) self._link_oauth2_user() GeneratedCertificateFactory( user=self.alice, course_id=self.course_id, mode=MODES.verified, status=CertificateStatuses.downloadable, ) GeneratedCertificateFactory( user=self.bob, course_id=self.alternate_course_id, 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( organizations=[factories.Organization()], course_codes=[ factories.CourseCode(run_modes=[ factories.RunMode(course_key=course_id), ]), ] ), factories.Program( organizations=[factories.Organization()], course_codes=[ factories.CourseCode(run_modes=[ factories.RunMode(course_key=alternate_course_id), ]), ] ), ], [ factories.Program( organizations=[factories.Organization()], course_codes=[ factories.CourseCode(run_modes=[ factories.RunMode(course_key=course_id), ]), factories.CourseCode(run_modes=[ factories.RunMode(course_key=alternate_course_id), ]), ] ), ], [ factories.Program( organizations=[factories.Organization()], course_codes=[ factories.CourseCode(run_modes=[ factories.RunMode(course_key=course_id), factories.RunMode(course_key=alternate_course_id), ]), ] ), ], ) def test_handle_flatten(self, data, mock_task): """Verify that program structures are flattened correctly.""" self._mock_programs_api(data) self._link_oauth2_user() GeneratedCertificateFactory( user=self.alice, course_id=self.course_id, mode=MODES.verified, status=CertificateStatuses.downloadable, ) GeneratedCertificateFactory( user=self.bob, course_id=self.alternate_course_id, 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): """Verify that only one task is enqueued for a user with multiple eligible certs.""" data = [ factories.Program( organizations=[factories.Organization()], course_codes=[ factories.CourseCode(run_modes=[ factories.RunMode(course_key=self.course_id), factories.RunMode(course_key=self.alternate_course_id), ]), ] ), ] self._mock_programs_api(data) self._link_oauth2_user() GeneratedCertificateFactory( user=self.alice, course_id=self.course_id, mode=MODES.verified, status=CertificateStatuses.downloadable, ) GeneratedCertificateFactory( user=self.alice, course_id=self.alternate_course_id, 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): """Verify that mode slugs are taken into account.""" data = [ factories.Program( organizations=[factories.Organization()], course_codes=[ factories.CourseCode(run_modes=[ factories.RunMode( course_key=self.course_id, mode_slug=MODES.honor ), ]), ] ), ] self._mock_programs_api(data) self._link_oauth2_user() GeneratedCertificateFactory( user=self.alice, course_id=self.course_id, status=CertificateStatuses.downloadable, ) GeneratedCertificateFactory( user=self.bob, course_id=self.course_id, 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): """Verify that only certificates with a passing status are selected.""" data = [ factories.Program( organizations=[factories.Organization()], course_codes=[ factories.CourseCode(run_modes=[ factories.RunMode(course_key=self.course_id), factories.RunMode(course_key=self.alternate_course_id), ]), ] ), ] self._mock_programs_api(data) self._link_oauth2_user() 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_id, mode=MODES.verified, status=passing_status, ) # The alternate course is used here to verify that the status and run_mode # queries are being ANDed together correctly. GeneratedCertificateFactory( user=self.bob, course_id=self.alternate_course_id, mode=MODES.verified, status=failing_status, ) call_command('backpopulate_program_credentials', commit=True) mock_task.assert_called_once_with(self.alice.username) def test_handle_unlinked_oauth2_user(self, mock_task): """Verify that the command fails when no user is associated with the OAuth2 client.""" data = [ factories.Program( organizations=[factories.Organization()], course_codes=[ factories.CourseCode(run_modes=[ factories.RunMode(course_key=self.course_id), ]), ] ), ] self._mock_programs_api(data) GeneratedCertificateFactory( user=self.alice, course_id=self.course_id, mode=MODES.verified, status=CertificateStatuses.downloadable, ) with self.assertRaises(CommandError): call_command('backpopulate_program_credentials') mock_task.assert_not_called() @mock.patch(COMMAND_MODULE + '.logger.exception') def test_handle_enqueue_failure(self, mock_log, mock_task): """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( organizations=[factories.Organization()], course_codes=[ factories.CourseCode(run_modes=[ factories.RunMode(course_key=self.course_id), ]), ] ), ] self._mock_programs_api(data) self._link_oauth2_user() GeneratedCertificateFactory( user=self.alice, course_id=self.course_id, mode=MODES.verified, status=CertificateStatuses.downloadable, ) GeneratedCertificateFactory( user=self.bob, course_id=self.course_id, 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 create_user_and_access_token(self): self.create_user() self.oauth_client = ClientFactory.create() self.access_token = AccessTokenFactory.create(user=self.user, client=self.oauth_client).token
def create_user_and_access_token(self): # pylint: disable=missing-docstring self.user = GlobalStaffFactory.create() self.oauth_client = ClientFactory.create() self.access_token = AccessTokenFactory.create(user=self.user, client=self.oauth_client).token