fix: Handle missing user profile when setting a name in a course certificate (#28319)
MICROBA-1410
This commit is contained in:
@@ -52,7 +52,7 @@ def get_course_enrollment(user, course_run_key):
|
||||
|
||||
def get_phone_number(user_id):
|
||||
"""
|
||||
Get a users phone number from the profile, if
|
||||
Get a user's phone number from the profile, if
|
||||
one exists. Otherwise, return None.
|
||||
"""
|
||||
try:
|
||||
@@ -63,6 +63,18 @@ def get_phone_number(user_id):
|
||||
return student.phone_number or None
|
||||
|
||||
|
||||
def get_name(user_id):
|
||||
"""
|
||||
Get a user's name from their profile, if one exists. Otherwise, return None.
|
||||
"""
|
||||
try:
|
||||
student = _UserProfile.objects.get(user_id=user_id)
|
||||
except _UserProfile.DoesNotExist:
|
||||
log.exception(f'Could not find UserProfile for id {user_id}')
|
||||
return None
|
||||
return student.name or None
|
||||
|
||||
|
||||
def get_course_access_role(user, org, course_id, role):
|
||||
"""
|
||||
Get a specific CourseAccessRole object. Return None if
|
||||
|
||||
@@ -26,8 +26,10 @@ from common.djangoapps.student.models import (
|
||||
ManualEnrollmentAudit,
|
||||
PendingEmailChange,
|
||||
PendingNameChange,
|
||||
UserCelebration
|
||||
UserCelebration,
|
||||
UserProfile
|
||||
)
|
||||
from common.djangoapps.student.models_api import get_name
|
||||
from common.djangoapps.student.tests.factories import AccountRecoveryFactory, CourseEnrollmentFactory, UserFactory
|
||||
from lms.djangoapps.courseware.models import DynamicUpgradeDeadlineConfiguration
|
||||
from lms.djangoapps.courseware.toggles import (
|
||||
@@ -728,3 +730,30 @@ class TestUserPostSaveCallback(SharedModuleStoreTestCase):
|
||||
course_enrollment.save()
|
||||
|
||||
return user
|
||||
|
||||
|
||||
class TestProfile(SharedModuleStoreTestCase):
|
||||
"""
|
||||
Tests for the user profile
|
||||
"""
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.user = UserFactory.create()
|
||||
self.profile = UserProfile.objects.get(user_id=self.user.id)
|
||||
self.name = self.profile.name
|
||||
self.course = CourseFactory.create()
|
||||
|
||||
def test_name(self):
|
||||
"""
|
||||
Test retrieval of the name
|
||||
"""
|
||||
assert self.name
|
||||
name = get_name(self.user.id)
|
||||
assert name == self.name
|
||||
|
||||
def test_name_missing_profile(self):
|
||||
"""
|
||||
Test retrieval of the name when the user profile doesn't exist
|
||||
"""
|
||||
name = get_name(None)
|
||||
assert not name
|
||||
|
||||
@@ -10,7 +10,7 @@ These methods should be called from tasks.
|
||||
import logging
|
||||
from uuid import uuid4
|
||||
|
||||
from common.djangoapps.student.models import UserProfile
|
||||
from common.djangoapps.student import models_api as student_api
|
||||
from lms.djangoapps.certificates.data import CertificateStatuses
|
||||
from lms.djangoapps.certificates.models import GeneratedCertificate
|
||||
from lms.djangoapps.certificates.utils import emit_certificate_event
|
||||
@@ -66,8 +66,9 @@ def _generate_certificate(user, course_key, status, enrollment_mode, course_grad
|
||||
# Retrieve the existing certificate for the learner if it exists
|
||||
existing_certificate = GeneratedCertificate.certificate_for_student(user, course_key)
|
||||
|
||||
profile = UserProfile.objects.get(user=user)
|
||||
profile_name = profile.name
|
||||
profile_name = student_api.get_name(user.id)
|
||||
if not profile_name:
|
||||
profile_name = ''
|
||||
|
||||
# Retain the `verify_uuid` from an existing certificate if possible, this will make it possible for the learner to
|
||||
# keep the existing URL to their certificate
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
Tests for certificate generation
|
||||
"""
|
||||
import logging
|
||||
from unittest import mock
|
||||
|
||||
from common.djangoapps.course_modes.models import CourseMode
|
||||
from common.djangoapps.student.models import UserProfile
|
||||
from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory
|
||||
from common.djangoapps.util.testing import EventTestMixin
|
||||
from lms.djangoapps.certificates.data import CertificateStatuses
|
||||
@@ -15,6 +17,8 @@ from xmodule.modulestore.tests.factories import CourseFactory
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
PROFILE_NAME_METHOD = 'common.djangoapps.student.models_api.get_name'
|
||||
|
||||
|
||||
class CertificateTests(EventTestMixin, ModuleStoreTestCase):
|
||||
"""
|
||||
@@ -26,6 +30,8 @@ class CertificateTests(EventTestMixin, ModuleStoreTestCase):
|
||||
|
||||
# Create user, a course run, and an enrollment
|
||||
self.u = UserFactory()
|
||||
self.profile = UserProfile.objects.get(user_id=self.u.id)
|
||||
self.name = self.profile.name
|
||||
self.cr = CourseFactory()
|
||||
self.key = self.cr.id # pylint: disable=no-member
|
||||
CourseEnrollmentFactory(
|
||||
@@ -65,6 +71,7 @@ class CertificateTests(EventTestMixin, ModuleStoreTestCase):
|
||||
assert cert.status == CertificateStatuses.downloadable
|
||||
assert cert.mode == self.enrollment_mode
|
||||
assert cert.grade == self.grade
|
||||
assert cert.name == self.name
|
||||
|
||||
def test_generation_existing_unverified(self):
|
||||
"""
|
||||
@@ -159,3 +166,24 @@ class CertificateTests(EventTestMixin, ModuleStoreTestCase):
|
||||
self.enrollment_mode, self.grade, self.gen_mode)
|
||||
assert generated_cert.status, CertificateStatuses.downloadable
|
||||
assert generated_cert.verify_uuid != ''
|
||||
|
||||
def test_generation_missing_profile(self):
|
||||
"""
|
||||
Test certificate generation when the user profile is missing
|
||||
"""
|
||||
GeneratedCertificateFactory(
|
||||
user=self.u,
|
||||
course_id=self.key,
|
||||
mode=CourseMode.AUDIT,
|
||||
status=CertificateStatuses.unverified
|
||||
)
|
||||
|
||||
with mock.patch(PROFILE_NAME_METHOD, return_value=None):
|
||||
generate_course_certificate(self.u, self.key, CertificateStatuses.downloadable, self.enrollment_mode,
|
||||
self.grade, self.gen_mode)
|
||||
|
||||
cert = GeneratedCertificate.objects.get(user=self.u, course_id=self.key)
|
||||
assert cert.status == CertificateStatuses.downloadable
|
||||
assert cert.mode == self.enrollment_mode
|
||||
assert cert.grade == self.grade
|
||||
assert cert.name == ''
|
||||
|
||||
Reference in New Issue
Block a user