Beispiel #1
0
    def test_add_entitlement_inactive_audit_enrollment(self,
                                                       mock_get_course_runs):
        """
        Verify that if an entitlement is added for a user, if the user has an inactive audit enrollment
        that enrollment is NOT upgraded to the mode of the entitlement and linked to the entitlement.
        """
        course_uuid = uuid.uuid4()
        entitlement_data = self._get_data_set(self.user, str(course_uuid))
        mock_get_course_runs.return_value = [{'key': str(self.course.id)}]  # pylint: disable=no-member

        # Add an audit course enrollment for user.
        enrollment = CourseEnrollment.enroll(
            self.user,
            self.course.id,  # pylint: disable=no-member
            mode=CourseMode.AUDIT)
        enrollment.update_enrollment(is_active=False)
        response = self.client.post(
            self.entitlements_list_url,
            data=json.dumps(entitlement_data),
            content_type='application/json',
        )
        assert response.status_code == 201
        results = response.data

        course_entitlement = CourseEntitlement.objects.get(
            user=self.user, course_uuid=course_uuid)
        # Assert that enrollment mode is now verified
        enrollment_mode, enrollment_active = CourseEnrollment.enrollment_mode_for_user(
            self.user,
            self.course.id  # pylint: disable=no-member
        )
        assert enrollment_mode == CourseMode.AUDIT
        assert enrollment_active is False
        assert course_entitlement.enrollment_course_run is None
        assert results == CourseEntitlementSerializer(course_entitlement).data
Beispiel #2
0
    def test_reinstate_entitlement(self):
        enrollment = CourseEnrollmentFactory(user=self.user, is_active=True)
        expired_entitlement = CourseEntitlementFactory.create(
            user=self.user,
            enrollment_course_run=enrollment,
            expired_at=datetime.now())
        url = reverse(self.ENTITLEMENTS_DETAILS_PATH,
                      args=[str(expired_entitlement.uuid)])

        update_data = {
            'expired_at':
            None,
            'enrollment_course_run':
            None,
            'support_details': [{
                'unenrolled_run': str(enrollment.course.id),
                'action': CourseEntitlementSupportDetail.REISSUE,
                'comments': 'Severe illness.'
            }]
        }

        response = self.client.patch(url,
                                     data=json.dumps(update_data),
                                     content_type='application/json')
        assert response.status_code == 200

        results = response.data
        reinstated_entitlement = CourseEntitlement.objects.get(
            uuid=expired_entitlement.uuid)
        assert results == CourseEntitlementSerializer(
            reinstated_entitlement).data
Beispiel #3
0
    def test_add_entitlement_with_support_detail(self):
        """
        Verify that an EntitlementSupportDetail entry is made when the request includes support interaction information.
        """
        course_uuid = uuid.uuid4()
        entitlement_data = self._get_data_set(self.user, str(course_uuid))
        entitlement_data['support_details'] = [
            {
                "action": "CREATE",
                "comments": "Family emergency."
            },
        ]

        response = self.client.post(
            self.entitlements_list_url,
            data=json.dumps(entitlement_data),
            content_type='application/json',
        )
        assert response.status_code == 201
        results = response.data

        course_entitlement = CourseEntitlement.objects.get(
            user=self.user,
            course_uuid=course_uuid
        )
        assert results == CourseEntitlementSerializer(course_entitlement).data
Beispiel #4
0
    def test_staff_get_only_staff_entitlements(self):
        CourseEntitlementFactory.create_batch(2)
        entitlement = CourseEntitlementFactory.create(user=self.user)

        response = self.client.get(
            self.entitlements_list_url,
            content_type='application/json',
        )
        assert response.status_code == 200

        results = response.data.get('results', [])
        assert results == CourseEntitlementSerializer([entitlement], many=True).data
Beispiel #5
0
    def test_non_staff_get_select_entitlements(self):
        not_staff_user = UserFactory()
        self.client.login(username=not_staff_user.username, password=TEST_PASSWORD)
        CourseEntitlementFactory.create_batch(2)
        entitlement = CourseEntitlementFactory.create(user=not_staff_user)
        response = self.client.get(
            self.entitlements_list_url,
            content_type='application/json',
        )
        assert response.status_code == 200

        results = response.data.get('results', [])
        assert results == CourseEntitlementSerializer([entitlement], many=True).data
Beispiel #6
0
    def test_get_entitlement_by_uuid(self):
        entitlement = CourseEntitlementFactory.create()
        CourseEntitlementFactory.create_batch(2)

        url = reverse(self.ENTITLEMENTS_DETAILS_PATH, args=[str(entitlement.uuid)])

        response = self.client.get(
            url,
            content_type='application/json',
        )
        assert response.status_code == 200

        results = response.data
        assert results == CourseEntitlementSerializer(entitlement).data and results.get('expired_at') is None
Beispiel #7
0
    def test_get_user_entitlements(self):
        user2 = UserFactory()
        CourseEntitlementFactory.create()
        entitlement_user2 = CourseEntitlementFactory.create(user=user2)
        url = reverse('entitlements_api:v1:entitlements-list')
        url += '?user={username}'.format(username=user2.username)
        response = self.client.get(
            url,
            content_type='application/json',
        )
        assert response.status_code == 200

        results = response.data.get('results', [])
        assert results == CourseEntitlementSerializer([entitlement_user2], many=True).data
Beispiel #8
0
    def create(self, request, *args, **kwargs):
        support_details = request.data.pop('support_details', [])
        email_opt_in = request.data.pop('email_opt_in', False)

        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)

        entitlement = serializer.instance
        set_entitlement_policy(entitlement, request.site)

        # The owners for a course are the organizations that own the course. By taking owner.key,
        # we are able to pass in the organization key for email_opt_in
        owners = get_owners_for_course(entitlement.course_uuid)
        for owner in owners:
            update_email_opt_in(entitlement.user, owner['key'], email_opt_in)

        if support_details:
            for support_detail in support_details:
                support_detail['entitlement'] = entitlement
                support_detail['support_user'] = request.user
                CourseEntitlementSupportDetail.objects.create(**support_detail)
        else:
            user = entitlement.user
            upgradeable_enrollments = self.get_upgradeable_enrollments_for_entitlement(
                entitlement)

            # if there is only one upgradeable enrollment, update the mode to the paid entitlement.mode
            # if there is any ambiguity about which enrollment to upgrade
            # (i.e. multiple upgradeable enrollments or no available upgradeable enrollment), don't alter
            # the enrollment
            if len(upgradeable_enrollments) == 1:
                enrollment = upgradeable_enrollments[0]
                log.info(
                    'Upgrading enrollment [%s] from %s to %s while adding entitlement for user [%s] for course [%s]',
                    enrollment, enrollment.mode, serializer.data.get('mode'),
                    user.username, serializer.data.get('course_uuid'))
                enrollment.update_enrollment(mode=entitlement.mode)
                entitlement.set_enrollment(enrollment)
            else:
                log.info(
                    'No enrollment upgraded while adding entitlement for user [%s] for course [%s] ',
                    user.username, serializer.data.get('course_uuid'))

        headers = self.get_success_headers(serializer.data)
        # Note, the entitlement is re-serialized before getting added to the Response,
        # so that the 'modified' date reflects changes that occur when upgrading enrollment.
        return Response(CourseEntitlementSerializer(entitlement).data,
                        status=status.HTTP_201_CREATED,
                        headers=headers)
Beispiel #9
0
    def test_add_entitlement(self):
        course_uuid = uuid.uuid4()
        entitlement_data = self._get_data_set(self.user, str(course_uuid))

        response = self.client.post(
            self.entitlements_list_url,
            data=json.dumps(entitlement_data),
            content_type='application/json',
        )
        assert response.status_code == 201
        results = response.data

        course_entitlement = CourseEntitlement.objects.get(
            user=self.user, course_uuid=course_uuid)
        assert results == CourseEntitlementSerializer(course_entitlement).data
Beispiel #10
0
    def test_add_entitlement_and_upgrade_audit_enrollment_with_dynamic_deadline(
            self, mock_get_course_runs):
        """
        Verify that if an entitlement is added for a user, if the user has one upgradeable enrollment
        that enrollment is upgraded to the mode of the entitlement and linked to the entitlement regardless of
        dynamic upgrade deadline being set.
        """
        DynamicUpgradeDeadlineConfiguration.objects.create(enabled=True)
        course = CourseFactory.create(self_paced=True)
        course_uuid = uuid.uuid4()
        course_mode = CourseModeFactory(
            course_id=course.id,
            mode_slug=CourseMode.VERIFIED,
            # This must be in the future to ensure it is returned by downstream code.
            expiration_datetime=now() + timedelta(days=1))

        # Set up Entitlement
        entitlement_data = self._get_data_set(self.user, str(course_uuid))
        mock_get_course_runs.return_value = [{'key': str(course.id)}]

        # Add an audit course enrollment for user.
        enrollment = CourseEnrollment.enroll(self.user,
                                             course.id,
                                             mode=CourseMode.AUDIT)

        # Set an upgrade schedule so that dynamic upgrade deadlines are used
        ScheduleFactory.create(
            enrollment=enrollment,
            upgrade_deadline=course_mode.expiration_datetime +
            timedelta(days=-3))

        # The upgrade should complete and ignore the deadline
        response = self.client.post(
            self.entitlements_list_url,
            data=json.dumps(entitlement_data),
            content_type='application/json',
        )
        assert response.status_code == 201
        results = response.data

        course_entitlement = CourseEntitlement.objects.get(
            user=self.user, course_uuid=course_uuid)
        # Assert that enrollment mode is now verified
        enrollment_mode = CourseEnrollment.enrollment_mode_for_user(
            self.user, course.id)[0]
        assert enrollment_mode == course_entitlement.mode
        assert course_entitlement.enrollment_course_run == enrollment
        assert results == CourseEntitlementSerializer(course_entitlement).data
Beispiel #11
0
    def test_data(self):
        entitlement = CourseEntitlementFactory()
        request = RequestFactory().get('')
        serializer = CourseEntitlementSerializer(entitlement,
                                                 context={'request': request})

        expected = {
            'user': entitlement.user.username,
            'uuid': str(entitlement.uuid),
            'expired_at': entitlement.expired_at,
            'course_uuid': str(entitlement.course_uuid),
            'mode': entitlement.mode,
            'refund_locked': False,
            'order_number': entitlement.order_number,
            'created': entitlement.created.strftime('%Y-%m-%dT%H:%M:%S.%fZ'),
            'modified': entitlement.modified.strftime('%Y-%m-%dT%H:%M:%S.%fZ'),
            'support_details': [],
        }

        assert serializer.data == expected