def test_course_with_honor_seat_sku(self, user_is_active): """ If the course has a SKU, the view should get authorization from the E-Commerce API before enrolling the user in the course. If authorization is approved, the user should be redirected to the user dashboard. """ # Set user's active flag self.user.is_active = user_is_active self.user.save() # pylint: disable=no-member return_value = { 'id': TEST_BASKET_ID, 'payment_data': None, 'order': { 'number': TEST_ORDER_NUMBER } } with mock_create_basket(response=return_value): # Test that call without utm tracking works self._test_successful_ecommerce_api_call() with mock.patch( 'student.models.RegistrationCookieConfiguration.current' ) as config: instance = config.return_value instance.utm_cookie_name = UTM_COOKIE_NAME # Test that call with cookie passes cookie along self._test_successful_ecommerce_api_call( utm_tracking_present=True)
def test_marketing_email_opt_in(self, is_opt_in, has_sku, is_exception, mock_update): """ Ensures the email opt-in flag is handled, if present, and that problems handling the flag don't cause the rest of the enrollment transaction to fail. """ if not has_sku: for course_mode in CourseMode.objects.filter( course_id=self.course.id): course_mode.sku = None course_mode.save() if is_exception: mock_update.side_effect = Exception("boink") return_value = { 'id': TEST_BASKET_ID, 'payment_data': None, 'order': { 'number': TEST_ORDER_NUMBER } } with mock_create_basket(response=return_value, expect_called=has_sku): response = self._post_to_view(marketing_email_opt_in=is_opt_in) self.assertEqual(mock_update.called, is_opt_in) self.assertEqual(response.status_code, 200)
def test_ecommerce_api_timeout(self): """ If the call to the E-Commerce API times out, the view should log an error and return an HTTP 503 status. """ with mock_create_basket(exception=exceptions.Timeout): response = self._post_to_view() self.assertValidEcommerceInternalRequestErrorResponse(response) self.assertUserNotEnrolled()
def test_closed_course(self): """ Ensure that the view does not attempt to create a basket for closed courses. """ self.course.enrollment_end = datetime.now(pytz.UTC) - timedelta(days=1) modulestore().update_item(self.course, self.user.id) # pylint:disable=no-member with mock_create_basket(expect_called=False): self.assertEqual(self._post_to_view().status_code, 406)
def test_ecommerce_api_error(self): """ If the E-Commerce API raises an error, the view should return an HTTP 503 status. """ with mock_create_basket(exception=exceptions.SlumberBaseException): response = self._post_to_view() self.assertValidEcommerceInternalRequestErrorResponse(response) self.assertUserNotEnrolled()
def test_course_with_paid_seat_sku(self, user_is_active): """ If the course has a SKU, the view should return data that the client will use to redirect the user to an external payment processor. """ # Set user's active flag self.user.is_active = user_is_active self.user.save() # pylint: disable=no-member return_value = {'id': TEST_BASKET_ID, 'payment_data': TEST_PAYMENT_DATA, 'order': None} with mock_create_basket(response=return_value): self._test_successful_ecommerce_api_call(False)
def test_course_with_paid_seat_sku(self, user_is_active): """ If the course has a SKU, the view should return data that the client will use to redirect the user to an external payment processor. """ # Set user's active flag self.user.is_active = user_is_active self.user.save() # pylint: disable=no-member return_value = {"id": TEST_BASKET_ID, "payment_data": TEST_PAYMENT_DATA, "order": None} with mock_create_basket(response=return_value): self._test_successful_ecommerce_api_call(False)
def _test_course_without_sku(self): """ Validates the view bypasses the E-Commerce API when the course has no CourseModes with SKUs. """ # Place an order with mock_create_basket(expect_called=False): response = self._post_to_view() # Validate the response content self.assertEqual(response.status_code, 200) msg = Messages.NO_SKU_ENROLLED.format(enrollment_mode='honor', course_id=self.course.id, username=self.user.username) self.assertResponseMessage(response, msg)
def test_course_with_honor_seat_sku(self, user_is_active): """ If the course has a SKU, the view should get authorization from the E-Commerce API before enrolling the user in the course. If authorization is approved, the user should be redirected to the user dashboard. """ # Set user's active flag self.user.is_active = user_is_active self.user.save() # pylint: disable=no-member return_value = {"id": TEST_BASKET_ID, "payment_data": None, "order": {"number": TEST_ORDER_NUMBER}} with mock_create_basket(response=return_value): self._test_successful_ecommerce_api_call()
def test_course_with_honor_seat_sku(self, user_is_active): """ If the course has a SKU, the view should get authorization from the E-Commerce API before enrolling the user in the course. If authorization is approved, the user should be redirected to the user dashboard. """ # Set user's active flag self.user.is_active = user_is_active self.user.save() # pylint: disable=no-member return_value = {'id': TEST_BASKET_ID, 'payment_data': None, 'order': {'number': TEST_ORDER_NUMBER}} with mock_create_basket(response=return_value): self._test_successful_ecommerce_api_call()
def test_existing_inactive_enrollment(self): """ If the user has an inactive enrollment for the course, the view should behave as if the user has no enrollment. """ # Create an inactive enrollment CourseEnrollment.enroll(self.user, self.course.id) CourseEnrollment.unenroll(self.user, self.course.id, True) self.assertFalse(CourseEnrollment.is_enrolled(self.user, self.course.id)) self.assertIsNotNone(get_enrollment(self.user.username, unicode(self.course.id))) with mock_create_basket(): self._test_successful_ecommerce_api_call(False)
def test_ecommerce_service_not_configured(self): """ If the E-Commerce Service is not configured, the view should enroll the user. """ with mock_create_basket(expect_called=False): response = self._post_to_view() # Validate the response self.assertEqual(response.status_code, 200) msg = Messages.NO_ECOM_API.format(username=self.user.username, course_id=self.course.id) self.assertResponseMessage(response, msg) # Ensure that the user is not enrolled and that no calls were made to the E-Commerce API self.assertTrue(CourseEnrollment.is_enrolled(self.user, self.course.id))
def assertProfessionalModeBypassed(self): """ Verifies that the view returns HTTP 406 when a course with no honor mode is encountered. """ CourseMode.objects.filter(course_id=self.course.id).delete() mode = CourseMode.NO_ID_PROFESSIONAL_MODE CourseModeFactory.create(course_id=self.course.id, mode_slug=mode, mode_display_name=mode, sku=uuid4().hex.decode('ascii')) with mock_create_basket(expect_called=False): response = self._post_to_view() # The view should return an error status code self.assertEqual(response.status_code, 406) msg = Messages.NO_HONOR_MODE.format(course_id=self.course.id) self.assertResponseMessage(response, msg)
def assertProfessionalModeBypassed(self): """ Verifies that the view returns HTTP 406 when a course with no honor or audit mode is encountered. """ CourseMode.objects.filter(course_id=self.course.id).delete() mode = CourseMode.NO_ID_PROFESSIONAL_MODE CourseModeFactory.create(course_id=self.course.id, mode_slug=mode, mode_display_name=mode, sku=uuid4().hex.decode('ascii')) with mock_create_basket(expect_called=False): response = self._post_to_view() # The view should return an error status code self.assertEqual(response.status_code, 406) msg = Messages.NO_DEFAULT_ENROLLMENT_MODE.format(course_id=self.course.id) self.assertResponseMessage(response, msg)
def test_course_without_creating_order(self, user_is_active): """ If the course has a SKU, and the STOP_BASKET_CREATION waffle flag is on, the enrollment should happen without contacting ecommerce api """ # Set user's active flag self.user.is_active = user_is_active self.user.save() # pylint: disable=no-member with mock_create_basket(expect_called=False): response = self._post_to_view() # Validate the response content self.assertEqual(response.status_code, 200) msg = Messages.ENROLL_DIRECTLY.format(course_id=self.course.id, username=self.user.username) self.assertResponseMessage(response, msg)
def test_marketing_email_opt_in(self, is_opt_in, has_sku, is_exception, mock_update): """ Ensures the email opt-in flag is handled, if present, and that problems handling the flag don't cause the rest of the enrollment transaction to fail. """ if not has_sku: for course_mode in CourseMode.objects.filter(course_id=self.course.id): course_mode.sku = None course_mode.save() if is_exception: mock_update.side_effect = Exception("boink") return_value = {"id": TEST_BASKET_ID, "payment_data": None, "order": {"number": TEST_ORDER_NUMBER}} with mock_create_basket(response=return_value, expect_called=has_sku): response = self._post_to_view(marketing_email_opt_in=is_opt_in) self.assertEqual(mock_update.called, is_opt_in) self.assertEqual(response.status_code, 200)
def test_course_with_honor_seat_sku(self, user_is_active): """ If the course has a SKU, the view should get authorization from the E-Commerce API before enrolling the user in the course. If authorization is approved, the user should be redirected to the user dashboard. """ # Set user's active flag self.user.is_active = user_is_active self.user.save() # pylint: disable=no-member return_value = {'id': TEST_BASKET_ID, 'payment_data': None, 'order': {'number': TEST_ORDER_NUMBER}} with mock_create_basket(response=return_value): # Test that call without utm tracking works self._test_successful_ecommerce_api_call() with mock.patch('student.models.RegistrationCookieConfiguration.current') as config: instance = config.return_value instance.utm_cookie_name = UTM_COOKIE_NAME # Test that call with cookie passes cookie along self._test_successful_ecommerce_api_call(utm_tracking_present=True)