Allow PMs to Invalidate Certificates

This commit is contained in:
Saleem Latif
2015-12-22 18:34:19 +05:00
parent 5e972b2a66
commit 9aa0a01cae
19 changed files with 1399 additions and 29 deletions

View File

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