tests.py 5.94 KB
Newer Older
1 2 3
"""
Tests for the certificates models.
"""
4
from ddt import ddt, data, unpack
5 6
from mock import patch
from django.conf import settings
7
from nose.plugins.attrib import attr
8 9

from xmodule.modulestore.tests.factories import CourseFactory
10
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
11 12

from student.tests.factories import UserFactory
13 14 15 16 17 18
from certificates.models import (
    CertificateStatuses,
    GeneratedCertificate,
    certificate_status_for_student,
    certificate_info_for_user
)
19 20 21 22 23 24 25
from certificates.tests.factories import GeneratedCertificateFactory

from util.milestones_helpers import (
    set_prerequisite_courses,
    milestones_achieved_by_user,
    seed_milestone_relationship_types,
)
26 27


28
@attr('shard_1')
29
@ddt
30
class CertificatesModelTest(ModuleStoreTestCase):
31 32 33 34 35 36 37 38 39 40 41
    """
    Tests for the GeneratedCertificate model
    """

    def test_certificate_status_for_student(self):
        student = UserFactory()
        course = CourseFactory.create(org='edx', number='verified', display_name='Verified Course')

        certificate_status = certificate_status_for_student(student, course.id)
        self.assertEqual(certificate_status['status'], CertificateStatuses.unavailable)
        self.assertEqual(certificate_status['mode'], GeneratedCertificate.MODES.honor)
42

43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
    @unpack
    @data(
        {'allow_certificate': False, 'whitelisted': False, 'grade': None, 'output': ['N', 'N', 'N/A']},
        {'allow_certificate': True, 'whitelisted': True, 'grade': None, 'output': ['Y', 'N', 'N/A']},
        {'allow_certificate': True, 'whitelisted': False, 'grade': 0.9, 'output': ['Y', 'N', 'N/A']},
        {'allow_certificate': False, 'whitelisted': True, 'grade': 0.8, 'output': ['N', 'N', 'N/A']},
        {'allow_certificate': False, 'whitelisted': None, 'grade': 0.8, 'output': ['N', 'N', 'N/A']}
    )
    def test_certificate_info_for_user(self, allow_certificate, whitelisted, grade, output):
        """
        Verify that certificate_info_for_user works.
        """
        student = UserFactory()
        course = CourseFactory.create(org='edx', number='verified', display_name='Verified Course')
        student.profile.allow_certificate = allow_certificate
        student.profile.save()

        certificate_info = certificate_info_for_user(student, course.id, grade, whitelisted)
        self.assertEqual(certificate_info, output)

63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
    @unpack
    @data(
        {'allow_certificate': False, 'whitelisted': False, 'grade': None, 'output': ['N', 'Y', 'honor']},
        {'allow_certificate': True, 'whitelisted': True, 'grade': None, 'output': ['Y', 'Y', 'honor']},
        {'allow_certificate': True, 'whitelisted': False, 'grade': 0.9, 'output': ['Y', 'Y', 'honor']},
        {'allow_certificate': False, 'whitelisted': True, 'grade': 0.8, 'output': ['N', 'Y', 'honor']},
        {'allow_certificate': False, 'whitelisted': None, 'grade': 0.8, 'output': ['N', 'Y', 'honor']}
    )
    def test_certificate_info_for_user_when_grade_changes(self, allow_certificate, whitelisted, grade, output):
        """
        Verify that certificate_info_for_user works as expect in scenario when grading of problems
        changes after certificates already generated. In such scenario `Certificate delivered` should not depend
        on student's eligibility to get certificates since in above scenario eligibility can change over period
        of time.
        """
        student = UserFactory()
        course = CourseFactory.create(org='edx', number='verified', display_name='Verified Course')
        student.profile.allow_certificate = allow_certificate
        student.profile.save()

        GeneratedCertificateFactory.create(
            user=student,
            course_id=course.id,
            status=CertificateStatuses.downloadable,
            mode='honor'
        )

        certificate_info = certificate_info_for_user(student, course.id, grade, whitelisted)
        self.assertEqual(certificate_info, output)

93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
    @patch.dict(settings.FEATURES, {'ENABLE_PREREQUISITE_COURSES': True, 'MILESTONES_APP': True})
    def test_course_milestone_collected(self):
        seed_milestone_relationship_types()
        student = UserFactory()
        course = CourseFactory.create(org='edx', number='998', display_name='Test Course')
        pre_requisite_course = CourseFactory.create(org='edx', number='999', display_name='Pre requisite Course')
        # set pre-requisite course
        set_prerequisite_courses(course.id, [unicode(pre_requisite_course.id)])
        # get milestones collected by user before completing the pre-requisite course
        completed_milestones = milestones_achieved_by_user(student, unicode(pre_requisite_course.id))
        self.assertEqual(len(completed_milestones), 0)

        GeneratedCertificateFactory.create(
            user=student,
            course_id=pre_requisite_course.id,
            status=CertificateStatuses.generating,
            mode='verified'
        )
        # get milestones collected by user after user has completed the pre-requisite course
        completed_milestones = milestones_achieved_by_user(student, unicode(pre_requisite_course.id))
        self.assertEqual(len(completed_milestones), 1)
        self.assertEqual(completed_milestones[0]['namespace'], unicode(pre_requisite_course.id))
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131

    @patch.dict(settings.FEATURES, {'ENABLE_OPENBADGES': True})
    @patch('certificates.badge_handler.BadgeHandler', spec=True)
    def test_badge_callback(self, handler):
        student = UserFactory()
        course = CourseFactory.create(org='edx', number='998', display_name='Test Course', issue_badges=True)
        cert = GeneratedCertificateFactory.create(
            user=student,
            course_id=course.id,
            status=CertificateStatuses.generating,
            mode='verified'
        )
        # Check return value since class instance will be stored there.
        self.assertFalse(handler.return_value.award.called)
        cert.status = CertificateStatuses.downloadable
        cert.save()
        self.assertTrue(handler.return_value.award.called)