예제 #1
0
    def test_set_get_credit_requirements(self):
        """Test that if same requirement is added multiple times
        then it is added only one time and update for next all iterations.
        """
        self.add_credit_course()
        requirements = [
            {
                "namespace": "grade",
                "name": "grade",
                "display_name": "Grade",
                "criteria": {
                    "min_grade": 0.8
                }
            },
            {
                "namespace": "grade",
                "name": "grade",
                "display_name": "Grade",
                "criteria": {
                    "min_grade": 0.9
                }
            }
        ]
        set_credit_requirements(self.course_key, requirements)
        self.assertEqual(len(get_credit_requirements(self.course_key)), 1)

        # now verify that the saved requirement has values of last requirement
        # from all same requirements
        self.assertEqual(get_credit_requirements(self.course_key)[0], requirements[1])
예제 #2
0
    def test_set_credit_requirement_status(self):
        self.add_credit_course()
        requirements = [
            {"namespace": "grade", "name": "grade", "display_name": "Grade", "criteria": {"min_grade": 0.8}},
            {
                "namespace": "reverification",
                "name": "i4x://edX/DemoX/edx-reverification-block/assessment_uuid",
                "display_name": "Assessment 1",
                "criteria": {},
            },
        ]

        api.set_credit_requirements(self.course_key, requirements)
        course_requirements = api.get_credit_requirements(self.course_key)
        self.assertEqual(len(course_requirements), 2)

        # Initially, the status should be None
        req_status = api.get_credit_requirement_status(self.course_key, "staff", namespace="grade", name="grade")
        self.assertEqual(req_status[0]["status"], None)

        # Set the requirement to "satisfied" and check that it's actually set
        api.set_credit_requirement_status("staff", self.course_key, "grade", "grade")
        req_status = api.get_credit_requirement_status(self.course_key, "staff", namespace="grade", name="grade")
        self.assertEqual(req_status[0]["status"], "satisfied")

        # Set the requirement to "failed" and check that it's actually set
        api.set_credit_requirement_status("staff", self.course_key, "grade", "grade", status="failed")
        req_status = api.get_credit_requirement_status(self.course_key, "staff", namespace="grade", name="grade")
        self.assertEqual(req_status[0]["status"], "failed")
예제 #3
0
    def test_disable_credit_requirements(self):
        self.add_credit_course()
        requirements = [
            {
                "namespace": "grade",
                "name": "grade",
                "criteria": {
                    "min_grade": 0.8
                }
            },
            {
                "namespace": "grade",
                "name": "grade",
                "criteria": {
                    "min_grade": 0.8
                }
            }
        ]
        set_credit_requirements(self.course_key, requirements)
        self.assertEqual(len(get_credit_requirements(self.course_key)), 1)

        requirements = [
            {
                "namespace": "reverification",
                "name": "midterm",
                "criteria": {}
            }
        ]
        set_credit_requirements(self.course_key, requirements)
        self.assertEqual(len(get_credit_requirements(self.course_key)), 1)
        grade_req = CreditRequirement.objects.filter(namespace="grade", name="grade")
        self.assertEqual(len(grade_req), 1)
        self.assertEqual(grade_req[0].active, False)
예제 #4
0
    def setUp(self):
        super(TestMinGradedRequirementStatus, self).setUp()
        self.course = CourseFactory.create(
            org='Robot', number='999', display_name='Test Course'
        )

        self.user = UserFactory()
        self.request = RequestFactory().get('/')
        self.request.user = self.user
        self.client.login(username=self.user.username, password=self.user.password)

        # Enable the course for credit
        CreditCourse.objects.create(
            course_key=self.course.id,
            enabled=True,
        )

        # Configure a credit provider for the course
        CreditProvider.objects.create(
            provider_id="ASU",
            enable_integration=True,
            provider_url="https://credit.example.com/request",
        )

        requirements = [{
            "namespace": "grade",
            "name": "grade",
            "display_name": "Grade",
            "criteria": {"min_grade": 0.52},
        }]
        # Add a single credit requirement (final grade)
        set_credit_requirements(self.course.id, requirements)
예제 #5
0
    def test_declined_verification_on_skip(self):
        """Test that status with value 'declined' is added in credit
        requirement status model when a user skip's an ICRV.
        """
        reverification_service = ReverificationService()
        checkpoint = VerificationCheckpoint.objects.create(
            course_id=unicode(self.course_id),
            checkpoint_location=self.final_checkpoint_location
        )
        # Create credit course and set credit requirements.
        CreditCourse.objects.create(course_key=self.course_key, enabled=True)
        set_credit_requirements(
            self.course_key,
            [
                {
                    "namespace": "reverification",
                    "name": checkpoint.checkpoint_location,
                    "display_name": "Assessment 1",
                    "criteria": {},
                }
            ]
        )

        reverification_service.skip_verification(self.user.id, unicode(self.course_id), self.final_checkpoint_location)
        requirement_status = get_credit_requirement_status(
            self.course_key, self.user.username, 'reverification', checkpoint.checkpoint_location
        )
        self.assertEqual(SkippedReverification.objects.filter(user=self.user, course_id=self.course_id).count(), 1)
        self.assertEqual(len(requirement_status), 1)
        self.assertEqual(requirement_status[0].get('name'), checkpoint.checkpoint_location)
        self.assertEqual(requirement_status[0].get('status'), 'declined')
예제 #6
0
    def test_disable_existing_requirement(self):
        self.add_credit_course()

        # Set initial requirements
        requirements = [
            {
                "namespace": "reverification",
                "name": "midterm",
                "display_name": "Midterm",
                "criteria": {},
            },
            {
                "namespace": "grade",
                "name": "grade",
                "display_name": "Grade",
                "criteria": {
                    "min_grade": 0.8
                },
            }
        ]
        api.set_credit_requirements(self.course_key, requirements)

        # Update the requirements, removing an existing requirement
        api.set_credit_requirements(self.course_key, requirements[1:])

        # Expect that now only the grade requirement is returned
        visible_reqs = api.get_credit_requirements(self.course_key)
        self.assertEqual(len(visible_reqs), 1)
        self.assertEqual(visible_reqs[0]["namespace"], "grade")
예제 #7
0
    def setUp(self):
        """Create a course and an enrollment. """
        super(CreditCourseDashboardTest, self).setUp()

        # Create a user and log in
        self.user = UserFactory.create(username=self.USERNAME, password=self.PASSWORD)
        result = self.client.login(username=self.USERNAME, password=self.PASSWORD)
        self.assertTrue(result, msg="Could not log in")

        # Create a course and configure it as a credit course
        self.course = CourseFactory()
        CreditCourse.objects.create(course_key=self.course.id, enabled=True)  # pylint: disable=no-member

        # Configure a credit provider
        CreditProvider.objects.create(
            provider_id=self.PROVIDER_ID,
            display_name=self.PROVIDER_NAME,
            provider_status_url=self.PROVIDER_STATUS_URL,
            enable_integration=True,
        )

        # Configure a single credit requirement (minimum passing grade)
        credit_api.set_credit_requirements(
            self.course.id,  # pylint: disable=no-member
            [{"namespace": "grade", "name": "grade", "display_name": "Final Grade", "criteria": {"min_grade": 0.8}}],
        )

        # Enroll the user in the course as "verified"
        self.enrollment = CourseEnrollmentFactory(
            user=self.user, course_id=self.course.id, mode="verified"  # pylint: disable=no-member
        )
예제 #8
0
    def test_disable_credit_requirements(self):
        self.add_credit_course()
        requirements = [
            {
                "namespace": "grade",
                "name": "grade",
                "display_name": "Grade",
                "criteria": {
                    "min_grade": 0.8
                }
            }
        ]
        set_credit_requirements(self.course_key, requirements)
        self.assertEqual(len(get_credit_requirements(self.course_key)), 1)

        requirements = [
            {
                "namespace": "reverification",
                "name": "i4x://edX/DemoX/edx-reverification-block/assessment_uuid",
                "display_name": "Assessment 1",
                "criteria": {}
            }
        ]
        set_credit_requirements(self.course_key, requirements)
        self.assertEqual(len(get_credit_requirements(self.course_key)), 1)

        grade_req = CreditRequirement.objects.filter(namespace="grade", name="grade")
        self.assertEqual(len(grade_req), 1)
        self.assertEqual(grade_req[0].active, False)
예제 #9
0
    def test_get_credit_requirement(self):
        self.add_credit_course()
        requirements = [
            {
                "namespace": "grade",
                "name": "grade",
                "display_name": "Grade",
                "criteria": {
                    "min_grade": 0.8
                }
            }
        ]
        requirement = get_credit_requirement(self.course_key, "grade", "grade")
        self.assertIsNone(requirement)

        expected_requirement = {
            "course_key": self.course_key,
            "namespace": "grade",
            "name": "grade",
            "display_name": "Grade",
            "criteria": {
                "min_grade": 0.8
            }
        }
        set_credit_requirements(self.course_key, requirements)
        requirement = get_credit_requirement(self.course_key, "grade", "grade")
        self.assertIsNotNone(requirement)
        self.assertEqual(requirement, expected_requirement)
예제 #10
0
    def test_min_grade_credit_requirements_status(self):
        """
        Test for credit course. If user passes minimum grade requirement then
        status will be updated as satisfied in requirement status table.
        """
        self.basic_setup()
        self.submit_question_answer('p1', {'2_1': 'Correct'})
        self.submit_question_answer('p2', {'2_1': 'Correct'})

        # Enable the course for credit
        credit_course = CreditCourse.objects.create(
            course_key=self.course.id,
            enabled=True,
        )

        # Configure a credit provider for the course
        CreditProvider.objects.create(
            provider_id="ASU",
            enable_integration=True,
            provider_url="https://credit.example.com/request",
        )

        requirements = [{
            "namespace": "grade",
            "name": "grade",
            "display_name": "Grade",
            "criteria": {"min_grade": 0.52},
        }]
        # Add a single credit requirement (final grade)
        set_credit_requirements(self.course.id, requirements)

        self.get_grade_summary()
        req_status = get_credit_requirement_status(self.course.id, self.student_user.username, 'grade', 'grade')
        self.assertEqual(req_status[0]["status"], 'satisfied')
예제 #11
0
    def test_eligibility_email_with_providers(self, providers_list, providers_email_message, expected_subject):
        """ Test the credit requirements, eligibility notification, email
        for different providers combinations.
        """
        # Configure a course with two credit requirements
        self.add_credit_course()
        CourseFactory.create(org='edX', number='DemoX', display_name='Demo_Course')
        requirements = [
            {
                "namespace": "grade",
                "name": "grade",
                "display_name": "Grade",
                "criteria": {
                    "min_grade": 0.8
                },
            },
            {
                "namespace": "reverification",
                "name": "i4x://edX/DemoX/edx-reverification-block/assessment_uuid",
                "display_name": "Assessment 1",
                "criteria": {},
            }
        ]
        api.set_credit_requirements(self.course_key, requirements)

        user = UserFactory.create(username=self.USER_INFO['username'], password=self.USER_INFO['password'])

        # Satisfy one of the requirements, but not the other
        api.set_credit_requirement_status(
            user.username,
            self.course_key,
            requirements[0]["namespace"],
            requirements[0]["name"]
        )
        # Satisfy the other requirement. And mocked the api to return different kind of data.
        with mock.patch('openedx.core.djangoapps.credit.email_utils.get_credit_provider_display_names') as mock_method:
            mock_method.return_value = providers_list
            api.set_credit_requirement_status(
                "bob",
                self.course_key,
                requirements[1]["namespace"],
                requirements[1]["name"]
            )
        # Now the user should be eligible
        self.assertTrue(api.is_user_eligible_for_credit("bob", self.course_key))

        # Credit eligibility email should be sent
        self.assertEqual(len(mail.outbox), 1)

        # Verify the email subject
        self.assertEqual(mail.outbox[0].subject, expected_subject)

        # Now verify them email content
        email_payload_first = mail.outbox[0].attachments[0]._payload  # pylint: disable=protected-access
        html_content_first = email_payload_first[0]._payload[1]._payload  # pylint: disable=protected-access
        self.assertIn(providers_email_message, html_content_first)

        # test text email
        text_content_first = email_payload_first[0]._payload[0]._payload  # pylint: disable=protected-access
        self.assertIn(providers_email_message, text_content_first)
예제 #12
0
    def test_remove_credit_requirement_status(self):
        self.add_credit_course()
        requirements = [
            {"namespace": "grade", "name": "grade", "display_name": "Grade", "criteria": {"min_grade": 0.8}},
            {
                "namespace": "reverification",
                "name": "i4x://edX/DemoX/edx-reverification-block/assessment_uuid",
                "display_name": "Assessment 1",
                "criteria": {},
            },
        ]

        api.set_credit_requirements(self.course_key, requirements)
        course_requirements = api.get_credit_requirements(self.course_key)
        self.assertEqual(len(course_requirements), 2)

        # before setting credit_requirement_status
        api.remove_credit_requirement_status("staff", self.course_key, "grade", "grade")
        req_status = api.get_credit_requirement_status(self.course_key, "staff", namespace="grade", name="grade")
        self.assertIsNone(req_status[0]["status"])
        self.assertIsNone(req_status[0]["status_date"])
        self.assertIsNone(req_status[0]["reason"])

        # Set the requirement to "satisfied" and check that it's actually set
        api.set_credit_requirement_status("staff", self.course_key, "grade", "grade")
        req_status = api.get_credit_requirement_status(self.course_key, "staff", namespace="grade", name="grade")
        self.assertEqual(len(req_status), 1)
        self.assertEqual(req_status[0]["status"], "satisfied")

        # remove the credit requirement status and check that it's actually removed
        api.remove_credit_requirement_status("staff", self.course_key, "grade", "grade")
        req_status = api.get_credit_requirement_status(self.course_key, "staff", namespace="grade", name="grade")
        self.assertIsNone(req_status[0]["status"])
        self.assertIsNone(req_status[0]["status_date"])
        self.assertIsNone(req_status[0]["reason"])
예제 #13
0
 def test_set_get_credit_requirements(self):
     # Test that if same requirement is added multiple times
     self.add_credit_course()
     requirements = [
         {"namespace": "grade", "name": "grade", "display_name": "Grade", "criteria": {"min_grade": 0.8}},
         {"namespace": "grade", "name": "grade", "display_name": "Grade", "criteria": {"min_grade": 0.9}},
     ]
     api.set_credit_requirements(self.course_key, requirements)
     self.assertEqual(len(api.get_credit_requirements(self.course_key)), 1)
예제 #14
0
    def test_set_credit_requirements_invalid_course(self):
        # Test that 'InvalidCreditCourse' exception is raise if we try to
        # set credit requirements for a non credit course.
        requirements = [{"namespace": "grade", "name": "grade", "display_name": "Grade", "criteria": {}}]
        with self.assertRaises(InvalidCreditCourse):
            api.set_credit_requirements(self.course_key, requirements)

        self.add_credit_course(enabled=False)
        with self.assertRaises(InvalidCreditCourse):
            api.set_credit_requirements(self.course_key, requirements)
예제 #15
0
    def test_satisfy_all_requirements(self):
        # Configure a course with two credit requirements
        self.add_credit_course()
        requirements = [
            {
                "namespace": "grade",
                "name": "grade",
                "display_name": "Grade",
                "criteria": {
                    "min_grade": 0.8
                },
            },
            {
                "namespace": "reverification",
                "name": "i4x://edX/DemoX/edx-reverification-block/assessment_uuid",
                "display_name": "Assessment 1",
                "criteria": {},
            }
        ]
        api.set_credit_requirements(self.course_key, requirements)

        # Satisfy one of the requirements, but not the other
        with self.assertNumQueries(7):
            api.set_credit_requirement_status(
                "bob",
                self.course_key,
                requirements[0]["namespace"],
                requirements[0]["name"]
            )

        # The user should not be eligible (because only one requirement is satisfied)
        self.assertFalse(api.is_user_eligible_for_credit("bob", self.course_key))

        # Satisfy the other requirement
        with self.assertNumQueries(10):
            api.set_credit_requirement_status(
                "bob",
                self.course_key,
                requirements[1]["namespace"],
                requirements[1]["name"]
            )

        # Now the user should be eligible
        self.assertTrue(api.is_user_eligible_for_credit("bob", self.course_key))

        # The user should remain eligible even if the requirement status is later changed
        api.set_credit_requirement_status(
            "bob",
            self.course_key,
            requirements[0]["namespace"],
            requirements[0]["name"],
            status="failed"
        )
        self.assertTrue(api.is_user_eligible_for_credit("bob", self.course_key))
예제 #16
0
 def test_set_credit_requirements_invalid_course(self):
     requirements = [
         {
             "namespace": "grade",
             "name": "grade",
             "criteria": {}
         }
     ]
     with self.assertRaises(InvalidCreditCourse):
         set_credit_requirements(self.course_key, requirements)
     self.add_credit_course(enabled=False)
     with self.assertRaises(InvalidCreditCourse):
         set_credit_requirements(self.course_key, requirements)
예제 #17
0
    def test_requirements_to_disable(self):
        self.add_credit_course()
        requirements = [
            {
                "namespace": "grade",
                "name": "grade",
                "criteria": {
                    "min_grade": 0.8
                }
            },
            {
                "namespace": "grade",
                "name": "grade",
                "criteria": {
                    "min_grade": 0.8
                }
            }
        ]

        set_credit_requirements(self.course_key, requirements)
        old_requirements = CreditRequirement.get_course_requirements(self.course_key)
        self.assertEqual(len(old_requirements), 1)

        requirements = [
            {
                "namespace": "reverification",
                "name": "midterm",
                "criteria": {}
            }
        ]
        requirements_to_disabled = _get_requirements_to_disable(old_requirements, requirements)
        self.assertEqual(len(requirements_to_disabled), 1)
        self.assertEqual(requirements_to_disabled[0], old_requirements[0].id)

        requirements = [
            {
                "namespace": "grade",
                "name": "grade",
                "criteria": {
                    "min_grade": 0.8
                }
            },
            {
                "namespace": "reverification",
                "name": "midterm",
                "criteria": {}
            }
        ]
        requirements_to_disabled = _get_requirements_to_disable(old_requirements, requirements)
        self.assertEqual(len(requirements_to_disabled), 0)
예제 #18
0
    def test_set_credit_requirement_status_req_not_configured(self):
        # Configure a credit course with no requirements
        self.add_credit_course()

        # A user satisfies a requirement.  This could potentially
        # happen if there's a lag when the requirements are updated
        # after the course is published.
        api.set_credit_requirement_status("bob", self.course_key, "grade", "grade")

        # Since the requirement hasn't been published yet, it won't show
        # up in the list of requirements.
        req_status = api.get_credit_requirement_status(self.course_key, "bob", namespace="grade", name="grade")
        self.assertEqual(req_status, [])

        # Now add the requirements, simulating what happens when a course is published.
        requirements = [
            {
                "namespace": "grade",
                "name": "grade",
                "display_name": "Grade",
                "criteria": {
                    "min_grade": 0.8
                },
            },
            {
                "namespace": "reverification",
                "name": "i4x://edX/DemoX/edx-reverification-block/assessment_uuid",
                "display_name": "Assessment 1",
                "criteria": {},
            }
        ]
        api.set_credit_requirements(self.course_key, requirements)

        # The user should not have satisfied the requirements, since they weren't
        # in effect when the user completed the requirement
        req_status = api.get_credit_requirement_status(self.course_key, "bob")
        self.assertEqual(len(req_status), 2)
        self.assertEqual(req_status[0]["status"], None)
        self.assertEqual(req_status[0]["status"], None)

        # The user should *not* have satisfied the reverification requirement
        req_status = api.get_credit_requirement_status(
            self.course_key,
            "bob",
            namespace=requirements[1]["namespace"],
            name=requirements[1]["name"]
        )
        self.assertEqual(len(req_status), 1)
        self.assertEqual(req_status[0]["status"], None)
예제 #19
0
    def test_requirements_to_disable(self):
        self.add_credit_course()
        requirements = [
            {
                "namespace": "grade",
                "name": "grade",
                "display_name": "Grade",
                "criteria": {
                    "min_grade": 0.8
                }
            }
        ]

        set_credit_requirements(self.course_key, requirements)
        old_requirements = CreditRequirement.get_course_requirements(self.course_key)
        self.assertEqual(len(old_requirements), 1)

        requirements = [
            {
                "namespace": "reverification",
                "name": "i4x://edX/DemoX/edx-reverification-block/assessment_uuid",
                "display_name": "Assessment 1",
                "criteria": {}
            }
        ]
        requirements_to_disabled = _get_requirements_to_disable(old_requirements, requirements)
        self.assertEqual(len(requirements_to_disabled), 1)
        self.assertEqual(requirements_to_disabled[0], old_requirements[0].id)

        requirements = [
            {
                "namespace": "grade",
                "name": "grade",
                "display_name": "Grade",
                "criteria": {
                    "min_grade": 0.8
                }
            },
            {
                "namespace": "reverification",
                "name": "i4x://edX/DemoX/edx-reverification-block/assessment_uuid",
                "display_name": "Assessment 1",
                "criteria": {}
            }
        ]
        requirements_to_disabled = _get_requirements_to_disable(old_requirements, requirements)
        self.assertEqual(len(requirements_to_disabled), 0)
    def setUp(self):
        super(ProgressPageCreditRequirementsTest, self).setUp()

        # Create a course and configure it as a credit course
        self.course = CourseFactory.create()
        CreditCourse.objects.create(course_key=self.course.id, enabled=True)

        # Configure credit requirements (passing grade and in-course reverification)
        credit_api.set_credit_requirements(
            self.course.id,
            [
                {
                    "namespace": "grade",
                    "name": "grade",
                    "display_name": self.MIN_GRADE_REQ_DISPLAY,
                    "criteria": {
                        "min_grade": 0.8
                    }
                },
                {
                    "namespace": "reverification",
                    "name": "midterm",
                    "display_name": self.VERIFICATION_REQ_DISPLAY,
                    "criteria": {}
                }
            ]
        )

        # Create a user and log in
        self.user = UserFactory.create(username=self.USERNAME, password=self.PASSWORD)
        self.user.profile.name = self.USER_FULL_NAME
        self.user.profile.save()

        result = self.client.login(username=self.USERNAME, password=self.PASSWORD)
        self.assertTrue(result, msg="Could not log in")

        # Enroll the user in the course as "verified"
        self.enrollment = CourseEnrollmentFactory(
            user=self.user,
            course_id=self.course.id,
            mode="verified"
        )
    def test_min_grade_credit_requirements_status(self, mode):
        """
        Test for credit course. If user passes minimum grade requirement then
        status will be updated as satisfied in requirement status table.
        """
        self.basic_setup()

        # Enroll student in credit eligible mode.
        # Note that we can't call self.enroll here since that goes through
        # the Django student views, and does not update enrollment if it already exists.
        CourseEnrollment.enroll(self.student_user, self.course.id, mode)

        # Enable the course for credit
        CreditCourse.objects.create(course_key=self.course.id, enabled=True)

        # Configure a credit provider for the course
        CreditProvider.objects.create(
            provider_id="ASU",
            enable_integration=True,
            provider_url="https://credit.example.com/request",
        )

        requirements = [{
            "namespace": "grade",
            "name": "grade",
            "display_name": "Grade",
            "criteria": {"min_grade": 0.52},
        }]
        # Add a single credit requirement (final grade)
        set_credit_requirements(self.course.id, requirements)

        # Credit requirement is not satisfied before passing grade
        req_status = get_credit_requirement_status(self.course.id, self.student_user.username, 'grade', 'grade')
        self.assertEqual(req_status[0]["status"], None)

        self._stop_signal_patch()
        self.submit_question_answer('p1', {'2_1': 'Correct'})
        self.submit_question_answer('p2', {'2_1': 'Correct'})

        # Credit requirement is now satisfied after passing grade
        req_status = get_credit_requirement_status(self.course.id, self.student_user.username, 'grade', 'grade')
        self.assertEqual(req_status[0]["status"], 'satisfied')
예제 #22
0
 def test_set_get_credit_requirements(self):
     self.add_credit_course()
     requirements = [
         {
             "namespace": "grade",
             "name": "grade",
             "criteria": {
                 "min_grade": 0.8
             }
         },
         {
             "namespace": "grade",
             "name": "grade",
             "criteria": {
                 "min_grade": 0.8
             }
         }
     ]
     set_credit_requirements(self.course_key, requirements)
     self.assertEqual(len(get_credit_requirements(self.course_key)), 1)
예제 #23
0
    def setUp(self):
        super(ProgressPageCreditRequirementsTest, self).setUp()

        # Configure course as a credit course
        CreditCourse.objects.create(course_key=self.course.id, enabled=True)

        # Configure credit requirements (passing grade and in-course reverification)
        credit_api.set_credit_requirements(
            self.course.id,
            [
                {
                    "namespace": "grade",
                    "name": "grade",
                    "display_name": self.MIN_GRADE_REQ_DISPLAY,
                    "criteria": {
                        "min_grade": 0.8
                    }
                },
                {
                    "namespace": "reverification",
                    "name": "midterm",
                    "display_name": self.VERIFICATION_REQ_DISPLAY,
                    "criteria": {}
                }
            ]
        )

        # Create a user and log in
        self.user = UserFactory.create(username=self.USERNAME, password=self.PASSWORD)
        self.user.profile.name = self.USER_FULL_NAME
        self.user.profile.save()

        result = self.client.login(username=self.USERNAME, password=self.PASSWORD)
        self.assertTrue(result, msg="Could not log in")

        # Enroll the user in the course as "verified"
        self.enrollment = CourseEnrollmentFactory(
            user=self.user,
            course_id=self.course.id,
            mode="verified"
        )
    def test_min_grade_credit_requirements_status(self, mode):
        """
        Test for credit course. If user passes minimum grade requirement then
        status will be updated as satisfied in requirement status table.
        """
        self.basic_setup()

        # Enroll student in credit eligible mode.
        # Note that we can't call self.enroll here since that goes through
        # the Django student views, and does not update enrollment if it already exists.
        CourseEnrollment.enroll(self.student_user, self.course.id, mode)

        # Enable the course for credit
        CreditCourse.objects.create(course_key=self.course.id, enabled=True)

        # Configure a credit provider for the course
        CreditProvider.objects.create(
            provider_id="ASU",
            enable_integration=True,
            provider_url="https://credit.example.com/request",
        )

        requirements = [{
            "namespace": "grade",
            "name": "grade",
            "display_name": "Grade",
            "criteria": {"min_grade": 0.52},
        }]
        # Add a single credit requirement (final grade)
        set_credit_requirements(self.course.id, requirements)

        # Credit requirement is not satisfied before passing grade
        req_status = get_credit_requirement_status(self.course.id, self.student_user.username, 'grade', 'grade')
        assert req_status[0]['status'] is None

        self.submit_question_answer('p1', {'2_1': 'Correct'})
        self.submit_question_answer('p2', {'2_1': 'Correct'})

        # Credit requirement is now satisfied after passing grade
        req_status = get_credit_requirement_status(self.course.id, self.student_user.username, 'grade', 'grade')
        assert req_status[0]['status'] == 'satisfied'
예제 #25
0
    def setUp(self):
        """Create a course and an enrollment. """
        super(CreditCourseDashboardTest, self).setUp()

        # Create a user and log in
        self.user = UserFactory.create(username=self.USERNAME,
                                       password=self.PASSWORD)
        result = self.client.login(username=self.USERNAME,
                                   password=self.PASSWORD)
        self.assertTrue(result, msg="Could not log in")

        # Create a course and configure it as a credit course
        self.course = CourseFactory()
        CreditCourse.objects.create(course_key=self.course.id, enabled=True)  # pylint: disable=no-member

        # Configure a credit provider
        CreditProvider.objects.create(
            provider_id=self.PROVIDER_ID,
            display_name=self.PROVIDER_NAME,
            provider_status_url=self.PROVIDER_STATUS_URL,
            enable_integration=True,
        )

        # Configure a single credit requirement (minimum passing grade)
        credit_api.set_credit_requirements(
            self.course.id,  # pylint: disable=no-member
            [{
                "namespace": "grade",
                "name": "grade",
                "display_name": "Final Grade",
                "criteria": {
                    "min_grade": 0.8
                }
            }])

        # Enroll the user in the course as "verified"
        self.enrollment = CourseEnrollmentFactory(
            user=self.user,
            course_id=self.course.id,  # pylint: disable=no-member
            mode="verified")
    def setUp(self):
        super().setUp()
        self.course = CourseFactory.create(org='Robot',
                                           number='999',
                                           display_name='Test Course')

        self.user = UserFactory()
        self.request = RequestFactory().get('/')
        self.request.user = self.user
        self.client.login(username=self.user.username,
                          password=self.user.password)

        # Enable the course for credit
        CreditCourse.objects.create(
            course_key=self.course.id,
            enabled=True,
        )

        # Configure a credit provider for the course
        CreditProvider.objects.create(
            provider_id="ASU",
            enable_integration=True,
            provider_url="https://credit.example.com/request",
        )

        requirements = [{
            "namespace": "grade",
            "name": "grade",
            "display_name": "Grade",
            "criteria": {
                "min_grade": 0.52
            },
        }]
        # Add a single credit requirement (final grade)
        set_credit_requirements(self.course.id, requirements)

        # Enroll user in verified mode.
        self.enrollment = CourseEnrollment.enroll(self.user,
                                                  self.course.id,
                                                  mode=CourseMode.VERIFIED)
예제 #27
0
def update_credit_course_requirements(course_id):
    """
    Updates course requirements table for a course.

     Args:
        course_id(str): A string representation of course identifier

    Returns:
        None

    """
    try:
        course_key = CourseKey.from_string(course_id)
        is_credit_course = CreditCourse.is_credit_course(course_key)
        if is_credit_course:
            requirements = _get_course_credit_requirements(course_key)
            set_credit_requirements(course_key, requirements)
    except (InvalidKeyError, ItemNotFoundError, InvalidCreditRequirements) as exc:
        LOGGER.error('Error on adding the requirements for course %s - %s', course_id, str(exc))
        raise update_credit_course_requirements.retry(args=[course_id], exc=exc)
    else:
        LOGGER.info('Requirements added for course %s', course_id)
예제 #28
0
def update_credit_course_requirements(course_id):
    """
    Updates course requirements table for a course.

     Args:
        course_id(str): A string representation of course identifier

    Returns:
        None

    """
    try:
        course_key = CourseKey.from_string(course_id)
        is_credit_course = CreditCourse.is_credit_course(course_key)
        if is_credit_course:
            requirements = _get_course_credit_requirements(course_key)
            set_credit_requirements(course_key, requirements)
    except (InvalidKeyError, ItemNotFoundError, InvalidCreditRequirements) as exc:
        LOGGER.error(u'Error on adding the requirements for course %s - %s', course_id, six.text_type(exc))
        raise update_credit_course_requirements.retry(args=[course_id], exc=exc)
    else:
        LOGGER.info(u'Requirements added for course %s', course_id)
예제 #29
0
    def test_set_credit_requirement_status(self):
        self.add_credit_course()
        requirements = [
            {
                "namespace": "grade",
                "name": "grade",
                "display_name": "Grade",
                "criteria": {
                    "min_grade": 0.8
                }
            },
            {
                "namespace": "reverification",
                "name": "i4x://edX/DemoX/edx-reverification-block/assessment_uuid",
                "display_name": "Assessment 1",
                "criteria": {}
            }
        ]

        set_credit_requirements(self.course_key, requirements)
        course_requirements = CreditRequirement.get_course_requirements(self.course_key)
        self.assertEqual(len(course_requirements), 2)

        requirement = get_credit_requirement(self.course_key, "grade", "grade")
        set_credit_requirement_status("staff", requirement, 'satisfied', {})
        course_requirement = CreditRequirement.get_course_requirement(
            requirement['course_key'], requirement['namespace'], requirement['name']
        )
        status = CreditRequirementStatus.objects.get(username="******", requirement=course_requirement)
        self.assertEqual(status.requirement.namespace, requirement['namespace'])
        self.assertEqual(status.status, "satisfied")

        set_credit_requirement_status(
            "staff", requirement, 'failed', {'failure_reason': "requirements not satisfied"}
        )
        status = CreditRequirementStatus.objects.get(username="******", requirement=course_requirement)
        self.assertEqual(status.requirement.namespace, requirement['namespace'])
        self.assertEqual(status.status, "failed")
예제 #30
0
    def test_min_grade_credit_requirements_status(self):
        """
        Test for credit course. If user passes minimum grade requirement then
        status will be updated as satisfied in requirement status table.
        """
        self.basic_setup()
        self.submit_question_answer('p1', {'2_1': 'Correct'})
        self.submit_question_answer('p2', {'2_1': 'Correct'})

        # Enable the course for credit
        credit_course = CreditCourse.objects.create(  # pylint: disable=unused-variable
            course_key=self.course.id,
            enabled=True,
        )

        # Configure a credit provider for the course
        CreditProvider.objects.create(
            provider_id="ASU",
            enable_integration=True,
            provider_url="https://credit.example.com/request",
        )

        requirements = [{
            "namespace": "grade",
            "name": "grade",
            "display_name": "Grade",
            "criteria": {
                "min_grade": 0.52
            },
        }]
        # Add a single credit requirement (final grade)
        set_credit_requirements(self.course.id, requirements)

        self.get_grade_summary()
        req_status = get_credit_requirement_status(self.course.id,
                                                   self.student_user.username,
                                                   'grade', 'grade')
        self.assertEqual(req_status[0]["status"], 'satisfied')
예제 #31
0
 def test_set_get_credit_requirements(self):
     # Test that if same requirement is added multiple times
     self.add_credit_course()
     requirements = [
         {
             "namespace": "grade",
             "name": "grade",
             "display_name": "Grade",
             "criteria": {
                 "min_grade": 0.8
             },
         },
         {
             "namespace": "grade",
             "name": "grade",
             "display_name": "Grade",
             "criteria": {
                 "min_grade": 0.9
             },
         }
     ]
     api.set_credit_requirements(self.course_key, requirements)
     self.assertEqual(len(api.get_credit_requirements(self.course_key)), 1)
예제 #32
0
    def test_set_credit_requirement_status(self):
        self.add_credit_course()
        requirements = [
            {
                "namespace": "grade",
                "name": "grade",
                "display_name": "Grade",
                "criteria": {
                    "min_grade": 0.8
                },
            },
            {
                "namespace": "reverification",
                "name": "i4x://edX/DemoX/edx-reverification-block/assessment_uuid",
                "display_name": "Assessment 1",
                "criteria": {},
            }
        ]

        api.set_credit_requirements(self.course_key, requirements)
        course_requirements = api.get_credit_requirements(self.course_key)
        self.assertEqual(len(course_requirements), 2)

        # Initially, the status should be None
        req_status = api.get_credit_requirement_status(self.course_key, "staff", namespace="grade", name="grade")
        self.assertEqual(req_status[0]["status"], None)

        # Set the requirement to "satisfied" and check that it's actually set
        api.set_credit_requirement_status("staff", self.course_key, "grade", "grade")
        req_status = api.get_credit_requirement_status(self.course_key, "staff", namespace="grade", name="grade")
        self.assertEqual(req_status[0]["status"], "satisfied")

        # Set the requirement to "failed" and check that it's actually set
        api.set_credit_requirement_status("staff", self.course_key, "grade", "grade", status="failed")
        req_status = api.get_credit_requirement_status(self.course_key, "staff", namespace="grade", name="grade")
        self.assertEqual(req_status[0]["status"], "failed")
예제 #33
0
    def test_satisfy_all_requirements(self):
        """ Test the credit requirements, eligibility notification, email
        content caching for a credit course.
        """
        # Configure a course with two credit requirements
        self.add_credit_course()
        CourseFactory.create(org='edX',
                             number='DemoX',
                             display_name='Demo_Course')

        requirements = [{
            "namespace": "grade",
            "name": "grade",
            "display_name": "Grade",
            "criteria": {
                "min_grade": 0.8
            },
        }, {
            "namespace": "reverification",
            "name": "i4x://edX/DemoX/edx-reverification-block/assessment_uuid",
            "display_name": "Assessment 1",
            "criteria": {},
        }]
        api.set_credit_requirements(self.course_key, requirements)

        user = UserFactory.create(username=self.USER_INFO['username'],
                                  password=self.USER_INFO['password'])

        # Satisfy one of the requirements, but not the other
        with self.assertNumQueries(7):
            api.set_credit_requirement_status(user.username, self.course_key,
                                              requirements[0]["namespace"],
                                              requirements[0]["name"])

        # The user should not be eligible (because only one requirement is satisfied)
        self.assertFalse(
            api.is_user_eligible_for_credit("bob", self.course_key))

        # Satisfy the other requirement
        with self.assertNumQueries(11):
            api.set_credit_requirement_status("bob", self.course_key,
                                              requirements[1]["namespace"],
                                              requirements[1]["name"])

        # Now the user should be eligible
        self.assertTrue(api.is_user_eligible_for_credit(
            "bob", self.course_key))

        # Credit eligibility email should be sent
        self.assertEqual(len(mail.outbox), 1)
        self.assertEqual(mail.outbox[0].subject, 'Course Credit Eligibility')

        # Now verify them email content
        email_payload_first = mail.outbox[0].attachments[0]._payload  # pylint: disable=protected-access

        # Test that email has two payloads [multipart (plain text and html
        # content), attached image]
        self.assertEqual(len(email_payload_first), 2)
        # pylint: disable=protected-access
        self.assertIn('text/plain',
                      email_payload_first[0]._payload[0]['Content-Type'])
        # pylint: disable=protected-access
        self.assertIn('text/html',
                      email_payload_first[0]._payload[1]['Content-Type'])
        self.assertIn('image/png', email_payload_first[1]['Content-Type'])

        # Now check that html email content has same logo image 'Content-ID'
        # as the attached logo image 'Content-ID'
        email_image = email_payload_first[1]
        html_content_first = email_payload_first[0]._payload[1]._payload  # pylint: disable=protected-access

        # strip enclosing angle brackets from 'logo_image' cache 'Content-ID'
        image_id = email_image.get('Content-ID', '')[1:-1]
        self.assertIsNotNone(image_id)
        self.assertIn(image_id, html_content_first)

        # Delete the eligibility entries and satisfy the user's eligibility
        # requirement again to trigger eligibility notification
        CreditEligibility.objects.all().delete()
        with self.assertNumQueries(12):
            api.set_credit_requirement_status("bob", self.course_key,
                                              requirements[1]["namespace"],
                                              requirements[1]["name"])

        # Credit eligibility email should be sent
        self.assertEqual(len(mail.outbox), 2)
        # Now check that on sending eligibility notification again cached
        # logo image is used
        email_payload_second = mail.outbox[1].attachments[0]._payload  # pylint: disable=protected-access
        html_content_second = email_payload_second[0]._payload[1]._payload  # pylint: disable=protected-access
        self.assertIn(image_id, html_content_second)

        # The user should remain eligible even if the requirement status is later changed
        api.set_credit_requirement_status("bob",
                                          self.course_key,
                                          requirements[0]["namespace"],
                                          requirements[0]["name"],
                                          status="failed")
        self.assertTrue(api.is_user_eligible_for_credit(
            "bob", self.course_key))
예제 #34
0
 def test_set_credit_requirements_invalid_requirements(self, requirements):
     self.add_credit_course()
     with self.assertRaises(InvalidCreditRequirements):
         api.set_credit_requirements(self.course_key, requirements)
예제 #35
0
    def test_satisfy_all_requirements(self):
        # Configure a course with two credit requirements
        self.add_credit_course()
        CourseFactory.create(org='edX', number='DemoX', display_name='Demo_Course')

        requirements = [
            {
                "namespace": "grade",
                "name": "grade",
                "display_name": "Grade",
                "criteria": {
                    "min_grade": 0.8
                },
            },
            {
                "namespace": "reverification",
                "name": "i4x://edX/DemoX/edx-reverification-block/assessment_uuid",
                "display_name": "Assessment 1",
                "criteria": {},
            }
        ]
        api.set_credit_requirements(self.course_key, requirements)

        user = UserFactory.create(username=self.USER_INFO['username'], password=self.USER_INFO['password'])

        # Satisfy one of the requirements, but not the other
        with self.assertNumQueries(7):
            api.set_credit_requirement_status(
                user.username,
                self.course_key,
                requirements[0]["namespace"],
                requirements[0]["name"]
            )

        # The user should not be eligible (because only one requirement is satisfied)
        self.assertFalse(api.is_user_eligible_for_credit("bob", self.course_key))

        # Satisfy the other requirement
        with self.assertNumQueries(11):
            api.set_credit_requirement_status(
                "bob",
                self.course_key,
                requirements[1]["namespace"],
                requirements[1]["name"]
            )

        # Now the user should be eligible
        self.assertTrue(api.is_user_eligible_for_credit("bob", self.course_key))

        # Credit eligible mail should be sent
        self.assertEqual(len(mail.outbox), 1)
        self.assertEqual(mail.outbox[0].subject, 'Course Credit Eligibility')

        # The user should remain eligible even if the requirement status is later changed
        api.set_credit_requirement_status(
            "bob",
            self.course_key,
            requirements[0]["namespace"],
            requirements[0]["name"],
            status="failed"
        )
        self.assertTrue(api.is_user_eligible_for_credit("bob", self.course_key))
예제 #36
0
    def test_set_credit_requirement_status(self):
        username = "******"
        credit_course = self.add_credit_course()
        requirements = [
            {
                "namespace": "grade",
                "name": "grade",
                "display_name": "Grade",
                "criteria": {
                    "min_grade": 0.8
                },
            },
            {
                "namespace": "reverification",
                "name": "i4x://edX/DemoX/edx-reverification-block/assessment_uuid",
                "display_name": "Assessment 1",
                "criteria": {},
            }
        ]

        api.set_credit_requirements(self.course_key, requirements)
        course_requirements = api.get_credit_requirements(self.course_key)
        self.assertEqual(len(course_requirements), 2)

        # Initially, the status should be None
        self.assert_grade_requirement_status(None, 0)

        # Requirement statuses cannot be changed if a CreditRequest exists
        credit_request = CreditRequest.objects.create(
            course=credit_course,
            provider=CreditProvider.objects.first(),
            username=username,
        )
        api.set_credit_requirement_status(username, self.course_key, "grade", "grade")
        self.assert_grade_requirement_status(None, 0)
        credit_request.delete()

        # Set the requirement to "satisfied" and check that it's actually set
        api.set_credit_requirement_status(username, self.course_key, "grade", "grade")
        self.assert_grade_requirement_status('satisfied', 0)

        # Set the requirement to "failed" and check that it's actually set
        api.set_credit_requirement_status(username, self.course_key, "grade", "grade", status="failed")
        self.assert_grade_requirement_status('failed', 0)

        req_status = api.get_credit_requirement_status(self.course_key, "staff")
        self.assertEqual(req_status[0]["status"], "failed")
        self.assertEqual(req_status[0]["order"], 0)

        # make sure the 'order' on the 2nd requirement is set correctly (aka 1)
        self.assertEqual(req_status[1]["status"], None)
        self.assertEqual(req_status[1]["order"], 1)

        # Set the requirement to "declined" and check that it's actually set
        api.set_credit_requirement_status(
            username, self.course_key,
            "reverification",
            "i4x://edX/DemoX/edx-reverification-block/assessment_uuid",
            status="declined"
        )
        req_status = api.get_credit_requirement_status(
            self.course_key,
            username,
            namespace="reverification",
            name="i4x://edX/DemoX/edx-reverification-block/assessment_uuid"
        )
        self.assertEqual(req_status[0]["status"], "declined")
예제 #37
0
    def test_set_credit_requirement_status(self):
        username = "******"
        credit_course = self.add_credit_course()
        requirements = [
            {
                "namespace": "grade",
                "name": "grade",
                "display_name": "Grade",
                "criteria": {
                    "min_grade": 0.8
                },
            },
            {
                "namespace": "reverification",
                "name": "i4x://edX/DemoX/edx-reverification-block/assessment_uuid",
                "display_name": "Assessment 1",
                "criteria": {},
            }
        ]

        api.set_credit_requirements(self.course_key, requirements)
        course_requirements = api.get_credit_requirements(self.course_key)
        self.assertEqual(len(course_requirements), 2)

        # Initially, the status should be None
        self.assert_grade_requirement_status(None, 0)

        # Requirement statuses cannot be changed if a CreditRequest exists
        credit_request = CreditRequest.objects.create(
            course=credit_course,
            provider=CreditProvider.objects.first(),
            username=username,
        )
        api.set_credit_requirement_status(username, self.course_key, "grade", "grade")
        self.assert_grade_requirement_status(None, 0)
        credit_request.delete()

        # Set the requirement to "satisfied" and check that it's actually set
        api.set_credit_requirement_status(username, self.course_key, "grade", "grade")
        self.assert_grade_requirement_status('satisfied', 0)

        # Set the requirement to "failed" and check that it's actually set
        api.set_credit_requirement_status(username, self.course_key, "grade", "grade", status="failed")
        self.assert_grade_requirement_status('failed', 0)

        req_status = api.get_credit_requirement_status(self.course_key, "staff")
        self.assertEqual(req_status[0]["status"], "failed")
        self.assertEqual(req_status[0]["order"], 0)

        # make sure the 'order' on the 2nd requirement is set correctly (aka 1)
        self.assertEqual(req_status[1]["status"], None)
        self.assertEqual(req_status[1]["order"], 1)

        # Set the requirement to "declined" and check that it's actually set
        api.set_credit_requirement_status(
            username, self.course_key,
            "reverification",
            "i4x://edX/DemoX/edx-reverification-block/assessment_uuid",
            status="declined"
        )
        req_status = api.get_credit_requirement_status(
            self.course_key,
            username,
            namespace="reverification",
            name="i4x://edX/DemoX/edx-reverification-block/assessment_uuid"
        )
        self.assertEqual(req_status[0]["status"], "declined")
예제 #38
0
    def test_satisfy_all_requirements(self):
        """ Test the credit requirements, eligibility notification, email
        content caching for a credit course.
        """
        # Configure a course with two credit requirements
        self.add_credit_course()
        CourseFactory.create(org='edX', number='DemoX', display_name='Demo_Course')

        requirements = [
            {
                "namespace": "grade",
                "name": "grade",
                "display_name": "Grade",
                "criteria": {
                    "min_grade": 0.8
                },
            },
            {
                "namespace": "reverification",
                "name": "i4x://edX/DemoX/edx-reverification-block/assessment_uuid",
                "display_name": "Assessment 1",
                "criteria": {},
            }
        ]
        api.set_credit_requirements(self.course_key, requirements)

        user = UserFactory.create(username=self.USER_INFO['username'], password=self.USER_INFO['password'])

        # Satisfy one of the requirements, but not the other
        with self.assertNumQueries(11):
            api.set_credit_requirement_status(
                user.username,
                self.course_key,
                requirements[0]["namespace"],
                requirements[0]["name"]
            )

        # The user should not be eligible (because only one requirement is satisfied)
        self.assertFalse(api.is_user_eligible_for_credit("bob", self.course_key))

        # Satisfy the other requirement
        with self.assertNumQueries(15):
            api.set_credit_requirement_status(
                "bob",
                self.course_key,
                requirements[1]["namespace"],
                requirements[1]["name"]
            )

        # Now the user should be eligible
        self.assertTrue(api.is_user_eligible_for_credit("bob", self.course_key))

        # Credit eligibility email should be sent
        self.assertEqual(len(mail.outbox), 1)
        self.assertEqual(mail.outbox[0].subject, 'Course Credit Eligibility')

        # Now verify them email content
        email_payload_first = mail.outbox[0].attachments[0]._payload  # pylint: disable=protected-access

        # Test that email has two payloads [multipart (plain text and html
        # content), attached image]
        self.assertEqual(len(email_payload_first), 2)
        # pylint: disable=protected-access
        self.assertIn('text/plain', email_payload_first[0]._payload[0]['Content-Type'])
        # pylint: disable=protected-access
        self.assertIn('text/html', email_payload_first[0]._payload[1]['Content-Type'])
        self.assertIn('image/png', email_payload_first[1]['Content-Type'])

        # Now check that html email content has same logo image 'Content-ID'
        # as the attached logo image 'Content-ID'
        email_image = email_payload_first[1]
        html_content_first = email_payload_first[0]._payload[1]._payload  # pylint: disable=protected-access

        # strip enclosing angle brackets from 'logo_image' cache 'Content-ID'
        image_id = email_image.get('Content-ID', '')[1:-1]
        self.assertIsNotNone(image_id)
        self.assertIn(image_id, html_content_first)

        # Delete the eligibility entries and satisfy the user's eligibility
        # requirement again to trigger eligibility notification
        CreditEligibility.objects.all().delete()
        with self.assertNumQueries(13):
            api.set_credit_requirement_status(
                "bob",
                self.course_key,
                requirements[1]["namespace"],
                requirements[1]["name"]
            )

        # Credit eligibility email should be sent
        self.assertEqual(len(mail.outbox), 2)
        # Now check that on sending eligibility notification again cached
        # logo image is used
        email_payload_second = mail.outbox[1].attachments[0]._payload  # pylint: disable=protected-access
        html_content_second = email_payload_second[0]._payload[1]._payload  # pylint: disable=protected-access
        self.assertIn(image_id, html_content_second)

        # The user should remain eligible even if the requirement status is later changed
        api.set_credit_requirement_status(
            "bob",
            self.course_key,
            requirements[0]["namespace"],
            requirements[0]["name"],
            status="failed"
        )
        self.assertTrue(api.is_user_eligible_for_credit("bob", self.course_key))
예제 #39
0
 def test_set_credit_requirements_invalid_requirements(self, requirements):
     self.add_credit_course()
     with self.assertRaises(InvalidCreditRequirements):
         set_credit_requirements(self.course_key, requirements)