def test_add_variation_product_to_basket(admin_user, settings): configure(settings) shop = factories.get_default_shop() basket = factories.get_basket() factories.get_default_payment_method() factories.get_default_shipping_method() parent = factories.create_product("ComplexVarParent", shop=shop, supplier=factories.get_default_supplier()) sizes = [("%sL" % ("X" * x)) for x in range(4)] for size in sizes: child = factories.create_product("ComplexVarChild-%s" % size, shop=shop, supplier=factories.get_default_supplier()) child.link_to_parent(parent, variables={"size": size}) parent_shop_product = parent.get_shop_instance(shop) parent_shop_product.refresh_from_db() client = _get_client(admin_user) # add parent shop product payload = { 'shop_product': parent_shop_product.id } response = client.post('/api/shuup/basket/{}-{}/add/'.format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_400_BAD_REQUEST # add children shop product children_shop_product = parent_shop_product.product.variation_children.first().get_shop_instance(shop) payload = { 'shop_product': children_shop_product.pk, } response = client.post('/api/shuup/basket/{}-{}/add/'.format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) assert len(response_data["items"]) == 1 assert not response_data["validation_errors"]
def test_update_line_quantity(admin_user, settings): configure(settings) shop = factories.get_default_shop() basket = factories.get_basket() factories.get_default_payment_method() factories.get_default_shipping_method() shop_product = factories.get_default_shop_product() shop_product.default_price = TaxfulPrice(1, shop.currency) shop_product.save() client = _get_client(admin_user) # add shop product payload = { 'shop_product': shop_product.id } response = client.post('/api/shuup/basket/{}-{}/add/'.format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) assert len(response_data["items"]) == 1 payload = { "line_id": response_data["items"][0]["line_id"], "quantity": 5 } response = client.post('/api/shuup/basket/{}-{}/update_quantity/'.format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) assert len(response_data["items"]) == 1 assert response_data["items"][0]["shop_product"] == shop_product.pk assert float(response_data["items"][0]["quantity"]) == 5 assert float(response_data["total_price"]) == 5 basket.refresh_from_db() assert Basket.objects.first().data["lines"][0]["quantity"] == 5
def test_add_product_to_basket(admin_user, settings): configure(settings) shop = factories.get_default_shop() basket = factories.get_basket() factories.get_default_payment_method() factories.get_default_shipping_method() shop_product = factories.get_default_shop_product() shop_product.default_price = TaxfulPrice(1, shop.currency) shop_product.save() client = _get_client(admin_user) # add shop product payload = { 'shop_product': shop_product.id } response = client.post('/api/shuup/basket/{}-{}/add/'.format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) assert len(response_data["items"]) == 1 assert response_data["items"][0]["shop_product"] == shop_product.pk assert not response_data["validation_errors"] assert float(response_data["total_price"]) == 1 # add product payload = { 'product': shop_product.product.pk, 'shop': shop.pk } response = client.post('/api/shuup/basket/{}-{}/add/'.format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) assert len(response_data["items"]) == 1 assert not response_data["validation_errors"] assert float(response_data["total_price"]) == 2
def test_set_shipping_address(admin_user): shop = factories.get_default_shop() basket = factories.get_basket() factories.get_default_payment_method() factories.get_default_shipping_method() client = _get_client(admin_user) addr1 = factories.get_address() addr1.save() # use existing address payload = { 'id': addr1.id } response = client.post('/api/shuup/basket/{}-{}/set_shipping_address/'.format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) shipping_addr = response_data["shipping_address"] assert shipping_addr["id"] == addr1.id assert shipping_addr["prefix"] == addr1.prefix assert shipping_addr["name"] == addr1.name assert shipping_addr["postal_code"] == addr1.postal_code assert shipping_addr["street"] == addr1.street assert shipping_addr["city"] == addr1.city assert shipping_addr["country"] == addr1.country # create a new address address_data = { 'name': 'name', 'prefix': 'prefix', 'postal_code': 'postal_code', 'street': 'street', 'city': 'city', 'country': 'BR' } response = client.post('/api/shuup/basket/{}-{}/set_shipping_address/'.format(shop.pk, basket.key), address_data) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) shipping_addr = response_data["shipping_address"] assert shipping_addr["id"] == addr1.id+1 assert shipping_addr["prefix"] == address_data["prefix"] assert shipping_addr["name"] == address_data["name"] assert shipping_addr["postal_code"] == address_data["postal_code"] assert shipping_addr["street"] == address_data["street"] assert shipping_addr["city"] == address_data["city"] assert shipping_addr["country"] == address_data["country"] # get the basket and check the address response = client.get('/api/shuup/basket/{}-{}/'.format(shop.pk, basket.key)) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) shipping_addr = response_data["shipping_address"] assert shipping_addr["id"] == addr1.id+1 assert shipping_addr["prefix"] == address_data["prefix"] assert shipping_addr["name"] == address_data["name"] assert shipping_addr["postal_code"] == address_data["postal_code"] assert shipping_addr["street"] == address_data["street"] assert shipping_addr["city"] == address_data["city"] assert shipping_addr["country"] == address_data["country"]
def seed_source(user): source = BasketishOrderSource(get_default_shop()) billing_address = get_address() shipping_address = get_address(name="Shippy Doge") source.status = get_initial_order_status() source.billing_address = billing_address source.shipping_address = shipping_address source.customer = get_person_contact(user) source.payment_method = get_default_payment_method() source.shipping_method = get_default_shipping_method() assert source.payment_method_id == get_default_payment_method().id assert source.shipping_method_id == get_default_shipping_method().id return source
def test_create_order(admin_user, settings, target_customer): configure(settings) shop = factories.get_default_shop() basket = factories.get_basket() factories.create_default_order_statuses() shop_product = factories.get_default_shop_product() shop_product.default_price = TaxfulPrice(1, shop.currency) shop_product.save() client = _get_client(admin_user) # add shop product payload = { 'shop_product': shop_product.id } if target_customer == "other": target = factories.create_random_person() payload["customer_id"] = target.pk else: target = get_person_contact(admin_user) response = client.post('/api/shuup/basket/{}-{}/add/'.format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) assert len(response_data["items"]) == 1 response = client.post('/api/shuup/basket/{}-{}/create_order/'.format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_400_BAD_REQUEST response_data = json.loads(response.content.decode("utf-8")) assert "errors" in response_data factories.get_default_payment_method() factories.get_default_shipping_method() response = client.post('/api/shuup/basket/{}-{}/create_order/'.format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_201_CREATED response_data = json.loads(response.content.decode("utf-8")) basket.refresh_from_db() assert basket.finished order = Order.objects.get(reference_number=response_data["reference_number"]) assert order.status == OrderStatus.objects.get_default_initial() assert order.payment_status == PaymentStatus.NOT_PAID assert order.shipping_status == ShippingStatus.NOT_SHIPPED assert not order.payment_method assert not order.shipping_method assert float(order.taxful_total_price_value) == 1 assert order.customer == target assert order.orderer == get_person_contact(admin_user) assert order.creator == admin_user assert not order.billing_address assert not order.shipping_address
def test_abandoned_baskets(admin_user, settings): configure(settings) shop = factories.get_default_shop() factories.get_default_payment_method() factories.get_default_shipping_method() basket1 = factories.get_basket() shop_product = factories.get_default_shop_product() shop_product.default_price = TaxfulPrice(1, shop.currency) shop_product.save() client = _get_client(admin_user) # add shop product payload = {'shop_product': shop_product.id} response = client.post('/api/shuup/basket/{}-{}/add/'.format(shop.pk, basket1.key), payload) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) assert len(response_data["items"]) == 1 assert response_data["items"][0]["shop_product"] == shop_product.pk assert not response_data["validation_errors"] assert float(response_data["total_price"]) == 1 assert Basket.objects.count() == 1 response = client.get("/api/shuup/basket/abandoned/?shop={}&days_ago=0¬_updated_in_hours=0".format(shop.pk)) response_data = json.loads(response.content.decode("utf-8")) assert len(response_data) == 1 basket_data = response_data[0] assert basket_data["id"] == basket1.id basket2 = factories.get_basket() response = client.post('/api/shuup/basket/{}-{}/add/'.format(shop.pk, basket2.key), payload) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) assert len(response_data["items"]) == 1 assert response_data["items"][0]["shop_product"] == shop_product.pk assert not response_data["validation_errors"] assert float(response_data["total_price"]) == 1 assert Basket.objects.count() == 2 response = client.get("/api/shuup/basket/abandoned/?shop={}&days_ago=0¬_updated_in_hours=0".format(shop.pk)) response_data = json.loads(response.content.decode("utf-8")) assert len(response_data) == 2 basket_data = response_data[1] assert basket_data["id"] == basket2.id # there is no shop with this id thus it should return 404 response = client.get("/api/shuup/basket/abandoned/?shop=2&days_ago=0¬_updated_in_hours=0") assert response.status_code == status.HTTP_404_NOT_FOUND
def seed_source(user, shop): source = BasketishOrderSource(shop) source.status = get_initial_order_status() source.customer = get_person_contact(user) source.payment_method = get_default_payment_method() source.shipping_method = get_default_shipping_method() return source
def create_simple_order(request, creator, customer): billing_address = get_address().to_immutable() shipping_address = get_address(name="Shippy Doge").to_immutable() shipping_address.save() shop = request.shop order = Order( creator=creator, customer=customer, shop=shop, payment_method=get_default_payment_method(), shipping_method=get_default_shipping_method(), billing_address=billing_address, shipping_address=shipping_address, order_date=now(), status=get_initial_order_status(), currency=shop.currency, prices_include_tax=shop.prices_include_tax, ) order.full_clean() order.save() order.cache_prices() order.check_all_verified() order.save() return order
def get_frontend_order_state(contact, valid_lines=True): """ Get a dict structure mirroring what the frontend JavaScript would submit. :type contact: Contact|None """ translation.activate("en") shop = get_default_shop() tax = Tax.objects.create(code="test_code", rate=decimal.Decimal("0.20"), name="Default") tax_class = TaxClass.objects.create(identifier="test_tax_class", name="Default") rule = TaxRule.objects.create(tax=tax) rule.tax_classes.add(tax_class) rule.save() product = create_product( sku=printable_gibberish(), supplier=get_default_supplier(), shop=shop ) product.tax_class = tax_class product.save() if valid_lines: lines = [ {"id": "x", "type": "product", "product": {"id": product.id}, "quantity": "32", "baseUnitPrice": 50}, {"id": "y", "type": "other", "sku": "hello", "text": "A greeting", "quantity": 1, "unitPrice": "5.5"}, {"id": "z", "type": "text", "text": "This was an order!", "quantity": 0}, ] else: unshopped_product = create_product(sku=printable_gibberish(), supplier=get_default_supplier()) not_visible_product = create_product( sku=printable_gibberish(), supplier=get_default_supplier(), shop=shop ) not_visible_shop_product = not_visible_product.get_shop_instance(shop) not_visible_shop_product.visible = False not_visible_shop_product.save() lines = [ {"id": "x", "type": "product"}, # no product? {"id": "x", "type": "product", "product": {"id": unshopped_product.id}}, # not in this shop? {"id": "y", "type": "product", "product": {"id": -product.id}}, # invalid product? {"id": "z", "type": "other", "quantity": 1, "unitPrice": "q"}, # what's that price? {"id": "rr", "type": "product", "quantity": 1, "product": {"id": not_visible_product.id}} # not visible ] state = { "customer": {"id": contact.id if contact else None}, "lines": lines, "methods": { "shippingMethod": {"id": get_default_shipping_method().id}, "paymentMethod": {"id": get_default_payment_method().id}, }, "shop": { "selected": { "id": shop.id, "name": shop.name, "currency": shop.currency, "priceIncludeTaxes": shop.prices_include_tax } } } return state
def test_single_page_checkout_with_login_and_register(browser, live_server, settings): # initialize product_name = "Test Product" get_default_shop() pm = get_default_payment_method() sm = get_default_shipping_method() product = create_orderable_product(product_name, "test-123", price=100) OrderStatus.objects.create( identifier="initial", role=OrderStatusRole.INITIAL, name="initial", default=True ) # Initialize test and go to front page browser = initialize_front_browser_test(browser, live_server) wait_until_condition(browser, lambda x: x.is_text_present("Welcome to Default!")) navigate_to_checkout(browser, product) # Let's assume that after addresses the checkout is normal wait_until_condition(browser, lambda x: x.is_text_present("Checkout Method")) test_username = "******" test_email = "*****@*****.**" test_password = "******" register_test(browser, live_server, test_username, test_email, test_password) login_and_finish_up_the_checkout(browser, live_server, test_username, test_email, test_password)
def get_order_and_source(admin_user, product): # create original source to tamper with source = BasketishOrderSource(get_default_shop()) source.status = get_initial_order_status() source.billing_address = MutableAddress.objects.create(name="Original Billing") source.shipping_address = MutableAddress.objects.create(name="Original Shipping") source.customer = get_person_contact(admin_user) source.payment_method = get_default_payment_method() source.shipping_method = get_default_shipping_method() source.add_line( type=OrderLineType.PRODUCT, product=product, supplier=get_default_supplier(), quantity=1, base_unit_price=source.create_price(10), ) source.add_line( type=OrderLineType.OTHER, quantity=1, base_unit_price=source.create_price(10), require_verification=True, ) assert len(source.get_lines()) == 2 source.creator = admin_user creator = OrderCreator() order = creator.create_order(source) return order, source
def test_coupon(browser, live_server, settings): activate("en") # initialize cache.clear() shop = get_default_shop() get_default_payment_method() get_default_shipping_method() first_category = Category.objects.create( identifier="cat-1", status=CategoryStatus.VISIBLE, name="First Category") first_category.shops.add(shop) _populate_products_form_data(CATEGORY_PRODUCT_DATA, shop, first_category) # initialize test and go to front page browser = initialize_front_browser_test(browser, live_server) _add_product_to_basket_from_category(live_server, browser, first_category, shop) _activate_basket_campaign_through_coupon(browser, first_category, shop)
def test_add_product_to_basket_with_custom_shop_product_fields(admin_user, settings): product_name = "Product Name" shop_product_name = "SHOP Product Name" configure(settings) shop = factories.get_default_shop() basket = factories.get_basket() factories.get_default_payment_method() factories.get_default_shipping_method() shop_product = factories.get_default_shop_product() shop_product.default_price = TaxfulPrice(1, shop.currency) shop_product.save() shop_product.product.name = product_name shop_product.product.save() client = _get_client(admin_user) payload = { 'product': shop_product.product.pk, 'shop': shop.pk } response = client.post('/api/shuup/basket/{}-{}/add/'.format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) assert len(response_data["items"]) == 1 assert response_data["items"][0]["shop_product"] == shop_product.pk assert response_data["items"][0]["text"] == product_name # set shop product name shop_product.product.name = shop_product_name shop_product.product.save() # add product payload = { 'product': shop_product.product.pk, 'shop': shop.pk } response = client.post('/api/shuup/basket/{}-{}/add/'.format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) assert len(response_data["items"]) == 1 assert response_data["items"][0]["text"] == shop_product_name
def seed_source(user, extra_addr=True): source = BasketishOrderSource(get_default_shop()) billing_address = get_address() shipping_address = get_address(name="Shippy Doge") if extra_addr: billing_address.extra = ExtraMutableAddress.from_data(EXTRA_MUTABLE_ADDRESS_1) if extra_addr: shipping_address.extra = ExtraMutableAddress.from_data(EXTRA_MUTABLE_ADDRESS_2) source.status = get_initial_order_status() source.billing_address = billing_address source.shipping_address = shipping_address source.customer = get_person_contact(user) source.payment_method = get_default_payment_method() source.shipping_method = get_default_shipping_method() assert source.payment_method_id == get_default_payment_method().id assert source.shipping_method_id == get_default_shipping_method().id return source
def _save_cart_with_products(rf, user): shop = get_default_shop() person = get_person_contact(user) get_default_payment_method() get_default_shipping_method() request = rf.post("/", {"title": "test"}) request.shop = shop request.user = user request.person = person request.customer = person basket = get_basket(request) request = apply_request_middleware(request, user=user, person=person, customer=person, basket=basket) basket = _add_products_to_basket(basket) basket.save() response = CartSaveView.as_view()(request) basket = StoredBasket.objects.filter(title="test").first() data = json.loads(response.content.decode("utf8")) assert data["ok"], "cart saved successfully" return basket
def test_fetch_basket(admin_user, settings): configure(settings) shop = factories.get_default_shop() shop2 = create_shop("foobar") basket = factories.get_basket() factories.get_default_payment_method() factories.get_default_shipping_method() assert basket.shop == shop client = _get_client(admin_user) response = client.get('/api/shuup/basket/{}-{}/'.format(shop.pk, basket.key)) assert response.status_code == status.HTTP_200_OK basket_data = json.loads(response.content.decode("utf-8")) assert basket_data["key"] == basket.key assert not basket_data["validation_errors"] # malformed uuid response = client.get('/api/shuup/basket/{}/'.format(basket.key)) assert response.status_code == status.HTTP_400_BAD_REQUEST # wrong shop response = client.get('/api/shuup/basket/{}-{}/'.format(shop2.pk, basket.key)) assert response.status_code == 400
def test_add_product_shop_mismatch(admin_user, settings): configure(settings) shop = factories.get_default_shop() shop2 = create_shop("foobar") basket = factories.get_basket() factories.get_default_payment_method() factories.get_default_shipping_method() sp = factories.create_product( "test", shop=shop2, supplier=factories.get_default_supplier()).get_shop_instance(shop2) client = _get_client(admin_user) payload = {'shop_product': sp.id} response = client.post( '/api/shuup/basket/{}-{}/add/'.format(shop.pk, basket.key), payload) assert response.status_code == 400 assert "different shop" in str(response.content) # add product belonging to different shop than basket shop payload = {'shop': sp.shop.id, 'product': sp.product.id} response = client.post( '/api/shuup/basket/{}-{}/add/'.format(shop.pk, basket.key), payload) assert response.status_code == 400 assert "different shop" in str(response.content)
def test_coupon(browser, live_server, reindex_catalog): activate("en") # initialize cache.clear() shop = get_default_shop() get_default_payment_method() get_default_shipping_method() first_category = Category.objects.create(identifier="cat-1", status=CategoryStatus.VISIBLE, name="First Category") first_category.shops.add(shop) _populate_products_form_data(CATEGORY_PRODUCT_DATA, shop, first_category) reindex_catalog() # initialize test and go to front page browser = initialize_front_browser_test(browser, live_server) _add_product_to_basket_from_category(live_server, browser, first_category, shop, reindex_catalog) _activate_basket_campaign_through_coupon(browser, first_category, shop)
def _configure_basket(client): """ * Adds a product * Sets a default shipping method * Sets a CieloPaymentProcessor payment method * Sets user address """ default_product = get_default_product() sp = ShopProduct.objects.get(product=default_product, shop=get_default_shop()) sp.default_price = get_default_shop().create_price(PRODUCT_PRICE) sp.save() basket_path = reverse("shuup:basket") client.post(basket_path, data={ "command": "add", "product_id": default_product.pk, "quantity": PRODUCT_QTNTY, "supplier": get_default_supplier().pk }) # Create methods shipping_method = get_default_shipping_method() processor = get_payment_provider() assert isinstance(processor, CieloPaymentProcessor) payment_method = processor.create_service( CIELO_SERVICE_CREDIT, identifier="cielo_phase_cc", shop=get_default_shop(), name="credit card", enabled=True, tax_class=get_default_tax_class()) # Resolve paths addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"}) # Phase: Addresses addresses_soup = client.soup(addresses_path) inputs = fill_address_inputs(addresses_soup, with_company=False) client.post(addresses_path, data=inputs) # Phase: Methods client.post(reverse("shuup:checkout", kwargs={"phase": "methods"}), data={ "payment_method": payment_method.pk, "shipping_method": shipping_method.pk })
def _configure_basket(client): """ * Adds a product * Sets a default shipping method * Sets a CieloPaymentProcessor payment method * Sets user address """ default_product = get_default_product() sp = ShopProduct.objects.get(product=default_product, shop=get_default_shop()) sp.default_price = get_default_shop().create_price(PRODUCT_PRICE) sp.save() basket_path = reverse("shuup:basket") client.post(basket_path, data={ "command": "add", "product_id": default_product.pk, "quantity": PRODUCT_QTNTY, "supplier": get_default_supplier().pk }) # Create methods shipping_method = get_default_shipping_method() processor = get_payment_provider() assert isinstance(processor, CieloPaymentProcessor) payment_method = processor.create_service( CIELO_SERVICE_CREDIT, identifier="cielo_phase_cc", shop=get_default_shop(), name="credit card", enabled=True, tax_class=get_default_tax_class()) # Resolve paths addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"}) # Phase: Addresses addresses_soup = client.soup(addresses_path) inputs = fill_address_inputs(addresses_soup, with_company=False) client.post(addresses_path, data=inputs) # Phase: Methods client.post( reverse("shuup:checkout", kwargs={"phase": "methods"}), data={ "payment_method": payment_method.pk, "shipping_method": shipping_method.pk } )
def test_checkout_with_login_and_register(browser, live_server, settings): cache.clear() # Avoid caches from past tests # initialize product_name = "Test Product" get_default_shop() get_default_payment_method() get_default_shipping_method() product = create_orderable_product(product_name, "test-123", price=100) OrderStatus.objects.create(identifier="initial", role=OrderStatusRole.INITIAL, name="initial", default=True) # Initialize test and go to front page browser = initialize_front_browser_test(browser, live_server) wait_until_condition(browser, lambda x: x.is_text_present("Welcome to Default!")) navigate_to_checkout(browser, product) # Let's assume that after addresses the checkout is normal wait_until_condition(browser, lambda x: x.is_text_present("Checkout Method")) guest_ordering_test(browser, live_server) test_username = "******" test_email = "*****@*****.**" test_password = "******" wait_until_condition(browser, lambda x: x.is_text_present("Checkout Method")) register_test(browser, live_server, test_username, test_email, test_password) wait_until_condition(browser, lambda x: x.is_text_present("Checkout Method")) login_and_finish_up_the_checkout(browser, live_server, test_username, test_email, test_password)
def test_create_without_a_contact(admin_user): create_default_order_statuses() shop = get_default_shop() sm = get_default_shipping_method() pm = get_default_payment_method() assert not Order.objects.count() client = _get_client(admin_user) lines = [ { "type": "other", "sku": "hello", "text": "A greeting", "quantity": 1, "base_unit_price_value": "3.5" }, ] response = client.post( "/api/shuup/order/", content_type="application/json", data=json.dumps({ "shop": shop.pk, "customer": None, "shipping_method": sm.pk, "payment_method": pm.pk, "lines": lines }), ) assert response.status_code == 201 assert Order.objects.count() == 1 order = Order.objects.first() assert order.shop == shop assert order.customer is None assert order.creator == admin_user assert order.shipping_method == sm assert order.payment_method == pm assert order.billing_address is None assert order.shipping_address is None assert order.payment_status == PaymentStatus.NOT_PAID assert order.shipping_status == ShippingStatus.NOT_SHIPPED assert order.status == OrderStatus.objects.get_default_initial() assert order.taxful_total_price_value == decimal.Decimal(3.5) assert order.lines.count( ) == 3 # shipping line, payment line, 2 product lines, 2 other lines for idx, line in enumerate(order.lines.all()[:1]): assert line.quantity == decimal.Decimal(lines[idx].get("quantity")) assert line.base_unit_price_value == decimal.Decimal(lines[idx].get( "base_unit_price_value", 0)) assert line.discount_amount_value == decimal.Decimal(lines[idx].get( "discount_amount_value", 0))
def test_add_product_shop_mismatch(admin_user, settings): configure(settings) shop = factories.get_default_shop() shop2 = create_shop("foobar") basket = factories.get_basket() factories.get_default_payment_method() factories.get_default_shipping_method() sp = factories.create_product("test", shop=shop2, supplier=factories.get_default_supplier()).get_shop_instance(shop2) client = _get_client(admin_user) payload = { 'shop_product': sp.id } response = client.post('/api/shuup/basket/{}-{}/add/'.format(shop.pk, basket.key), payload) assert response.status_code == 400 assert "different shop" in str(response.content) # add product belonging to different shop than basket shop payload = { 'shop': sp.shop.id, 'product': sp.product.id } response = client.post('/api/shuup/basket/{}-{}/add/'.format(shop.pk, basket.key), payload) assert response.status_code == 400 assert "different shop" in str(response.content)
def test_order_create_without_default_address(admin_user): create_default_order_statuses() shop = get_default_shop() sm = get_default_shipping_method() pm = get_default_payment_method() contact = create_random_person(locale="en_US", minimum_name_comp_len=5) contact.default_billing_address = None contact.default_shipping_address = None contact.save() product = create_product( sku=printable_gibberish(), supplier=get_default_supplier(), shop=shop ) assert not Order.objects.count() client = _get_client(admin_user) lines = [ {"type": "product", "product": product.id, "quantity": "1", "base_unit_price_value": "5.00"}, {"type": "product", "product": product.id, "quantity": "2", "base_unit_price_value": "1.00", "discount_amount_value": "0.50"}, {"type": "other", "sku": "hello", "text": "A greeting", "quantity": 1, "base_unit_price_value": "3.5"}, {"type": "text", "text": "This was an order!", "quantity": 0}, ] response = client.post("/api/shuup/order/", content_type="application/json", data=json.dumps({ "shop": shop.pk, "shipping_method": sm.pk, "payment_method": pm.pk, "customer": contact.pk, "lines": lines })) assert response.status_code == 201 assert Order.objects.count() == 1 order = Order.objects.first() assert order.shop == shop assert order.shipping_method == sm assert order.payment_method == pm assert order.customer == contact assert order.creator == admin_user assert order.billing_address is None assert order.shipping_address is None assert order.payment_status == PaymentStatus.NOT_PAID assert order.shipping_status == ShippingStatus.NOT_SHIPPED assert order.status == OrderStatus.objects.get_default_initial() assert order.taxful_total_price_value == decimal.Decimal(10) assert order.lines.count() == 6 # shipping line, payment line, 2 product lines, 2 other lines for idx, line in enumerate(order.lines.all()[:4]): assert line.quantity == decimal.Decimal(lines[idx].get("quantity")) assert line.base_unit_price_value == decimal.Decimal(lines[idx].get("base_unit_price_value", 0)) assert line.discount_amount_value == decimal.Decimal(lines[idx].get("discount_amount_value", 0))
def test_different_suppliers(admin_user): supplier_1 = get_supplier("simple_supplier", name="Supplier 1", shop=get_shop()) supplier_2 = get_supplier("simple_supplier", name="Supplier 2", shop=get_shop()) # this service will only be available for supplier_2 shipping_method = get_default_shipping_method() shipping_method.supplier = supplier_2 shipping_method.save() component = WaivingCostBehaviorComponent.objects.create( price_value=decimal.Decimal(10), waive_limit_value=decimal.Decimal(20), ) shipping_method.behavior_components.add(component) source = seed_source(admin_user) product_1 = create_product(sku="sup1", shop=source.shop, supplier=supplier_1, default_price=25) product_2 = create_product(sku="sup2", shop=source.shop, supplier=supplier_2, default_price=4) source.add_line( type=OrderLineType.PRODUCT, product=product_1, supplier=supplier_1, base_unit_price=source.create_price(25), ) source.add_line( type=OrderLineType.PRODUCT, product=product_2, supplier=supplier_2, base_unit_price=source.create_price(4), ) source.shipping_method = shipping_method # there not waiving costs as the total is below 20 for supplier_2 costs = list(shipping_method.get_costs(source)) assert costs[0].price.value == decimal.Decimal(10) # add more items of supplier_2 source.add_line( type=OrderLineType.PRODUCT, product=product_2, supplier=supplier_2, quantity=10, base_unit_price=source.create_price(4), ) # now that the total is greater than 20, there is no cost costs = list(shipping_method.get_costs(source)) assert costs[0].price.value == decimal.Decimal(0)
def test_set_customer_with_custom_basket_lines(rf): """ Set anonymous to the basket customer """ with override_settings(**CORE_BASKET_SETTINGS): factories.get_default_shop() user = factories.create_random_user() request = apply_request_middleware(rf.get("/"), user=user) basket = get_basket(request, "basket") shipping_method = factories.get_default_shipping_method() payment_method = factories.get_default_payment_method() customer = get_person_contact(user) customer_comment = "Some comment" base_unit_price = basket.shop.create_price("10.99") cache_key = basket.get_cache_key() basket.add_line( text="Custom Line", type=OrderLineType.OTHER, line_id="random-you-know", shop=basket.shop, quantity=1, base_unit_price=base_unit_price, extra={"this is purely extra": "oh is it"}, ) assert cache_key != basket.get_cache_key() cache_key = basket.get_cache_key() basket.customer = customer assert cache_key != basket.get_cache_key() cache_key = basket.get_cache_key() assert basket.customer_comment is None basket.customer_comment = customer_comment assert basket.payment_method is None assert basket.shipping_method is None assert cache_key != basket.get_cache_key() basket.payment_method = payment_method basket.shipping_method = shipping_method basket.refresh_lines() basket.save() assert basket.customer == get_person_contact(user) assert basket.customer_comment == "Some comment" assert basket.shipping_method == shipping_method assert basket.payment_method == payment_method assert len(basket.get_lines()) == 1 assert basket.get_lines( )[0].data["extra"]["this is purely extra"] == "oh is it"
def test_order_creator_view(browser, admin_user, live_server): shop = get_default_shop() pm = get_default_payment_method() sm = get_default_shipping_method() get_initial_order_status() supplier = get_default_supplier() person = create_random_person() product0 = create_product("test-sku0", shop=shop, default_price=10, supplier=supplier) product1 = create_product("test-sku1", shop=shop, default_price=10, supplier=supplier) initialize_admin_browser_test(browser, live_server) _visit_order_creator_view(browser, live_server) _test_customer_data(browser, person) _test_add_lines(browser) _test_quick_add_lines(browser) _test_methods(browser) _test_confirm(browser)
def seed_source(shipping_method=None, produce_price=10): source = BasketishOrderSource(get_default_shop()) billing_address = get_address() shipping_address = get_address(name="Shippy Doge") source.status = get_initial_order_status() source.billing_address = billing_address source.shipping_address = shipping_address source.customer = create_random_person() source.payment_method = get_default_payment_method() source.shipping_method = shipping_method if shipping_method else get_default_shipping_method() source.add_line( type=OrderLineType.PRODUCT, product=get_default_product(), supplier=get_default_supplier(), quantity=1, base_unit_price=source.create_price(produce_price), ) return source
def get_order_and_source(admin_user, product, language, language_fallback): # create original source to tamper with contact = get_person_contact(admin_user) contact.language = language contact.save() assert contact.language == language # contact language is naive source = BasketishOrderSource(get_default_shop()) source.status = get_initial_order_status() source.billing_address = MutableAddress.objects.create( name="Original Billing") source.shipping_address = MutableAddress.objects.create( name="Original Shipping") source.customer = contact source.payment_method = get_default_payment_method() source.shipping_method = get_default_shipping_method() source.add_line( type=OrderLineType.PRODUCT, product=product, supplier=get_default_supplier(), quantity=1, base_unit_price=source.create_price(10), ) source.add_line( type=OrderLineType.OTHER, quantity=1, base_unit_price=source.create_price(10), require_verification=True, ) assert len(source.get_lines()) == 2 source.creator = admin_user assert not source._language # is None because it was not directly assigned assert source.language == language_fallback creator = OrderCreator() order = creator.create_order(source) assert order.language == source.language return order, source
def test_get_installments_9x_with_simples_intereset(): """ Max 9 installs with SIMPLE intereset interest_rate = 4.00% """ patch_cielo_request() shop = get_default_shop() create_default_order_statuses() populate_if_required() set_current_theme('shuup.themes.classic_gray') c = SmartClient() _configure_basket(c) cielo_config = CieloConfig.objects.create( shop=shop, max_installments=9, installments_without_interest=3, interest_type=InterestType.Simple, interest_rate=Decimal(4.0)) SHIP_AMOUNT = Decimal(19.0) shipping_method = get_default_shipping_method() shipping_method.behavior_components.add( FixedCostBehaviorComponent.objects.create(price_value=SHIP_AMOUNT)) order_total = (PRODUCT_QTNTY * PRODUCT_PRICE) + SHIP_AMOUNT installment_choices = InstallmentContext( order_total, cielo_config).get_intallments_choices() response = c.get(INSTALLMENTS_PATH, {"cc_brand": CieloCardBrand.Visa}) json_content = json.loads(response.content.decode("utf-8")) assert len(json_content['installments']) == len(installment_choices) for installment in range(len(installment_choices)): total = format_money( shop.create_price(installment_choices[installment][2])) installment_amount = format_money( shop.create_price(installment_choices[installment][1])) assert json_content['installments'][installment][ 'number'] == installment + 1 assert installment_amount in json_content['installments'][installment][ 'name'] assert total in json_content['installments'][installment]['name']
def test_order_creator_view_2(browser, admin_user, live_server, settings): shop = get_default_shop() pm = get_default_payment_method() sm = get_default_shipping_method() get_initial_order_status() supplier = get_default_supplier() person = create_random_person() create_product("test-sku0", shop=shop, default_price=10, supplier=supplier) create_product("test-sku1", shop=shop, default_price=10, supplier=supplier) object_created.connect(_add_custom_order_created_message, sender=Order, dispatch_uid="object_created_signal_test") initialize_admin_browser_test(browser, live_server, settings) browser.driver.set_window_size(1920, 1080) _visit_order_creator_view(browser, live_server) _test_customer_using_search(browser, person) _test_add_lines(browser) _test_methods(browser, sm, pm) _test_confirm(browser) assert Order.objects.first().log_entries.filter(identifier=OBJECT_CREATED_LOG_IDENTIFIER).count() == 1 object_created.disconnect(sender=Order, dispatch_uid="object_created_signal_test")
def get_order_and_source(admin_user, product, language, language_fallback): # create original source to tamper with contact = get_person_contact(admin_user) contact.language = language contact.save() assert contact.language == language # contact language is naive source = BasketishOrderSource(get_default_shop()) source.status = get_initial_order_status() source.billing_address = MutableAddress.objects.create(name="Original Billing") source.shipping_address = MutableAddress.objects.create(name="Original Shipping") source.customer = contact source.payment_method = get_default_payment_method() source.shipping_method = get_default_shipping_method() source.add_line( type=OrderLineType.PRODUCT, product=product, supplier=get_default_supplier(), quantity=1, base_unit_price=source.create_price(10), ) source.add_line( type=OrderLineType.OTHER, quantity=1, base_unit_price=source.create_price(10), require_verification=True, ) assert len(source.get_lines()) == 2 source.creator = admin_user assert not source._language # is None because it was not directly assigned assert source.language == language_fallback creator = OrderCreator() order = creator.create_order(source) assert order.language == source.language return order, source
def test_order_creator_view(browser, admin_user, live_server, settings): shop = get_default_shop() pm = get_default_payment_method() sm = get_default_shipping_method() get_initial_order_status() supplier = get_default_supplier() person = create_random_person() product0 = create_product("test-sku0", shop=shop, default_price=10, supplier=supplier) product1 = create_product("test-sku1", shop=shop, default_price=10, supplier=supplier) object_created.connect(_add_custom_order_created_message, sender=Order, dispatch_uid="object_created_signal_test") initialize_admin_browser_test(browser, live_server, settings) browser.driver.maximize_window() _visit_order_creator_view(browser, live_server) _test_language_change(browser) _test_customer_data(browser, person) _test_regions(browser, person) _test_add_lines(browser) _test_quick_add_lines(browser) _test_methods(browser) _test_confirm(browser) assert Order.objects.first().log_entries.filter(identifier=OBJECT_CREATED_LOG_IDENTIFIER).count() == 1 object_created.disconnect(sender=Order, dispatch_uid="object_created_signal_test")
def test_get_installments_9x_with_simples_intereset(): """ Max 9 installs with SIMPLE intereset interest_rate = 4.00% """ patch_cielo_request() shop = get_default_shop() create_default_order_statuses() populate_if_required() set_current_theme('shuup.themes.classic_gray') c = SmartClient() _configure_basket(c) cielo_config = CieloConfig.objects.create(shop=shop, max_installments=9, installments_without_interest=3, interest_type=InterestType.Simple, interest_rate=Decimal(4.0)) SHIP_AMOUNT = Decimal(19.0) shipping_method = get_default_shipping_method() shipping_method.behavior_components.add( FixedCostBehaviorComponent.objects.create(price_value=SHIP_AMOUNT) ) order_total = (PRODUCT_QTNTY * PRODUCT_PRICE) + SHIP_AMOUNT installment_choices = InstallmentContext(order_total, cielo_config).get_intallments_choices() response = c.get(INSTALLMENTS_PATH, {"cc_brand": CieloCardBrand.Visa}) json_content = json.loads(response.content.decode("utf-8")) assert len(json_content['installments']) == len(installment_choices) for installment in range(len(installment_choices)): total = format_money(shop.create_price(installment_choices[installment][2])) installment_amount = format_money(shop.create_price(installment_choices[installment][1])) assert json_content['installments'][installment]['number'] == installment+1 assert installment_amount in json_content['installments'][installment]['name'] assert total in json_content['installments'][installment]['name']
def test_set_customer_with_custom_basket_lines(rf): """ Set anonymous to the basket customer """ with override_settings(**CORE_BASKET_SETTINGS): factories.get_default_shop() user = factories.create_random_user() request = apply_request_middleware(rf.get("/"), user=user) basket = get_basket(request, "basket") shipping_method = factories.get_default_shipping_method() payment_method = factories.get_default_payment_method() customer = get_person_contact(user) customer_comment = "Some comment" base_unit_price = basket.shop.create_price("10.99") basket.add_line(text="Custom Line", type=OrderLineType.OTHER, line_id="random-you-know", shop=basket.shop, quantity=1, base_unit_price=base_unit_price) basket.customer = customer assert basket.customer_comment is None basket.customer_comment = customer_comment assert basket.payment_method is None assert basket.shipping_method is None basket.payment_method = payment_method basket.shipping_method = shipping_method basket.refresh_lines() basket.save() assert basket.customer == get_person_contact(user) assert basket.customer_comment == "Some comment" assert basket.shipping_method == shipping_method assert basket.payment_method == payment_method
def test_basket_clearing(rf): StoredBasket.objects.all().delete() shop = get_default_shop() supplier = get_default_supplier() product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price=50) request = rf.get("/") request.session = {} request.shop = shop apply_request_middleware(request) basket = get_basket(request) pm = get_default_payment_method() sm = get_default_shipping_method() basket.shipping_method = sm basket.payment_method = pm basket.save() assert basket.shipping_method assert basket.payment_method basket.clear_all() assert not basket.shipping_method assert not basket.payment_method
def test_create_without_a_contact(admin_user): create_default_order_statuses() shop = get_default_shop() sm = get_default_shipping_method() pm = get_default_payment_method() assert not Order.objects.count() client = _get_client(admin_user) lines = [ {"type": "other", "sku": "hello", "text": "A greeting", "quantity": 1, "base_unit_price_value": "3.5"}, ] response = client.post("/api/shuup/order/", content_type="application/json", data=json.dumps({ "shop": shop.pk, "customer": None, "shipping_method": sm.pk, "payment_method": pm.pk, "lines": lines })) assert response.status_code == 201 assert Order.objects.count() == 1 order = Order.objects.first() assert order.shop == shop assert order.customer == None assert order.creator == admin_user assert order.shipping_method == sm assert order.payment_method == pm assert order.billing_address == None assert order.shipping_address == None assert order.payment_status == PaymentStatus.NOT_PAID assert order.shipping_status == ShippingStatus.NOT_SHIPPED assert order.status == OrderStatus.objects.get_default_initial() assert order.taxful_total_price_value == decimal.Decimal(3.5) assert order.lines.count() == 3 # shipping line, payment line, 2 product lines, 2 other lines for idx, line in enumerate(order.lines.all()[:1]): assert line.quantity == decimal.Decimal(lines[idx].get("quantity")) assert line.base_unit_price_value == decimal.Decimal(lines[idx].get("base_unit_price_value", 0)) assert line.discount_amount_value == decimal.Decimal(lines[idx].get("discount_amount_value", 0))
def test_reorder_view(): shop = factories.get_default_shop() factories.get_default_shipping_method() factories.get_default_payment_method() supplier1 = factories.get_supplier(SimpleSupplierModule.identifier, shop=shop) supplier2 = factories.get_supplier(SimpleSupplierModule.identifier, shop=shop) assert supplier1.pk != supplier2.pk product_supplier1 = factories.create_product( "product_supplier1", shop=shop, supplier=supplier1, default_price=10, shipping_mode=ShippingMode.NOT_SHIPPED) product_supplier2 = factories.create_product( "product_supplier2", shop=shop, supplier=supplier2, default_price=20, shipping_mode=ShippingMode.NOT_SHIPPED) user = factories.create_random_user("en") user.set_password("user") user.save() customer = factories.create_random_person("en") customer.user = user customer.save() order = factories.create_random_order( customer=customer, shop=shop, products=[product_supplier1, product_supplier2], completion_probability=0, random_products=False) suppliers = [line.supplier for line in order.lines.products()] assert supplier1 in suppliers assert supplier2 in suppliers client = Client() client.login(username=user.username, password="******") # list orders response = client.get(reverse("shuup:personal-orders")) assert response.status_code == 200 content = response.content.decode("utf-8") assert "<td>%d</td>" % order.id in content assert "<td>Received</td>" in content # go to order detail response = client.get(reverse("shuup:show-order", kwargs=dict(pk=order.pk))) assert response.status_code == 200 content = response.content.decode("utf-8") assert "Add all products to cart" in content reorder_url = reverse("shuup:reorder-order", kwargs=dict(pk=order.pk)) assert reorder_url in content # reorder products response = client.get(reorder_url) assert response.status_code == 302 assert response.url.endswith(reverse("shuup:basket")) # go to basket response = client.get(response.url) assert response.status_code == 200 content = response.content.decode("utf-8") # ensure the basket contain those products and suppliers basket_key = client.session["basket_basket_key"]["key"] from shuup.front.models import StoredBasket basket = StoredBasket.objects.get(key=basket_key) lines = basket.data["lines"] product_supplier = [(line["product_id"], line["supplier_id"]) for line in lines] assert (product_supplier1.pk, supplier1.pk) in product_supplier assert (product_supplier2.pk, supplier2.pk) in product_supplier assert product_supplier1.name in content assert product_supplier2.name in content assert "You are unable to proceed to checkout!" not in content
def test_boleto_cecred_success(): """ Usuário faz a compra e seleciona boleto como forma de pagamento (3 vezes seguidas) Boleto CECRED configurado """ initialize() # Create methods shipping_method = get_default_shipping_method() processor = get_payment_provider() assert isinstance(processor, BoletoPaymentProcessor) choices = processor.get_service_choices() assert len(choices) == 1 payment_method = processor.create_service( BankService.CECRED.value, identifier="cecred", shop=get_default_shop(), name="boleto cecred", enabled=True, tax_class=get_default_tax_class()) # Configura de acordo behavior_component = payment_method.behavior_components.first() behavior_component.local_pagamento = "a simple test" behavior_component.cedente = "a simple user" behavior_component.prazo_vencimento = 4 behavior_component.instrucoes = ["line1", "line2"] behavior_component.especie_doc = DocumentType.DM behavior_component.layout = 'v06' behavior_component.agencia = '123431' behavior_component.conta = '6427364732' behavior_component.convenio = '123456' behavior_component.carteira = '12' behavior_component.save() for ix in range(3): c = SmartClient() default_product = get_default_product() basket_path = reverse("shuup:basket") add_to_basket_resp = c.post(basket_path, data={ "command": "add", "product_id": default_product.pk, "quantity": 1, "supplier": get_default_supplier().pk }) assert add_to_basket_resp.status_code < 400 # Resolve paths addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"}) methods_path = reverse("shuup:checkout", kwargs={"phase": "methods"}) confirm_path = reverse("shuup:checkout", kwargs={"phase": "confirm"}) # Phase: Addresses addresses_soup = c.soup(addresses_path) inputs = fill_address_inputs(addresses_soup, with_company=False) response = c.post(addresses_path, data=inputs) assert response.status_code == 302, "Address phase should redirect forth" assert response.url.endswith(methods_path) # Phase: Methods assert Order.objects.filter(payment_method=payment_method).count() == ix response = c.post( methods_path, data={ "payment_method": payment_method.pk, "shipping_method": shipping_method.pk } ) assert response.status_code == 302, "Methods phase should redirect forth" assert response.url.endswith(confirm_path) response = c.get(confirm_path) assert response.status_code == 200 # Phase: Confirm assert Order.objects.count() == ix confirm_soup = c.soup(confirm_path) response = c.post(confirm_path, data=extract_form_fields(confirm_soup)) assert response.status_code == 302, "Confirm should redirect forth" assert Order.objects.count() == ix+1 order = Order.objects.filter(payment_method=payment_method).first() assert order.payment_status == PaymentStatus.NOT_PAID process_payment_path = reverse("shuup:order_process_payment", kwargs={"pk": order.pk, "key": order.key}) process_payment_return_path = reverse("shuup:order_process_payment_return",kwargs={"pk": order.pk, "key": order.key}) order_complete_path = reverse("shuup:order_complete",kwargs={"pk": order.pk, "key": order.key}) assert response.url.endswith(process_payment_path), ("Confirm should have redirected to payment page") response = c.get(process_payment_path) assert response.status_code == 302, "Payment page should redirect forth" assert response.url.endswith(process_payment_return_path) response = c.get(process_payment_return_path) assert response.status_code == 302, "Payment return should redirect forth" assert response.url.endswith(order_complete_path) order.refresh_from_db() assert order.payment_status == PaymentStatus.NOT_PAID from python_boleto.cecred import CecredBoleto bcecred = CecredBoleto(**order.boleto.info) bcecred.validate() assert len(order.boleto.html) > 0 # "visualiza o boleto" view_boleto_path = reverse("shuup:view_boleto", kwargs={"order_pk": order.pk, "order_key": order.key}) response = c.get(view_boleto_path) assert HttpResponse(order.boleto.html).content == response.content
def test_boleto_cecred_error2(): """ Usuário faz a compra e seleciona boleto como forma de pagamento Boleto CECRED configurado incorretamente Pedido finalizado com sucesso, boleto NÃO é gerado """ initialize() c = SmartClient() default_product = get_default_product() basket_path = reverse("shuup:basket") add_to_basket_resp = c.post(basket_path, data={ "command": "add", "product_id": default_product.pk, "quantity": 1, "supplier": get_default_supplier().pk }) assert add_to_basket_resp.status_code < 400 # Create methods shipping_method = get_default_shipping_method() processor = get_payment_provider() assert isinstance(processor, BoletoPaymentProcessor) payment_method = processor.create_service( BankService.CECRED.value, identifier="cecred", shop=get_default_shop(), name="boleto cecred", enabled=True, tax_class=get_default_tax_class()) # Configura de acordo behavior_component = payment_method.behavior_components.first() behavior_component.local_pagamento = "a simple test" behavior_component.cedente = "a simple user" behavior_component.prazo_vencimento = 4 behavior_component.instrucoes = ["line1", "line2"] behavior_component.especie_doc = DocumentType.DM behavior_component.layout = 'v06' behavior_component.agencia = '123431' behavior_component.conta = '6427364732' behavior_component.convenio = '32312' behavior_component.carteira = '12' behavior_component.save() # Resolve paths addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"}) methods_path = reverse("shuup:checkout", kwargs={"phase": "methods"}) confirm_path = reverse("shuup:checkout", kwargs={"phase": "confirm"}) # Phase: Addresses addresses_soup = c.soup(addresses_path) inputs = fill_address_inputs(addresses_soup, with_company=False) response = c.post(addresses_path, data=inputs) assert response.status_code == 302, "Address phase should redirect forth" assert response.url.endswith(methods_path) # Phase: Methods assert Order.objects.filter(payment_method=payment_method).count() == 0 response = c.post( methods_path, data={ "payment_method": payment_method.pk, "shipping_method": shipping_method.pk } ) assert response.status_code == 302, "Methods phase should redirect forth" assert response.url.endswith(confirm_path) response = c.get(confirm_path) assert response.status_code == 200 # quando vai gerar boleto estoura uma exceção with patch.object(CecredBoletoBehaviorComponent, 'generate_boleto') as mocked: mocked.side_effect = NotImplementedError() # Phase: Confirm assert Order.objects.count() == 0 confirm_soup = c.soup(confirm_path) response = c.post(confirm_path, data=extract_form_fields(confirm_soup)) assert response.status_code == 302, "Confirm should redirect forth" assert Order.objects.count() == 1 order = Order.objects.filter(payment_method=payment_method).first() assert order.payment_status == PaymentStatus.NOT_PAID process_payment_path = reverse("shuup:order_process_payment", kwargs={"pk": order.pk, "key": order.key}) process_payment_return_path = reverse("shuup:order_process_payment_return",kwargs={"pk": order.pk, "key": order.key}) order_complete_path = reverse("shuup:order_complete",kwargs={"pk": order.pk, "key": order.key}) assert response.url.endswith(process_payment_path), ("Confirm should have redirected to payment page") response = c.get(process_payment_path) assert response.status_code == 302, "Payment page should redirect forth" assert response.url.endswith(process_payment_return_path) response = c.get(process_payment_return_path) assert response.status_code == 302, "Payment return should redirect forth" assert response.url.endswith(order_complete_path) order.refresh_from_db() assert order.payment_status == PaymentStatus.NOT_PAID # BOLETO NÃO EXISTE assert not hasattr(order, 'boleto') assert not StoredBoleto.objects.filter(order=order).exists()
def create_order(request, creator, customer, product): billing_address = get_address().to_immutable() shipping_address = get_address(name="Shippy Doge").to_immutable() shipping_address.save() shop = request.shop order = Order( creator=creator, customer=customer, shop=shop, payment_method=get_default_payment_method(), shipping_method=get_default_shipping_method(), billing_address=billing_address, shipping_address=shipping_address, order_date=now(), status=get_initial_order_status(), currency=shop.currency, prices_include_tax=shop.prices_include_tax, ) order.full_clean() order.save() supplier = get_default_supplier() product_order_line = OrderLine(order=order) update_order_line_from_product(pricing_context=request, order_line=product_order_line, product=product, quantity=5, supplier=supplier) assert product_order_line.text == product.safe_translation_getter("name") product_order_line.base_unit_price = shop.create_price(100) assert product_order_line.price.value > 0 product_order_line.save() line_tax = get_line_taxes_for(product_order_line)[0] order_line_tax = OrderLineTax.from_tax( tax=line_tax.tax, base_amount=line_tax.base_amount, order_line=product_order_line, ) order_line_tax.save( ) # Save order_line_tax before linking to order_line.tax product_order_line.taxes.add(order_line_tax) discount_order_line = OrderLine(order=order, quantity=1, type=OrderLineType.OTHER) discount_order_line.discount_amount = shop.create_price(30) assert discount_order_line.discount_amount.value == 30 assert discount_order_line.price.value == -30 assert discount_order_line.base_unit_price.value == 0 discount_order_line.save() order.cache_prices() order.check_all_verified() order.save() assert not order.can_set_complete() base = 5 * shop.create_price(100).amount discount = shop.create_price(30).amount tax_value = line_tax.amount if not order.prices_include_tax: assert order.taxless_total_price.amount == base - discount assert order.taxful_total_price.amount == base + tax_value - discount else: assert_almost_equal(order.taxless_total_price.amount, base - tax_value - discount) assert_almost_equal(order.taxful_total_price.amount, base - discount) assert not order.is_fully_shipped() shipment = order.create_shipment_of_all_products(supplier=supplier) assert order.is_fully_shipped() assert shipment.total_products == 5, "All products were shipped" assert shipment.weight == product.gross_weight * 5 / 1000, "Gravity works" assert not order.get_unshipped_products( ), "Nothing was left in the warehouse" assert order.can_set_complete() order.create_payment(order.taxful_total_price) assert order.is_paid() assert Order.objects.paid().filter( pk=order.pk).exists(), "It was paid! Honestly!" assert order.has_products()
def test_debit_auto_capture_with_auth(): """ Caso: - Transação com Cartão de Débito - Auto captura HABILITADO - Com URL para autenticação - 1 parcela """ initialize() c = SmartClient() default_product = get_default_product() basket_path = reverse("shuup:basket") add_to_basket_resp = c.post(basket_path, data={ "command": "add", "product_id": default_product.pk, "quantity": 10, "supplier": get_default_supplier().pk }) assert add_to_basket_resp.status_code < 400 ORDER_TOTAL = PRODUCT_PRICE * 10 # Create methods shipping_method = get_default_shipping_method() processor = get_payment_provider() assert isinstance(processor, CieloPaymentProcessor) # aumenta o limite máximo de parcelas para 4 cielo_config = get_cielo_config() cielo_config.max_installments = 4 cielo_config.save() payment_method = processor.create_service( CIELO_SERVICE_CREDIT, identifier="cielo_phase_cc", shop=get_default_shop(), name="credit card", enabled=True, tax_class=get_default_tax_class()) # Resolve paths addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"}) methods_path = reverse("shuup:checkout", kwargs={"phase": "methods"}) payment_path = reverse("shuup:checkout", kwargs={"phase": "payment"}) transaction_path = reverse("shuup:cielo_make_transaction") confirm_path = reverse("shuup:checkout", kwargs={"phase": "confirm"}) # Phase: Addresses addresses_soup = c.soup(addresses_path) inputs = fill_address_inputs(addresses_soup, with_company=False) response = c.post(addresses_path, data=inputs) assert response.status_code == 302, "Address phase should redirect forth" assert response.url.endswith(methods_path) # Phase: Methods assert Order.objects.filter(payment_method=payment_method).count() == 0 response = c.post(methods_path, data={ "payment_method": payment_method.pk, "shipping_method": shipping_method.pk }) assert response.status_code == 302, "Methods phase should redirect forth" assert response.url.endswith(confirm_path) response = c.get(confirm_path) assert response.status_code == 302, "Confirm should first redirect forth" assert response.url.endswith(payment_path) tid = uuid.uuid4().hex transacao = get_in_progress_transaction(1, decimal_to_int_cents(ORDER_TOTAL), CieloProduct.InstallmentCredit, CieloCardBrand.Visa, CC_VISA_4X_INFO['installments'], tid, return_url=None) transacao = get_approved_transaction(transacao) transacao = get_captured_transaction(transacao) with patch.object(CieloRequest, 'autorizar', return_value=transacao): with patch.object(CieloRequest, 'consultar', return_value=transacao): with patch.object(CieloRequest, 'capturar', return_value=transacao): # Phase: pay response = c.soup(payment_path) response = c.post(transaction_path, CC_VISA_4X_INFO) assert response.status_code == 200 json_content = json.loads(response.content.decode("utf-8")) assert json_content['redirect_url'].endswith( reverse("shuup:cielo_transaction_return", kwargs={"cielo_order_pk": 1})) cielo_transaction = CieloTransaction.objects.get(tid=tid) assert cielo_transaction.cc_brand == CC_VISA_4X_INFO[ 'cc_brand'] assert cielo_transaction.cc_holder == CC_VISA_4X_INFO[ 'cc_holder'] assert cielo_transaction.installments == CC_VISA_4X_INFO[ 'installments'] assert cielo_transaction.cc_product == CieloProduct.InstallmentCredit assert abs(cielo_transaction.total_value - ORDER_TOTAL) < 0.01 assert cielo_transaction.status.value == transacao.status response = c.post(json_content['redirect_url']) assert response.status_code == 302 assert response.url.endswith(confirm_path) # Phase: Confirm assert Order.objects.count() == 0 confirm_soup = c.soup(confirm_path) response = c.post(confirm_path, data=extract_form_fields(confirm_soup)) assert response.status_code == 302, "Confirm should redirect forth" order = Order.objects.filter( payment_method=payment_method).first() process_payment_path = reverse("shuup:order_process_payment", kwargs={ "pk": order.pk, "key": order.key }) process_payment_return_path = reverse( "shuup:order_process_payment_return", kwargs={ "pk": order.pk, "key": order.key }) order_complete_path = reverse("shuup:order_complete", kwargs={ "pk": order.pk, "key": order.key }) response = c.get(process_payment_path) assert response.status_code == 302, "Payment page should redirect forth" assert response.url.endswith(process_payment_return_path) # Check payment return response = c.get(process_payment_return_path) assert response.status_code == 302, "Payment return should redirect forth" assert response.url.endswith(order_complete_path) cielo_transaction = CieloTransaction.objects.get( order_transaction__order=order, tid=tid) assert cielo_transaction.status == CieloTransactionStatus.Captured assert cielo_transaction.authorization_nsu == str( transacao.autorizacao.nsu) assert cielo_transaction.authorization_lr == str( transacao.autorizacao.lr) assert cielo_transaction.authorization_date == iso8601.parse_date( transacao.autorizacao.data_hora) assert cielo_transaction.authentication_eci == transacao.autenticacao.eci assert cielo_transaction.authentication_date == iso8601.parse_date( transacao.autenticacao.data_hora) assert cielo_transaction.total_captured_value == ORDER_TOTAL assert cielo_transaction.total_reversed_value == Decimal() order.refresh_from_db() assert order.payment_data.get(CIELO_TRANSACTION_ID_KEY) assert order.payment_data.get(CIELO_ORDER_TRANSACTION_ID_KEY) assert order.payment_status == PaymentStatus.NOT_PAID
def test_credit_card_fail2(): """ Caso: - Transação com Cartão de Crédito - Auto captura desabilidato - Sem URL para autenticação - 4 parcelas - valor total do parcelado diferente do total do pedido """ initialize() c = SmartClient() default_product = get_default_product() basket_path = reverse("shuup:basket") c.post(basket_path, data={ "command": "add", "product_id": default_product.pk, "quantity": 10, "supplier": get_default_supplier().pk }) ORDER_TOTAL = PRODUCT_PRICE * 10 # Create methods shipping_method = get_default_shipping_method() processor = get_payment_provider() # aumenta o limite máximo de parcelas para 4 cielo_config = get_cielo_config() cielo_config.max_installments = 4 cielo_config.save() payment_method = processor.create_service( CIELO_SERVICE_CREDIT, identifier="cielo_phase_cc", shop=get_default_shop(), name="credit card", enabled=True, tax_class=get_default_tax_class()) # Resolve paths addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"}) methods_path = reverse("shuup:checkout", kwargs={"phase": "methods"}) payment_path = reverse("shuup:checkout", kwargs={"phase": "payment"}) transaction_path = reverse("shuup:cielo_make_transaction") confirm_path = reverse("shuup:checkout", kwargs={"phase": "confirm"}) # Phase: Addresses addresses_soup = c.soup(addresses_path) inputs = fill_address_inputs(addresses_soup, with_company=False) c.post(addresses_path, data=inputs) c.post(methods_path, data={ "payment_method": payment_method.pk, "shipping_method": shipping_method.pk }) c.get(confirm_path) tid = uuid.uuid4().hex transacao = get_in_progress_transaction(1, decimal_to_int_cents(ORDER_TOTAL), CieloProduct.InstallmentCredit, CieloCardBrand.Visa, CC_VISA_4X_INFO['installments'], tid, return_url=None) transacao = get_approved_transaction(transacao) with patch.object(CieloRequest, 'autorizar', return_value=transacao): with patch.object(CieloRequest, 'consultar', return_value=transacao): # Phase: pay c.soup(payment_path) response = c.post(transaction_path, CC_VISA_4X_INFO) json_content = json.loads(response.content.decode("utf-8")) response = c.post(json_content['redirect_url']) # ok, no redirect response = c.get(confirm_path) assert response.status_code == 200 # sabotagem: adiciona um item ao carrinho c.post(basket_path, data={ "command": "add", "product_id": default_product.pk, "quantity": 10, "supplier": get_default_supplier().pk }) # again, now with redirect response = c.get(confirm_path) assert response.status_code == 302 assert response.url.endswith(payment_path)
def login_and_finish_up_the_checkout(browser, live_server, test_username, test_email, test_password): fields = browser.driver.find_elements_by_name("login-username") # there should be only a single username field assert len(fields) == 1 browser.fill("login-username", test_email) browser.fill("login-password", test_password) click_element(browser, "button[name='login']") wait_until_condition(browser, lambda x: x.is_text_present("Addresses"), timeout=100) # Reload here just in case since there might have been reload with JS # which might cause issues with tests since the elements is in cache browser.reload() # This should be first order upcoming assert Order.objects.count() == 0 # Fnish the checkout customer_name = "Test Tester" customer_street = "Test Street" customer_city = "Test City" customer_region = "CA" customer_country = "US" # Fill all necessary information browser.fill("billing-name", customer_name) browser.fill("billing-street", customer_street) browser.fill("billing-city", customer_city) wait_until_appeared(browser, "#id_billing-region") browser.select("billing-country", customer_country) wait_until_disappeared(browser, "#id_billing-region") wait_until_appeared(browser, "select[name='billing-region_code']") browser.select("billing-region_code", customer_region) click_element(browser, "#addresses button[type='submit']") # Shouldn't submit since required fields browser.fill("shipping-name", customer_name) browser.fill("shipping-street", customer_street) browser.fill("shipping-city", customer_city) wait_until_appeared(browser, "#id_shipping-region") browser.select("shipping-country", customer_country) wait_until_disappeared(browser, "#id_shipping-region") wait_until_appeared(browser, "select[name='shipping-region_code']") click_element(browser, "#addresses button[type='submit']") wait_until_condition(browser, lambda x: x.is_text_present("Shipping & Payment")) pm = get_default_payment_method() sm = get_default_shipping_method() wait_until_condition(browser, lambda x: x.is_text_present(sm.name)) # shipping method name is present wait_until_condition(browser, lambda x: x.is_text_present(pm.name)) # payment method name is present click_element(browser, ".btn.btn-primary.btn-lg.pull-right") # click "continue" on methods page wait_until_condition(browser, lambda x: x.is_text_present("Confirmation")) # we are indeed in confirmation page product = Product.objects.first() # See that all expected texts are present wait_until_condition(browser, lambda x: x.is_text_present(product.name)) wait_until_condition(browser, lambda x: x.is_text_present(sm.name)) wait_until_condition(browser, lambda x: x.is_text_present(pm.name)) wait_until_condition(browser, lambda x: x.is_text_present("Delivery")) wait_until_condition(browser, lambda x: x.is_text_present("Billing")) # check that user information is available wait_until_condition(browser, lambda x: x.is_text_present(customer_name)) wait_until_condition(browser, lambda x: x.is_text_present(customer_street)) wait_until_condition(browser, lambda x: x.is_text_present(customer_city)) wait_until_condition(browser, lambda x: x.is_text_present("United States")) browser.execute_script('document.getElementById("id_accept_terms").checked=true') # click accept terms click_element(browser, ".btn.btn-primary.btn-lg") # click "place order" wait_until_condition(browser, lambda x: x.is_text_present("Thank you for your order!")) # order succeeded # Let's make sure the order now has a customer assert Order.objects.count() == 1 order = Order.objects.first() assert order.customer == PersonContact.objects.filter(user__username=test_username).first() assert order.customer.name == customer_name assert order.customer.default_shipping_address is not None assert order.customer.default_billing_address is not None assert order.customer.user.username == test_username
def test_credit_card_success_3(): """ Caso: - Transação com Cartão de Crédito - Auto captura desabilidato - Sem URL para autenticação - 4 parcelas com juros """ initialize() c = SmartClient() default_product = get_default_product() basket_path = reverse("shuup:basket") c.post(basket_path, data={ "command": "add", "product_id": default_product.pk, "quantity": 10, "supplier": get_default_supplier().pk }) ORDER_TOTAL = PRODUCT_PRICE * 10 # Create methods shipping_method = get_default_shipping_method() processor = get_payment_provider() # aumenta o limite máximo de parcelas para 4 cielo_config = get_cielo_config() cielo_config.max_installments = 4 cielo_config.installments_without_interest = 1 cielo_config.interest_rate = Decimal(3.20) cielo_config.save() payment_method = processor.create_service( CIELO_SERVICE_CREDIT, identifier="cielo_phase_cc", shop=get_default_shop(), name="credit card", enabled=True, tax_class=get_default_tax_class()) # Resolve paths addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"}) methods_path = reverse("shuup:checkout", kwargs={"phase": "methods"}) payment_path = reverse("shuup:checkout", kwargs={"phase": "payment"}) transaction_path = reverse("shuup:cielo_make_transaction") confirm_path = reverse("shuup:checkout", kwargs={"phase": "confirm"}) addresses_soup = c.soup(addresses_path) inputs = fill_address_inputs(addresses_soup, with_company=False) c.post(addresses_path, data=inputs) c.post(methods_path, data={ "payment_method": payment_method.pk, "shipping_method": shipping_method.pk }) c.get(confirm_path) tid = uuid.uuid4().hex transacao = get_in_progress_transaction( numero=1, valor=decimal_to_int_cents(ORDER_TOTAL), produto=CieloProduct.Credit, bandeira=CieloCardBrand.Visa, parcelas=CC_VISA_1X_INFO['installments'], tid=tid, return_url=None) transacao = get_approved_transaction(transacao) with patch.object(CieloRequest, 'autorizar', return_value=transacao): with patch.object(CieloRequest, 'consultar', return_value=transacao): # Phase: pay c.soup(payment_path) response = c.post(transaction_path, CC_VISA_4X_INFO) assert response.status_code == 200 json_content = json.loads(response.content.decode("utf-8")) assert json_content['redirect_url'].endswith( reverse("shuup:cielo_transaction_return", kwargs={"cielo_order_pk": 1})) choices = InstallmentContext( ORDER_TOTAL, cielo_config).get_intallments_choices() cielo_transaction = CieloTransaction.objects.get(tid=tid) assert cielo_transaction.cc_product == CieloProduct.InstallmentCredit assert abs(cielo_transaction.total_value - choices[3][2]) <= Decimal(0.01) assert cielo_transaction.status.value == transacao.status response = c.post(json_content['redirect_url']) confirm_soup = c.soup(confirm_path) response = c.post(confirm_path, data=extract_form_fields(confirm_soup)) order = Order.objects.filter(payment_method=payment_method).first() assert abs(order.taxful_total_price.value - choices[3][2]) <= Decimal(0.01) process_payment_path = reverse("shuup:order_process_payment", kwargs={ "pk": order.pk, "key": order.key }) process_payment_return_path = reverse( "shuup:order_process_payment_return", kwargs={ "pk": order.pk, "key": order.key }) response = c.get(process_payment_path) response = c.get(process_payment_return_path) cielo_transaction = CieloTransaction.objects.get( order_transaction__order=order, tid=tid) order.refresh_from_db() assert order.payment_data.get(CIELO_TRANSACTION_ID_KEY) assert order.payment_data.get(CIELO_ORDER_TRANSACTION_ID_KEY) assert order.payment_status == PaymentStatus.NOT_PAID
def test_order_flow_with_multiple_suppliers(): cache.clear() shop = factories.get_default_shop() factories.create_default_order_statuses() factories.get_default_payment_method() factories.get_default_shipping_method() n_orders_pre = Order.objects.count() product = factories.create_product("sku", shop=shop, default_price=30) shop_product = product.get_shop_instance(shop) # Activate show supplier info for front assert ThemeSettings.objects.count() == 1 theme_settings = ThemeSettings.objects.first() theme_settings.update_settings({"show_supplier_info": True}) supplier_data = [ ("Johnny Inc", 30), ("Mike Inc", 10), ("Simon Inc", 20), ] for name, product_price in supplier_data: supplier = Supplier.objects.create(name=name) shop_product.suppliers.add(supplier) SupplierPrice.objects.create(supplier=supplier, shop=shop, product=product, amount_value=product_price) strategy = "shuup.testing.supplier_pricing.supplier_strategy:CheapestSupplierPriceSupplierStrategy" with override_settings(SHUUP_PRICING_MODULE="supplier_pricing", SHUUP_SHOP_PRODUCT_SUPPLIERS_STRATEGY=strategy): # Ok so cheapest price should be default supplier expected_supplier = shop_product.get_supplier() assert expected_supplier.name == "Mike Inc" with override_current_theme_class( ClassicGrayTheme, shop): # Ensure settings is refreshed from DB c = SmartClient() # Case 1: use default supplier _add_to_basket(c, product.pk, 2) order = _complete_checkout(c, n_orders_pre + 1) assert order product_lines = order.lines.products() assert len(product_lines) == 1 assert product_lines[0].supplier.pk == expected_supplier.pk assert product_lines[0].base_unit_price_value == decimal.Decimal( "10") # Case 2: force supplier to Johnny Inc johnny_supplier = Supplier.objects.filter( name="Johnny Inc").first() _add_to_basket(c, product.pk, 3, johnny_supplier) order = _complete_checkout(c, n_orders_pre + 2) assert order product_lines = order.lines.products() assert len(product_lines) == 1 assert product_lines[0].supplier.pk == johnny_supplier.pk assert product_lines[0].base_unit_price_value == decimal.Decimal( "30") # Case 3: order 2 pcs from Mike and 3 pcs from Simon Inc mike_supplier = Supplier.objects.filter(name="Mike Inc").first() _add_to_basket(c, product.pk, 2, mike_supplier) simon_supplier = Supplier.objects.filter(name="Simon Inc").first() _add_to_basket(c, product.pk, 3, simon_supplier) order = _complete_checkout(c, n_orders_pre + 3) assert order assert order.taxful_total_price_value == decimal.Decimal( "80") # Math: 2x10e + 3x20e product_lines = order.lines.products() assert len(product_lines) == 2 mikes_line = [ line for line in product_lines if line.supplier.pk == mike_supplier.pk ][0] assert mikes_line assert mikes_line.quantity == 2 assert mikes_line.base_unit_price_value == decimal.Decimal("10") simon_line = [ line for line in product_lines if line.supplier.pk == simon_supplier.pk ][0] assert simon_line assert simon_line.quantity == 3 assert simon_line.base_unit_price_value == decimal.Decimal("20")
def test_order_create_without_default_address(admin_user): create_default_order_statuses() shop = get_default_shop() sm = get_default_shipping_method() pm = get_default_payment_method() contact = create_random_person(locale="en_US", minimum_name_comp_len=5) contact.default_billing_address = None contact.default_shipping_address = None contact.save() product = create_product(sku=printable_gibberish(), supplier=get_default_supplier(), shop=shop) assert not Order.objects.count() client = _get_client(admin_user) lines = [ { "type": "product", "product": product.id, "quantity": "1", "base_unit_price_value": "5.00" }, { "type": "product", "product": product.id, "quantity": "2", "base_unit_price_value": "1.00", "discount_amount_value": "0.50" }, { "type": "other", "sku": "hello", "text": "A greeting", "quantity": 1, "base_unit_price_value": "3.5" }, { "type": "text", "text": "This was an order!", "quantity": 0 }, ] response = client.post("/api/shuup/order/", content_type="application/json", data=json.dumps({ "shop": shop.pk, "shipping_method": sm.pk, "payment_method": pm.pk, "customer": contact.pk, "lines": lines })) assert response.status_code == 201 assert Order.objects.count() == 1 order = Order.objects.first() assert order.shop == shop assert order.shipping_method == sm assert order.payment_method == pm assert order.customer == contact assert order.creator == admin_user assert order.billing_address is None assert order.shipping_address is None assert order.payment_status == PaymentStatus.NOT_PAID assert order.shipping_status == ShippingStatus.NOT_SHIPPED assert order.status == OrderStatus.objects.get_default_initial() assert order.taxful_total_price_value == decimal.Decimal(10) assert order.lines.count( ) == 6 # shipping line, payment line, 2 product lines, 2 other lines for idx, line in enumerate(order.lines.all()[:4]): assert line.quantity == decimal.Decimal(lines[idx].get("quantity")) assert line.base_unit_price_value == decimal.Decimal(lines[idx].get( "base_unit_price_value", 0)) assert line.discount_amount_value == decimal.Decimal(lines[idx].get( "discount_amount_value", 0))
def test_create_order(admin_user, currency): create_default_order_statuses() shop = get_default_shop() shop.currency = currency tax = get_default_tax() Currency.objects.get_or_create(code=currency, decimal_places=2) shop.save() sm = get_default_shipping_method() pm = get_default_payment_method() contact = create_random_person(locale="en_US", minimum_name_comp_len=5) product = create_product(sku=printable_gibberish(), supplier=get_default_supplier(), shop=shop) assert not Order.objects.count() client = _get_client(admin_user) lines = [ { "type": "product", "product": product.id, "quantity": "1", "base_unit_price_value": "5.00" }, { "type": "product", "product": product.id, "quantity": "2", "base_unit_price_value": "1.00", "discount_amount_value": "0.50" }, { "type": "other", "sku": "hello", "text": "A greeting", "quantity": 1, "base_unit_price_value": "3.5" }, { "type": "text", "text": "This was an order!", "quantity": 0 }, ] response = client.post("/api/shuup/order/", content_type="application/json", data=json.dumps({ "shop": shop.pk, "shipping_method": sm.pk, "payment_method": pm.pk, "customer": contact.pk, "lines": lines })) assert response.status_code == 201 assert Order.objects.count() == 1 order = Order.objects.first() assert order.shop == shop assert order.shipping_method == sm assert order.payment_method == pm assert order.customer == contact assert order.creator == admin_user assert order.billing_address == contact.default_billing_address.to_immutable( ) assert order.shipping_address == contact.default_shipping_address.to_immutable( ) assert order.payment_status == PaymentStatus.NOT_PAID assert order.shipping_status == ShippingStatus.NOT_SHIPPED assert order.status == OrderStatus.objects.get_default_initial() assert order.taxful_total_price_value == decimal.Decimal(10) assert order.lines.count( ) == 6 # shipping line, payment line, 2 product lines, 2 other lines assert order.currency == currency for idx, line in enumerate(order.lines.all()[:4]): assert line.quantity == decimal.Decimal(lines[idx].get("quantity")) assert line.base_unit_price_value == decimal.Decimal(lines[idx].get( "base_unit_price_value", 0)) assert line.discount_amount_value == decimal.Decimal(lines[idx].get( "discount_amount_value", 0)) # Test tax summary response_data = json.loads(response.content.decode("utf-8")) # Tax summary should not be present here assert "summary" not in response_data response = client.get('/api/shuup/order/{}/taxes/'.format(order.pk)) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) assert "lines" in response_data assert "summary" in response_data line_summary = response_data["lines"] summary = response_data["summary"] first_tax_summary = summary[0] assert int(first_tax_summary["tax_id"]) == tax.id assert first_tax_summary["tax_rate"] == tax.rate first_line_summary = line_summary[0] assert "tax" in first_line_summary
def test_encode_method_weights(): payment_method = get_default_payment_method() assert encode_method(payment_method).get("minWeight") is None shipping_method = get_default_shipping_method() assert encode_method(shipping_method).get("minWeight") is None
def test_broken_order(admin_user): """""" quantities = [44, 23, 65] expected = sum(quantities) * 50 expected_based_on = expected / 1.5 # Shuup is calculating taxes per line so there will be some "errors" expected_based_on = ensure_decimal_places( Decimal("%s" % (expected_based_on + 0.01))) shop = get_default_shop() supplier = get_default_supplier() product1 = create_product("simple-test-product1", shop, supplier, 50) product2 = create_product("simple-test-product2", shop, supplier, 50) product3 = create_product("simple-test-product3", shop, supplier, 50) tax = get_default_tax() source = BasketishOrderSource(get_default_shop()) billing_address = get_address(country="US") shipping_address = get_address(name="Test street", country="US") source.status = get_initial_order_status() source.billing_address = billing_address source.shipping_address = shipping_address source.customer = create_random_person() source.payment_method = get_default_payment_method() source.shipping_method = get_default_shipping_method() source.add_line( type=OrderLineType.PRODUCT, product=product1, supplier=get_default_supplier(), quantity=quantities[0], base_unit_price=source.create_price(50), ) source.add_line( type=OrderLineType.PRODUCT, product=product2, supplier=get_default_supplier(), quantity=quantities[1], base_unit_price=source.create_price(50), ) source.add_line( type=OrderLineType.PRODUCT, product=product3, supplier=get_default_supplier(), quantity=quantities[2], base_unit_price=source.create_price(50), ) currency = "EUR" summary = source.get_tax_summary() assert len(summary) == 1 summary = summary[0] assert summary.taxful == Money(expected, "EUR") assert summary.based_on == Money(expected_based_on, "EUR") # originally non-rounded value assert bankers_round(source.get_total_tax_amount()) == summary.tax_amount assert source.taxless_total_price.value == expected_based_on assert summary.taxful.value == source.taxful_total_price.value assert summary.tax_amount == Money( bankers_round(source.taxful_total_price.value - source.taxless_total_price.value), currency) assert summary.taxful == summary.raw_based_on + summary.tax_amount assert summary.tax_rate == tax.rate assert summary.taxful.value == ( summary.based_on + summary.tax_amount).value - Decimal("%s" % 0.01) # create order from basket creator = OrderCreator() order = creator.create_order(source) assert order.taxless_total_price.value == expected_based_on # originally non-rounded value assert bankers_round(order.get_total_tax_amount()) == summary.tax_amount
def test_credit_card_fail(): """ Caso: - Transação com Cartão de Crédito - Auto captura desabilidato - Sem URL para autenticação - 4 parcelas - dados do pagamento nao existem """ initialize() c = SmartClient() default_product = get_default_product() basket_path = reverse("shuup:basket") c.post(basket_path, data={ "command": "add", "product_id": default_product.pk, "quantity": 10, "supplier": get_default_supplier().pk }) ORDER_TOTAL = PRODUCT_PRICE * 10 # Create methods shipping_method = get_default_shipping_method() processor = get_payment_provider() # aumenta o limite máximo de parcelas para 4 cielo_config = get_cielo_config() cielo_config.max_installments = 4 cielo_config.save() payment_method = processor.create_service( CIELO_SERVICE_CREDIT, identifier="cielo_phase_cc", shop=get_default_shop(), name="credit card", enabled=True, tax_class=get_default_tax_class()) # Resolve paths addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"}) methods_path = reverse("shuup:checkout", kwargs={"phase": "methods"}) payment_path = reverse("shuup:checkout", kwargs={"phase": "payment"}) transaction_path = reverse("shuup:cielo_make_transaction") confirm_path = reverse("shuup:checkout", kwargs={"phase": "confirm"}) # Phase: Addresses addresses_soup = c.soup(addresses_path) inputs = fill_address_inputs(addresses_soup, with_company=False) c.post(addresses_path, data=inputs) c.post(methods_path, data={ "payment_method": payment_method.pk, "shipping_method": shipping_method.pk }) c.get(confirm_path) tid = uuid.uuid4().hex transacao = get_in_progress_transaction(1, decimal_to_int_cents(ORDER_TOTAL), CieloProduct.InstallmentCredit, CieloCardBrand.Visa, CC_VISA_4X_INFO['installments'], tid, return_url=None) transacao = get_approved_transaction(transacao) with patch.object(CieloRequest, 'autorizar', return_value=transacao): with patch.object(CieloRequest, 'consultar', return_value=transacao): # Phase: pay c.soup(payment_path) response = c.post(transaction_path, CC_VISA_4X_INFO) json_content = json.loads(response.content.decode("utf-8")) response = c.post(json_content['redirect_url']) confirm_soup = c.soup(confirm_path) response = c.post(confirm_path, data=extract_form_fields(confirm_soup)) order = Order.objects.filter(payment_method=payment_method).first() process_payment_path = reverse("shuup:order_process_payment", kwargs={ "pk": order.pk, "key": order.key }) # FORCE CLEAR ORDER PAYMENT DATA order.payment_data = {} order.save() response = c.get(process_payment_path) order.refresh_from_db() assert order.status == OrderStatus.objects.get_default_canceled()
def test_admin(rf, admin_user): initialize() c = SmartClient() default_product = get_default_product() basket_path = reverse("shuup:basket") c.post(basket_path, data={ "command": "add", "product_id": default_product.pk, "quantity": 1, "supplier": get_default_supplier().pk }) shipping_method = get_default_shipping_method() processor = get_payment_provider() payment_method = processor.create_service( PagSeguroPaymentMethod.ONLINE_DEBIT.value, identifier="pagseguro_debit", shop=get_default_shop(), name="debit", enabled=True, tax_class=get_default_tax_class()) service_choices = processor.get_service_choices() assert len(service_choices) == 2 assert service_choices[0].identifier == PagSeguroPaymentMethod.BOLETO.value assert service_choices[ 1].identifier == PagSeguroPaymentMethod.ONLINE_DEBIT.value addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"}) methods_path = reverse("shuup:checkout", kwargs={"phase": "methods"}) payment_path = reverse("shuup:checkout", kwargs={"phase": "payment"}) confirm_path = reverse("shuup:checkout", kwargs={"phase": "confirm"}) addresses_soup = c.soup(addresses_path) inputs = fill_address_inputs(addresses_soup, with_company=False) c.post(addresses_path, data=inputs) c.post(methods_path, data={ "payment_method": payment_method.pk, "shipping_method": shipping_method.pk }) c.get(confirm_path) c.soup(payment_path) c.post( payment_path, { "paymentMethod": PagSeguroPaymentMethodIdentifier.Debito, "bankOption": "{0}".format(PagSeguroPaymentMethodCode.DebitoOnlineBB.value), "senderHash": "J7E98Y37WEIRUHDIAI9U8RYE7UQE" }) confirm_soup = c.soup(confirm_path) c.post(confirm_path, data=extract_form_fields(confirm_soup)) order = Order.objects.filter(payment_method=payment_method).first() payment = PagSeguroPayment.objects.create(order=order, code="u3928uhu8y9i3") PagSeguroOrderSection() PagSeguroOrderSection.get_context_data(order) assert PagSeguroOrderSection.visible_for_object(order) is True view = load("shuup_pagseguro.admin.views.PaymentRefreshView").as_view() request = apply_request_middleware(rf.post("/"), user=admin_user) response = view(request) assert response.status_code == 400 request = apply_request_middleware(rf.post("/", {"pk": payment.pk}), user=admin_user) response = view(request) assert response.status_code == 200 # somente visita view = load("shuup_pagseguro.admin.views.config.ConfigListView").as_view() request = apply_request_middleware(rf.get("/"), user=admin_user) response = view(request) assert response.status_code == 200 view = load("shuup_pagseguro.admin.views.DashboardView").as_view() request = apply_request_middleware(rf.get("/"), user=admin_user) response = view(request) assert response.status_code == 200
def get_frontend_order_state(contact, valid_lines=True): """ Get a dict structure mirroring what the frontend JavaScript would submit. :type contact: Contact|None """ translation.activate("en") shop = get_default_shop() tax, created = Tax.objects.get_or_create(code="test_code", defaults={ "rate": decimal.Decimal("0.20"), "name": "Default" }) tax_class, created = TaxClass.objects.get_or_create( identifier="test_tax_class", defaults={"name": "Default"}) rule, created = TaxRule.objects.get_or_create(tax=tax) rule.tax_classes.add(tax_class) rule.save() product = create_product(sku=printable_gibberish(), supplier=get_default_supplier(), shop=shop) product.tax_class = tax_class product.save() if valid_lines: lines = [ { "id": "x", "type": "product", "product": { "id": product.id }, "quantity": "32", "baseUnitPrice": 50 }, { "id": "y", "type": "other", "sku": "hello", "text": "A greeting", "quantity": 1, "unitPrice": "5.5" }, { "id": "z", "type": "text", "text": "This was an order!", "quantity": 0 }, ] else: unshopped_product = create_product(sku=printable_gibberish(), supplier=get_default_supplier()) not_visible_product = create_product(sku=printable_gibberish(), supplier=get_default_supplier(), shop=shop) not_visible_shop_product = not_visible_product.get_shop_instance(shop) not_visible_shop_product.visibility = ShopProductVisibility.NOT_VISIBLE not_visible_shop_product.save() lines = [ { "id": "x", "type": "product" }, # no product? { "id": "x", "type": "product", "product": { "id": unshopped_product.id } }, # not in this shop? { "id": "y", "type": "product", "product": { "id": -product.id } }, # invalid product? { "id": "z", "type": "other", "quantity": 1, "unitPrice": "q" }, # what's that price? { "id": "rr", "type": "product", "quantity": 1, "product": { "id": not_visible_product.id } } # not visible ] state = { "customer": { "id": contact.id if contact else None, "billingAddress": encode_address(contact.default_billing_address) if contact else {}, "shippingAddress": encode_address(contact.default_shipping_address) if contact else {}, }, "lines": lines, "methods": { "shippingMethod": { "id": get_default_shipping_method().id }, "paymentMethod": { "id": get_default_payment_method().id }, }, "shop": { "selected": { "id": shop.id, "name": shop.name, "currency": shop.currency, "priceIncludeTaxes": shop.prices_include_tax } } } return state