If support user re-generates the cert. Removes the invalidation entry if exists.
ECOM-4199
This commit is contained in:
@@ -9,13 +9,18 @@ from django.conf import settings
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.test.utils import override_settings
|
||||
|
||||
from certificates.models import (
|
||||
CertificateInvalidation,
|
||||
CertificateStatuses,
|
||||
GeneratedCertificate
|
||||
)
|
||||
from certificates.tests.factories import CertificateInvalidationFactory
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from student.tests.factories import UserFactory
|
||||
from student.models import CourseEnrollment
|
||||
from student.roles import GlobalStaff, SupportStaffRole
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
from xmodule.modulestore.tests.factories import CourseFactory
|
||||
from certificates.models import GeneratedCertificate, CertificateStatuses
|
||||
|
||||
FEATURES_WITH_CERTS_ENABLED = settings.FEATURES.copy()
|
||||
FEATURES_WITH_CERTS_ENABLED['CERTIFICATES_HTML_VIEW'] = True
|
||||
@@ -326,6 +331,33 @@ class CertificateRegenerateTests(CertificateSupportTestCase):
|
||||
num_certs = GeneratedCertificate.eligible_certificates.filter(user=self.student).count()
|
||||
self.assertEqual(num_certs, 1)
|
||||
|
||||
def test_regenerate_cert_with_invalidated_record(self):
|
||||
""" If the certificate is marked as invalid, regenerate the certificate
|
||||
and verify the invalidate entry is deactivated. """
|
||||
|
||||
# mark certificate as invalid
|
||||
self._invalidate_certificate(self.cert)
|
||||
self.assertInvalidatedCertExists()
|
||||
# after invalidation certificate status become un-available.
|
||||
self.assertGeneratedCertExists(
|
||||
user=self.student, status=CertificateStatuses.unavailable
|
||||
)
|
||||
|
||||
# Should be able to regenerate
|
||||
response = self._regenerate(
|
||||
course_key=self.CERT_COURSE_KEY,
|
||||
username=self.STUDENT_USERNAME
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertInvalidatedCertDoesNotExist()
|
||||
|
||||
# Check that the user's certificate was updated
|
||||
# Since the student hasn't actually passed the course,
|
||||
# we'd expect that the certificate status will be "notpassing"
|
||||
self.assertGeneratedCertExists(
|
||||
user=self.student, status=CertificateStatuses.notpassing
|
||||
)
|
||||
|
||||
def _regenerate(self, course_key=None, username=None):
|
||||
"""Call the regeneration end-point and return the response. """
|
||||
url = reverse("certificates:regenerate_certificate_for_user")
|
||||
@@ -339,6 +371,41 @@ class CertificateRegenerateTests(CertificateSupportTestCase):
|
||||
|
||||
return self.client.post(url, params)
|
||||
|
||||
def _invalidate_certificate(self, certificate):
|
||||
""" Dry method to mark certificate as invalid. """
|
||||
CertificateInvalidationFactory.create(
|
||||
generated_certificate=certificate,
|
||||
invalidated_by=self.support,
|
||||
active=True
|
||||
)
|
||||
# Invalidate user certificate
|
||||
certificate.invalidate()
|
||||
self.assertFalse(certificate.is_valid())
|
||||
|
||||
def assertInvalidatedCertExists(self):
|
||||
""" Dry method to check certificate invalidated entry exists. """
|
||||
self.assertTrue(
|
||||
CertificateInvalidation.objects.filter(
|
||||
generated_certificate__user=self.student, active=True
|
||||
).exists()
|
||||
)
|
||||
|
||||
def assertInvalidatedCertDoesNotExist(self):
|
||||
""" Dry method to check certificate invalidated entry does not exists. """
|
||||
self.assertFalse(
|
||||
CertificateInvalidation.objects.filter(
|
||||
generated_certificate__user=self.student, active=True
|
||||
).exists()
|
||||
)
|
||||
|
||||
def assertGeneratedCertExists(self, user, status):
|
||||
""" Dry method to check if certificate exists. """
|
||||
self.assertTrue(
|
||||
GeneratedCertificate.objects.filter( # pylint: disable=no-member
|
||||
user=user, status=status
|
||||
).exists()
|
||||
)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class CertificateGenerateTests(CertificateSupportTestCase):
|
||||
|
||||
@@ -19,15 +19,16 @@ from django.db import transaction
|
||||
from django.db.models import Q
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from certificates import api
|
||||
from certificates.models import CertificateInvalidation
|
||||
from courseware.access import has_access
|
||||
from instructor_task.api import generate_certificates_for_students
|
||||
from opaque_keys import InvalidKeyError
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from student.models import User, CourseEnrollment
|
||||
from courseware.access import has_access
|
||||
from util.json_request import JsonResponse
|
||||
from certificates import api
|
||||
from instructor_task.api import generate_certificates_for_students
|
||||
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
|
||||
from student.models import User, CourseEnrollment
|
||||
from util.json_request import JsonResponse
|
||||
from xmodule.modulestore.django import modulestore
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@@ -196,7 +197,7 @@ def regenerate_certificate_for_user(request):
|
||||
|
||||
# Attempt to regenerate certificates
|
||||
try:
|
||||
api.regenerate_user_certificates(params["user"], params["course_key"], course=course)
|
||||
certificate = api.regenerate_user_certificates(params["user"], params["course_key"], course=course)
|
||||
except: # pylint: disable=bare-except
|
||||
# We are pessimistic about the kinds of errors that might get thrown by the
|
||||
# certificates API. This may be overkill, but we're logging everything so we can
|
||||
@@ -208,6 +209,9 @@ def regenerate_certificate_for_user(request):
|
||||
)
|
||||
return HttpResponseServerError(_("An unexpected error occurred while regenerating certificates."))
|
||||
|
||||
# Deactivate certificate invalidation by setting active to False.
|
||||
_deactivate_invalidation(certificate)
|
||||
|
||||
log.info(
|
||||
"Started regenerating certificates for user %s in course %s from the support page.",
|
||||
params["user"].id, params["course_key"]
|
||||
@@ -267,3 +271,25 @@ def generate_certificate_for_user(request):
|
||||
specific_student_id=params["user"].id
|
||||
)
|
||||
return HttpResponse(200)
|
||||
|
||||
|
||||
def _deactivate_invalidation(certificate):
|
||||
"""
|
||||
Deactivate certificate invalidation by setting active to False.
|
||||
|
||||
Arguments:
|
||||
certificate : The student certificate object
|
||||
|
||||
Return:
|
||||
None
|
||||
"""
|
||||
try:
|
||||
# Fetch CertificateInvalidation object
|
||||
certificate_invalidation = CertificateInvalidation.objects.get(
|
||||
generated_certificate=certificate,
|
||||
active=True
|
||||
)
|
||||
# Deactivate certificate invalidation if it was fetched successfully.
|
||||
certificate_invalidation.deactivate()
|
||||
except CertificateInvalidation.DoesNotExist: # pylint: disable=bare-except
|
||||
pass
|
||||
|
||||
Reference in New Issue
Block a user