Ejemplo n.º 1
0
class VoucherRemoveMessagesViewTests(CouponMixin, CourseCatalogTestMixin, TestCase):
    """ VoucherRemoveMessagesView view tests. """

    def setUp(self):
        super(VoucherRemoveMessagesViewTests, self).setUp()
        self.user = self.create_user()
        self.client.login(username=self.user.username, password=self.password)

        self.course = CourseFactory()
        self.course.create_or_update_seat('verified', True, 50, self.partner)
        self.product = self.course.create_or_update_seat('verified', False, 0, self.partner)
        self.voucher, __ = prepare_voucher(code=COUPON_CODE)

        self.request = RequestFactory().request()
        # Fallback storage is needed in tests with messages
        setattr(self.request, 'session', 'session')
        messages = FallbackStorage(self.request)
        setattr(self.request, '_messages', messages)
        self.request.user = self.user

        basket = factories.BasketFactory(owner=self.user, site=self.site)
        basket.add_product(self.product, 1)
        self.request.basket = basket

        self.voucher_remove_view = VoucherRemoveMessagesView()

    def test_remove_voucher_pk_conversion(self):
        """ Verify that voucher primary key is converted to integer """
        self.voucher_remove_view.post(self.request, pk=self.voucher.id)
        request_message = list(get_messages(self.request))[-1].message
        self.assertEqual(
            str(request_message),
            "No voucher found with id '{0}'".format(self.voucher.id)
        )
    def setUp(self):
        super(CouponViewSetTest, self).setUp()
        self.user = self.create_user(is_staff=True)
        self.client.login(username=self.user.username, password=self.password)

        course = CourseFactory(id='edx/Demo_Course/DemoX')
        course.create_or_update_seat('verified', True, 50, self.partner)

        self.catalog = Catalog.objects.create(partner=self.partner)
        self.product_class, __ = ProductClass.objects.get_or_create(name='Coupon')
        self.coupon_data = {
            'title': 'Test Coupon',
            'partner': self.partner,
            'benefit_type': Benefit.PERCENTAGE,
            'benefit_value': 100,
            'catalog': self.catalog,
            'end_date': '2020-1-1',
            'code': '',
            'quantity': 2,
            'start_date': '2015-1-1',
            'voucher_type': Voucher.ONCE_PER_CUSTOMER,
            'categories': [self.category],
            'note': None,
            'max_uses': None,
        }
Ejemplo n.º 3
0
 def setUp(self):
     super(EnrollmentCodeFulfillmentModuleTests, self).setUp()
     toggle_switch(ENROLLMENT_CODE_SWITCH, True)
     course = CourseFactory()
     course.create_or_update_seat('verified', True, 50, self.partner)
     enrollment_code = Product.objects.get(product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
     user = UserFactory()
     basket = BasketFactory()
     basket.add_product(enrollment_code, self.QUANTITY)
     self.order = factories.create_order(number=1, basket=basket, user=user)
Ejemplo n.º 4
0
    def setUp(self):
        super(BasketSingleItemViewTests, self).setUp()
        self.user = self.create_user()
        self.client.login(username=self.user.username, password=self.password)

        course = CourseFactory()
        course.create_or_update_seat('verified', True, 50, self.partner)
        product = course.create_or_update_seat('verified', False, 0, self.partner)
        self.stock_record = StockRecordFactory(product=product, partner=self.partner)
        self.catalog = Catalog.objects.create(partner=self.partner)
        self.catalog.stock_records.add(self.stock_record)
Ejemplo n.º 5
0
 def test_enrollment_code_seat_type(self):
     """Verify the correct seat type attribute is retrieved."""
     course = CourseFactory()
     toggle_switch(ENROLLMENT_CODE_SWITCH, True)
     course.create_or_update_seat('verified', False, 10, self.partner)
     enrollment_code = Product.objects.get(product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
     self.create_basket_and_add_product(enrollment_code)
     self.mock_course_api_response(course)
     response = self.client.get(self.path)
     self.assertEqual(response.status_code, 200)
     line_data = response.context['formset_lines_data'][0][1]
     self.assertEqual(line_data['seat_type'], _(enrollment_code.attr.seat_type.capitalize()))
Ejemplo n.º 6
0
 def test_basket_switch_data(self):
     """Verify the correct basket switch data (single vs. multi quantity) is retrieved."""
     course = CourseFactory()
     toggle_switch(ENROLLMENT_CODE_SWITCH, True)
     course.create_or_update_seat('invalid', False, 10, self.partner)
     seat = course.create_or_update_seat('verified', False, 10, self.partner)
     seat_sku = StockRecord.objects.get(product=seat).partner_sku
     enrollment_code = Product.objects.get(product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
     ec_sku = StockRecord.objects.get(product=enrollment_code).partner_sku
     __, partner_sku = get_basket_switch_data(seat)
     self.assertEqual(partner_sku, ec_sku)
     __, partner_sku = get_basket_switch_data(enrollment_code)
     self.assertEqual(partner_sku, seat_sku)
    def test_prof_ed_stale_product_removal(self):
        """
        Verify that stale professional education seats are deleted if they have not been purchased.
        """
        course = CourseFactory()
        course.create_or_update_seat('professional', False, 0, self.partner)
        self.assertEqual(course.products.count(), 2)

        course.create_or_update_seat('professional', True, 0, self.partner)
        self.assertEqual(course.products.count(), 2)

        product_mode = course.products.first()
        self.assertEqual(product_mode.attr.id_verification_required, True)
        self.assertEqual(product_mode.attr.certificate_type, 'professional')
Ejemplo n.º 8
0
    def test_create_seat_with_enrollment_code(self):
        """Verify an enrollment code product is created."""
        course = CourseFactory()
        seat_type = 'verified'
        price = 5
        toggle_switch(ENROLLMENT_CODE_SWITCH, True)
        course.create_or_update_seat(seat_type, True, price, self.partner)

        enrollment_code = Product.objects.get(product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
        self.assertEqual(enrollment_code.attr.course_key, course.id)
        self.assertEqual(enrollment_code.attr.seat_type, seat_type)

        stock_record = StockRecord.objects.get(product=enrollment_code)
        self.assertEqual(stock_record.price_excl_tax, price)
        self.assertEqual(stock_record.price_currency, settings.OSCAR_DEFAULT_CURRENCY)
        self.assertEqual(stock_record.partner, self.partner)
Ejemplo n.º 9
0
    def test_notify_purchaser(self, mock_task):
        """ Verify the notification is scheduled if the site has notifications enabled
        and the refund is for a course seat.
        """
        site_configuration = self.site.siteconfiguration
        site_configuration.send_refund_notifications = True

        user = UserFactory()

        course = CourseFactory()
        price = Decimal(100.00)
        product = course.create_or_update_seat('verified', True, price, self.partner)

        basket = create_basket(empty=True)
        basket.site = self.site
        basket.add_product(product)

        order = create_order(basket=basket, user=user)
        order_url = get_receipt_page_url(site_configuration, order.number)

        refund = Refund.create_with_lines(order, order.lines.all())

        with LogCapture(REFUND_MODEL_LOGGER_NAME) as l:
            refund._notify_purchaser()  # pylint: disable=protected-access

        msg = 'Course refund notification scheduled for Refund [{}].'.format(refund.id)
        l.check(
            (REFUND_MODEL_LOGGER_NAME, 'INFO', msg)
        )

        amount = format_currency(order.currency, price)
        mock_task.assert_called_once_with(
            user.email, refund.id, amount, course.name, order.number, order_url, site_code=self.partner.short_code
        )
Ejemplo n.º 10
0
class UtilTests(CourseCatalogTestMixin, TestCase):

    def setUp(self):
        super(UtilTests, self).setUp()
        self.course = CourseFactory()
        self.verified_seat = self.course.create_or_update_seat('verified', False, 100, self.partner)
        self.stock_record = StockRecord.objects.filter(product=self.verified_seat).first()
        self.seat_price = self.stock_record.price_excl_tax
        self._range = RangeFactory(products=[self.verified_seat, ])

        self.percentage_benefit = BenefitFactory(type=Benefit.PERCENTAGE, range=self._range, value=35.00)
        self.value_benefit = BenefitFactory(type=Benefit.FIXED, range=self._range, value=self.seat_price - 10)

    def test_format_benefit_value(self):
        """ format_benefit_value(benefit) should format benefit value based on benefit type """
        benefit_value = format_benefit_value(self.percentage_benefit)
        self.assertEqual(benefit_value, '35%')

        benefit_value = format_benefit_value(self.value_benefit)
        self.assertEqual(benefit_value, currency(self.seat_price - 10))

    @ddt.data(
        ('1.0', '1'),
        ('5000.0', '5000'),
        ('1.45000', '1.45'),
        ('5000.40000', '5000.4'),
    )
    @ddt.unpack
    def test_remove_exponent_and_trailing_zeros(self, value, expected):
        """
        _remove_exponent_and_trailing_zeros(decimal) should remove exponent and trailing zeros
        from decimal number
        """
        decimal = _remove_exponent_and_trailing_zeros(Decimal(value))
        self.assertEqual(decimal, Decimal(expected))
Ejemplo n.º 11
0
    def setUp(self):
        super(CouponViewSetTest, self).setUp()
        self.user = self.create_user(is_staff=True)
        self.client.login(username=self.user.username, password=self.password)

        course = CourseFactory(id='edx/Demo_Course/DemoX')
        self.seat = course.create_or_update_seat('verified', True, 50, self.partner)

        self.catalog = Catalog.objects.create(partner=self.partner)
        self.coupon_data = {
            'title': 'Tešt Čoupon',
            'partner': self.partner,
            'benefit_type': Benefit.PERCENTAGE,
            'benefit_value': 100,
            'catalog': self.catalog,
            'end_datetime': str(now() + datetime.timedelta(days=10)),
            'enterprise_customer': {'id': str(uuid4()).decode('utf-8')},
            'code': '',
            'quantity': 2,
            'start_datetime': str(now() - datetime.timedelta(days=1)),
            'voucher_type': Voucher.ONCE_PER_CUSTOMER,
            'category': {'name': self.category.name},
            'note': None,
            'max_uses': None,
            'catalog_query': None,
            'course_seat_types': None,
            'email_domains': None,
        }
Ejemplo n.º 12
0
    def create_course_and_seat(
            self, course_id=None, seat_type='verified', id_verification=False, price=10, partner=None
    ):
        """
        Create a course and a seat from that course.

        Arguments:
            course_name (str): name of the course
            seat_type (str): the seat type
            id_verification (bool): if id verification is required
            price (int): seat price
            partner(Partner): the site partner

        Returns:
            The created course and seat.
        """

        if not partner:
            partner = PartnerFactory()
        if not course_id:
            course = CourseFactory()
        else:
            course = CourseFactory(id=course_id)

        seat = course.create_or_update_seat(seat_type, id_verification, price, partner)
        return course, seat
Ejemplo n.º 13
0
    def test_proper_code(self):
        """ Verify that proper information is returned when a valid code is provided. """
        course = CourseFactory()
        seat = course.create_or_update_seat('verified', True, 50, self.partner)
        sr = StockRecord.objects.get(product=seat)
        catalog = Catalog.objects.create(name='Test catalog', partner=self.partner)
        catalog.stock_records.add(sr)
        range_ = RangeFactory(catalog=catalog)
        self.prepare_voucher(range_=range_)

        course_info = {
            "media": {
                "course_image": {
                    "uri": "/asset-v1:edX+DemoX+Demo_Course+type@asset+block@images_course_image.jpg"
                }
            },
            "name": "edX Demonstration Course",
        }
        course_info_json = json.dumps(course_info)
        course_url = get_lms_url('api/courses/v1/courses/{}/'.format(course.id))
        httpretty.register_uri(httpretty.GET, course_url, body=course_info_json, content_type='application/json')

        url = self.offer_url + '?code={}'.format('COUPONTEST')
        response = self.client.get(url)
        self.assertEqual(response.context['course']['name'], _('edX Demonstration Course'))
        self.assertEqual(response.context['code'], _('COUPONTEST'))
Ejemplo n.º 14
0
    def test_prepare_basket_enrollment_with_voucher(self):
        """Verify the basket does not contain a voucher if enrollment code is added to it."""
        course = CourseFactory()
        toggle_switch(ENROLLMENT_CODE_SWITCH, True)
        course.create_or_update_seat('verified', False, 10, self.partner, create_enrollment_code=True)
        enrollment_code = Product.objects.get(product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
        voucher, product = prepare_voucher()

        basket = prepare_basket(self.request, product, voucher)
        self.assertIsNotNone(basket)
        self.assertEqual(basket.all_lines()[0].product, product)
        self.assertTrue(basket.contains_a_voucher)

        basket = prepare_basket(self.request, enrollment_code, voucher)
        self.assertIsNotNone(basket)
        self.assertEqual(basket.all_lines()[0].product, enrollment_code)
        self.assertFalse(basket.contains_a_voucher)
Ejemplo n.º 15
0
    def test_multiple_providers(self):
        """ Verify offer contains information about credit providers. """
        course = CourseFactory()
        seat1 = course.create_or_update_seat(
            'credit', False, 100, partner=self.partner, credit_provider='test_provider_1'
        )
        seat2 = course.create_or_update_seat(
            'credit', False, 100, partner=self.partner, credit_provider='test_provider_2'
        )
        self.assertEqual(Product.objects.filter(parent=seat1.parent).count(), 2)

        __, request, voucher = self.prepare_get_offers_response(seats=[seat1, seat2], seat_type='credit')
        self.mock_eligibility_api(request, self.user, course.id)
        offers = VoucherViewSet().get_offers(request=request, voucher=voucher)['results']
        for offer in offers:
            self.assertTrue(offer['multiple_credit_providers'])
            self.assertIsNone(offer['credit_provider_price'])
Ejemplo n.º 16
0
    def test_create_or_update_seat_without_stale_seat_removal(self):
        """
        Verify that professional education seats are not deleted if remove_stale_modes flag is not set.
        """
        course = CourseFactory()
        course.create_or_update_seat('professional', False, 0, self.partner)
        self.assertEqual(course.products.count(), 2)

        course.create_or_update_seat('professional', True, 0, self.partner, remove_stale_modes=False)
        self.assertEqual(course.products.count(), 3)

        product_mode = course.products.all()[0]
        self.assertEqual(product_mode.attr.id_verification_required, True)
        self.assertEqual(product_mode.attr.certificate_type, 'professional')

        product_mode = course.products.all()[1]
        self.assertEqual(product_mode.attr.id_verification_required, False)
        self.assertEqual(product_mode.attr.certificate_type, 'professional')
Ejemplo n.º 17
0
    def setUp(self):
        super(CouponRedeemViewTests, self).setUp()
        self.user = self.create_user()
        self.client.login(username=self.user.username, password=self.password)
        course = CourseFactory()
        self.seat = course.create_or_update_seat('verified', True, 50, self.partner)

        self.catalog = Catalog.objects.create(partner=self.partner)
        self.catalog.stock_records.add(StockRecord.objects.get(product=self.seat))
Ejemplo n.º 18
0
 def test_restricted_course_mode(self, mode):
     """Test that an exception is raised when a black-listed course mode is used."""
     course = CourseFactory(id='black/list/mode')
     seat = course.create_or_update_seat(mode, False, 0, self.partner)
     # Seats derived from a migrated "audit" mode do not have a certificate_type attribute.
     if mode == 'audit':
         seat = ProductFactory()
     self.data.update({'stock_record_ids': [StockRecord.objects.get(product=seat).id]})
     self.assert_post_response_status(self.data)
Ejemplo n.º 19
0
    def test_seat_products(self):
        """
        Verify the method returns a list containing purchasable course seats.

        These seats should be the child products.
        """
        # Create a new course and verify it has a parent product, but no children.
        course = CourseFactory()
        self.assertEqual(course.products.count(), 1)
        self.assertEqual(len(course.seat_products), 0)

        # Create the seat products
        seats = [course.create_or_update_seat('honor', False, 0, self.partner),
                 course.create_or_update_seat('verified', True, 50, self.partner)]
        self.assertEqual(course.products.count(), 3)

        # The property should return only the child seats.
        self.assertEqual(set(course.seat_products), set(seats))
Ejemplo n.º 20
0
 def prepare_course_information(self):
     """ Helper function to prepare an API endpoint that provides course information. """
     course = CourseFactory(name='Test course')
     seat = course.create_or_update_seat('verified', True, 50, self.partner)
     stock_record = StockRecord.objects.get(product=seat)
     catalog = Catalog.objects.create(name='Test catalog', partner=self.partner)
     catalog.stock_records.add(stock_record)
     _range = RangeFactory(catalog=catalog)
     self.mock_course_api_response(course=course)
     return _range
Ejemplo n.º 21
0
    def test_filter_product_class(self):
        """ Verify the method supports filtering by product class or the parent product's class. """
        course = CourseFactory()
        seat = course.create_or_update_seat('verified', True, 1, self.partner)
        parent = course.parent_seat_product
        product_class_name = self.seat_product_class.name
        queryset = Product.objects.all()

        actual = list(self.filter.filter_product_class(queryset, product_class_name))
        self.assertListEqual(actual, [seat, parent])
Ejemplo n.º 22
0
 def test_restricted_course_mode(self, mode):
     """Test that an exception is raised when a black-listed course mode is used."""
     course = CourseFactory(id='black/list/mode')
     seat = course.create_or_update_seat(mode, False, 0, self.partner)
     # Seats derived from a migrated "audit" mode do not have a certificate_type attribute.
     if mode == 'audit':
         seat = ProductFactory()
     self.data.update({'stock_record_ids': [StockRecord.objects.get(product=seat).id]})
     response = self.client.post(COUPONS_LINK, data=self.data, format='json')
     self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
Ejemplo n.º 23
0
    def test_enrolled_verified_student_for_enrollment_code(self, mode, id_verification):
        """
        Verify the view return HTTP 303 if the student is enrolled as verified and purchasing enrollment code
        (The Enrollment API call being used returns an inactive enrollment record in this case)
        """
        course = CourseFactory()
        self.mock_enrollment_api_success_enrolled(course.id, mode=mode)
        toggle_switch(ENROLLMENT_CODE_SWITCH, True)
        course.create_or_update_seat(mode, id_verification, 10, self.partner, create_enrollment_code=True)
        product = Product.objects.get(product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
        stock_record = StockRecordFactory(product=product, partner=self.partner)
        catalog = Catalog.objects.create(partner=self.partner)
        catalog.stock_records.add(stock_record)

        url = '{path}?sku={sku}'.format(path=self.path, sku=stock_record.partner_sku)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 303)
        self.assertEqual(response.reason_phrase, "SEE OTHER")
        self.assertEqual(response.wsgi_request.path_info, '/basket/single-item/')
        self.assertEqual(response.wsgi_request.GET['sku'], stock_record.partner_sku)
Ejemplo n.º 24
0
class CouponReportCSVViewTest(CouponMixin, DiscoveryTestMixin, LmsApiMockMixin, TestCase):
    """Unit tests for getting coupon report."""

    def setUp(self):
        super(CouponReportCSVViewTest, self).setUp()

        self.user = self.create_user(full_name="Test User", is_staff=True)
        self.client.login(username=self.user.username, password=self.password)

        self.course = CourseFactory()
        self.verified_seat = self.course.create_or_update_seat('verified', False, 0, self.partner)

        self.stock_record = StockRecord.objects.filter(product=self.verified_seat).first()

        partner1 = PartnerFactory(name='Tester1')
        catalog1 = Catalog.objects.create(name="Test catalog 1", partner=partner1)
        catalog1.stock_records.add(self.stock_record)
        self.coupon1 = self.create_coupon(partner=partner1, catalog=catalog1)
        self.coupon1.history.all().update(history_user=self.user)
        partner2 = PartnerFactory(name='Tester2')
        catalog2 = Catalog.objects.create(name="Test catalog 2", partner=partner2)
        catalog2.stock_records.add(self.stock_record)
        self.coupon2 = self.create_coupon(partner=partner2, catalog=catalog2)
        self.coupon2.history.all().update(history_user=self.user)

    def request_specific_voucher_report(self, coupon):
        client = factories.UserFactory()
        basket = Basket.get_basket(client, self.site)
        basket.add_product(coupon)

        request = RequestFactory()
        response = CouponReportCSVView().get(request, coupon_id=coupon.id)

        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.content.splitlines()), 7)

    @httpretty.activate
    def test_get_csv_report_for_specific_coupon(self):
        """
        Test the get method.
        CSV voucher report should contain coupon specific voucher data.
        """
        self.mock_course_api_response(course=self.course)
        self.request_specific_voucher_report(self.coupon1)
        self.request_specific_voucher_report(self.coupon2)

    def test_report_missing_stockrecord_raises_http404(self):
        """ Verify that Http404 is raised when no StockRecord for coupon """
        StockRecord.objects.get(product=self.coupon1).delete()
        request = RequestFactory().get('')
        response = CouponReportCSVView().get(request, self.coupon1.id)
        self.assertEqual(response.content,
                         'Failed to find a matching stock record for coupon, report download canceled.')
        self.assertEqual(response.status_code, 404)
Ejemplo n.º 25
0
    def test_prepare_basket_enrollment_with_voucher(self):
        """Verify the basket does not contain a voucher if enrollment code is added to it."""
        course = CourseFactory(partner=self.partner)
        course.create_or_update_seat('verified',
                                     False,
                                     10,
                                     create_enrollment_code=True)
        enrollment_code = Product.objects.get(
            product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
        voucher, product = prepare_voucher()

        basket = prepare_basket(self.request, [product], voucher)
        self.assertIsNotNone(basket)
        self.assertEqual(basket.all_lines()[0].product, product)
        self.assertTrue(basket.contains_a_voucher)

        basket = prepare_basket(self.request, [enrollment_code], voucher)
        self.assertIsNotNone(basket)
        self.assertEqual(basket.all_lines()[0].product, enrollment_code)
        self.assertFalse(basket.contains_a_voucher)
Ejemplo n.º 26
0
    def test_collision_avoidance(self):
        """
        Sanity check verifying that course IDs which produced collisions due to a
        lossy slug generation process no longer do so.
        """
        dotted_course = CourseFactory(id='a/...course.../id',
                                      partner=self.partner)
        regular_course = CourseFactory(id='a/course/id', partner=self.partner)

        certificate_type = 'honor'
        id_verification_required = False
        price = 0
        dotted_course.create_or_update_seat(certificate_type,
                                            id_verification_required, price)
        regular_course.create_or_update_seat(certificate_type,
                                             id_verification_required, price)

        child_products = Product.objects.filter(
            structure=Product.CHILD).count()
        self.assertEqual(child_products, 2)
Ejemplo n.º 27
0
class CouponReportCSVViewTest(CouponMixin, CourseCatalogTestMixin, LmsApiMockMixin, TestCase):
    """Unit tests for getting coupon report."""

    def setUp(self):
        super(CouponReportCSVViewTest, self).setUp()

        self.user = self.create_user(full_name="Test User", is_staff=True)
        self.client.login(username=self.user.username, password=self.password)

        self.course = CourseFactory()
        self.verified_seat = self.course.create_or_update_seat('verified', False, 0, self.partner)

        self.stock_record = StockRecord.objects.filter(product=self.verified_seat).first()

        partner1 = PartnerFactory(name='Tester1')
        catalog1 = Catalog.objects.create(name="Test catalog 1", partner=partner1)
        catalog1.stock_records.add(self.stock_record)
        self.coupon1 = self.create_coupon(partner=partner1, catalog=catalog1)
        self.coupon1.history.all().update(history_user=self.user)
        partner2 = PartnerFactory(name='Tester2')
        catalog2 = Catalog.objects.create(name="Test catalog 2", partner=partner2)
        catalog2.stock_records.add(self.stock_record)
        self.coupon2 = self.create_coupon(partner=partner2, catalog=catalog2)
        self.coupon2.history.all().update(history_user=self.user)

    def request_specific_voucher_report(self, coupon):
        client = factories.UserFactory()
        basket = Basket.get_basket(client, self.site)
        basket.add_product(coupon)

        request = RequestFactory()
        response = CouponReportCSVView().get(request, coupon_id=coupon.id)

        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.content.splitlines()), 7)

    @httpretty.activate
    def test_get_csv_report_for_specific_coupon(self):
        """
        Test the get method.
        CSV voucher report should contain coupon specific voucher data.
        """
        self.mock_course_api_response(course=self.course)
        self.request_specific_voucher_report(self.coupon1)
        self.request_specific_voucher_report(self.coupon2)

    def test_report_missing_stockrecord_raises_http404(self):
        """ Verify that Http404 is raised when no StockRecord for coupon """
        StockRecord.objects.get(product=self.coupon1).delete()
        request = RequestFactory().get('')
        response = CouponReportCSVView().get(request, self.coupon1.id)
        self.assertEqual(response.content,
                         'Failed to find a matching stock record for coupon, report download canceled.')
        self.assertEqual(response.status_code, 404)
Ejemplo n.º 28
0
    def test_track_completed_enrollment_order(self):
        """ Make sure we are sending GA events for Enrollment Code orders """
        with mock.patch(
                'ecommerce.extensions.checkout.signals.track_segment_event'
        ) as mock_track:

            course = CourseFactory(partner=self.partner)
            course.create_or_update_seat('verified',
                                         True,
                                         50,
                                         create_enrollment_code=True)
            enrollment_code = Product.objects.get(
                product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)

            basket = factories.BasketFactory(owner=self.user, site=self.site)
            basket.add_product(enrollment_code)

            order = factories.create_order(basket=basket, user=self.user)
            track_completed_order(None, order)
            assert mock_track.called
Ejemplo n.º 29
0
 def setUp(self):
     super(EnterpriseDiscountMixinTests, self).setUp()
     course = CourseFactory(id='edX/DemoX/Demo_Course',
                            name='Demo Course',
                            partner=self.partner)
     user = UserFactory()
     basket = factories.BasketFactory(owner=user, site=self.site)
     basket.add_product(
         course.create_or_update_seat('test-certificate-type', False, 100,
                                      None), 1)
     self.order = create_order(number=1, basket=basket, user=user)
Ejemplo n.º 30
0
    def test_all_already_purchased_products(self):
        """
        Test user can not purchase products again using the multiple item view
        """
        course = CourseFactory()
        product1 = course.create_or_update_seat("Verified", True, 0, self.partner)
        product2 = course.create_or_update_seat("Professional", True, 0, self.partner)
        stock_record = StockRecordFactory(product=product1, partner=self.partner)
        catalog = Catalog.objects.create(partner=self.partner)
        catalog.stock_records.add(stock_record)
        stock_record = StockRecordFactory(product=product2, partner=self.partner)
        catalog.stock_records.add(stock_record)

        qs = urllib.urlencode({'sku': [product.stockrecords.first().partner_sku for product in [product1, product2]]},
                              True)
        url = '{root}?{qs}'.format(root=self.path, qs=qs)
        with mock.patch.object(UserAlreadyPlacedOrder, 'user_already_placed_order', return_value=True):
            response = self.client.get(url)
            self.assertEqual(response.status_code, 200)
            self.assertEqual(response.context['error'], 'You have already purchased these products')
Ejemplo n.º 31
0
 def test_mode_for_product(self, certificate_type, id_verification_required,
                           mode):
     """ Verify the correct enrollment mode is returned for a given seat. """
     course = CourseFactory(id='edx/Demo_Course/DemoX', site=self.site)
     seat = course.create_or_update_seat(certificate_type,
                                         id_verification_required, 10.00,
                                         self.partner)
     self.assertEqual(mode_for_product(seat), mode)
     enrollment_code = course.enrollment_code_product
     if enrollment_code:  # We should only have enrollment codes for allowed types
         self.assertEqual(mode_for_product(enrollment_code), mode)
Ejemplo n.º 32
0
    def test_seat_products(self):
        """
        Verify the method returns a list containing purchasable course seats.

        These seats should be the child products.
        """
        # Create a new course and verify it has a parent product, but no children.
        course = CourseFactory()
        self.assertEqual(course.products.count(), 1)
        self.assertEqual(len(course.seat_products), 0)

        # Create the seat products
        seats = [
            course.create_or_update_seat('honor', False, 0, self.partner),
            course.create_or_update_seat('verified', True, 50, self.partner)
        ]
        self.assertEqual(course.products.count(), 3)

        # The property should return only the child seats.
        self.assertEqual(set(course.seat_products), set(seats))
Ejemplo n.º 33
0
 def prepare_course_information(self):
     """ Helper function to prepare an API endpoint that provides course information. """
     course = CourseFactory(name='Test course')
     seat = course.create_or_update_seat('verified', True, 50, self.partner)
     stock_record = StockRecord.objects.get(product=seat)
     catalog = Catalog.objects.create(name='Test catalog',
                                      partner=self.partner)
     catalog.stock_records.add(stock_record)
     _range = RangeFactory(catalog=catalog)
     self.mock_course_api_response(course=course)
     return _range
Ejemplo n.º 34
0
    def test_successful_order_for_bulk_purchase(self):
        """
        Verify the view redirects to the Receipt page when the Order has been
        successfully placed for bulk purchase and also that the order is linked
        to the provided business client.
        """
        toggle_switch(ENROLLMENT_CODE_SWITCH, True)

        course = CourseFactory()
        course.create_or_update_seat('verified',
                                     True,
                                     50,
                                     create_enrollment_code=True)
        enrollment_code = Product.objects.get(
            product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
        self.basket = create_basket(owner=self.user, site=self.site)
        self.basket.add_product(enrollment_code, quantity=1)

        # The basket should not have an associated order if no payment was made.
        self.assertFalse(Order.objects.filter(basket=self.basket).exists())

        request_data = self.generate_notification(
            self.basket,
            billing_address=self.billing_address,
        )
        request_data.update({'organization': 'Dummy Business Client'})
        request_data.update({PURCHASER_BEHALF_ATTRIBUTE: "False"})
        # Manually add organization and purchaser attributes on the basket for testing
        basket_add_organization_attribute(self.basket, request_data)

        response = self.client.post(self.path, request_data)
        self.assertTrue(Order.objects.filter(basket=self.basket).exists())
        self.assertEqual(response.status_code, 302)

        # Now verify that a new business client has been created and current
        # order is now linked with that client through Invoice model.
        order = Order.objects.filter(basket=self.basket).first()
        business_client = BusinessClient.objects.get(
            name=request_data['organization'])
        assert Invoice.objects.get(
            order=order).business_client == business_client
Ejemplo n.º 35
0
    def test_execution_for_bulk_purchase(self):
        """
        Verify redirection to LMS receipt page after attempted payment
        execution if the Otto receipt page is disabled for bulk purchase and
        also that the order is linked to the provided business client..
        """
        toggle_switch(ENROLLMENT_CODE_SWITCH, True)
        self.mock_oauth2_response()

        course = CourseFactory()
        course.create_or_update_seat('verified', True, 50, self.partner, create_enrollment_code=True)
        self.basket = create_basket(owner=factories.UserFactory(), site=self.site)
        enrollment_code = Product.objects.get(product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
        factories.create_stockrecord(enrollment_code, num_in_stock=2, price_excl_tax='10.00')
        self.basket.add_product(enrollment_code, quantity=1)

        # Create a payment record the view can use to retrieve a basket
        self.mock_payment_creation_response(self.basket)
        self.processor.get_transaction_parameters(self.basket, request=self.request)
        self.mock_payment_execution_response(self.basket)
        self.mock_payment_creation_response(self.basket, find=True)

        # Manually add organization attribute on the basket for testing
        self.RETURN_DATA.update({'organization': 'Dummy Business Client'})
        basket_add_organization_attribute(self.basket, self.RETURN_DATA)

        response = self.client.get(reverse('paypal:execute'), self.RETURN_DATA)
        self.assertRedirects(
            response,
            get_receipt_page_url(
                order_number=self.basket.order_number,
                site_configuration=self.basket.site.siteconfiguration
            ),
            fetch_redirect_response=False
        )

        # Now verify that a new business client has been created and current
        # order is now linked with that client through Invoice model.
        order = Order.objects.filter(basket=self.basket).first()
        business_client = BusinessClient.objects.get(name=self.RETURN_DATA['organization'])
        assert Invoice.objects.get(order=order).business_client == business_client
Ejemplo n.º 36
0
    def test_handle_with_existing_course(self):
        """ The command should create the demo course with audit and verified seats,
        and publish that data to the LMS.
        """
        self.mock_access_token_response()

        course = CourseFactory(
            id='course-v1:edX+DemoX+Demo_Course',
            name='edX Demonstration Course',
            verification_deadline=datetime(year=2022, month=4, day=24, tzinfo=pytz.utc),
            partner=self.partner
        )

        seat_attrs = {'certificate_type': '', 'expires': None, 'price': 0.00, 'id_verification_required': False}
        course.create_or_update_seat(**seat_attrs)

        with mock.patch.object(Course, 'publish_to_lms', return_value=None) as mock_publish:
            call_command('create_demo_data', '--partner={}'.format(self.partner.short_code))
            mock_publish.assert_called_once_with()

        self.assert_seats_created('course-v1:edX+DemoX+Demo_Course', 'edX Demonstration Course', 149)
Ejemplo n.º 37
0
    def test_product_events_with_free_items(self):
        """ Product Added/Removed events should not be fired for free products. """
        course = CourseFactory(partner=self.partner)
        basket = create_basket(empty=True)
        seat = course.create_or_update_seat('audit', False, 0)

        with mock.patch(
                'ecommerce.extensions.basket.models.track_segment_event'
        ) as mock_track:
            basket.add_product(seat)
            basket.flush()
            self.assertEqual(mock_track.call_count, 0)
Ejemplo n.º 38
0
 def test_restricted_course_mode(self, mode):
     """Test that an exception is raised when a black-listed course mode is used."""
     course = CourseFactory(id='black/list/mode')
     seat = course.create_or_update_seat(mode, False, 0, self.partner)
     # Seats derived from a migrated "audit" mode do not have a certificate_type attribute.
     if mode == 'audit':
         seat = ProductFactory()
     self.data.update(
         {'stock_record_ids': [StockRecord.objects.get(product=seat).id]})
     response = self.client.post(COUPONS_LINK, json.dumps(self.data),
                                 'application/json')
     self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
Ejemplo n.º 39
0
    def test_create_or_update_seat_without_stale_seat_removal(self):
        """
        Verify that professional education seats are not deleted if remove_stale_modes flag is not set.
        """
        course = CourseFactory(partner=self.partner)
        course.create_or_update_seat('professional', False, 0)
        self.assertEqual(course.products.count(), 2)

        course.create_or_update_seat('professional',
                                     True,
                                     0,
                                     remove_stale_modes=False)
        self.assertEqual(course.products.count(), 3)

        product_mode = course.products.all()[0]
        self.assertEqual(product_mode.attr.id_verification_required, True)
        self.assertEqual(product_mode.attr.certificate_type, 'professional')

        product_mode = course.products.all()[1]
        self.assertEqual(product_mode.attr.id_verification_required, False)
        self.assertEqual(product_mode.attr.certificate_type, 'professional')
Ejemplo n.º 40
0
    def test_filter_product_class(self):
        """ Verify the method supports filtering by product class or the parent product's class. """
        course = CourseFactory(partner=self.partner)
        seat = course.create_or_update_seat('verified', True, 1)
        parent = course.parent_seat_product
        product_class_name = self.seat_product_class.name
        queryset = Product.objects.all()

        actual = list(
            self.filter.filter_product_class(queryset, 'product_class',
                                             product_class_name))
        self.assertListEqual(actual, [seat, parent])
Ejemplo n.º 41
0
class ConvertHonorToAuditTests(CourseCatalogTestMixin, TestCase):
    def setUp(self):
        super(ConvertHonorToAuditTests, self).setUp()
        self.course = CourseFactory()
        self.honor_seat = self.course.create_or_update_seat(
            'honor', False, 0, self.partner)

    def test_honor_course(self):
        """ The command should delete the honor seat, and create a new audit seat. """
        # Mock the LMS call
        with mock.patch.object(LMSPublisher, 'publish') as mock_publish:
            mock_publish.return_value = True
            call_command('convert_honor_to_audit',
                         self.course.id,
                         access_token=ACCESS_TOKEN,
                         commit=True)

        # Verify honor seat deleted
        self.assertFalse(
            Product.objects.filter(id=self.honor_seat.id).exists())

        # Verify audit seat created
        audit_seats = [
            seat for seat in self.course.seat_products
            if getattr(seat.attr, 'certificate_type', '') == ''
        ]
        self.assertEqual(len(audit_seats), 1)

        # Verify data published to LMS
        self.assertTrue(mock_publish.called)

    def test_honor_course_without_commit(self):
        """ The command should raise an error and change no data if the commit flag is not set. """
        try:
            call_command('convert_honor_to_audit',
                         self.course.id,
                         access_token=ACCESS_TOKEN,
                         commit=False)
            self.fail(
                'An exception should be raised if the commit flag is not set.')
        except Exception:  # pylint: disable=broad-except
            pass

        # Verify honor seat still exists
        self.assertTrue(Product.objects.filter(id=self.honor_seat.id).exists())

        # Verify audit seat not in database
        audit_seats = [
            seat for seat in self.course.seat_products
            if getattr(seat.attr, 'certificate_type', '') == ''
        ]
        self.assertEqual(len(audit_seats), 0)
Ejemplo n.º 42
0
    def test_list_for_course(self):
        """ Verify the view supports listing products for a single course. """
        # Create another course and seat to confirm filtering.
        other_course = CourseFactory(id='edX/DemoX/XYZ',
                                     name='Test Course 2',
                                     site=self.site)
        other_course.create_or_update_seat('honor', False, 0, self.partner)

        path = reverse('api:v2:course-product-list',
                       kwargs={'parent_lookup_course_id': self.course.id})
        response = self.client.get(path)
        self.assertEqual(response.status_code, 200)
        results = [
            self.serialize_product(p) for p in self.course.products.all()
        ]
        expected = {
            'count': 2,
            'next': None,
            'previous': None,
            'results': results
        }
        self.assertDictEqual(json.loads(response.content), expected)
Ejemplo n.º 43
0
    def test_prof_ed_stale_product_removal_with_orders(self):
        """
        Verify that professional education seats are never deleted if they have been purchased.
        """
        user = self.create_user()
        course = CourseFactory()
        professional_product_no_verification = course.create_or_update_seat('professional', False, 0, self.partner)
        self.assertEqual(course.products.count(), 2)

        basket = BasketFactory(owner=user)
        basket.add_product(professional_product_no_verification)
        create_order(basket=basket, user=user)
        course.create_or_update_seat('professional', True, 0, self.partner)
        self.assertEqual(course.products.count(), 3)

        product_mode = course.products.all()[0]
        self.assertEqual(product_mode.attr.id_verification_required, True)
        self.assertEqual(product_mode.attr.certificate_type, 'professional')

        product_mode = course.products.all()[1]
        self.assertEqual(product_mode.attr.id_verification_required, False)
        self.assertEqual(product_mode.attr.certificate_type, 'professional')
Ejemplo n.º 44
0
    def use_voucher(self, voucher, user):
        """
        Mark voucher as used by provided user
        """
        partner = PartnerFactory(short_code='testX')
        course = CourseFactory(id='course-v1:test-org+course+run', partner=partner)
        verified_seat = course.create_or_update_seat('verified', False, 100)

        order = OrderFactory()
        order_line = OrderLineFactory(product=verified_seat, partner_sku='test_sku')
        order.lines.add(order_line)
        voucher.record_usage(order, user)
        voucher.offers.first().record_usage(discount={'freq': 1, 'discount': 1})
Ejemplo n.º 45
0
    def test_get_transaction_parameters_with_quoted_product_title(self):
        """ Verify quotes are removed from item name """
        course = CourseFactory(id='a/b/c/d', name='Course with "quotes"')
        product = course.create_or_update_seat(self.CERTIFICATE_TYPE, False, 20, self.partner)

        basket = factories.create_basket(empty=True)
        basket.add_product(product)
        basket.owner = factories.UserFactory()
        basket.site = self.site
        basket.save()

        response = self.processor.get_transaction_parameters(basket)
        self.assertEqual(response['item_0_name'], 'Seat in Course with quotes with test-certificate-type certificate')
Ejemplo n.º 46
0
 def test_add_product_not_tracked_for_temporary_basket_calculation(self):
     """
     Verify the method does NOT fire Product Added analytic event when a product is added to the basket
     """
     course = CourseFactory(partner=self.partner)
     basket = create_basket(empty=True)
     seat = course.create_or_update_seat('verified', True, 100)
     DEFAULT_REQUEST_CACHE.set(TEMPORARY_BASKET_CACHE_KEY, True)
     with mock.patch('ecommerce.extensions.basket.models.track_segment_event') as mock_track:
         basket.add_product(seat)
         properties = translate_basket_line_for_segment(basket.lines.first())
         properties['cart_id'] = basket.id
         mock_track.assert_not_called()
Ejemplo n.º 47
0
    def test_enrollment_code_seat_type(self):
        """Verify the correct seat type attribute is retrieved."""
        course = CourseFactory()
        toggle_switch(ENROLLMENT_CODE_SWITCH, True)
        course.create_or_update_seat('verified', False, 10, self.partner, create_enrollment_code=True)
        enrollment_code = Product.objects.get(product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
        self.create_basket_and_add_product(enrollment_code)
        self.mock_course_api_response(course)

        response = self.client.get(self.path)
        self.assertEqual(response.status_code, 200)
        self.assertFalse(response.context['is_bulk_purchase'])

        # Enable enrollment codes
        self.site.siteconfiguration.enable_enrollment_codes = True
        self.site.siteconfiguration.save()

        response = self.client.get(self.path)
        self.assertEqual(response.status_code, 200)
        self.assertTrue(response.context['is_bulk_purchase'])
        line_data = response.context['formset_lines_data'][0][1]
        self.assertEqual(line_data['seat_type'], _(enrollment_code.attr.seat_type.capitalize()))
Ejemplo n.º 48
0
    def create_course_and_seats(self):
        # Delete existing Courses and products so we can retry creation.
        Course.objects.all().delete()

        # Create a Course.
        course = CourseFactory(
            id=self.course_id,
            name=self.course_name,
            verification_deadline=EXPIRES,
            site=self.site
        )

        # Create associated products.
        for product in self.data['products']:
            attrs = {'certificate_type': ''}
            attrs.update({attr['name']: attr['value'] for attr in product['attribute_values']})

            attrs['expires'] = EXPIRES if product['expires'] else None
            attrs['price'] = Decimal(product['price'])
            attrs['partner'] = self.partner

            course.create_or_update_seat(**attrs)
Ejemplo n.º 49
0
    def test_prof_ed_stale_product_removal_with_orders(self):
        """
        Verify that professional education seats are never deleted if they have been purchased.
        """
        user = self.create_user()
        course = CourseFactory()
        professional_product_no_verification = course.create_or_update_seat('professional', False, 0, self.partner)
        self.assertEqual(course.products.count(), 2)

        basket = BasketFactory(owner=user)
        basket.add_product(professional_product_no_verification)
        create_order(basket=basket, user=user)
        course.create_or_update_seat('professional', True, 0, self.partner)
        self.assertEqual(course.products.count(), 3)

        product_mode = course.products.all()[0]
        self.assertEqual(product_mode.attr.id_verification_required, True)
        self.assertEqual(product_mode.attr.certificate_type, 'professional')

        product_mode = course.products.all()[1]
        self.assertEqual(product_mode.attr.id_verification_required, False)
        self.assertEqual(product_mode.attr.certificate_type, 'professional')
Ejemplo n.º 50
0
    def test_create_seat_with_enrollment_code(self):
        """Verify an enrollment code product is created."""
        course = CourseFactory()
        seat_type = 'verified'
        price = 5
        toggle_switch(ENROLLMENT_CODE_SWITCH, True)
        course.create_or_update_seat(seat_type, True, price, self.partner)

        enrollment_code = Product.objects.get(product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
        self.assertEqual(enrollment_code.attr.course_key, course.id)
        self.assertEqual(enrollment_code.attr.seat_type, seat_type)

        # Second time should skip over the enrollment code creation logic but result in the same data
        course.create_or_update_seat(seat_type, True, price, self.partner)
        enrollment_code = Product.objects.get(product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
        self.assertEqual(enrollment_code.attr.course_key, course.id)
        self.assertEqual(enrollment_code.attr.seat_type, seat_type)

        stock_record = StockRecord.objects.get(product=enrollment_code)
        self.assertEqual(stock_record.price_excl_tax, price)
        self.assertEqual(stock_record.price_currency, settings.OSCAR_DEFAULT_CURRENCY)
        self.assertEqual(stock_record.partner, self.partner)
Ejemplo n.º 51
0
 def test_add_product(self):
     """ Verify the method fires Product Added analytic event when a product is added to the basket """
     course = CourseFactory(partner=self.partner)
     basket = create_basket(empty=True)
     seat = course.create_or_update_seat('verified', True, 100)
     with mock.patch(
             'ecommerce.extensions.basket.models.track_segment_event'
     ) as mock_track:
         basket.add_product(seat)
         properties = translate_basket_line_for_segment(
             basket.lines.first())
         properties['cart_id'] = basket.id
         mock_track.assert_called_once_with(basket.site, basket.owner,
                                            'Product Added', properties)
Ejemplo n.º 52
0
    def test_basket_switch_data(self):
        """Verify the correct basket switch data (single vs. multi quantity) is retrieved."""
        course = CourseFactory()
        toggle_switch(ENROLLMENT_CODE_SWITCH, True)

        seat = course.create_or_update_seat('verified', False, 10, self.partner, create_enrollment_code=True)
        seat_sku = StockRecord.objects.get(product=seat).partner_sku
        enrollment_code = Product.objects.get(product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
        ec_sku = StockRecord.objects.get(product=enrollment_code).partner_sku

        __, partner_sku = get_basket_switch_data(seat)
        self.assertEqual(partner_sku, ec_sku)
        __, partner_sku = get_basket_switch_data(enrollment_code)
        self.assertEqual(partner_sku, seat_sku)
Ejemplo n.º 53
0
    def test_multiple_providers(self):
        """ Verify offer contains information about credit providers. """
        course = CourseFactory(partner=self.partner)
        seat1 = course.create_or_update_seat('credit',
                                             False,
                                             100,
                                             credit_provider='test_provider_1')
        seat2 = course.create_or_update_seat('credit',
                                             False,
                                             100,
                                             credit_provider='test_provider_2')
        self.assertEqual(
            Product.objects.filter(parent=seat1.parent).count(), 2)

        self.mock_access_token_response()
        __, request, voucher = self.prepare_get_offers_response(
            seats=[seat1, seat2], seat_type='credit')
        self.mock_eligibility_api(request, self.user, course.id)
        offers = VoucherViewSet().get_offers(request=request,
                                             voucher=voucher)['results']
        for offer in offers:
            self.assertTrue(offer['multiple_credit_providers'])
            self.assertIsNone(offer['credit_provider_price'])
Ejemplo n.º 54
0
    def test_create_or_update_seat(self):
        """ Verify the method creates or updates a seat Product. """
        course = CourseFactory(id='a/b/c', name='Test Course', site=self.site)

        # Test seat creation
        certificate_type = 'verified'
        id_verification_required = True
        price = 5
        course.create_or_update_seat(certificate_type, id_verification_required, price, self.partner)

        # Two seats: one verified, the other the parent seat product
        self.assertEqual(course.products.count(), 2)
        seat = course.seat_products[0]
        self.assert_course_seat_valid(seat, course, certificate_type, id_verification_required, price)

        # Test seat update
        price = 10
        course.create_or_update_seat(certificate_type, id_verification_required, price, self.partner)

        # Again, only two seats with one being the parent seat product.
        self.assertEqual(course.products.count(), 2)
        seat = course.seat_products[0]
        self.assert_course_seat_valid(seat, course, certificate_type, id_verification_required, price)
Ejemplo n.º 55
0
 def test_update_credit_seat(self):
     """
     Tests that model's seat update method updates the seat and attribute values
     """
     course = CourseFactory()
     credit_provider = 'MIT'
     credit_hours = 2
     certificate_type = 'credit'
     id_verification_required = True
     price = 10
     course.create_or_update_seat(
         certificate_type,
         id_verification_required,
         price,
         self.partner,
         credit_provider=credit_provider,
         credit_hours=credit_hours
     )
     credit_hours = 4
     price = 100
     credit_seat = course.create_or_update_seat(
         certificate_type,
         id_verification_required,
         price,
         self.partner,
         credit_provider=credit_provider,
         credit_hours=credit_hours
     )
     self.assert_course_seat_valid(
         credit_seat,
         course,
         certificate_type,
         id_verification_required,
         price,
         credit_provider=credit_provider,
         credit_hours=credit_hours
     )
Ejemplo n.º 56
0
    def test_already_verified_student(self, mode, id_verification):
        """
        Verify the view return HTTP 400 if the student is already enrolled as verified student in the course
        """
        course = CourseFactory()
        self.mock_enrollment_api_success(course.id, mode=mode)
        product = course.create_or_update_seat(mode, id_verification, 0, self.partner)
        stock_record = StockRecordFactory(product=product, partner=self.partner)
        catalog = Catalog.objects.create(partner=self.partner)
        catalog.stock_records.add(stock_record)

        url = '{path}?sku={sku}'.format(path=self.path, sku=stock_record.partner_sku)
        expected_content = 'You are already enrolled in {product}.'.format(product=product.course.name)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 400)
        self.assertEqual(response.content, expected_content)
Ejemplo n.º 57
0
    def test_course_information_error(self):
        """ Verify a response is returned when course information is not accessable. """
        course = CourseFactory()
        seat = course.create_or_update_seat('verified', True, 50, self.partner)
        _range = RangeFactory(products=[seat, ])
        prepare_voucher(code=COUPON_CODE, _range=_range)

        course_url = get_lms_url('api/courses/v1/courses/{}/'.format(course.id))
        httpretty.register_uri(httpretty.GET, course_url, status=404, content_type=CONTENT_TYPE)

        response = self.client.get(self.path_with_code)
        response_text = (
            'Could not get course information. '
            '[Client Error 404: http://127.0.0.1:8000/api/courses/v1/courses/{}/]'
        ).format(course.id)
        self.assertEqual(response.context['error'], _(response_text))
Ejemplo n.º 58
0
    def prepare_course_seat_and_enrollment_code(self, seat_type='verified', id_verification=False):
        """Helper function that creates a new course, enables enrollment codes and creates a new
        seat and enrollment code for it.

        Args:
            seat_type (str): Seat/certification type.
            is_verification (bool): Whether or not id verification is required for the seat.
        Returns:
            The newly created course, seat and enrollment code.
        """
        course = CourseFactory()
        toggle_switch(ENROLLMENT_CODE_SWITCH, True)
        self.site.siteconfiguration.enable_enrollment_codes = True
        self.site.siteconfiguration.save()
        seat = course.create_or_update_seat(seat_type, id_verification, 10, self.partner, create_enrollment_code=True)
        enrollment_code = Product.objects.get(product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
        return course, seat, enrollment_code
Ejemplo n.º 59
0
    def prepare_order(self, seat_type, credit_provider_id=None):
        """
        Prepares order for a post-checkout test.

        Args:
            seat_type (str): Course seat type
            credit_provider_id (str): Credit provider associated with the course seat.

        Returns:
            Order
        """
        course = CourseFactory()
        seat = course.create_or_update_seat(seat_type, False, 50, self.partner, credit_provider_id, None, 2)
        basket = BasketFactory(site=self.site)
        basket.add_product(seat, 1)
        order = factories.create_order(basket=basket, user=self.user)
        return order