def test_get_pagination_variables():
    populate_if_required()  # Makes sure there is at least 30 products in db

    products = Product.objects.all()[:19]
    assert len(products) == 19
    vars = {"products": products}

    context = get_jinja_context(**vars)
    variables = general.get_pagination_variables(context, context["products"], limit=4)
    assert variables["page"].number == 1
    assert len(variables["objects"]) == 4

    context = get_jinja_context(path="/?page=5", **vars)
    variables = general.get_pagination_variables(context, context["products"], limit=4)
    assert variables["page"].number == 5
    assert len(variables["objects"]) == 3

    variables = general.get_pagination_variables(context, context["products"], limit=20)
    assert not variables["is_paginated"]
    assert variables["page"].number == 1

    context = get_jinja_context(path="/?page=42", **vars)
    variables = general.get_pagination_variables(context, context["products"], limit=4)
    assert variables["page"].number == 5
    assert len(variables["objects"]) == 3

    vars = {"products": []}
    context = get_jinja_context(path="/", **vars)
    variables = general.get_pagination_variables(context, context["products"], limit=4)
    assert not variables["is_paginated"]
def test_basic_order_flow(with_company):
    create_default_order_statuses()
    n_orders_pre = Order.objects.count()
    populate_if_required()
    c = SmartClient()
    product_ids = _populate_client_basket(c)

    addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"})
    addresses_soup = c.soup(addresses_path)
    inputs = fill_address_inputs(addresses_soup, with_company=with_company)
    response = c.post(addresses_path, data=inputs)
    assert response.status_code == 302  # Should redirect forth

    methods_path = reverse("shuup:checkout", kwargs={"phase": "methods"})
    methods_soup = c.soup(methods_path)
    assert c.post(methods_path, data=extract_form_fields(methods_soup)).status_code == 302  # Should redirect forth

    confirm_path = reverse("shuup:checkout", kwargs={"phase": "confirm"})
    confirm_soup = c.soup(confirm_path)
    Product.objects.get(pk=product_ids[0]).soft_delete()
    assert c.post(confirm_path, data=extract_form_fields(confirm_soup)).status_code == 200  # user needs to reconfirm
    data = extract_form_fields(confirm_soup)
    data['product_ids'] = ','.join(product_ids[1:])
    assert c.post(confirm_path, data=data).status_code == 302  # Should redirect forth

    n_orders_post = Order.objects.count()
    assert n_orders_post > n_orders_pre, "order was created"
Beispiel #3
0
def test_get_installments_12x_with_simples_intereset():
    """
        Max 12 installs with PRICE intereset
        interest_rate = 2.30%
        min_installment_amount = 30.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=12,
                                              installments_without_interest=2,
                                              interest_type=InterestType.Price,
                                              interest_rate=Decimal(2.3),
                                              min_installment_amount=Decimal(30))

    order_total = (PRODUCT_QTNTY * PRODUCT_PRICE)
    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']
Beispiel #4
0
def test_get_installments_cc_does_not_allow_installments():
    """
        Max 9 installs with SIMPLE intereset
        interest_rate = 4.00%
        Credit card does not allow installments
    """
    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)
    CieloConfig.objects.create(shop=shop,
                               max_installments=9,
                               installments_without_interest=3,
                               interest_type=InterestType.Simple,
                               interest_rate=Decimal(4.0))

    order_total = (PRODUCT_QTNTY * PRODUCT_PRICE)
    total_price_str = "{0}".format(format_money(shop.create_price(order_total)))

    response = c.get(INSTALLMENTS_PATH, {"cc_brand": CieloCardBrand.Discover})
    json_content = json.loads(response.content.decode("utf-8"))
    assert len(json_content['installments']) == 1
    assert json_content['installments'][0]['number'] == 1
    assert total_price_str in json_content['installments'][0]['name']
Beispiel #5
0
def test_get_installments_3x_no_intereset():
    """
        Max 3 installs with no intereset
    """
    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)
    CieloConfig.objects.create(shop=shop,
                               max_installments=3,
                               installments_without_interest=3)

    order_total = PRODUCT_QTNTY * PRODUCT_PRICE
    total_price_str = "{0}".format(format_money(shop.create_price(order_total)))

    response = c.get(INSTALLMENTS_PATH, {"cc_brand": CieloCardBrand.Visa})
    json_content = json.loads(response.content.decode("utf-8"))
    assert len(json_content['installments']) == 3

    assert json_content['installments'][0]['number'] == 1
    assert total_price_str in json_content['installments'][0]['name']

    total_2x_no_interest = format_money(shop.create_price(order_total / Decimal(2)))
    assert json_content['installments'][1]['number'] == 2
    assert total_price_str in json_content['installments'][1]['name']
    assert total_2x_no_interest in json_content['installments'][1]['name']

    total_3x_no_interest = format_money(shop.create_price(order_total / Decimal(3)))
    assert json_content['installments'][2]['number'] == 3
    assert total_price_str in json_content['installments'][2]['name']
    assert total_3x_no_interest in json_content['installments'][2]['name']
def test_basic_order_flow_registered(regular_user):
    cache.clear()
    create_default_order_statuses()
    n_orders_pre = Order.objects.count()
    populate_if_required()
    get_test_script("test script", "order_received")
    # 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"})

    template_data = STEP_DATA[0]["actions"][0]["template_data"]

    LANG_CODE = {
        "en": "US",
        "fi": "FI"
    }

    for lang in ["en", "fi"]:
        n_outbox_pre = len(mail.outbox)
        contact = get_person_contact(regular_user)
        contact.language = lang
        contact.save()

        c = SmartClient()
        c.login(username=REGULAR_USER_USERNAME, password=REGULAR_USER_PASSWORD)

        product_ids = _populate_client_basket(c)

        addresses_soup = c.soup(addresses_path)
        address = get_address(country=LANG_CODE[lang])

        inputs = fill_address_inputs(addresses_soup, address)
        response = c.post(addresses_path, data=inputs)
        assert response.status_code == 302  # Should redirect forth

        methods_soup = c.soup(methods_path)
        assert c.post(methods_path, data=extract_form_fields(methods_soup)).status_code == 302  # Should redirect forth

        confirm_soup = c.soup(confirm_path)
        Product.objects.get(pk=product_ids[0]).soft_delete()
        assert c.post(confirm_path, data=extract_form_fields(confirm_soup)).status_code == 200  # user needs to reconfirm
        data = extract_form_fields(confirm_soup)
        data['product_ids'] = ','.join(product_ids[1:])
        assert c.post(confirm_path, data=data).status_code == 302  # Should redirect forth

        n_orders_post = Order.objects.count()
        assert n_orders_post > n_orders_pre, "order was created"
        assert (len(mail.outbox) == n_outbox_pre + 1), "Sending email failed"
        latest_mail = mail.outbox[-1]

        # mail is always sent in fallback language since user is not registered
        assert latest_mail.subject == template_data[lang]["subject"], "Subject doesn't match"
        assert latest_mail.body == template_data[lang]["body"], "Body doesn't match"
Beispiel #7
0
def initialize():
    get_cielo_config()
    get_default_shop()
    set_current_theme('shuup.themes.classic_gray')
    create_default_order_statuses()
    populate_if_required()

    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()
Beispiel #8
0
def _get_configured_basket_client():
    """
    Initialized and configure client
    adding product and setting address,
    ready to make transactions
    """
    get_default_shop()
    create_default_order_statuses()
    populate_if_required()
    set_current_theme('shuup.themes.classic_gray')
    c = SmartClient()
    _configure_basket(c)
    return c
def test_checkout_empty_basket(rf):
    create_default_order_statuses()
    n_orders_pre = Order.objects.count()
    populate_if_required()
    c = SmartClient()
    product_ids = _populate_client_basket(c)
    addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"})
    addresses_soup = c.soup(addresses_path)
    inputs = fill_address_inputs(addresses_soup)
    for product_id in product_ids:
        Product.objects.get(pk=product_id).soft_delete()
    response, soup = c.response_and_soup(addresses_path, data=inputs, method="post")
    assert response.status_code == 200  # Should redirect forth
    assert b"Your shopping cart is empty." in soup.renderContents()
Beispiel #10
0
def test_basic_order_flow(with_company, with_signal):
    cache.clear()
    create_default_order_statuses()
    n_orders_pre = Order.objects.count()
    populate_if_required()
    c = SmartClient()
    product_ids = _populate_client_basket(c)

    addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"})
    addresses_soup = c.soup(addresses_path)
    inputs = fill_address_inputs(addresses_soup, with_company=with_company)
    response = c.post(addresses_path, data=inputs)
    assert response.status_code == 302  # Should redirect forth

    # Make sure the address is initialized from storage
    # Go back to addresses right before back to methods
    c.soup(addresses_path)

    methods_path = reverse("shuup:checkout", kwargs={"phase": "methods"})
    methods_soup = c.soup(methods_path)
    assert c.post(methods_path, data=extract_form_fields(methods_soup)).status_code == 302  # Should redirect forth

    if with_signal:
        checkout_complete.connect(checkout_complete_signal, dispatch_uid="checkout_complete_signal")

    confirm_path = reverse("shuup:checkout", kwargs={"phase": "confirm"})
    confirm_soup = c.soup(confirm_path)
    Product.objects.get(pk=product_ids[0]).soft_delete()
    assert c.post(confirm_path, data=extract_form_fields(confirm_soup)).status_code == 200  # user needs to reconfirm
    data = extract_form_fields(confirm_soup)
    data['product_ids'] = ','.join(product_ids[1:])
    assert c.post(confirm_path, data=data).status_code == 302  # Should redirect forth

    n_orders_post = Order.objects.count()
    assert n_orders_post > n_orders_pre, "order was created"

    order = Order.objects.first()
    expected_ip = "127.0.0.2" if with_signal else "127.0.0.1"
    assert order.ip_address == expected_ip

    if with_signal:
        checkout_complete.disconnect(dispatch_uid="checkout_complete_signal")
Beispiel #11
0
def test_get_installments_options_rest():
    patch_cielo_request()
    shop = get_default_shop()
    c = SmartClient()

    # method not allowed
    response = c.post(INSTALLMENTS_PATH)
    assert response.status_code == 405

    # missing parameters
    response = c.get(INSTALLMENTS_PATH)
    assert response.status_code == 400

    # no CieloConfig for shop
    response = c.get(INSTALLMENTS_PATH, {"cc_brand": CieloCardBrand.Visa})
    assert response.status_code == 400

    CieloConfig.objects.create(shop=shop)

    # basket not valid (no products and not payment/shipping methods)
    response = c.get(INSTALLMENTS_PATH, {"cc_brand": CieloCardBrand.Visa})
    assert response.status_code == 400

    create_default_order_statuses()
    populate_if_required()
    set_current_theme('shuup.themes.classic_gray')

    # configures the user basket
    _configure_basket(c)

    # only 1 installment, because no configurations were set on CieloConfig
    response = c.get(INSTALLMENTS_PATH, {"cc_brand": CieloCardBrand.Visa})
    assert response.status_code == 200

    # should be the order total
    order_total = PRODUCT_QTNTY * PRODUCT_PRICE
    total_price_str = "{0}".format(format_money(shop.create_price(order_total)))

    json_content = json.loads(response.content.decode("utf-8"))
    assert len(json_content['installments']) == 1
    assert json_content['installments'][0]['number'] == 1
    assert total_price_str in json_content['installments'][0]['name']
def test_get_pagination_variables():
    from shuup.front.template_helpers import general

    populate_if_required()  # Makes sure there is at least 30 products in db

    products = Product.objects.all()[:19]
    assert len(products) == 19
    vars = {"products": products}

    context = get_jinja_context(**vars)
    variables = general.get_pagination_variables(context, context["products"], limit=2)
    assert variables["page"].number == 1
    assert len(variables["objects"]) == 2
    assert variables["page_range"][0] == 1
    assert variables["page_range"][-1] == 5

    context = get_jinja_context(path="/?page=5", **vars)
    variables = general.get_pagination_variables(context, context["products"], limit=2)
    assert variables["page"].number == 5
    assert len(variables["objects"]) == 2
    assert variables["page_range"][0] == 3
    assert variables["page_range"][-1] == 7

    variables = general.get_pagination_variables(context, context["products"], limit=20)
    assert not variables["is_paginated"]
    assert variables["page"].number == 1
    assert variables["page_range"][0] == variables["page_range"][-1] == 1

    context = get_jinja_context(path="/?page=42", **vars)
    variables = general.get_pagination_variables(context, context["products"], limit=4)
    assert variables["page"].number == 5
    assert len(variables["objects"]) == 3
    assert variables["page_range"][0] == 1
    assert variables["page_range"][-1] == 5

    vars = {"products": []}
    context = get_jinja_context(path="/", **vars)
    variables = general.get_pagination_variables(context, context["products"], limit=4)
    assert not variables["is_paginated"]
    assert variables["page_range"][0] == variables["page_range"][-1] == 1
Beispiel #13
0
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']
Beispiel #14
0
def test_picotable_correctly_sorts_translated_fields(rf, admin_user, regular_user):
    """
    Make sure that translated fields, such as product names, are correctly sorted
    """
    populate_if_required()

    columns = [
        Column("id", "Id", filter_config=Filter(), display=instance_id),
        Column(
            "name", "Name", sort_field="translations__name",
            filter_config=TextFilter(filter_field="translations__name")),
    ]

    pico = get_pico(rf, model=Product, columns=columns)

    # Verify ascending sort
    sorted_products = pico.get_data({"perPage": 100, "page": 1, "sort": "+name"})
    sorted_names = [p["name"] for p in sorted_products["items"]]
    assert sorted_names == sorted(sorted_names)

    # Verify descending sort
    sorted_products = pico.get_data({"perPage": 100, "page": 1, "sort": "-name"})
    sorted_names = [p["name"] for p in sorted_products["items"]]
    assert sorted_names == sorted(sorted_names, reverse=True)
def test_get_random_products():
    populate_if_required()
    context = get_jinja_context()
    assert len(list(general.get_random_products(context, n_products=4))) == 4
def test_get_root_categories():
    populate_if_required()
    context = get_jinja_context()
    for root in general.get_root_categories(context=context):
        assert not root.parent_id
Beispiel #17
0
def test_order_flow_with_phases(get_shipping_method, shipping_data, get_payment_method, payment_data):
    cache.clear()
    create_default_order_statuses()
    populate_if_required()
    c = SmartClient()
    _populate_client_basket(c)

    # Create methods
    shipping_method = get_shipping_method()
    payment_method = get_payment_method()
    # Resolve paths
    addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"})
    methods_path = reverse("shuup:checkout", kwargs={"phase": "methods"})
    shipping_path = reverse("shuup:checkout", kwargs={"phase": "shipping"})
    payment_path = reverse("shuup:checkout", kwargs={"phase": "payment"})
    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 to methods"

    # Phase: Methods
    response = c.get(methods_path)
    assert response.status_code == 200
    response = c.post(
        methods_path,
        data={
            "shipping_method": shipping_method.pk,
            "payment_method": payment_method.pk
        }
    )
    assert response.status_code == 302, "Methods phase should redirect forth"

    if isinstance(shipping_method.carrier, CarrierWithCheckoutPhase):
        # Phase: Shipping
        response = c.get(shipping_path)
        assert response.status_code == 200
        response = c.post(shipping_path, data=shipping_data)
        assert response.status_code == 302, "Payments phase should redirect forth"

    if isinstance(payment_method.payment_processor, PaymentWithCheckoutPhase):
        # Phase: payment
        response = c.get(payment_path)
        assert response.status_code == 200
        response = c.post(payment_path, data=payment_data)
        assert response.status_code == 302, "Payments phase should redirect forth"

    # Phase: Confirm
    assert Order.objects.count() == 0
    confirm_soup = c.soup(confirm_path)

    data = extract_form_fields(confirm_soup)
    data["accept_terms"] = True
    response = c.post(confirm_path, data)
    assert response.status_code == 302, "Confirm should redirect forth"

    order = Order.objects.first()

    if isinstance(shipping_method.carrier, CarrierWithCheckoutPhase):
        assert order.shipping_data.get("input_value") == "20540"

    if isinstance(payment_method.payment_processor, PaymentWithCheckoutPhase):
        assert order.payment_data.get("input_value")
        assert order.payment_status == PaymentStatus.NOT_PAID
        # Resolve order specific paths (payment and complete)
        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})

        # Check confirm redirection to payment page
        assert response.url.endswith(process_payment_path), (
            "Confirm should have redirected to payment page")

        # Visit 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)

        # 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)

        # Check payment status has changed to DEFERRED
        order = Order.objects.get(pk=order.pk)  # reload
        assert order.payment_status == PaymentStatus.DEFERRED
def test_get_all_manufacturers():
    populate_if_required()
    context = get_jinja_context()
    # TODO: This is not a good test
    assert len(general.get_all_manufacturers(context)) == 0
Beispiel #19
0
def test_get_root_categories():
    populate_if_required()
    context = get_jinja_context()
    from shuup.front.template_helpers import general
    for root in general.get_root_categories(context=context):
        assert not root.parent_id
def test_checkout(admin_user):
    get_default_shop()
    set_current_theme('shuup.themes.classic_gray')
    create_default_order_statuses()
    populate_if_required()
    create_test_data()

    default_product = get_default_product()
    sp = ShopProduct.objects.get(product=default_product,
                                 shop=get_default_shop())
    sp.default_price = get_default_shop().create_price(Decimal(10.0))
    sp.save()

    service = get_custom_carrier_service()
    component = SpecificShippingTableBehaviorComponent.objects.create(
        table=ShippingTable.objects.get(identifier='table-1'))
    service.behavior_components.add(component)

    c = SmartClient()

    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

    shipping_method = service
    payment_method = get_payment_method(name="neat", price=4)

    # 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)

    inputs['shipping-postal_code'] = "89060201"
    inputs['shipping-country'] = "BR"

    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

    # 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
Beispiel #21
0
def test_get_all_manufacturers():
    from shuup.front.template_helpers import general
    populate_if_required()
    context = get_jinja_context()
    # TODO: This is not a good test
    assert len(general.get_all_manufacturers(context)) == 0
def test_get_root_categories():
    populate_if_required()
    context = get_jinja_context()
    for root in general.get_root_categories(context=context):
        assert not root.parent_id
def test_get_all_manufacturers():
    populate_if_required()
    context = get_jinja_context()
    # TODO: This is not a good test
    assert len(general.get_all_manufacturers(context)) == 0
def test_checkout(admin_user):
    get_default_shop()
    set_current_theme('shuup.themes.classic_gray')
    create_default_order_statuses()
    populate_if_required()
    create_test_data()

    default_product = get_default_product()
    sp = ShopProduct.objects.get(product=default_product, shop=get_default_shop())
    sp.default_price = get_default_shop().create_price(Decimal(10.0))
    sp.save()

    service = get_custom_carrier_service()
    component = SpecificShippingTableBehaviorComponent.objects.create(
        table=ShippingTable.objects.get(identifier='table-1')
    )
    service.behavior_components.add(component)

    c = SmartClient()

    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

    shipping_method = service
    payment_method = get_payment_method(name="neat", price=4)

    # 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)

    inputs['shipping-postal_code'] = "89060201"
    inputs['shipping-country'] = "BR"

    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

    # 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
Beispiel #25
0
def test_checkout_with_success():
    get_default_shop()
    set_current_theme('shuup.themes.classic_gray')
    create_default_order_statuses()
    populate_if_required()

    client = SmartClient()

    # first step - register user
    person_data = {
        "email": "*****@*****.**",
        "password1": "password",
        "password2": "password",
        "person_type": PersonType.FISICA.value,
        "PF-name": "NOME DA PESSOA",
        "PF-cpf": "012.345.678-90",
        "PF-rg": "312321",
        "PF-birth_date": "03/28/1954",
        "PF-gender": Gender.MALE.value
    }

    result = client.post(reverse("shuup:registration_register"), data=person_data)
    assert not result is None
    user = get_user_model().objects.get(email=person_data['email'])
    assert user.is_active


    # second step -add something into the basket
    default_product = get_default_product()

    basket_path = reverse("shuup:basket")
    add_to_basket_resp = client.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


    # third step - go to checkout and set the addresses
    addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"})
    addresses_data = {
        'billing-name': 'maria da silva',
        'billing-street': 'rua billing',
        'billing-street2': 'apto',
        'billing-street3': 'bairro outrem',
        'billing-postal_code': '89090-200',
        'billing-city': 'plumenau',
        'billing-region': 'PR',
        'billing-country': 'BR',
        'billing-phone': '41 2332-0213',
        'billing_extra-numero': '563',
        'billing_extra-cel': '13 98431-4345',
        'billing_extra-ponto_ref': 'longe de tudo',

        'shipping-name': 'joao da silva',
        'shipping-street': 'rua shipping',
        'shipping-street2': 'complemento',
        'shipping-street3': 'bairro',
        'shipping-postal_code': '89050120',
        'shipping-city': 'indaial',
        'shipping-region': 'SC',
        'shipping-country': 'BR',
        'shipping-phone': '39 9999-2332',
        'shipping_extra-numero': '323',
        'shipping_extra-cel': '21 4444-3333',
        'shipping_extra-ponto_ref': 'proximo posto',
    }

    response = client.post(addresses_path, data=addresses_data)
    print (response.content)
    assert response.status_code == 302  # Should redirect forth


    # Set the payment and shipping methods
    methods_path = reverse("shuup:checkout", kwargs={"phase": "methods"})
    methods_soup = client.soup(methods_path)
    assert client.post(methods_path, data=extract_form_fields(methods_soup)).status_code == 302  # Should redirect forth


    # Confirm the order
    confirm_path = reverse("shuup:checkout", kwargs={"phase": "confirm"})
    confirm_soup = client.soup(confirm_path)
    assert client.post(confirm_path, data=extract_form_fields(confirm_soup)).status_code == 302  # Should redirect forth
def test_get_random_products():
    populate_if_required()
    context = get_jinja_context()
    assert len(list(general.get_random_products(context, n_products=4))) == 4
Beispiel #27
0
def test_order_flow_with_phases(get_shipping_method, shipping_data, get_payment_method, payment_data):
    create_default_order_statuses()
    populate_if_required()
    c = SmartClient()
    _populate_client_basket(c)

    # Create methods
    shipping_method = get_shipping_method()
    payment_method = get_payment_method()

    # Resolve paths
    addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"})
    methods_path = reverse("shuup:checkout", kwargs={"phase": "methods"})
    shipping_path = reverse("shuup:checkout", kwargs={"phase": "shipping"})
    payment_path = reverse("shuup:checkout", kwargs={"phase": "payment"})
    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 to methods"

    # Phase: Methods
    response = c.get(methods_path)
    assert response.status_code == 200
    response = c.post(
        methods_path,
        data={
            "shipping_method": shipping_method.pk,
            "payment_method": payment_method.pk
        }
    )
    assert response.status_code == 302, "Methods phase should redirect forth"

    if isinstance(shipping_method.carrier, CarrierWithCheckoutPhase):
        # Phase: Shipping
        response = c.get(shipping_path)
        assert response.status_code == 200
        response = c.post(shipping_path, data=shipping_data)
        assert response.status_code == 302, "Payments phase should redirect forth"

    if isinstance(payment_method.payment_processor, PaymentWithCheckoutPhase):
        # Phase: payment
        response = c.get(payment_path)
        assert response.status_code == 200
        response = c.post(payment_path, data=payment_data)
        assert response.status_code == 302, "Payments phase should redirect forth"

    # 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.first()

    if isinstance(shipping_method.carrier, CarrierWithCheckoutPhase):
        assert order.shipping_data.get("input_value") == "20540"

    if isinstance(payment_method.payment_processor, PaymentWithCheckoutPhase):
        assert order.payment_data.get("input_value")
        assert order.payment_status == PaymentStatus.NOT_PAID
        # Resolve order specific paths (payment and complete)
        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})

        # Check confirm redirection to payment page
        assert response.url.endswith(process_payment_path), (
            "Confirm should have redirected to payment page")

        # Visit 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)

        # 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)

        # Check payment status has changed to DEFERRED
        order = Order.objects.get(pk=order.pk)  # reload
        assert order.payment_status == PaymentStatus.DEFERRED
def test_simple_packager1(rf):
    populate_if_required()
    MAX_WIDTH = 1050
    MAX_LENGTH = 1050
    MAX_HEIGHT = 1050
    MAX_EDGES_SUM = 2000
    MAX_WEIGHT = 30000

    constraint1 = SimplePackageDimensionConstraint(MAX_WIDTH, MAX_LENGTH,
                                                   MAX_HEIGHT, MAX_EDGES_SUM)
    constraint2 = WeightPackageConstraint(MAX_WEIGHT)

    packager = SimplePackager()
    assert packager._constraints == set()
    packager.add_constraint(constraint1)
    packager.add_constraint(constraint2)
    assert constraint1 in packager._constraints
    assert constraint2 in packager._constraints

    product1 = create_product(sku='p1',
                              width=250,
                              depth=200,
                              height=50,
                              gross_weight=2340,
                              shop=get_default_shop(),
                              supplier=get_default_supplier())

    product2 = create_product(sku='p2',
                              width=500,
                              depth=150,
                              height=90,
                              gross_weight=690,
                              shop=get_default_shop(),
                              supplier=get_default_supplier())

    assert packager._product_has_valid_attrs(product1) is True
    assert packager._product_has_valid_attrs(product2) is True

    # cria produtos invalidos, sem propriedades necessárias

    # no gross_weight
    product_invalid_1 = create_product(sku='pi1',
                                       width=100,
                                       depth=200,
                                       height=50,
                                       gross_weight=100)
    product_invalid_1.gross_weight = 0
    assert packager._product_has_valid_attrs(product_invalid_1) is False

    # no height
    product_invalid_2 = create_product(sku='pi2',
                                       width=100,
                                       depth=200,
                                       height=50,
                                       gross_weight=100)
    product_invalid_2.height = 0
    assert packager._product_has_valid_attrs(product_invalid_2) is False

    # no depth
    product_invalid_3 = create_product(sku='pi3',
                                       width=100,
                                       depth=200,
                                       height=50,
                                       gross_weight=100)
    product_invalid_3.depth = 0
    assert packager._product_has_valid_attrs(product_invalid_3) is False

    # no width
    product_invalid_4 = create_product(sku='pi4',
                                       width=100,
                                       depth=200,
                                       height=50,
                                       gross_weight=100)
    product_invalid_4.width = 0
    assert packager._product_has_valid_attrs(product_invalid_4) is False

    # cria um basket vazio
    request = rf.get("/")
    request.session = {}
    request.shop = get_default_shop()
    apply_request_middleware(request)
    basket = get_basket(request)

    # adiciona um item no carrinho
    basket.add_product(supplier=get_default_supplier(),
                       shop=get_default_shop(),
                       product=product1,
                       quantity=2)

    basket.add_product(supplier=get_default_supplier(),
                       shop=get_default_shop(),
                       product=product2,
                       quantity=3)

    # cria o pedido a partir do carrinho
    order_creator = get_basket_order_creator()
    basket.status = OrderStatus.objects.get_default_initial()
    order = order_creator.create_order(basket)

    packages_from_source = packager.pack_source(basket)
    packages_from_order = packager.pack_order(order)

    # os produtos cabem todos no mesmo pacote
    assert len(packages_from_source) == 1
    assert len(packages_from_order) == 1

    pkge_from_source = packages_from_source[0]
    pkge_from_order = packages_from_order[0]

    for pkge in (pkge_from_source, pkge_from_order):
        assert pkge.count == 5  # 5 produtos
        assert pkge.weight == (product1.gross_weight * 2 +
                               product2.gross_weight * 3)  # peso igual
        assert pkge.width == 500  # product2 width
        assert pkge.length == 200  # product1 depth
        assert pkge.height == (product1.height * 2 + product2.height * 3
                               )  # soma as alturas