test_course_meta.py 7.66 KB
Newer Older
1 2 3
"""
Tests the course meta badging events
"""
4 5
from ddt import data, ddt, unpack
from django.conf import settings
6 7 8
from django.test.utils import override_settings
from mock import patch

9 10
from badges.tests.factories import CourseEventBadgesConfigurationFactory, RandomBadgeClassFactory
from certificates.models import CertificateStatuses, GeneratedCertificate
11 12 13 14 15 16
from student.models import CourseEnrollment
from student.tests.factories import UserFactory
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory


17
@ddt
18
@patch.dict(settings.FEATURES, {'ENABLE_OPENBADGES': True})
19
@override_settings(BADGING_BACKEND='lms.djangoapps.badges.backends.tests.dummy_backend.DummyBackend')
20 21 22 23 24 25 26 27
class CourseEnrollmentBadgeTest(ModuleStoreTestCase):
    """
    Tests the event which awards badges based on number of courses a user is enrolled in.
    """
    def setUp(self):
        super(CourseEnrollmentBadgeTest, self).setUp()
        self.badge_classes = [
            RandomBadgeClassFactory(
28
                issuing_component='openedx__course'
29 30
            ),
            RandomBadgeClassFactory(
31
                issuing_component='openedx__course'
32 33
            ),
            RandomBadgeClassFactory(
34
                issuing_component='openedx__course'
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
            ),
        ]
        nums = ['3', '5', '8']
        entries = [','.join(pair) for pair in zip(nums, [badge.slug for badge in self.badge_classes])]
        enrollment_config = '\r'.join(entries)
        self.config = CourseEventBadgesConfigurationFactory(courses_enrolled=enrollment_config)

    def test_no_match(self):
        """
        Make sure a badge isn't created before a user's reached any checkpoint.
        """
        user = UserFactory()
        course = CourseFactory()
        # pylint: disable=no-member
        CourseEnrollment.enroll(user, course_key=course.location.course_key)
        self.assertFalse(user.badgeassertion_set.all())

52 53 54
    @unpack
    @data((1, 3), (2, 5), (3, 8))
    def test_checkpoint_matches(self, checkpoint, required_badges):
55 56 57 58
        """
        Make sure the proper badges are awarded at the right checkpoints.
        """
        user = UserFactory()
59
        courses = [CourseFactory() for _i in range(required_badges)]
60 61 62 63
        for course in courses:
            CourseEnrollment.enroll(user, course_key=course.location.course_key)
        # pylint: disable=no-member
        assertions = user.badgeassertion_set.all().order_by('id')
64 65
        self.assertEqual(user.badgeassertion_set.all().count(), checkpoint)
        self.assertEqual(assertions[checkpoint - 1].badge_class, self.badge_classes[checkpoint - 1])
66 67


68
@ddt
69
@patch.dict(settings.FEATURES, {'ENABLE_OPENBADGES': True})
70
@override_settings(BADGING_BACKEND='lms.djangoapps.badges.backends.tests.dummy_backend.DummyBackend')
71 72 73 74 75 76 77 78
class CourseCompletionBadgeTest(ModuleStoreTestCase):
    """
    Tests the event which awards badges based on the number of courses completed.
    """
    def setUp(self, **kwargs):
        super(CourseCompletionBadgeTest, self).setUp()
        self.badge_classes = [
            RandomBadgeClassFactory(
79
                issuing_component='openedx__course'
80 81
            ),
            RandomBadgeClassFactory(
82
                issuing_component='openedx__course'
83 84
            ),
            RandomBadgeClassFactory(
85
                issuing_component='openedx__course'
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
            ),
        ]
        nums = ['2', '6', '9']
        entries = [','.join(pair) for pair in zip(nums, [badge.slug for badge in self.badge_classes])]
        completed_config = '\r'.join(entries)
        self.config = CourseEventBadgesConfigurationFactory.create(courses_completed=completed_config)
        self.config.clean_fields()

    def test_no_match(self):
        """
        Make sure a badge isn't created before a user's reached any checkpoint.
        """
        user = UserFactory()
        course = CourseFactory()
        GeneratedCertificate(
            # pylint: disable=no-member
            user=user, course_id=course.location.course_key, status=CertificateStatuses.downloadable
        ).save()
        # pylint: disable=no-member
        self.assertFalse(user.badgeassertion_set.all())

107 108 109
    @unpack
    @data((1, 2), (2, 6), (3, 9))
    def test_checkpoint_matches(self, checkpoint, required_badges):
110 111 112 113
        """
        Make sure the proper badges are awarded at the right checkpoints.
        """
        user = UserFactory()
114
        courses = [CourseFactory() for _i in range(required_badges)]
115 116 117 118 119 120 121 122
        for course in courses:
            GeneratedCertificate(
                # pylint: disable=no-member
                user=user, course_id=course.location.course_key, status=CertificateStatuses.downloadable
            ).save()
        # pylint: disable=no-member
        assertions = user.badgeassertion_set.all().order_by('id')
        # pylint: disable=no-member
123 124
        self.assertEqual(user.badgeassertion_set.all().count(), checkpoint)
        self.assertEqual(assertions[checkpoint - 1].badge_class, self.badge_classes[checkpoint - 1])
125 126 127


@patch.dict(settings.FEATURES, {'ENABLE_OPENBADGES': True})
128
@override_settings(BADGING_BACKEND='lms.djangoapps.badges.backends.tests.dummy_backend.DummyBackend')
129 130 131 132 133 134 135 136
class CourseGroupBadgeTest(ModuleStoreTestCase):
    """
    Tests the event which awards badges when a user completes a set of courses.
    """
    def setUp(self):
        super(CourseGroupBadgeTest, self).setUp()
        self.badge_classes = [
            RandomBadgeClassFactory(
137
                issuing_component='openedx__course'
138 139
            ),
            RandomBadgeClassFactory(
140
                issuing_component='openedx__course'
141 142
            ),
            RandomBadgeClassFactory(
143
                issuing_component='openedx__course'
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
            ),
        ]
        self.courses = []
        for _badge_class in self.badge_classes:
            # pylint: disable=no-member
            self.courses.append([CourseFactory().location.course_key for _i in range(3)])
        lines = [badge_class.slug + ',' + ','.join([unicode(course_key) for course_key in keys])
                 for badge_class, keys in zip(self.badge_classes, self.courses)]
        config = '\r'.join(lines)
        self.config = CourseEventBadgesConfigurationFactory(course_groups=config)
        self.config_map = dict(zip(self.badge_classes, self.courses))

    def test_no_match(self):
        """
        Make sure a badge isn't created before a user's completed any course groups.
        """
        user = UserFactory()
        course = CourseFactory()
        GeneratedCertificate(
            # pylint: disable=no-member
            user=user, course_id=course.location.course_key, status=CertificateStatuses.downloadable
        ).save()
        # pylint: disable=no-member
        self.assertFalse(user.badgeassertion_set.all())

    def test_group_matches(self):
        """
        Make sure the proper badges are awarded when groups are completed.
        """
        user = UserFactory()
        items = list(self.config_map.items())
        for badge_class, course_keys in items:
            for i, key in enumerate(course_keys):
                GeneratedCertificate(
                    user=user, course_id=key, status=CertificateStatuses.downloadable
                ).save()
                # We don't award badges until all three are set.
                if i + 1 == len(course_keys):
                    self.assertTrue(badge_class.get_for_user(user))
                else:
                    self.assertFalse(badge_class.get_for_user(user))
        # pylint: disable=no-member
        classes = [badge.badge_class.id for badge in user.badgeassertion_set.all()]
        source_classes = [badge.id for badge in self.badge_classes]
        self.assertEqual(classes, source_classes)