Merge pull request #28470 from edx/ork/MICROBA-1423_send-date-override
feat: Send date override to credentials
This commit is contained in:
@@ -1239,3 +1239,31 @@ class CertificateDateOverride(TimeStampedModel):
|
||||
def __str__(self):
|
||||
return "Certificate %s, date overridden to %s by %s on %s." % \
|
||||
(self.generated_certificate, self.date, self.overridden_by, self.created)
|
||||
|
||||
def save(self, *args, **kwargs): # pylint: disable=signature-differs
|
||||
"""
|
||||
After the base save() method finishes, fire the COURSE_CERT_CHANGED
|
||||
signal.
|
||||
"""
|
||||
super().save(*args, **kwargs)
|
||||
COURSE_CERT_CHANGED.send_robust(
|
||||
sender=self.__class__,
|
||||
user=self.generated_certificate.user,
|
||||
course_key=self.generated_certificate.course_id,
|
||||
mode=self.generated_certificate.mode,
|
||||
status=self.generated_certificate.status,
|
||||
)
|
||||
|
||||
def delete(self, *args, **kwargs): # pylint: disable=signature-differs
|
||||
"""
|
||||
After the base delete() method finishes, fire the COURSE_CERT_CHANGED
|
||||
signal.
|
||||
"""
|
||||
super().delete(*args, **kwargs)
|
||||
COURSE_CERT_CHANGED.send_robust(
|
||||
sender=self.__class__,
|
||||
user=self.generated_certificate.user,
|
||||
course_key=self.generated_certificate.course_id,
|
||||
mode=self.generated_certificate.mode,
|
||||
status=self.generated_certificate.status,
|
||||
)
|
||||
|
||||
@@ -9,6 +9,7 @@ from celery.utils.log import get_task_logger
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user
|
||||
from django.contrib.sites.models import Site
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from edx_django_utils.monitoring import set_code_owner_attribute
|
||||
from edx_rest_api_client import exceptions
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
@@ -293,7 +294,7 @@ def post_course_certificate_configuration(client, cert_config, certificate_avail
|
||||
})
|
||||
|
||||
|
||||
def post_course_certificate(client, username, certificate, visible_date):
|
||||
def post_course_certificate(client, username, certificate, visible_date, date_override=None):
|
||||
"""
|
||||
POST a certificate that has been updated to Credentials
|
||||
"""
|
||||
@@ -305,6 +306,7 @@ def post_course_certificate(client, username, certificate, visible_date):
|
||||
'mode': certificate.mode,
|
||||
'type': COURSE_CERTIFICATE,
|
||||
},
|
||||
'date_override': date_override.strftime(VISIBLE_DATE_FORMAT) if date_override else None,
|
||||
'attributes': [
|
||||
{
|
||||
'name': 'visible_date',
|
||||
@@ -458,7 +460,19 @@ def award_course_certificate(self, username, course_run_key, certificate_availab
|
||||
"Task award_course_certificate will award certificate for course "
|
||||
f"{course_key} with a visible date of {visible_date}"
|
||||
)
|
||||
post_course_certificate(credentials_client, username, certificate, visible_date)
|
||||
|
||||
# If the certificate has an associated CertificateDateOverride, send
|
||||
# it along
|
||||
try:
|
||||
date_override = certificate.date_override.date
|
||||
LOGGER.info(
|
||||
"Task award_course_certificate will award certificate for "
|
||||
f"course {course_key} with a date override of {date_override}"
|
||||
)
|
||||
except ObjectDoesNotExist:
|
||||
date_override = None
|
||||
|
||||
post_course_certificate(credentials_client, username, certificate, visible_date, date_override)
|
||||
|
||||
LOGGER.info(f"Awarded certificate for course {course_key} to user {username}")
|
||||
except Exception as exc:
|
||||
|
||||
@@ -20,7 +20,7 @@ from edx_rest_api_client.client import EdxRestApiClient
|
||||
|
||||
from common.djangoapps.course_modes.tests.factories import CourseModeFactory
|
||||
from common.djangoapps.student.tests.factories import UserFactory
|
||||
from lms.djangoapps.certificates.tests.factories import GeneratedCertificateFactory
|
||||
from lms.djangoapps.certificates.tests.factories import CertificateDateOverrideFactory, GeneratedCertificateFactory
|
||||
from openedx.core.djangoapps.catalog.tests.mixins import CatalogIntegrationMixin
|
||||
from openedx.core.djangoapps.content.course_overviews.tests.factories import CourseOverviewFactory
|
||||
from openedx.core.djangoapps.credentials.tests.mixins import CredentialsApiConfigMixin
|
||||
@@ -493,6 +493,7 @@ class PostCourseCertificateTestCase(TestCase):
|
||||
'mode': self.certificate.mode,
|
||||
'type': tasks.COURSE_CERTIFICATE,
|
||||
},
|
||||
'date_override': None,
|
||||
'attributes': [{
|
||||
'name': 'visible_date',
|
||||
'value': visible_date.strftime('%Y-%m-%dT%H:%M:%SZ') # text representation of date
|
||||
@@ -536,6 +537,15 @@ class AwardCourseCertificatesTestCase(CredentialsApiConfigMixin, TestCase):
|
||||
ApplicationFactory.create(name='credentials')
|
||||
UserFactory.create(username=settings.CREDENTIALS_SERVICE_USERNAME)
|
||||
|
||||
def _add_certificate_date_override(self):
|
||||
"""
|
||||
Creates a mock CertificateDateOverride and adds it to the certificate
|
||||
"""
|
||||
self.certificate.date_override = CertificateDateOverrideFactory.create(
|
||||
generated_certificate=self.certificate,
|
||||
overridden_by=UserFactory.create(username='test-admin'),
|
||||
)
|
||||
|
||||
@ddt.data(
|
||||
'verified',
|
||||
'no-id-professional',
|
||||
@@ -564,6 +574,18 @@ class AwardCourseCertificatesTestCase(CredentialsApiConfigMixin, TestCase):
|
||||
assert call_args[2] == self.certificate
|
||||
assert call_args[3] == self.available_date
|
||||
|
||||
def test_award_course_certificates_override_date(self, mock_post_course_certificate):
|
||||
"""
|
||||
Tests the API POST method is called with date override when present
|
||||
"""
|
||||
self._add_certificate_date_override()
|
||||
tasks.award_course_certificate.delay(self.student.username, str(self.course.id)).get()
|
||||
call_args, _ = mock_post_course_certificate.call_args
|
||||
assert call_args[1] == self.student.username
|
||||
assert call_args[2] == self.certificate
|
||||
assert call_args[3] == self.certificate.modified_date
|
||||
assert call_args[4] == self.certificate.date_override.date.date()
|
||||
|
||||
def test_award_course_cert_not_called_if_disabled(self, mock_post_course_certificate):
|
||||
"""
|
||||
Test that the post method is never called if the config is disabled
|
||||
|
||||
Reference in New Issue
Block a user