Commit 7ae64b4f by Awais

If support user re-generates the cert. Removes the invalidation entry if exists.

ECOM-4199
parent cae69f96
...@@ -9,13 +9,18 @@ from django.conf import settings ...@@ -9,13 +9,18 @@ from django.conf import settings
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.test.utils import override_settings 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 opaque_keys.edx.keys import CourseKey
from student.tests.factories import UserFactory from student.tests.factories import UserFactory
from student.models import CourseEnrollment from student.models import CourseEnrollment
from student.roles import GlobalStaff, SupportStaffRole from student.roles import GlobalStaff, SupportStaffRole
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory from xmodule.modulestore.tests.factories import CourseFactory
from certificates.models import GeneratedCertificate, CertificateStatuses
FEATURES_WITH_CERTS_ENABLED = settings.FEATURES.copy() FEATURES_WITH_CERTS_ENABLED = settings.FEATURES.copy()
FEATURES_WITH_CERTS_ENABLED['CERTIFICATES_HTML_VIEW'] = True FEATURES_WITH_CERTS_ENABLED['CERTIFICATES_HTML_VIEW'] = True
...@@ -326,6 +331,33 @@ class CertificateRegenerateTests(CertificateSupportTestCase): ...@@ -326,6 +331,33 @@ class CertificateRegenerateTests(CertificateSupportTestCase):
num_certs = GeneratedCertificate.eligible_certificates.filter(user=self.student).count() num_certs = GeneratedCertificate.eligible_certificates.filter(user=self.student).count()
self.assertEqual(num_certs, 1) 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): def _regenerate(self, course_key=None, username=None):
"""Call the regeneration end-point and return the response. """ """Call the regeneration end-point and return the response. """
url = reverse("certificates:regenerate_certificate_for_user") url = reverse("certificates:regenerate_certificate_for_user")
...@@ -339,6 +371,41 @@ class CertificateRegenerateTests(CertificateSupportTestCase): ...@@ -339,6 +371,41 @@ class CertificateRegenerateTests(CertificateSupportTestCase):
return self.client.post(url, params) 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 @ddt.ddt
class CertificateGenerateTests(CertificateSupportTestCase): class CertificateGenerateTests(CertificateSupportTestCase):
......
...@@ -19,15 +19,16 @@ from django.db import transaction ...@@ -19,15 +19,16 @@ from django.db import transaction
from django.db.models import Q from django.db.models import Q
from django.utils.translation import ugettext as _ 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 import InvalidKeyError
from opaque_keys.edx.keys import CourseKey from opaque_keys.edx.keys import CourseKey
from xmodule.modulestore.django import modulestore from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
from student.models import User, CourseEnrollment from student.models import User, CourseEnrollment
from courseware.access import has_access
from util.json_request import JsonResponse from util.json_request import JsonResponse
from certificates import api from xmodule.modulestore.django import modulestore
from instructor_task.api import generate_certificates_for_students
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
...@@ -196,7 +197,7 @@ def regenerate_certificate_for_user(request): ...@@ -196,7 +197,7 @@ def regenerate_certificate_for_user(request):
# Attempt to regenerate certificates # Attempt to regenerate certificates
try: 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 except: # pylint: disable=bare-except
# We are pessimistic about the kinds of errors that might get thrown by the # 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 # certificates API. This may be overkill, but we're logging everything so we can
...@@ -208,6 +209,9 @@ def regenerate_certificate_for_user(request): ...@@ -208,6 +209,9 @@ def regenerate_certificate_for_user(request):
) )
return HttpResponseServerError(_("An unexpected error occurred while regenerating certificates.")) return HttpResponseServerError(_("An unexpected error occurred while regenerating certificates."))
# Deactivate certificate invalidation by setting active to False.
_deactivate_invalidation(certificate)
log.info( log.info(
"Started regenerating certificates for user %s in course %s from the support page.", "Started regenerating certificates for user %s in course %s from the support page.",
params["user"].id, params["course_key"] params["user"].id, params["course_key"]
...@@ -267,3 +271,25 @@ def generate_certificate_for_user(request): ...@@ -267,3 +271,25 @@ def generate_certificate_for_user(request):
specific_student_id=params["user"].id specific_student_id=params["user"].id
) )
return HttpResponse(200) 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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment