def test_single_usage(self): user = AnonymousUser() creator = OrderCreator() product = factories.ProductFactory(stockrecords__num_in_stock=1000) # Make the order creator a bit more slow too reliable trigger # concurrency issues org_create_order_model = OrderCreator.create_order_model def new_create_order_model(*args, **kwargs): time.sleep(0.5) return org_create_order_model(creator, *args, **kwargs) creator.create_order_model = new_create_order_model # Start 5 threads to place an order concurrently def worker(): order_number = threading.current_thread().name basket = factories.BasketFactory() basket.add_product(product) place_order(creator, basket=basket, order_number=order_number, user=user) exceptions = run_concurrently(worker, num_threads=5) assert all(isinstance(x, ValueError) for x in exceptions), exceptions assert len(exceptions) == 0 assert Order.objects.count() == 5 stockrecord = product.stockrecords.first() assert stockrecord.num_allocated == 5
def test_single_usage(self): user = AnonymousUser() creator = OrderCreator() product = factories.ProductFactory(stockrecords__num_in_stock=1000) # Make the order creator a bit more slow too reliable trigger # concurrency issues org_create_order_model = OrderCreator.create_order_model def new_create_order_model(*args, **kwargs): time.sleep(0.5) return org_create_order_model(creator, *args, **kwargs) creator.create_order_model = new_create_order_model # Start 5 threads to place an order concurrently def worker(): order_number = threading.current_thread().name basket = factories.BasketFactory() basket.add_product(product) place_order( creator, basket=basket, order_number=order_number, user=user) exceptions = run_concurrently(worker, num_threads=5) assert all(isinstance(x, ValueError) for x in exceptions), exceptions assert len(exceptions) == 0 assert Order.objects.count() == 5 stockrecord = product.stockrecords.first() assert stockrecord.num_allocated == 5
def test_voucher_single_usage(self): user = AnonymousUser() creator = OrderCreator() product = factories.ProductFactory() voucher = factories.VoucherFactory(usage=Voucher.SINGLE_USE) voucher.offers.add(factories.create_offer(offer_type='Voucher')) # Make the order creator a bit more slow too reliable trigger # concurrency issues org_create_order_model = OrderCreator.create_order_model def new_create_order_model(*args, **kwargs): time.sleep(0.5) return org_create_order_model(creator, *args, **kwargs) creator.create_order_model = new_create_order_model org_record_voucher_usage = OrderCreator.record_voucher_usage def record_voucher_usage(*args, **kwargs): time.sleep(0.5) return org_record_voucher_usage(creator, *args, **kwargs) creator.record_voucher_usage = record_voucher_usage # Start 5 threads to place an order concurrently def worker(): order_number = threading.current_thread().name basket = factories.BasketFactory() basket.add_product(product) basket.vouchers.add(voucher) surcharges = SurchargeApplicator().get_applicable_surcharges( basket) place_order(creator, surcharges=surcharges, basket=basket, order_number=order_number, user=user) exceptions = run_concurrently(worker, num_threads=5) voucher.refresh_from_db() assert all(isinstance(x, ValueError) for x in exceptions), exceptions assert len(exceptions) == 4 assert voucher.applications.count() == 1 assert Order.objects.count() == 1
class TestShippingOfferForOrder(TestCase): def setUp(self): self.creator = OrderCreator() self.basket = Basket.objects.create() def apply_20percent_shipping_offer(self): """Shipping offer 20% off""" range = Range.objects.create(name="All products range", includes_all_products=True) benefit = Benefit.objects.create( range=range, type=Benefit.SHIPPING_PERCENTAGE, value=20) offer = create_offer(range=range, benefit=benefit) Applicator().apply_offers(self.basket, [offer]) def test_shipping_offer_is_applied(self): self.basket.add_product(create_product(price=D('12.00'))) self.apply_20percent_shipping_offer() # Normal shipping 5.00 shipping = StubRepository().find_by_code(FixedPrice.code, self.basket) self.creator.place_order( basket=self.basket, order_number='1234', shipping_method=shipping) order = Order.objects.get(number='1234') self.assertEqual(1, len(order.shipping_discounts)) self.assertEqual(D('4.00'), order.shipping_incl_tax) self.assertEqual(D('16.00'), order.total_incl_tax) def test_zero_shipping_discount_is_not_created(self): self.basket.add_product(create_product(price=D('12.00'))) self.apply_20percent_shipping_offer() # Free shipping shipping = StubRepository().find_by_code(Free.code, self.basket) self.creator.place_order( basket=self.basket, order_number='1234', shipping_method=shipping) order = Order.objects.get(number='1234') # No shipping discount self.assertEqual(0, len(order.shipping_discounts)) self.assertEqual(D('0.00'), order.shipping_incl_tax) self.assertEqual(D('12.00'), order.total_incl_tax)
def test_has_discount_recorded_correctly_when_order_is_placed(self): for product in [create_product(price=D('12.00'))]: self.basket.add_product(product, 1) apply_offers(self.basket) methods = StubRepository().get_shipping_methods(self.basket) method = methods[0] creator = OrderCreator() order = creator.place_order(self.basket, shipping_method=method) discounts = order.discounts.all() self.assertEqual(1, len(discounts)) discount = discounts[0] self.assertTrue(discount.is_shipping_discount) self.assertEqual(D('9.00'), discount.amount)
def create_order(number=None, basket=None, user=None, shipping_address=None, shipping_method=None, billing_address=None, total_incl_tax=None, total_excl_tax=None, **kwargs): """ Helper method for creating an order for testing """ if not basket: basket = Basket.objects.create() basket.add_product(create_product(price=D('10.00'))) if not basket.id: basket.save() if shipping_method is None: shipping_method = Free() if total_incl_tax is None or total_excl_tax is None: calc = OrderTotalCalculator() total_incl_tax = calc.order_total_incl_tax(basket, shipping_method) total_excl_tax = calc.order_total_excl_tax(basket, shipping_method) order = OrderCreator().place_order( order_number=number, user=user, basket=basket, shipping_address=shipping_address, shipping_method=shipping_method, billing_address=billing_address, total_incl_tax=total_incl_tax, total_excl_tax=total_excl_tax, **kwargs ) return order
def test_alert_created_when_threhold_met(self): self.set_threshold(5) order = OrderCreator().place_order(self.basket) alerts = StockAlert.objects.filter( stockrecord=self.product.stockrecord) self.assertEqual(1, len(alerts))
def test_single_usage(self): user = AnonymousUser() basket = factories.create_basket() creator = OrderCreator() voucher = factories.VoucherFactory(usage=Voucher.SINGLE_USE) voucher.offers.add(factories.create_offer(offer_type='Voucher')) basket.vouchers.add(voucher) surcharges = SurchargeApplicator().get_applicable_surcharges(basket) place_order(creator, surcharges=surcharges, basket=basket, order_number='12346', user=user) assert voucher.applications.count() == 1 # Make sure the voucher usage is rechecked with pytest.raises(ValueError): place_order(creator, surcharges=surcharges, basket=basket, order_number='12347', user=user)
def test_stock_is_allocated_after_checkout(self): order = OrderCreator().place_order(self.basket) record = StockRecord.objects.get(product=self.product) self.assertEqual(5, record.num_in_stock) self.assertEqual(1, record.num_allocated) self.assertEqual(4, record.net_stock_level)
def setUp(self): self.creator = OrderCreator() self.basket = factories.create_basket(empty=True) self.site1 = factories.SiteFactory() self.site2 = factories.SiteFactory() self.surcharges = SurchargeApplicator().get_applicable_surcharges( self.basket)
def test_correctly_allocates_stock(self): OrderCreator().place_order(self.basket) record = StockRecord.objects.get(product=self.product) self.assertEqual(5, record.num_in_stock) self.assertEqual(1, record.num_allocated) self.assertEqual(4, record.net_stock_level)
def test_raises_alert_when_threshold_is_reached(self): self.set_threshold(5) OrderCreator().place_order(self.basket) alerts = StockAlert.objects.filter( stockrecord=self.product.stockrecord) self.assertEqual(1, len(alerts))
def test_alert_only_created_when_no_alert_exists_already(self): self.set_threshold(5) StockAlert.objects.create(stockrecord=self.product.stockrecord, threshold=10) order = OrderCreator().place_order(self.basket) alerts = StockAlert.objects.filter( stockrecord=self.product.stockrecord) self.assertEqual(1, len(alerts))
def test_only_raises_an_alert_once(self): self.set_threshold(5) StockAlert.objects.create(stockrecord=self.product.stockrecord, threshold=10) OrderCreator().place_order(self.basket) alerts = StockAlert.objects.filter( stockrecord=self.product.stockrecord) self.assertEqual(1, len(alerts))
class TestPlacingOrderForDigitalGoods(TestCase): def setUp(self): self.creator = OrderCreator() self.basket = Basket.objects.create() def test_does_not_allocate_stock(self): ProductClass.objects.create(name="Digital", track_stock=False) product = create_product(price=D('9.99'), product_class="Digital", num_in_stock=None) self.assertTrue(product.stockrecord.num_in_stock is None) self.assertTrue(product.stockrecord.num_allocated is None) self.basket.add_product(product) self.creator.place_order(basket=self.basket, order_number='1234') product_ = Product.objects.get(id=product.id) self.assertTrue(product_.stockrecord.num_in_stock is None) self.assertTrue(product_.stockrecord.num_allocated is None)
class TestPlacingOrderForDigitalGoods(TestCase): def setUp(self): self.creator = OrderCreator() self.basket = Basket.objects.create() def test_does_not_allocate_stock(self): ProductClass.objects.create( name="Digital", track_stock=False) product = create_product( price=D('9.99'), product_class="Digital", num_in_stock=None) self.assertTrue(product.stockrecord.num_in_stock is None) self.assertTrue(product.stockrecord.num_allocated is None) self.basket.add_product(product) self.creator.place_order(basket=self.basket, order_number='1234') product_ = Product.objects.get(id=product.id) self.assertTrue(product_.stockrecord.num_in_stock is None) self.assertTrue(product_.stockrecord.num_allocated is None)
def test_alert_closed_when_stock_replenished(self): self.set_threshold(5) order = OrderCreator().place_order(self.basket) alert = StockAlert.objects.get(stockrecord=self.product.stockrecord) self.assertEqual(StockAlert.OPEN, alert.status) self.product.stockrecord.num_in_stock = 15 self.product.stockrecord.save() alert = StockAlert.objects.get(stockrecord=self.product.stockrecord) self.assertEqual(StockAlert.CLOSED, alert.status)
def test_has_discount_recorded_correctly_when_order_is_placed(self): order = OrderCreator().place_order(self.basket) discounts = order.discounts.all() self.assertEqual(1, len(discounts)) self.assertEqual(1, len(order.post_order_actions)) discount = discounts[0] self.assertTrue(discount.is_post_order_action) self.assertEqual(D('0.00'), discount.amount) self.assertEqual('Something happened', discount.message)
def test_voucher_single_usage(self): user = AnonymousUser() creator = OrderCreator() product = factories.ProductFactory() voucher = factories.VoucherFactory(usage=Voucher.SINGLE_USE) voucher.offers.add(factories.create_offer(offer_type='Voucher')) # Make the order creator a bit more slow too reliable trigger # concurrency issues org_create_order_model = OrderCreator.create_order_model def new_create_order_model(*args, **kwargs): time.sleep(0.5) return org_create_order_model(creator, *args, **kwargs) creator.create_order_model = new_create_order_model org_record_voucher_usage = OrderCreator.record_voucher_usage def record_voucher_usage(*args, **kwargs): time.sleep(0.5) return org_record_voucher_usage(creator, *args, **kwargs) creator.record_voucher_usage = record_voucher_usage # Start 5 threads to place an order concurrently def worker(): order_number = threading.current_thread().name basket = factories.BasketFactory() basket.add_product(product) basket.vouchers.add(voucher) place_order( creator, basket=basket, order_number=order_number, user=user) exceptions = run_concurrently(worker, num_threads=5) voucher.refresh_from_db() assert all(isinstance(x, ValueError) for x in exceptions), exceptions assert len(exceptions) == 4 assert voucher.applications.count() == 1 assert Order.objects.count() == 1
def test_expired_voucher(self): user = AnonymousUser() basket = factories.create_basket() creator = OrderCreator() voucher = factories.VoucherFactory(usage=Voucher.SINGLE_USE) voucher.offers.add(factories.create_offer(offer_type='Voucher')) basket.vouchers.add(voucher) voucher.end_datetime = timezone.now() - datetime.timedelta(days=100) voucher.save() place_order(creator, basket=basket, order_number='12346', user=user) assert voucher.applications.count() == 0
def test_closes_open_alert(self): self.set_threshold(5) OrderCreator().place_order(self.basket) alert = StockAlert.objects.get(stockrecord=self.product.stockrecord) self.assertEqual(StockAlert.OPEN, alert.status) # Restock product self.product.stockrecord.num_in_stock = 15 self.product.stockrecord.save() alert = StockAlert.objects.get(stockrecord=self.product.stockrecord) self.assertEqual(StockAlert.CLOSED, alert.status)
class TestOrderCreatorErrorCases(TestCase): def setUp(self): self.creator = OrderCreator() self.basket = Basket() def test_raises_exception_when_empty_basket_passed(self): with self.assertRaises(ValueError): self.creator.place_order(basket=self.basket) def test_raises_exception_if_duplicate_order_number_passed(self): self.basket.add_product(create_product(price=D('12.00'))) self.creator.place_order(basket=self.basket, order_number='1234') with self.assertRaises(ValueError): self.creator.place_order(basket=self.basket, order_number='1234')
def setUp(self): self.creator = OrderCreator() self.basket = factories.create_basket(empty=True)
def setUp(self): self.creator = OrderCreator() self.basket = Basket()
class OrderCreatorTests(TestCase): def setUp(self): self.creator = OrderCreator() self.basket = Basket.objects.create() def tearDown(self): Order.objects.all().delete() def test_exception_raised_when_empty_basket_passed(self): with self.assertRaises(ValueError): self.creator.place_order(basket=self.basket) def test_order_models_are_created(self): self.basket.add_product(create_product(price=D('12.00'))) self.creator.place_order(basket=self.basket, order_number='1234') order = Order.objects.get(number='1234') lines = order.lines.all() self.assertEqual(1, len(lines)) def test_status_is_saved_if_passed(self): self.basket.add_product(create_product(price=D('12.00'))) self.creator.place_order(basket=self.basket, order_number='1234', status='Active') order = Order.objects.get(number='1234') self.assertEqual('Active', order.status) def test_shipping_is_free_by_default(self): self.basket.add_product(create_product(price=D('12.00'))) self.creator.place_order(basket=self.basket, order_number='1234') order = Order.objects.get(number='1234') self.assertEqual(order.total_incl_tax, self.basket.total_incl_tax) self.assertEqual(order.total_excl_tax, self.basket.total_excl_tax) def test_basket_totals_are_used_by_default(self): self.basket.add_product(create_product(price=D('12.00'))) method = Mock() method.basket_charge_incl_tax = Mock(return_value=D('2.00')) method.basket_charge_excl_tax = Mock(return_value=D('2.00')) self.creator.place_order(basket=self.basket, order_number='1234', shipping_method=method) order = Order.objects.get(number='1234') self.assertEqual(order.total_incl_tax, self.basket.total_incl_tax + D('2.00')) self.assertEqual(order.total_excl_tax, self.basket.total_excl_tax + D('2.00')) def test_exception_raised_if_duplicate_number_passed(self): self.basket.add_product(create_product(price=D('12.00'))) self.creator.place_order(basket=self.basket, order_number='1234') with self.assertRaises(ValueError): self.creator.place_order(basket=self.basket, order_number='1234') def test_default_order_status_comes_from_settings(self): self.basket.add_product(create_product(price=D('12.00'))) with patch_settings(OSCAR_INITIAL_ORDER_STATUS='A'): self.creator.place_order(basket=self.basket, order_number='1234') order = Order.objects.get(number='1234') self.assertEqual('A', order.status) def test_default_line_status_comes_from_settings(self): self.basket.add_product(create_product(price=D('12.00'))) with patch_settings(OSCAR_INITIAL_LINE_STATUS='A'): self.creator.place_order(basket=self.basket, order_number='1234') order = Order.objects.get(number='1234') line = order.lines.all()[0] self.assertEqual('A', line.status)
def setUp(self): self.creator = OrderCreator() self.basket = factories.create_basket(empty=True) self.shipping_method = Free() self.shipping_method.set_basket(self.basket)
def test_no_alert_raised_if_threshold_not_breached(self): self.set_threshold(3) order = OrderCreator().place_order(self.basket) alerts = StockAlert.objects.all() self.assertEqual(0, len(alerts))
def test_does_not_raise_an_alert_if_threshold_not_broken(self): self.set_threshold(4) OrderCreator().place_order(self.basket) alerts = StockAlert.objects.all() self.assertEqual(0, len(alerts))
def setUp(self): self.creator = OrderCreator() self.basket = factories.create_basket(empty=True) self.site1 = factories.SiteFactory() self.site2 = factories.SiteFactory()
class TestSuccessfulOrderCreation(TestCase): def setUp(self): self.creator = OrderCreator() self.basket = Basket.objects.create() def tearDown(self): Order.objects.all().delete() def test_creates_order_and_line_models(self): self.basket.add_product(create_product(price=D('12.00'))) self.creator.place_order(basket=self.basket, order_number='1234') order = Order.objects.get(number='1234') lines = order.lines.all() self.assertEqual(1, len(lines)) def test_sets_correct_order_status(self): self.basket.add_product(create_product(price=D('12.00'))) self.creator.place_order(basket=self.basket, order_number='1234', status='Active') order = Order.objects.get(number='1234') self.assertEqual('Active', order.status) def test_defaults_to_using_free_shipping(self): self.basket.add_product(create_product(price=D('12.00'))) self.creator.place_order(basket=self.basket, order_number='1234') order = Order.objects.get(number='1234') self.assertEqual(order.total_incl_tax, self.basket.total_incl_tax) self.assertEqual(order.total_excl_tax, self.basket.total_excl_tax) def test_defaults_to_setting_totals_to_basket_totals(self): self.basket.add_product(create_product(price=D('12.00'))) method = Mock() method.is_discounted = False method.basket_charge_incl_tax = Mock(return_value=D('2.00')) method.basket_charge_excl_tax = Mock(return_value=D('2.00')) self.creator.place_order(basket=self.basket, order_number='1234', shipping_method=method) order = Order.objects.get(number='1234') self.assertEqual(order.total_incl_tax, self.basket.total_incl_tax + D('2.00')) self.assertEqual(order.total_excl_tax, self.basket.total_excl_tax + D('2.00')) def test_uses_default_order_status_from_settings(self): self.basket.add_product(create_product(price=D('12.00'))) with override_settings(OSCAR_INITIAL_ORDER_STATUS='A'): self.creator.place_order(basket=self.basket, order_number='1234') order = Order.objects.get(number='1234') self.assertEqual('A', order.status) def test_uses_default_line_status_from_settings(self): self.basket.add_product(create_product(price=D('12.00'))) with override_settings(OSCAR_INITIAL_LINE_STATUS='A'): self.creator.place_order(basket=self.basket, order_number='1234') order = Order.objects.get(number='1234') line = order.lines.all()[0] self.assertEqual('A', line.status)
def setUp(self): self.creator = OrderCreator() self.basket = Basket.objects.create()