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)
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)
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)
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)
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')
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 )
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})
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)
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': '*****@*****.**' }
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)
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)
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)
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))
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)
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()
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)
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()
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))
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))))
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" }
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)
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()
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)
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)
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]
def setUp(self): self.offer = models.ConditionalOffer(max_user_applications=1) self.user = UserFactory()
def setUp(self): super(EdxOrderPlacementMixinTests, self).setUp() self.user = UserFactory() self.order = self.create_order(status=ORDER.OPEN)
def setUp(self): super(ApiTests, self).setUp() self.user = UserFactory()