Merge pull request #11483 from edx/renzo/programs-task-fixes
Fixes for program certificate generation
This commit is contained in:
@@ -1625,6 +1625,12 @@ REQUIRE_JS_PATH_OVERRIDES = [
|
||||
]
|
||||
################################# CELERY ######################################
|
||||
|
||||
# Celery's task autodiscovery won't find tasks nested in a tasks package.
|
||||
# Tasks are only registered when the module they are defined in is imported.
|
||||
CELERY_IMPORTS = (
|
||||
'openedx.core.djangoapps.programs.tasks.v1.tasks',
|
||||
)
|
||||
|
||||
# Message configuration
|
||||
|
||||
CELERY_TASK_SERIALIZER = 'json'
|
||||
|
||||
@@ -8,3 +8,6 @@ if and only if the service is deployed in the Open edX installation.
|
||||
To ensure maximum separation of concerns, and a minimum of interdependencies,
|
||||
this package should be kept small, thin, and stateless.
|
||||
"""
|
||||
|
||||
# Register signal handlers
|
||||
from . import signals
|
||||
|
||||
@@ -49,7 +49,7 @@ def get_completed_courses(student):
|
||||
"""
|
||||
all_certs = get_certificates_for_user(student.username)
|
||||
return [
|
||||
{'course_id': cert['course_key'], 'mode': cert['type']}
|
||||
{'course_id': unicode(cert['course_key']), 'mode': cert['type']}
|
||||
for cert in all_certs
|
||||
if is_passing_status(cert['status'])
|
||||
]
|
||||
@@ -108,7 +108,11 @@ def award_program_certificate(client, username, program_id):
|
||||
None
|
||||
|
||||
"""
|
||||
client.user_credentials.post({'program_id': program_id, 'username': username})
|
||||
client.user_credentials.post({
|
||||
'username': username,
|
||||
'credential': {'program_id': program_id},
|
||||
'attributes': []
|
||||
})
|
||||
|
||||
|
||||
@task(bind=True, ignore_result=True)
|
||||
|
||||
@@ -109,7 +109,7 @@ class GetCompletedProgramsTestCase(TestCase):
|
||||
{'course_id': 'test-course-2', 'mode': 'prof-ed'},
|
||||
]
|
||||
result = tasks.get_completed_programs(test_client, payload)
|
||||
self.assertEqual(httpretty.last_request().body, json.dumps({'completed_courses': payload}))
|
||||
self.assertEqual(json.loads(httpretty.last_request().body), {'completed_courses': payload})
|
||||
self.assertEqual(result, [1, 2, 3])
|
||||
|
||||
|
||||
@@ -165,12 +165,20 @@ class AwardProgramCertificateTestCase(TestCase):
|
||||
"""
|
||||
test_username = 'test-username'
|
||||
test_client = EdxRestApiClient('http://test-server', jwt='test-token')
|
||||
|
||||
httpretty.register_uri(
|
||||
httpretty.POST,
|
||||
'http://test-server/user_credentials/',
|
||||
)
|
||||
|
||||
tasks.award_program_certificate(test_client, test_username, 123)
|
||||
self.assertEqual(httpretty.last_request().body, json.dumps({'program_id': 123, 'username': test_username}))
|
||||
|
||||
expected_body = {
|
||||
'username': test_username,
|
||||
'credential': {'program_id': 123},
|
||||
'attributes': []
|
||||
}
|
||||
self.assertEqual(json.loads(httpretty.last_request().body), expected_body)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import calendar
|
||||
import datetime
|
||||
|
||||
import ddt
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.test import TestCase
|
||||
@@ -16,6 +17,7 @@ from student.models import anonymous_id_for_user
|
||||
from student.tests.factories import UserFactory, UserProfileFactory
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TestIdTokenGeneration(TestCase):
|
||||
"""Tests covering ID token generation."""
|
||||
client_name = 'edx-dummy-client'
|
||||
@@ -24,15 +26,17 @@ class TestIdTokenGeneration(TestCase):
|
||||
super(TestIdTokenGeneration, self).setUp()
|
||||
|
||||
self.oauth2_client = ClientFactory(name=self.client_name, client_type=CONFIDENTIAL)
|
||||
self.user = UserFactory()
|
||||
|
||||
# Create a profile for the user
|
||||
self.user_profile = UserProfileFactory(user=self.user)
|
||||
self.user = UserFactory.build()
|
||||
self.user.save()
|
||||
|
||||
@override_settings(OAUTH_OIDC_ISSUER='test-issuer', OAUTH_ID_TOKEN_EXPIRATION=1)
|
||||
@freezegun.freeze_time('2015-01-01 12:00:00')
|
||||
def test_get_id_token(self):
|
||||
@ddt.data(True, False)
|
||||
def test_get_id_token(self, has_profile):
|
||||
"""Verify that ID tokens are signed with the correct secret and generated with the correct claims."""
|
||||
full_name = UserProfileFactory(user=self.user).name if has_profile else None
|
||||
|
||||
token = get_id_token(self.user, self.client_name)
|
||||
|
||||
payload = jwt.decode(
|
||||
@@ -47,7 +51,7 @@ class TestIdTokenGeneration(TestCase):
|
||||
|
||||
expected_payload = {
|
||||
'preferred_username': self.user.username,
|
||||
'name': self.user_profile.name,
|
||||
'name': full_name,
|
||||
'email': self.user.email,
|
||||
'administrator': self.user.is_staff,
|
||||
'iss': settings.OAUTH_OIDC_ISSUER,
|
||||
|
||||
@@ -41,13 +41,18 @@ def get_id_token(user, client_name):
|
||||
except Client.DoesNotExist:
|
||||
raise ImproperlyConfigured('OAuth2 Client with name [%s] does not exist' % client_name)
|
||||
|
||||
user_profile = UserProfile.objects.get(user=user)
|
||||
try:
|
||||
# Service users may not have user profiles.
|
||||
full_name = UserProfile.objects.get(user=user).name
|
||||
except UserProfile.DoesNotExist:
|
||||
full_name = None
|
||||
|
||||
now = datetime.datetime.utcnow()
|
||||
expires_in = getattr(settings, 'OAUTH_ID_TOKEN_EXPIRATION', 30)
|
||||
|
||||
payload = {
|
||||
'preferred_username': user.username,
|
||||
'name': user_profile.name,
|
||||
'name': full_name,
|
||||
'email': user.email,
|
||||
'administrator': user.is_staff,
|
||||
'iss': settings.OAUTH_OIDC_ISSUER,
|
||||
|
||||
Reference in New Issue
Block a user