Merge pull request #28470 from edx/ork/MICROBA-1423_send-date-override

feat: Send date override to credentials
This commit is contained in:
Olivia Ruiz-Knott
2021-08-17 13:08:28 -06:00
committed by GitHub
3 changed files with 67 additions and 3 deletions

View File

@@ -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,
)

View File

@@ -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:

View File

@@ -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