diff --git a/lms/djangoapps/certificates/management/commands/cert_whitelist.py b/lms/djangoapps/certificates/management/commands/cert_whitelist.py index 9be42c7bd0040a10f668e31695b42d0345541a52..ada927673dd2db093a51461d24e7ea6f553b39d6 100644 --- a/lms/djangoapps/certificates/management/commands/cert_whitelist.py +++ b/lms/djangoapps/certificates/management/commands/cert_whitelist.py @@ -25,6 +25,10 @@ def get_user_from_identifier(identifier): class Command(BaseCommand): + """ + Management command to set or get the certificate whitelist + for a given user(s)/course + """ help = """ Sets or gets the certificate whitelist for a given @@ -88,7 +92,8 @@ class Command(BaseCommand): try: course = CourseKey.from_string(course_id) except InvalidKeyError: - print("Course id {} could not be parsed as a CourseKey; falling back to SSCK.from_dep_str".format(course_id)) + print(("Course id {} could not be parsed as a CourseKey; " + "falling back to SSCK.from_dep_str").format(course_id)) course = SlashSeparatedCourseKey.from_deprecated_string(course_id) if options['add'] and options['del']: diff --git a/lms/djangoapps/certificates/management/commands/fix_ungraded_certs.py b/lms/djangoapps/certificates/management/commands/fix_ungraded_certs.py index 3994012846b6d5dbcfcc6697bba81ddf7b0624d0..3c26d164473959b0b3c91af02cd0ca68206f2d5b 100644 --- a/lms/djangoapps/certificates/management/commands/fix_ungraded_certs.py +++ b/lms/djangoapps/certificates/management/commands/fix_ungraded_certs.py @@ -1,3 +1,8 @@ +""" +Management command which fixes ungraded certificates for students +""" + + from certificates.models import GeneratedCertificate from courseware import grades, courses from django.test.client import RequestFactory @@ -6,6 +11,9 @@ from optparse import make_option class Command(BaseCommand): + """ + Management command to find and grade all students that need to be graded. + """ help = """ Find all students that need to be graded diff --git a/lms/djangoapps/certificates/management/commands/gen_cert_report.py b/lms/djangoapps/certificates/management/commands/gen_cert_report.py index 763835e04939666b58df07a6919e0cfd52b9fe85..d0e6ef335d2fd60e3891f1c5420c7009cff03c5c 100644 --- a/lms/djangoapps/certificates/management/commands/gen_cert_report.py +++ b/lms/djangoapps/certificates/management/commands/gen_cert_report.py @@ -13,6 +13,10 @@ from django.db.models import Count class Command(BaseCommand): + """ + Management command to generate a certificate status + report for a given course. + """ help = """ @@ -48,7 +52,8 @@ class Command(BaseCommand): try: course_id = CourseKey.from_string(options['course']) except InvalidKeyError: - print("Course id {} could not be parsed as a CourseKey; falling back to SSCK.from_dep_str".format(options['course'])) + print ("Course id {} could not be parsed as a CourseKey; " + "falling back to SSCK.from_dep_str").format(options['course']) course_id = SlashSeparatedCourseKey.from_deprecated_string(options['course']) else: raise CommandError("You must specify a course") @@ -90,8 +95,10 @@ class Command(BaseCommand): ) cert_data[course_id].update( - {status['status']: status['dcount'] - for status in status_tally}) + { + status['status']: status['dcount'] for status in status_tally + } + ) mode_tally = GeneratedCertificate.objects.filter( course_id__exact=course_id, @@ -100,21 +107,17 @@ class Command(BaseCommand): dcount=Count('mode') ) cert_data[course_id].update( - {mode['mode']: mode['dcount'] - for mode in mode_tally} + {mode['mode']: mode['dcount'] for mode in mode_tally} ) # all states we have seen far all courses - status_headings = sorted(set( - [status for course in cert_data - for status in cert_data[course]]) + status_headings = sorted( + set([status for course in cert_data for status in cert_data[course]]) ) # print the heading for the report print "{:>26}".format("course ID"), - print ' '.join(["{:>16}".format(heading) - for heading in status_headings] - ) + print ' '.join(["{:>16}".format(heading) for heading in status_headings]) # print the report print "{0:>26}".format(course_id.to_deprecated_string()), diff --git a/lms/djangoapps/certificates/management/commands/regenerate_user.py b/lms/djangoapps/certificates/management/commands/regenerate_user.py index ff53c412145ead68342d78d358d461fe9fbdc234..0a9aa01d29a6ded71b70beb6e165193fa89d85d6 100644 --- a/lms/djangoapps/certificates/management/commands/regenerate_user.py +++ b/lms/djangoapps/certificates/management/commands/regenerate_user.py @@ -16,6 +16,11 @@ LOGGER = logging.getLogger(__name__) class Command(BaseCommand): + """ + Management command to recreate the certificate for + a given user in a given course. + """ + help = """Put a request on the queue to recreate the certificate for a particular user in a particular course.""" option_list = BaseCommand.option_list + ( diff --git a/lms/djangoapps/certificates/management/commands/ungenerated_certs.py b/lms/djangoapps/certificates/management/commands/ungenerated_certs.py index 1c7ddd67ac5bc4168fa03b69e782f8cbec5b797e..906bf85d845f65f7fb35c26ea879c1109a9b76cc 100644 --- a/lms/djangoapps/certificates/management/commands/ungenerated_certs.py +++ b/lms/djangoapps/certificates/management/commands/ungenerated_certs.py @@ -21,6 +21,10 @@ LOGGER = logging.getLogger(__name__) class Command(BaseCommand): + """ + Management command to find all students that need certificates + for courses that have finished and put their cert requests on the queue. + """ help = """ Find all students that need certificates for courses that have finished and diff --git a/lms/djangoapps/certificates/models.py b/lms/djangoapps/certificates/models.py index beada39f6990cd31b62272228e16c61bb6161af5..aefbe89522593e2a106f3805b666b331e0359a00 100644 --- a/lms/djangoapps/certificates/models.py +++ b/lms/djangoapps/certificates/models.py @@ -71,6 +71,9 @@ LOGGER = logging.getLogger(__name__) class CertificateStatuses(object): + """ + Enum for certificate statuses + """ deleted = 'deleted' deleting = 'deleting' downloadable = 'downloadable' @@ -108,6 +111,9 @@ class CertificateWhitelist(models.Model): class GeneratedCertificate(models.Model): + """ + Base model for generated certificates + """ MODES = Choices('verified', 'honor', 'audit', 'professional', 'no-id-professional') @@ -191,14 +197,16 @@ def certificate_status_for_student(student, course_id): try: generated_certificate = GeneratedCertificate.objects.get( user=student, course_id=course_id) - d = {'status': generated_certificate.status, - 'mode': generated_certificate.mode} + cert_status = { + 'status': generated_certificate.status, + 'mode': generated_certificate.mode + } if generated_certificate.grade: - d['grade'] = generated_certificate.grade + cert_status['grade'] = generated_certificate.grade if generated_certificate.status == CertificateStatuses.downloadable: - d['download_url'] = generated_certificate.download_url + cert_status['download_url'] = generated_certificate.download_url - return d + return cert_status except GeneratedCertificate.DoesNotExist: pass return {'status': CertificateStatuses.unavailable, 'mode': GeneratedCertificate.MODES.honor} diff --git a/lms/djangoapps/certificates/tests/test_api.py b/lms/djangoapps/certificates/tests/test_api.py index 0e80eb282575da0ade55f0e400d4e70d03fb4230..d264a67a931c25e58c57638562e96da12f268be3 100644 --- a/lms/djangoapps/certificates/tests/test_api.py +++ b/lms/djangoapps/certificates/tests/test_api.py @@ -118,7 +118,7 @@ class GenerateUserCertificatesTest(EventTestMixin, ModuleStoreTestCase): ERROR_REASON = "Kaboom!" - def setUp(self): + def setUp(self): # pylint: disable=arguments-differ super(GenerateUserCertificatesTest, self).setUp('certificates.api.tracker') self.student = UserFactory.create( @@ -233,7 +233,7 @@ class CertificateGenerationEnabledTest(EventTestMixin, TestCase): COURSE_KEY = CourseLocator(org='test', course='test', run='test') - def setUp(self): + def setUp(self): # pylint: disable=arguments-differ super(CertificateGenerationEnabledTest, self).setUp('certificates.api.tracker') # Since model-based configuration is cached, we need diff --git a/lms/djangoapps/certificates/tests/test_views.py b/lms/djangoapps/certificates/tests/test_views.py index eccfb78e39ac893b4bdd5231973b5dc40c3c6417..d51397573563c16462d15906b05a83ec0492be8c 100644 --- a/lms/djangoapps/certificates/tests/test_views.py +++ b/lms/djangoapps/certificates/tests/test_views.py @@ -15,7 +15,7 @@ from django.test.utils import override_settings from opaque_keys.edx.locator import CourseLocator from openedx.core.lib.tests.assertions.events import assert_event_matches -from student.tests.factories import UserFactory, CourseEnrollmentFactory +from student.tests.factories import UserFactory from track.tests import EventTrackingTestCase from xmodule.modulestore.tests.factories import CourseFactory from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase @@ -26,21 +26,12 @@ from certificates.models import ( ExampleCertificateSet, ExampleCertificate, GeneratedCertificate, - BadgeAssertion, - CertificateStatuses, CertificateHtmlViewConfiguration, - CertificateSocialNetworks, - CertificateTemplate, ) from certificates.tests.factories import ( - CertificateHtmlViewConfigurationFactory, - LinkedInAddToProfileConfigurationFactory, BadgeAssertionFactory, ) -from util import organizations_helpers as organizations_api -from django.test.client import RequestFactory -import urllib FEATURES_WITH_CERTS_ENABLED = settings.FEATURES.copy() FEATURES_WITH_CERTS_ENABLED['CERTIFICATES_HTML_VIEW'] = True