예제 #1
0
 def setUp(self):
     self.product = create_product()
     self.reviewer = UserFactory()
     self.voter = UserFactory()
     self.review = self.product.reviews.create(title='This is nice',
                                               score=3,
                                               body="This is the body",
                                               user=self.reviewer)
예제 #2
0
    def test_is_available_to_different_users(self):
        users, order = [UserFactory(), UserFactory()], OrderFactory()
        for user in users:
            is_voucher_available_to_user, __ = self.voucher.is_available_to_user(
                user=user)
            self.assertTrue(is_voucher_available_to_user)

            self.voucher.record_usage(order, user)
            is_voucher_available_to_user, __ = self.voucher.is_available_to_user(
                user=user)
            self.assertFalse(is_voucher_available_to_user)
예제 #3
0
 def setUp(self):
     super(CouponFulfillmentModuleTest, self).setUp()
     coupon = self.create_coupon()
     user = UserFactory()
     basket = BasketFactory()
     basket.add_product(coupon, 1)
     self.order = factories.create_order(number=1, basket=basket, user=user)
예제 #4
0
 def test_is_available_to_same_user_multiple_times(self):
     user, order = UserFactory(), OrderFactory()
     for i in range(10):
         self.voucher.record_usage(order, user)
         is_voucher_available_to_user, __ = self.voucher.is_available_to_user(
             user=user)
         self.assertTrue(is_voucher_available_to_user)
예제 #5
0
    def test_enrollment_headers(self):
        """ Test that the enrollment module 'EnrollmentFulfillmentModule' is
        sending enrollment request over to the LMS with proper headers.
        """
        # Create a dummy data for the enrollment request.
        data = {
            'user': '******',
            'is_active': True,
            'mode': 'honor',
            'course_details': {
                'course_id': self.course_id
            },
            'enrollment_attributes': []
        }

        # Create a dummy user and attach the tracking_context
        user = UserFactory()
        user.tracking_context = {'lms_user_id': '1', 'lms_client_id': '123.123', 'lms_ip': '11.22.33.44'}

        # Now call the enrollment api to send POST request to LMS and verify
        # that the header of the request being sent contains the analytics
        # header 'x-edx-ga-client-id'.
        # This will raise the exception 'ConnectionError' because the LMS is
        # not available for ecommerce tests.
        try:
            # pylint: disable=protected-access
            EnrollmentFulfillmentModule()._post_to_enrollment_api(data=data, user=user)
        except ConnectionError as exp:
            # Check that the enrollment request object has the analytics header
            # 'x-edx-ga-client-id' and 'x-forwarded-for'.
            self.assertEqual(exp.request.headers.get('x-edx-ga-client-id'), '123.123')
            self.assertEqual(exp.request.headers.get('x-forwarded-for'), '11.22.33.44')
예제 #6
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
        )
예제 #7
0
    def test_zero_dollar_refund(self, mock_revoke_line):
        """
        Given an order and order lines which total $0 and are not refunded, Refund.create_with_lines
        should create and approve a Refund with corresponding RefundLines.
        """
        httpretty.register_uri(httpretty.POST,
                               get_lms_enrollment_api_url(),
                               status=200,
                               body='{}',
                               content_type='application/json')

        order = self.create_order(user=UserFactory(), free=True)

        # Verify that the order totals $0.
        self.assertEqual(order.total_excl_tax, 0)

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

        # Verify that refund lines are not revoked.
        self.assertFalse(mock_revoke_line.called)

        # Verify that the refund has been successfully approved.
        self.assertEqual(refund.status, REFUND.COMPLETE)
        self.assertEqual(set([line.status for line in refund.lines.all()]),
                         {REFUND_LINE.COMPLETE})
예제 #8
0
    def test_notify_purchaser_course_entielement(self, mock_task):
        """ Verify the notification is scheduled if the site has notifications enabled
        and the refund is for a course entitlement.
        """
        site_configuration = self.site.siteconfiguration
        site_configuration.send_refund_notifications = True

        user = UserFactory()

        course_entitlement = create_or_update_course_entitlement(
            'verified', 100, self.partner, '111-222-333-444',
            'Course Entitlement')
        basket = create_basket(site=self.site, owner=user, empty=True)
        basket.add_product(course_entitlement, 1)

        order = create_order(number=1, 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, 100)
        mock_task.assert_called_once_with(user.email,
                                          refund.id,
                                          amount,
                                          course_entitlement.title,
                                          order.number,
                                          order_url,
                                          site_code=self.partner.short_code)
예제 #9
0
 def setUp(self):
     self.product = create_product()
     self.reviewer = UserFactory()
     self.data = {
         'title': '  This product is lovely',
         'body': 'I really like this cheese',
         'score': 0,
         'name': 'JR Hartley',
         'email': '*****@*****.**'
     }
예제 #10
0
    def test_is_available_to_a_user_once(self):
        user, order = UserFactory(), OrderFactory()
        is_voucher_available_to_user, __ = self.voucher.is_available_to_user(
            user=user)
        self.assertTrue(is_voucher_available_to_user)

        self.voucher.record_usage(order, user)
        is_voucher_available_to_user, __ = self.voucher.is_available_to_user(
            user=user)
        self.assertFalse(is_voucher_available_to_user)
예제 #11
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, create_enrollment_code=True)
     enrollment_code = Product.objects.get(product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
     user = UserFactory()
     basket = BasketFactory(owner=user, site=self.site)
     basket.add_product(enrollment_code, self.QUANTITY)
     self.order = create_order(number=1, basket=basket, user=user)
예제 #12
0
    def setUp(self):
        super(EnrollmentFulfillmentModuleTests, self).setUp()

        self.user = UserFactory()
        self.course = CourseFactory(id=self.course_id, name='Demo Course', site=self.site)

        self.seat = self.course.create_or_update_seat(self.certificate_type, False, 100, self.partner, self.provider)

        basket = BasketFactory(owner=self.user, site=self.site)
        basket.add_product(self.seat, 1)
        self.order = create_order(number=1, basket=basket, user=self.user)
예제 #13
0
    def test_has_permission_same_user(self):
        """ If the request.data['username'] matches request.user, return True. """
        user = UserFactory()

        # Normal users can create their own refunds
        request = self._get_request(data={'username': user.username},
                                    user=user)
        self.assertTrue(self.permissions_class.has_permission(request, None))

        # Normal users CANNOT create refunds for other users
        request = self._get_request(data={'username': '******'}, user=user)
        self.assertFalse(self.permissions_class.has_permission(request, None))
예제 #14
0
    def test_create_with_lines(self, multiple_lines):
        """
        Given an order and order lines that have not been refunded, Refund.create_with_lines
        should create a Refund with corresponding RefundLines.
        """
        order = self.create_order(user=UserFactory(), multiple_lines=multiple_lines)

        with LogCapture(LOGGER_NAME) as l:
            refund = Refund.create_with_lines(order, list(order.lines.all()))

            self.assert_refund_creation_logged(l, refund, order)

        self.assert_refund_matches_order(refund, order)
예제 #15
0
    def test_create_with_lines_with_existing_refund(self):
        """
        Refund.create_with_lines should not create RefundLines for order lines
        which have already been refunded.
        """
        order = self.create_order(user=UserFactory())
        line = order.lines.first()
        RefundLineFactory(order_line=line)

        with LogCapture(LOGGER_NAME) as l:
            refund = Refund.create_with_lines(order, [line])
            self.assertEqual(refund, None)

            l.check()
예제 #16
0
 def setUp(self):
     super(DonationsFromCheckoutTestFulfillmentModuleTest, self).setUp()
     donation_class = ProductClass.objects.get(
         name=DONATIONS_FROM_CHECKOUT_TESTS_PRODUCT_TYPE_NAME,
         track_stock=False)
     donation = factories.create_product(product_class=donation_class,
                                         title='Test product')
     user = UserFactory()
     basket = BasketFactory(owner=user, site=self.site)
     factories.create_stockrecord(donation,
                                  num_in_stock=2,
                                  price_excl_tax=10)
     basket.add_product(donation, 1)
     self.order = create_order(number=1, basket=basket, user=user)
예제 #17
0
    def test_create_with_lines_with_existing_refund(self, refund_status, refund_created):
        """
        Refund.create_with_lines should not create RefundLines for order lines
        which have already been refunded.
        """
        order = self.create_order(user=UserFactory())
        line = order.lines.first()
        RefundLineFactory(order_line=line, status=refund_status)

        with LogCapture(LOGGER_NAME) as l:
            refund = Refund.create_with_lines(order, [line])
            self.assertEqual(isinstance(refund, Refund), refund_created)
            if refund_created:
                self.assert_refund_creation_logged(l, refund, order)
            else:
                l.check()
예제 #18
0
    def test_has_permission_superuser(self):
        """ Return True if request.user is a superuser. """
        user = UserFactory(is_superuser=True)

        # Data is required, even if you're a superuser.
        request = self._get_request(user=user)
        self.assertFalse(self.permissions_class.has_permission(request, None))

        # Superusers can create their own refunds
        request = self._get_request(data={'username': user.username},
                                    user=user)
        self.assertTrue(self.permissions_class.has_permission(request, None))

        # Superusers can create refunds for other users
        request = self._get_request(data={'username': '******'}, user=user)
        self.assertTrue(self.permissions_class.has_permission(request, None))
예제 #19
0
    def test_post_checkout_callback(self):
        """
        When the post_checkout signal is emitted, the receiver should attempt
        to fulfill the newly-placed order and send receipt email.
        """
        httpretty.register_uri(httpretty.GET,
                               get_lms_url('api/credit/v1/providers/ASU'),
                               body='{"display_name": "Hogwarts"}',
                               content_type="application/json")
        toggle_switch('ENABLE_NOTIFICATIONS', True)
        user = UserFactory()
        course = Course.objects.create(id='edX/DemoX/Demo_Course',
                                       name='Demo Course')
        seat = course.create_or_update_seat('credit', False, 50, self.partner,
                                            'ASU', None, 2)

        basket = BasketFactory()
        basket.add_product(seat, 1)
        order = factories.create_order(number=1, basket=basket, user=user)
        send_course_purchase_email(None, order=order)
        self.assertEqual(len(mail.outbox), 1)
        self.assertEqual(mail.outbox[0].subject, 'Order Receipt')
        self.assertEqual(
            mail.outbox[0].body, '\nPayment confirmation for: {course_title}'
            '\n\nDear {full_name},'
            '\n\nThank you for purchasing {credit_hours} credit hours from {credit_provider} for {course_title}. '
            'A charge will appear on your credit or debit card statement with a company name of "{platform_name}".'
            '\n\nTo receive your course credit, you must also request credit at the {credit_provider} website. '
            'For a link to request credit from {credit_provider}, or to see the status of your credit request, '
            'go to your {platform_name} dashboard.'
            '\n\nTo explore other credit-eligible courses, visit the {platform_name} website. '
            'We add new courses frequently!'
            '\n\nTo view your payment information, visit the following website.'
            '\n{receipt_url}'
            '\n\nThank you. We hope you enjoyed your course!'
            '\nThe {platform_name} team'
            '\n\nYou received this message because you purchased credit hours for {course_title}, '
            'an {platform_name} course.\n'.format(
                course_title=order.lines.first().product.title,
                full_name=user.get_full_name(),
                credit_hours=2,
                credit_provider='Hogwarts',
                platform_name=settings.PLATFORM_NAME,
                receipt_url=get_lms_url(
                    '/commerce/checkout/receipt/?orderNum={}'.format(
                        order.number))))
예제 #20
0
 def setUp(self):
     super(EntitlementFulfillmentModuleTests, self).setUp()
     self.user = UserFactory()
     self.course_entitlement = create_or_update_course_entitlement(
         'verified', 100, self.partner, '111-222-333-444',
         'Course Entitlement')
     basket = BasketFactory(owner=self.user, site=self.site)
     basket.add_product(self.course_entitlement, 1)
     self.entitlement_option = Option.objects.get(name='Course Entitlement')
     self.order = create_order(number=1, basket=basket, user=self.user)
     self.logger_name = 'ecommerce.extensions.fulfillment.modules'
     self.return_data = {
         "user": "******",
         "course_uuid": "3b3123b8-d34b-44d8-9bbb-a12676e97123",
         "uuid": "111-222-333",
         "mode": "verified",
         "expired_at": "None"
     }
예제 #21
0
    def test_create_with_lines(self, multiple_lines):
        """
        Given an order and order lines that have not been refunded, Refund.create_with_lines
        should create a Refund with corresponding RefundLines.
        """
        order = self.create_order(user=UserFactory(),
                                  multiple_lines=multiple_lines)

        with LogCapture(LOGGER_NAME) as l:
            refund = Refund.create_with_lines(order, list(order.lines.all()))

            l.check((
                LOGGER_NAME, 'INFO',
                'refund_created: amount="{}", currency="{}", order_number="{}", '
                'refund_id="{}", user_id="{}"'.format(
                    refund.total_credit_excl_tax, refund.currency,
                    order.number, refund.id, refund.user.id)))

        self.assert_refund_matches_order(refund, order)
예제 #22
0
    def handle(self, *args, **options):
        orders = options['orders']
        sku = options['sku']

        try:
            stock_record = StockRecord.objects.get(partner_sku=sku)
            product = stock_record.product
            partner = stock_record.partner
        except StockRecord.DoesNotExist:
            msg = 'No StockRecord for partner_sku {} exists.'.format(sku)
            logger.exception(msg)
            raise CommandError(msg)

        try:
            site = partner.siteconfiguration.site
        except SiteConfiguration.DoesNotExist:
            msg = 'No Site Configuration exists for partner {}!'.format(
                partner.id)
            logger.exception(msg)
            raise CommandError(msg)

        user = UserFactory()

        for __ in range(orders):
            basket = create_basket(user, product, site)

            shipping_method = Free()
            shipping_charge = shipping_method.calculate(basket)
            total = OrderTotalCalculator().calculate(basket, shipping_charge)
            number = OrderNumberGenerator().order_number(basket)
            with transaction.atomic():
                OrderCreator().place_order(order_number=number,
                                           user=user,
                                           basket=basket,
                                           shipping_address=None,
                                           shipping_method=shipping_method,
                                           shipping_charge=shipping_charge,
                                           billing_address=None,
                                           total=total)

                basket.set_as_submitted()
예제 #23
0
    def setUp(self):
        super(EnrollmentFulfillmentModuleTests, self).setUp()

        self.user = UserFactory()
        self.user.tracking_context = {
            'ga_client_id': 'test-client-id',
            'lms_user_id': 'test-user-id',
            'lms_ip': '127.0.0.1'
        }
        self.user.save()
        self.course = CourseFactory(id=self.course_id,
                                    name='Demo Course',
                                    site=self.site)

        self.seat = self.course.create_or_update_seat(self.certificate_type,
                                                      False, 100, self.partner,
                                                      self.provider)

        basket = BasketFactory(owner=self.user, site=self.site)
        basket.add_product(self.seat, 1)
        self.order = create_order(number=1, basket=basket, user=self.user)
예제 #24
0
    def setUp(self):
        user = UserFactory()
        self.product_class = factories.ProductClassFactory(
            name='Seat', requires_shipping=False, track_stock=False
        )

        self.course = factories.ProductFactory(
            structure='parent', upc='001', title='EdX DemoX Course', product_class=self.product_class
        )
        self.seat = factories.ProductFactory(
            structure='child',
            upc='002',
            title='Seat in EdX DemoX Course with Honor Certificate',
            product_class=None,
            parent=self.course
        )
        for stock_record in self.seat.stockrecords.all():
            stock_record.price_currency = 'USD'
            stock_record.save()

        basket = BasketFactory()
        basket.add_product(self.seat, 1)
        self.order = factories.create_order(number=1, basket=basket, user=user)
예제 #25
0
 def setUp(self):
     user = UserFactory()
     product = create_product()
     self.alert = ProductAlert.objects.create(user=user, product=product)
    def setUp(self):
        super(RefundTrackingTests, self).setUp()

        self.user = UserFactory()
        self.refund = create_refunds([self.create_order()], self.course.id)[0]
예제 #27
0
 def setUp(self):
     self.offer = models.ConditionalOffer(max_user_applications=1)
     self.user = UserFactory()
예제 #28
0
    def setUp(self):
        super(EdxOrderPlacementMixinTests, self).setUp()

        self.user = UserFactory()
        self.order = self.create_order(status=ORDER.OPEN)
예제 #29
0
 def setUp(self):
     super(ApiTests, self).setUp()
     self.user = UserFactory()