Allow PMs to Invalidate Certificates
This commit is contained in:
@@ -13,9 +13,10 @@ from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
|
||||
from xmodule.modulestore.tests.factories import CourseFactory
|
||||
from config_models.models import cache
|
||||
from courseware.tests.factories import GlobalStaffFactory, InstructorFactory, UserFactory
|
||||
from certificates.tests.factories import GeneratedCertificateFactory, CertificateWhitelistFactory
|
||||
from certificates.tests.factories import GeneratedCertificateFactory, CertificateWhitelistFactory, \
|
||||
CertificateInvalidationFactory
|
||||
from certificates.models import CertificateGenerationConfiguration, CertificateStatuses, CertificateWhitelist, \
|
||||
GeneratedCertificate
|
||||
GeneratedCertificate, CertificateInvalidation
|
||||
from certificates import api as certs_api
|
||||
from student.models import CourseEnrollment
|
||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||
@@ -923,3 +924,299 @@ class TestCertificatesInstructorApiBulkWhiteListExceptions(SharedModuleStoreTest
|
||||
self.assertEqual(response.status_code, 200)
|
||||
data = json.loads(response.content)
|
||||
return data
|
||||
|
||||
|
||||
@attr('shard_1')
|
||||
@ddt.ddt
|
||||
class CertificateInvalidationViewTests(SharedModuleStoreTestCase):
|
||||
"""
|
||||
Test certificate invalidation view.
|
||||
"""
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(CertificateInvalidationViewTests, cls).setUpClass()
|
||||
cls.course = CourseFactory.create()
|
||||
cls.url = reverse('certificate_invalidation_view',
|
||||
kwargs={'course_id': cls.course.id})
|
||||
cls.notes = "Test notes."
|
||||
|
||||
def setUp(self):
|
||||
super(CertificateInvalidationViewTests, self).setUp()
|
||||
self.global_staff = GlobalStaffFactory()
|
||||
self.enrolled_user_1 = UserFactory(
|
||||
username='TestStudent1',
|
||||
email='test_student1@example.com',
|
||||
first_name='Enrolled',
|
||||
last_name='Student',
|
||||
)
|
||||
self.enrolled_user_2 = UserFactory(
|
||||
username='TestStudent2',
|
||||
email='test_student2@example.com',
|
||||
first_name='Enrolled',
|
||||
last_name='Student',
|
||||
)
|
||||
|
||||
self.not_enrolled_student = UserFactory(
|
||||
username='NotEnrolledStudent',
|
||||
email='nonenrolled@test.com',
|
||||
first_name='NotEnrolled',
|
||||
last_name='Student',
|
||||
)
|
||||
CourseEnrollment.enroll(self.enrolled_user_1, self.course.id)
|
||||
CourseEnrollment.enroll(self.enrolled_user_2, self.course.id)
|
||||
|
||||
self.generated_certificate = GeneratedCertificateFactory.create(
|
||||
user=self.enrolled_user_1,
|
||||
course_id=self.course.id,
|
||||
status=CertificateStatuses.downloadable,
|
||||
mode='honor',
|
||||
)
|
||||
|
||||
self.certificate_invalidation_data = dict(
|
||||
user=self.enrolled_user_1.username,
|
||||
notes=self.notes,
|
||||
)
|
||||
|
||||
# Global staff can see the certificates section
|
||||
self.client.login(username=self.global_staff.username, password="test")
|
||||
|
||||
def test_invalidate_certificate(self):
|
||||
"""
|
||||
Test user can invalidate a generated certificate.
|
||||
"""
|
||||
response = self.client.post(
|
||||
self.url,
|
||||
data=json.dumps(self.certificate_invalidation_data),
|
||||
content_type='application/json',
|
||||
)
|
||||
# Assert successful request processing
|
||||
self.assertEqual(response.status_code, 200)
|
||||
result = json.loads(response.content)
|
||||
|
||||
# Assert Certificate Exception Updated data
|
||||
self.assertEqual(result['user'], self.enrolled_user_1.username)
|
||||
self.assertEqual(result['invalidated_by'], self.global_staff.username)
|
||||
self.assertEqual(result['notes'], self.notes)
|
||||
|
||||
# Verify that CertificateInvalidation record has been created in the database i.e. no DoesNotExist error
|
||||
try:
|
||||
CertificateInvalidation.objects.get(
|
||||
generated_certificate=self.generated_certificate,
|
||||
invalidated_by=self.global_staff,
|
||||
notes=self.notes,
|
||||
active=True,
|
||||
)
|
||||
except ObjectDoesNotExist:
|
||||
self.fail("The certificate is not invalidated.")
|
||||
|
||||
# Validate generated certificate was invalidated
|
||||
generated_certificate = GeneratedCertificate.objects.get(
|
||||
user=self.enrolled_user_1,
|
||||
course_id=self.course.id,
|
||||
)
|
||||
self.assertFalse(generated_certificate.is_valid())
|
||||
|
||||
def test_missing_username_and_email_error(self):
|
||||
"""
|
||||
Test error message if user name or email is missing.
|
||||
"""
|
||||
self.certificate_invalidation_data.update({'user': ''})
|
||||
response = self.client.post(
|
||||
self.url,
|
||||
data=json.dumps(self.certificate_invalidation_data),
|
||||
content_type='application/json',
|
||||
)
|
||||
|
||||
# Assert 400 status code in response
|
||||
self.assertEqual(response.status_code, 400)
|
||||
res_json = json.loads(response.content)
|
||||
|
||||
# Assert Error Message
|
||||
self.assertEqual(
|
||||
res_json['message'],
|
||||
u'Student username/email field is required and can not be empty. '
|
||||
u'Kindly fill in username/email and then press "Invalidate Certificate" button.',
|
||||
)
|
||||
|
||||
def test_invalid_user_name_error(self):
|
||||
"""
|
||||
Test error message if invalid user name is given.
|
||||
"""
|
||||
invalid_user = "test_invalid_user_name"
|
||||
|
||||
self.certificate_invalidation_data.update({"user": invalid_user})
|
||||
|
||||
response = self.client.post(
|
||||
self.url,
|
||||
data=json.dumps(self.certificate_invalidation_data),
|
||||
content_type='application/json',
|
||||
)
|
||||
|
||||
# Assert 400 status code in response
|
||||
self.assertEqual(response.status_code, 400)
|
||||
res_json = json.loads(response.content)
|
||||
|
||||
# Assert Error Message
|
||||
self.assertEqual(
|
||||
res_json['message'],
|
||||
u"{user} does not exist in the LMS. Please check your spelling and retry.".format(user=invalid_user),
|
||||
)
|
||||
|
||||
def test_user_not_enrolled_error(self):
|
||||
"""
|
||||
Test error message if user is not enrolled in the course.
|
||||
"""
|
||||
self.certificate_invalidation_data.update({"user": self.not_enrolled_student.username})
|
||||
|
||||
response = self.client.post(
|
||||
self.url,
|
||||
data=json.dumps(self.certificate_invalidation_data),
|
||||
content_type='application/json',
|
||||
)
|
||||
|
||||
# Assert 400 status code in response
|
||||
self.assertEqual(response.status_code, 400)
|
||||
res_json = json.loads(response.content)
|
||||
|
||||
# Assert Error Message
|
||||
self.assertEqual(
|
||||
res_json['message'],
|
||||
u"{user} is not enrolled in this course. Please check your spelling and retry.".format(
|
||||
user=self.not_enrolled_student.username,
|
||||
),
|
||||
)
|
||||
|
||||
def test_no_generated_certificate_error(self):
|
||||
"""
|
||||
Test error message if there is no generated certificate for the student.
|
||||
"""
|
||||
self.certificate_invalidation_data.update({"user": self.enrolled_user_2.username})
|
||||
|
||||
response = self.client.post(
|
||||
self.url,
|
||||
data=json.dumps(self.certificate_invalidation_data),
|
||||
content_type='application/json',
|
||||
)
|
||||
|
||||
# Assert 400 status code in response
|
||||
self.assertEqual(response.status_code, 400)
|
||||
res_json = json.loads(response.content)
|
||||
|
||||
# Assert Error Message
|
||||
self.assertEqual(
|
||||
res_json['message'],
|
||||
u"The student {student} does not have certificate for the course {course}. "
|
||||
u"Kindly verify student username/email and the selected course are correct and try again.".format(
|
||||
student=self.enrolled_user_2.username,
|
||||
course=self.course.number,
|
||||
),
|
||||
)
|
||||
|
||||
def test_certificate_already_invalid_error(self):
|
||||
"""
|
||||
Test error message if certificate for the student is already invalid.
|
||||
"""
|
||||
# Invalidate user certificate
|
||||
self.generated_certificate.invalidate()
|
||||
|
||||
response = self.client.post(
|
||||
self.url,
|
||||
data=json.dumps(self.certificate_invalidation_data),
|
||||
content_type='application/json',
|
||||
)
|
||||
|
||||
# Assert 400 status code in response
|
||||
self.assertEqual(response.status_code, 400)
|
||||
res_json = json.loads(response.content)
|
||||
|
||||
# Assert Error Message
|
||||
self.assertEqual(
|
||||
res_json['message'],
|
||||
u"Certificate for student {user} is already invalid, kindly verify that certificate "
|
||||
u"was generated for this student and then proceed.".format(
|
||||
user=self.enrolled_user_1.username,
|
||||
),
|
||||
)
|
||||
|
||||
def test_duplicate_certificate_invalidation_error(self):
|
||||
"""
|
||||
Test error message if certificate invalidation for the student is already present.
|
||||
"""
|
||||
CertificateInvalidationFactory.create(
|
||||
generated_certificate=self.generated_certificate,
|
||||
invalidated_by=self.global_staff,
|
||||
)
|
||||
# Invalidate user certificate
|
||||
self.generated_certificate.invalidate()
|
||||
|
||||
response = self.client.post(
|
||||
self.url,
|
||||
data=json.dumps(self.certificate_invalidation_data),
|
||||
content_type='application/json',
|
||||
)
|
||||
|
||||
# Assert 400 status code in response
|
||||
self.assertEqual(response.status_code, 400)
|
||||
res_json = json.loads(response.content)
|
||||
|
||||
# Assert Error Message
|
||||
self.assertEqual(
|
||||
res_json['message'],
|
||||
u"Certificate of {user} has already been invalidated. Please check your spelling and retry.".format(
|
||||
user=self.enrolled_user_1.username,
|
||||
),
|
||||
)
|
||||
|
||||
def test_remove_certificate_invalidation(self):
|
||||
"""
|
||||
Test that user can remove certificate invalidation.
|
||||
"""
|
||||
# Invalidate user certificate
|
||||
self.generated_certificate.invalidate()
|
||||
|
||||
CertificateInvalidationFactory.create(
|
||||
generated_certificate=self.generated_certificate,
|
||||
invalidated_by=self.global_staff,
|
||||
)
|
||||
|
||||
response = self.client.post(
|
||||
self.url,
|
||||
data=json.dumps(self.certificate_invalidation_data),
|
||||
content_type='application/json',
|
||||
REQUEST_METHOD='DELETE'
|
||||
)
|
||||
|
||||
# Assert 204 status code in response
|
||||
self.assertEqual(response.status_code, 204)
|
||||
|
||||
# Verify that certificate invalidation successfully removed from database
|
||||
with self.assertRaises(ObjectDoesNotExist):
|
||||
CertificateInvalidation.objects.get(
|
||||
generated_certificate=self.generated_certificate,
|
||||
invalidated_by=self.global_staff,
|
||||
active=True,
|
||||
)
|
||||
|
||||
def test_remove_certificate_invalidation_error(self):
|
||||
"""
|
||||
Test error message if certificate invalidation does not exists.
|
||||
"""
|
||||
# Invalidate user certificate
|
||||
self.generated_certificate.invalidate()
|
||||
|
||||
response = self.client.post(
|
||||
self.url,
|
||||
data=json.dumps(self.certificate_invalidation_data),
|
||||
content_type='application/json',
|
||||
REQUEST_METHOD='DELETE'
|
||||
)
|
||||
|
||||
# Assert 400 status code in response
|
||||
self.assertEqual(response.status_code, 400)
|
||||
res_json = json.loads(response.content)
|
||||
|
||||
# Assert Error Message
|
||||
self.assertEqual(
|
||||
res_json['message'],
|
||||
u"Certificate Invalidation does not exist, Please refresh the page and try again.",
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user