示例#1
0
def test_order_creator_account_manager():
    company = create_random_company()
    shop = get_shop(identifier="random-shop", enabled=True)
    source = seed_source(create_random_user(), shop)
    source.customer = company
    source.add_line(
        type=OrderLineType.PRODUCT,
        product=get_default_product(),
        supplier=get_default_supplier(),
        quantity=1,
        base_unit_price=source.create_price(10),
    )
    creator = OrderCreator()
    order = creator.create_order(source)
    assert order.account_manager is None  # Company contact doesn't have account manager field

    person = create_random_person()
    person.account_manager = create_random_person()
    person.save()

    source = seed_source(create_random_user(), shop)
    source.customer = person
    source.add_line(
        type=OrderLineType.PRODUCT,
        product=get_default_product(),
        supplier=get_default_supplier(),
        quantity=1,
        base_unit_price=source.create_price(10),
    )
    creator = OrderCreator()
    order = creator.create_order(source)
    assert order.account_manager is not None
    assert order.account_manager == person.account_manager
    with pytest.raises(ProtectedError):
        person.account_manager.delete()
示例#2
0
def test_parallel_baskets(rf):
    request = get_request_with_basket()
    shop = get_default_shop()
    customer = create_random_person()

    request = rf.get("/")
    request.shop = shop
    apply_request_middleware(request)
    request.customer = customer

    basket_one = get_basket(request, basket_name="basket_one")
    basket_two = get_basket(request, basket_name="basket_two")

    product_one = get_default_product()
    product_two = get_default_product()
    product_two.sku = "derpy-hooves"
    sales_unit = SalesUnit.objects.create(identifier="test-sales-partial", decimals=2, name="Partial unit")
    product_two.sales_unit = sales_unit  # Set the sales unit for the product
    product_two.save()

    basket_commands.handle_add(request, basket_one, product_id=product_one.pk, quantity=1)
    basket_commands.handle_add(request, basket_two, product_id=product_two.pk, quantity=3.5)

    assert basket_one.product_count == 1
    assert basket_two.product_count == 3.5
示例#3
0
文件: fixtures.py 项目: ruqaiya/shuup
def get_initialized_test_event():
    get_default_product()
    customer = create_random_person()
    order = create_random_order(customer)
    return ATestEvent(
        order_language=order.language,
        order=order,
        just_some_text=random_title()
    )
示例#4
0
def test_broken_order_lines():
    with pytest.raises(ValidationError):
        OrderLine(type=OrderLineType.PRODUCT).save()

    with pytest.raises(ValidationError):
        OrderLine(product=get_default_product(), type=OrderLineType.PRODUCT, supplier=None).save()

    with pytest.raises(ValidationError):
        OrderLine(product=get_default_product(), type=OrderLineType.OTHER).save()

    with pytest.raises(ValidationError):
        OrderLine(product=get_default_product(), type=OrderLineType.OTHER).save()
示例#5
0
def test_refunds(browser, admin_user, live_server, settings):
    order = create_order_with_product(
        get_default_product(), get_default_supplier(), 10, decimal.Decimal("10"), n_lines=10,
        shop=get_default_shop())
    order2 = create_order_with_product(
        get_default_product(), get_default_supplier(), 10, decimal.Decimal("10"), n_lines=10,
        shop=get_default_shop())
    order2.create_payment(order2.taxful_total_price)
    initialize_admin_browser_test(browser, live_server, settings)
    _test_toolbar_visibility(browser, live_server, order)
    _test_create_full_refund(browser, live_server, order)
    _test_refund_view(browser, live_server, order2)
示例#6
0
def test_order_received(rf, regular_user):
    activate("en")
    get_default_product()
    get_default_supplier()
    get_test_script("test script", "order_received")

    template_data = STEP_DATA[0]["actions"][0]["template_data"]
    for lang in ["en", "fi"]:
        n_outbox_pre = len(mail.outbox)
        customer = create_random_person(locale=lang)
        create_random_order(customer)
        assert (len(mail.outbox) == n_outbox_pre + 1), "Sending email failed"
        latest_mail = mail.outbox[-1]
        assert latest_mail.subject == template_data[lang]["subject"], "Subject doesn't match"
        assert latest_mail.body == template_data[lang]["body"], "Body doesn't match"
示例#7
0
def test_processor_orderability(admin_user):
    source = OrderSource(Shop())
    processor = OrderProcessor()
    line = source.add_line(
        type=OrderLineType.PRODUCT,
        product=get_default_product(),
        supplier=get_default_supplier(),
        quantity=1,
        shop=get_default_shop(),
        base_unit_price=source.create_price(10),
    )
    line.order = Order(shop=get_default_shop())
    assert processor._check_orderability(line) is None

    unorderable_line = source.add_line(
        type=OrderLineType.PRODUCT,
        product=create_product("no-shop"),
        supplier=get_default_supplier(),
        quantity=1,
        shop=get_default_shop(),
        base_unit_price=source.create_price(20),
    )
    unorderable_line.order = Order(shop=get_default_shop())
    with pytest.raises(ValidationError) as exc:
        processor._check_orderability(unorderable_line)
    assert "Not available in" in exc.value.message
示例#8
0
def test_order_modifier(rf, admin_user):

    order, source = get_order_and_source(admin_user, get_default_product())

    # get original values
    taxful_total_price = order.taxful_total_price_value
    taxless_total_price = order.taxless_total_price_value
    original_line_count = order.lines.count()

    # modify source
    source.billing_address = MutableAddress.objects.create(name="New Billing")
    source.shipping_address = MutableAddress.objects.create(name="New Shipping")

    modifier = OrderModifier()
    modifier.update_order_from_source(source, order)  # new param to edit order from source

    assert Order.objects.count() == 1

    order = Order.objects.first()
    assert order.billing_address.name == "New Billing"
    assert order.shipping_address.name == "New Shipping"
    assert order.taxful_total_price_value == taxful_total_price
    assert order.taxless_total_price_value == taxless_total_price

    # add new line to order source
    source.add_line(
        type=OrderLineType.OTHER,
        quantity=1,
        base_unit_price=source.create_price(10),
        require_verification=True,
    )
    modifier.update_order_from_source(source, order)

    assert order.lines.count() == original_line_count + 1
示例#9
0
def test_report_writers():
    """
    Just check whether something breaks while writing differnt types of data
    """
    shop = get_default_shop()
    product = get_default_product()
    supplier = get_default_supplier()
    order = create_order_with_product(
        product=product, supplier=supplier, quantity=1, taxless_base_unit_price=10, tax_rate=0, n_lines=2, shop=shop)
    order.create_payment(order.taxful_total_price.amount)

    data = {
        "report": SalesTestReport.get_name(),
        "shop": shop.pk,
        "date_range": DateRangeChoices.THIS_YEAR,
        "writer": "html",
        "force_download": 1,
    }
    report = SalesTestReport(**data)

    for writer_cls in [ExcelReportWriter, PDFReportWriter, PprintReportWriter, HTMLReportWriter, JSONReportWriter]:
        writer = writer_cls()
        report_data = [
            {
                "date": order,
                "order_count": Decimal(2),
                "product_count": int(3),
                "taxless_total": lazy(lambda: order.taxless_total_price_value),
                "taxful_total": order.taxful_total_price,
            }
        ]
        writer.write_data_table(report, report_data)
        assert writer.get_rendered_output()
示例#10
0
def test_order_creator(rf):
    admin_user = get_user_model().objects.create_superuser(email='*****@*****.**', password='******')

    source = seed_source(admin_user)
    source.add_line(
        type=OrderLineType.PRODUCT,
        product=get_default_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,
    )

    creator = ShuupBRBasketOrderCreator()
    order = creator.create_order(source)
    assert get_data_dict(source.billing_address) == get_data_dict(order.billing_address)
    assert get_data_dict(source.shipping_address) == get_data_dict(order.shipping_address)
    assert get_data_dict(source.billing_address.extra) == get_data_dict(order.billing_address.extra)
    assert get_data_dict(source.shipping_address.extra) == get_data_dict(order.shipping_address.extra)
    assert source.customer == order.customer
    assert source.payment_method == order.payment_method
    assert source.shipping_method == order.shipping_method
    assert order.pk
示例#11
0
def test_order_source_extra_data(rf, admin_user):
    source = seed_source(admin_user)
    product = get_default_product()
    line1 = source.add_line(
        type=OrderLineType.PRODUCT,
        product=product,
        supplier=get_default_supplier(),
        quantity=1,
        base_unit_price=source.create_price(10),
        line_id="parent"
    )
    line2 = source.add_line(
        type=OrderLineType.OTHER,
        text="Child Line",
        sku="KIDKIDKID",
        quantity=1,
        base_unit_price=source.create_price(5),
        parent_line_id="parent"
    )

    creator = OrderCreator()
    order = Order.objects.get(pk=creator.create_order(source).pk)
    line_ids = [line.extra_data["source_line_id"] for line in order.lines.all()]
    assert line1.line_id in line_ids
    assert line2.line_id in line_ids
def test_order_creation_adds_usage(rf, admin_user):
    request, shop, group = initialize_test(rf, False)

    source = seed_source(admin_user)
    source.add_line(
        type=OrderLineType.PRODUCT,
        product=get_default_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,
    )

    # add coupon
    coupon = Coupon.objects.create(active=True, code="asdf")

    campaign = BasketCampaign.objects.create(
        active=True,
        shop=shop,
        name="test",
        public_name="test",
        coupon=coupon)
    BasketDiscountPercentage.objects.create(campaign=campaign, discount_percentage="0.1")

    source.add_code(coupon.code)

    creator = OrderCreator()
    creator.create_order(source)

    assert CouponUsage.objects.count() == 1
示例#13
0
def test_basket_partial_quantity_update():
    request = get_request_with_basket()
    basket = request.basket
    product = get_default_product()

    sales_unit = SalesUnit.objects.create(identifier="test-sales-partial", decimals=2, name="Partial unit")
    product.sales_unit = sales_unit  # Set the sales unit for the product
    product.save()

    basket_commands.handle_add(request, basket, product_id=product.pk, quantity=1.5)
    assert basket.product_count == 1.5
    line_id = basket.get_lines()[0].line_id
    basket_commands.handle_update(request, basket, **{"q_%s" % line_id: "1.5"})
    assert basket.product_count == 1.5

    basket_commands.handle_update(request, basket, **{"q_%s" % line_id: "3.5"})
    assert basket.product_count == 3.5

    basket_commands.handle_update(request, basket, **{"q_%s" % line_id: "3.0"})
    assert basket.product_count == 3.0

    basket_commands.handle_update(request, basket, **{"q_%s" % line_id: "4"})
    assert basket.product_count == 4

    basket_commands.handle_update(request, basket, **{"delete_%s" % line_id: "1"})
    assert basket.product_count == 0
def test_custom_payment_processor_cash_service(choice_identifier, expected_payment_status):
    shop = get_default_shop()
    product = get_default_product()
    supplier = get_default_supplier()
    processor = CustomPaymentProcessor.objects.create()
    payment_method = PaymentMethod.objects.create(
        shop=shop,
        payment_processor=processor,
        choice_identifier=choice_identifier,
        tax_class=get_default_tax_class())

    order = create_order_with_product(
        product=product,
        supplier=supplier,
        quantity=1,
        taxless_base_unit_price=Decimal('5.55'),
        shop=shop)
    order.taxful_total_price = TaxfulPrice(Decimal('5.55'), u'EUR')
    order.payment_method = payment_method
    order.save()

    assert order.payment_status == PaymentStatus.NOT_PAID
    processor.process_payment_return_request(choice_identifier, order, None)
    assert order.payment_status == expected_payment_status
    processor.process_payment_return_request(choice_identifier, order, None)
    assert order.payment_status == expected_payment_status
示例#15
0
def test_model_url():
    with admin_only_urls():
        with pytest.raises(NoModelUrl):
            get_model_url(Counter)  # That's silly!
        p = get_default_product()

        assert get_model_url(p)
示例#16
0
def test_ajax():
    product = get_default_product()
    commands = get_basket_command_dispatcher(get_request_with_basket())
    commands.ajax = True
    rv = commands.handle("add", kwargs=dict(product_id=product.pk, quantity=-3))
    assert isinstance(rv, JsonResponse)
    assert commands.basket.product_count == 0
示例#17
0
def test_tracking_codes():
    product = get_default_product()
    supplier = get_default_supplier()
    order = create_order_with_product(
        product,
        supplier=supplier,
        quantity=1,
        taxless_base_unit_price=10,
        tax_rate=decimal.Decimal("0.5")
    )
    _add_product_to_order(order, "duck-tape-1", 3, order.shop, supplier)
    _add_product_to_order(order, "water-1", 2, order.shop, supplier)

    order.cache_prices()
    order.check_all_verified()
    order.save()

    # Create shipment with tracking code for every product line.
    product_lines = order.lines.exclude(product_id=None)
    assert len(product_lines) == 3
    for line in product_lines:
        shipment = order.create_shipment({line.product: line.quantity}, supplier=supplier)
        if line.quantity != 3:
            shipment.tracking_code = "123FI"
            shipment.save()

    tracking_codes = order.get_tracking_codes()
    code_count = (len(product_lines)-1)  # We skipped that one
    assert len(tracking_codes) == code_count
    assert len([tracking_code for tracking_code in tracking_codes if tracking_code == "123FI"]) == code_count
示例#18
0
def test_order_source_parentage(rf, admin_user):
    source = seed_source(admin_user)
    product = get_default_product()
    source.add_line(
        type=OrderLineType.PRODUCT,
        product=product,
        supplier=get_default_supplier(),
        quantity=1,
        base_unit_price=source.create_price(10),
        line_id="parent"
    )
    source.add_line(
        type=OrderLineType.OTHER,
        text="Child Line",
        sku="KIDKIDKID",
        quantity=1,
        base_unit_price=source.create_price(5),
        parent_line_id="parent"
    )

    creator = OrderCreator()
    order = Order.objects.get(pk=creator.create_order(source).pk)
    kid_line = order.lines.filter(sku="KIDKIDKID").first()
    assert kid_line
    assert kid_line.parent_line.product_id == product.pk
示例#19
0
def test_edit_view_adding_messages_to_form_group(rf, admin_user):
    get_default_shop()  # obvious prerequisite
    product = get_default_product()
    view = ProductEditView.as_view()
    request = apply_request_middleware(rf.get("/"), user=admin_user)
    response = view(request, pk=product.pk)
    response.render()
    assert 200 <= response.status_code < 300

    assert ProductEditView.add_form_errors_as_messages

    content = force_text(response.content)
    post = extract_form_fields(BeautifulSoup(content))
    post_data = {
        # Error in the base form part
        "base-name__en": "",
    }
    post.update(post_data)
    request = apply_request_middleware(rf.post("/", post), user=admin_user)
    response = view(request, pk=product.pk)

    errors = response.context_data["form"].errors

    assert "base" in errors
    assert "name__en" in errors["base"]
示例#20
0
def test_basket_update_errors():
    request = get_request_with_basket()
    basket = request.basket
    product = get_default_product()
    basket_commands.handle_add(request, basket, product_id=product.pk, quantity=1)

    # Hide product and now updating quantity should give errors
    shop_product = product.get_shop_instance(request.shop)
    shop_product.suppliers.clear()

    line_id = basket.get_lines()[0].line_id
    basket_commands.handle_update(request, basket, **{"q_%s" % line_id: "2"})
    error_messages = messages.get_messages(request)
    # One warning is added to messages
    assert len(error_messages) == 1
    assert any("not supplied" in msg.message for msg in error_messages)

    shop_product.visible = False
    shop_product.save()

    basket_commands.handle_update(request, basket, **{"q_%s" % line_id: "2"})

    error_messages = messages.get_messages(request)
    # Two warnings is added to messages
    assert len(error_messages) == 3
    assert any("not visible" in msg.message for msg in error_messages)
    assert all("[" not in msg.message for msg in error_messages)
示例#21
0
def test_delete_payment(admin_user, rf):
    product = get_default_product()
    shop_product = product.get_shop_instance(get_default_shop())
    shop_product.default_price_value = 20
    shop_product.save()

    order = create_random_order(customer=create_random_person(), products=(product,), completion_probability=0)
    payment_amount = order.taxful_total_price_value

    # create a payment
    view = OrderCreatePaymentView.as_view()
    request = apply_request_middleware(rf.post("/", {"amount": payment_amount}), user=admin_user)
    response = view(request, pk=order.pk)
    assert response.status_code == 302

    order.refresh_from_db()
    assert order.is_paid()

    # delete the payment
    payment = order.payments.last()
    view = OrderDeletePaymentView.as_view()
    request = apply_request_middleware(rf.post("/", {"payment": payment.pk}), user=admin_user)
    response = view(request, pk=order.pk)
    assert response.status_code == 302

    order.refresh_from_db()
    assert order.is_not_paid()
示例#22
0
def test_all_categories_view(rf, admin_user):
    shop = get_default_shop()
    supplier = get_default_supplier()
    category = get_default_category()
    product = get_default_product()
    request = apply_request_middleware(rf.get("/"))
    _check_product_count(request, 0)

    shop_product = product.get_shop_instance(shop)
    shop_product.categories.add(category)
    _check_product_count(request, 1)

    # Create few categories for better test results
    for i in range(10):
        cat = Category.objects.create(name=printable_gibberish())
        cat.shops.add(shop)

    new_product_count = random.randint(1, 3) + 1
    for i in range(1, new_product_count):
        product = create_product("sku-%s" % i, shop=shop, supplier=supplier, default_price=10)
        shop_product = product.get_shop_instance(shop)

        # Add random categories expect default category which we will make
        # hidden to make sure that products linked to hidden categories are
        # not listed
        shop_product.categories = Category.objects.exclude(id=category.pk).order_by("?")[:i]

    _check_product_count(request, new_product_count)

    category.status = CategoryStatus.INVISIBLE
    category.save()
    _check_product_count(request, new_product_count - 1)
示例#23
0
def test_order_creator(rf, admin_user):
    source = seed_source(admin_user)
    source.add_line(
        type=OrderLineType.PRODUCT,
        product=get_default_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,
    )

    creator = OrderCreator()
    order = creator.create_order(source)
    assert get_data_dict(source.billing_address) == get_data_dict(order.billing_address)
    assert get_data_dict(source.shipping_address) == get_data_dict(order.shipping_address)
    customer = source.customer
    assert customer == order.customer
    assert customer.groups.count() == 1
    assert customer.groups.first() == order.customer_groups.first()
    assert customer.tax_group is not None
    assert customer.tax_group == order.tax_group

    assert source.payment_method == order.payment_method
    assert source.shipping_method == order.shipping_method
    assert order.pk
示例#24
0
def test_simple_search_get_ids_works(rf):
    cache.clear()
    prod = get_default_product()
    bit = prod.name[:5]
    request = apply_request_middleware(rf.get("/"))
    assert prod.pk in get_search_product_ids(request, bit)
    assert prod.pk in get_search_product_ids(request, bit)  # Should use cache
def test_shop_overview_block(rf, data):
    (today, expected_today, expected_mtd, expected_ytd) = data
    product = get_default_product()
    sp = product.get_shop_instance(get_default_shop())
    sp.default_price_value = "10"
    sp.save()
    get_order_for_date(today, product)
    o = get_order_for_date(today, product)
    o.customer = None
    o.save()
    get_order_for_date(date(today.year - 1, 12, 31), product)
    get_order_for_date(date(today.year, 1, 1), product)
    get_order_for_date(date(today.year, today.month, 1), product)

    block = get_shop_overview_block(rf.get("/"), DEFAULT_CURRENCY, today)
    soup = BeautifulSoup(block.content)
    _, today_sales, mtd, ytd, totals = soup.find_all("tr")

    assert today_sales.find_all("td")[NUM_ORDERS_COLUMN_INDEX].string == str(expected_today)
    assert today_sales.find_all("td")[NUM_CUSTOMERS_COLUMN_INDEX].string == str(expected_today)
    assert mtd.find_all("td")[NUM_ORDERS_COLUMN_INDEX].string == str(expected_mtd)
    assert mtd.find_all("td")[NUM_CUSTOMERS_COLUMN_INDEX].string == str(expected_mtd)
    assert ytd.find_all("td")[NUM_ORDERS_COLUMN_INDEX].string == str(expected_ytd)
    assert ytd.find_all("td")[NUM_CUSTOMERS_COLUMN_INDEX].string == str(expected_ytd)
    assert totals.find_all("td")[NUM_ORDERS_COLUMN_INDEX].string == "5"
    assert totals.find_all("td")[NUM_CUSTOMERS_COLUMN_INDEX].string == "5"
示例#26
0
def test_order_statuses(admin_user):
    create_default_order_statuses()

    source = seed_source(admin_user)
    source.add_line(
        type=OrderLineType.PRODUCT,
        product=get_default_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,
    )

    creator = OrderCreator()
    order = creator.create_order(source)
    # new order, status/role is new/initial
    assert order.status.identifier == DefaultOrderStatus.INITIAL.value
    assert order.status.role == OrderStatusRole.INITIAL

    # FUTURE: order gets payment the status changes to processing/processing
    total = order.taxful_total_price.amount
    order.create_payment(total)

    assert order.status.identifier == DefaultOrderStatus.INITIAL.value
    assert order.status.role == OrderStatusRole.INITIAL

    # FUTURE: order is fully shipped the status changes to complete/complete
    order.create_shipment_of_all_products()
    assert order.status.identifier == DefaultOrderStatus.INITIAL.value
    assert order.status.role == OrderStatusRole.INITIAL
示例#27
0
def test_methods_impossible(admin_user):
    contact = get_person_contact(admin_user)
    source = BasketishOrderSource(get_default_shop())

    default_product = get_default_product()
    default_product.width = 5000
    default_product.depth = 4000
    default_product.heith = 1300
    default_product.save()

    source.add_line(
        type=OrderLineType.PRODUCT,
        product=default_product,
        supplier=get_default_supplier(),
        quantity=1,
        base_unit_price=source.create_price(10),
        weight=Decimal("200"))
    billing_address = get_address()
    shipping_address = get_address(name="My House", country='BR')

    shipping_address.postal_code = "89070210"

    source.billing_address = billing_address
    source.shipping_address = shipping_address
    source.customer = contact

    source.shipping_method = get_correios_carrier_1()
    source.payment_method = get_payment_method(name="neat", price=4)
    assert source.shipping_method_id
    assert source.payment_method_id

    errors = list(source.get_validation_errors())
    assert len(errors) == 1
示例#28
0
def test_complex_order_tax(include_taxes):
    tax = get_default_tax()
    quantities = [44, 23, 65]
    product = get_default_product()
    supplier = get_default_supplier()
    shop = get_default_shop()
    shop.prices_include_tax = include_taxes
    shop.save()

    order = create_empty_order(shop=shop)
    order.full_clean()
    order.save()

    pricing_context = get_pricing_module().get_context_from_data(
        shop=shop,
        customer=order.customer or AnonymousContact(),
    )

    total_price = Decimal("0")
    price = Decimal("50")

    for quantity in quantities:
        total_price += quantity * price
        add_product_to_order(order, supplier, product, quantity, price, tax.rate, pricing_context)
    order.cache_prices()
    order.save()

    currency = "EUR"
    summary = order.get_tax_summary()[0]

    assert summary.tax_rate == tax.rate
    assert summary.based_on == Money(total_price, currency)
    assert summary.tax_amount == Money(total_price * tax.rate, currency)
    assert summary.taxful == summary.based_on + summary.tax_amount
    assert order.get_total_tax_amount() == Money(total_price * tax.rate, currency)
示例#29
0
def test_applied_attributes():
    product = get_default_product()
    for spec in ATTR_SPECS:  # This loop sets each attribute twice. That's okay.
        attr = Attribute.objects.get(identifier=spec["identifier"])
        pa, _ = ProductAttribute.objects.get_or_create(product=product, attribute=attr)
        _populate_applied_attribute(pa)
        pa.save()
        if not attr.is_translated:
            product.set_attribute_value(attr.identifier, pa.value)

    assert product.get_attribute_value("bogomips") == 320, "integer attribute loaded neatly"
    product.set_attribute_value("bogomips", 480)
    assert product.get_attribute_value("bogomips") == 480, "integer attribute updated neatly"
    Product.cache_attributes_for_targets(
        applied_attr_cls=ProductAttribute,
        targets=[product],
        attribute_identifiers=[a["identifier"] for a in ATTR_SPECS],
        language=get_language()
    )
    assert (get_language(), "bogomips",) in product._attr_cache, "integer attribute in cache"
    assert product.get_attribute_value("bogomips") == 480, "integer attribute value in cache"
    assert product.get_attribute_value("ba:gelmips", default="Britta") == "Britta", "non-existent attributes return default value"
    assert product._attr_cache[(get_language(), "ba:gelmips")] is NoSuchAttributeHere, "cache miss saved"
    attr_info = product.get_all_attribute_info(language=get_language(), visibility_mode=AttributeVisibility.SHOW_ON_PRODUCT_PAGE)
    assert set(attr_info.keys()) <= set(a["identifier"] for a in ATTR_SPECS), "get_all_attribute_info gets all attribute info"
示例#30
0
def test_add_and_remove_and_clear():
    product = get_default_product()
    supplier = get_default_supplier()
    request = get_request_with_basket()
    basket = request.basket

    with pytest.raises(ValidationError):
        basket_commands.handle_add(request, basket, product_id=product.pk, quantity=-3)  # Ordering antimatter is not supported

    # These will get merged into one line...
    basket_commands.handle_add(request, basket, **{"product_id": product.pk, "quantity": 1, "supplier_id": supplier.pk})
    basket_commands.handle_add(request, basket, **{"product_id": product.pk, "quantity": 2})
    # ... so there will be 3 products but one line
    assert basket.product_count == 3
    lines = basket.get_lines()
    assert len(lines) == 1
    # ... and deleting that line will clear the basket...
    basket_commands.handle_del(request, basket, lines[0].line_id)
    assert basket.product_count == 0
    # ... and adding another product will create a new line...
    basket_commands.handle_add(request, basket, product_id=product.pk, quantity=1)
    assert basket.product_count == 1
    # ... that can be cleared.
    basket_commands.handle_clear(request, basket)
    assert basket.product_count == 0
示例#31
0
def test_wishlist_create_with_product(admin_user, rf):
    shop = get_default_shop()
    person = get_person_contact(admin_user)
    product = get_default_product()
    view_func = WishlistCreateView.as_view()
    request = rf.post("/", {
        "name": "foo",
        "privacy": 0,
        "product_id": product.id
    })
    request = apply_request_middleware(request, shop=shop, customer=person)
    response = view_func(request)
    data = json.loads(response.content.decode("utf-8"))
    wishlists = Wishlist.objects.filter(shop=shop, customer=person).all()
    wishlist = wishlists.first()

    assert response.status_code == 200
    assert data.get('name', '') == 'foo'
    assert data.get('created', False)
    assert data.get('product_name', '') == product.name
    assert wishlists.count() == 1
    assert wishlist.name == 'foo'
    assert wishlist.privacy == WishlistPrivacy.PUBLIC
    assert wishlist.products.count() == 1
def test_shop_overview_block(rf):
    today = date.today()
    product = get_default_product()
    sp = product.get_shop_instance(get_default_shop())
    sp.default_price_value = "10"
    sp.save()
    get_order_for_date(today, product)
    o = get_order_for_date(today, product)
    o.customer = None
    o.save()
    get_order_for_date(date(today.year, 1, 1), product)
    get_order_for_date(date(today.year, today.month, 1), product)

    block = get_shop_overview_block(rf.get("/"), DEFAULT_CURRENCY)
    soup = BeautifulSoup(block.content)
    _, today_sales, mtd, ytd, totals = soup.find_all("tr")
    assert today_sales.find_all("td")[NUM_ORDERS_COLUMN_INDEX].string == "2"
    assert today_sales.find_all("td")[NUM_CUSTOMERS_COLUMN_INDEX].string == "2"
    assert mtd.find_all("td")[NUM_ORDERS_COLUMN_INDEX].string == ("4" if today.month == 1 else "3")
    assert mtd.find_all("td")[NUM_CUSTOMERS_COLUMN_INDEX].string == ("4" if today.month == 1 else "3")
    assert ytd.find_all("td")[NUM_ORDERS_COLUMN_INDEX].string == "4"
    assert ytd.find_all("td")[NUM_CUSTOMERS_COLUMN_INDEX].string == "4"
    assert totals.find_all("td")[NUM_ORDERS_COLUMN_INDEX].string == "4"
    assert totals.find_all("td")[NUM_CUSTOMERS_COLUMN_INDEX].string == "4"
示例#33
0
def test_order_creator(rf, admin_user):
    source = seed_source(admin_user)
    source.add_line(
        type=OrderLineType.PRODUCT,
        product=get_default_product(),
        supplier=get_default_supplier(),
        quantity=1,
        base_unit_price=source.create_price(10),
    )
    source.add_line(
        accounting_identifier="strawberries",
        type=OrderLineType.OTHER,
        quantity=1,
        base_unit_price=source.create_price(10),
        require_verification=True,
        extra={"runner": "runner"}
    )

    the_line = [sl for sl in source.get_lines() if sl.accounting_identifier == "strawberries"]
    assert the_line[0].data["extra"]["runner"] == "runner"

    creator = OrderCreator()
    order = creator.create_order(source)
    assert get_data_dict(source.billing_address) == get_data_dict(order.billing_address)
    assert get_data_dict(source.shipping_address) == get_data_dict(order.shipping_address)
    customer = source.customer
    assert customer == order.customer
    assert customer.groups.count() == 1
    assert customer.groups.first() == order.customer_groups.first()
    assert customer.tax_group is not None
    assert customer.tax_group == order.tax_group

    assert source.payment_method == order.payment_method
    assert source.shipping_method == order.shipping_method
    assert order.pk
    assert order.lines.filter(accounting_identifier="strawberries").first().extra_data["runner"] == "runner"
示例#34
0
def test_order_modifier(rf, admin_user):

    order, source = get_order_and_source(admin_user, get_default_product())

    # get original values
    taxful_total_price = order.taxful_total_price_value
    taxless_total_price = order.taxless_total_price_value
    original_line_count = order.lines.count()

    # modify source
    source.billing_address = MutableAddress.objects.create(name="New Billing")
    source.shipping_address = MutableAddress.objects.create(
        name="New Shipping")

    modifier = OrderModifier()
    modifier.update_order_from_source(
        source, order)  # new param to edit order from source

    assert Order.objects.count() == 1

    order = Order.objects.first()
    assert order.billing_address.name == "New Billing"
    assert order.shipping_address.name == "New Shipping"
    assert order.taxful_total_price_value == taxful_total_price
    assert order.taxless_total_price_value == taxless_total_price

    # add new line to order source
    source.add_line(
        type=OrderLineType.OTHER,
        quantity=1,
        base_unit_price=source.create_price(10),
        require_verification=True,
    )
    modifier.update_order_from_source(source, order)

    assert order.lines.count() == original_line_count + 1
示例#35
0
def initialize_report_test(product_price, product_count, tax_rate, line_count):
    shop = get_default_shop()
    product = get_default_product()
    supplier = get_default_supplier()
    expected_taxless_total = product_count * product_price
    expected_taxful_total = product_count * product_price * (1 + tax_rate)
    order = create_order_with_product(product=product,
                                      supplier=supplier,
                                      quantity=product_count,
                                      taxless_base_unit_price=product_price,
                                      tax_rate=tax_rate,
                                      n_lines=line_count,
                                      shop=shop)
    order.create_payment(order.taxful_total_price.amount)
    order2 = create_order_with_product(product=product,
                                       supplier=supplier,
                                       quantity=product_count,
                                       taxless_base_unit_price=product_price,
                                       tax_rate=tax_rate,
                                       n_lines=line_count,
                                       shop=shop)
    order2.create_payment(order2.taxful_total_price.amount)
    order2.set_canceled()  # Shouldn't affect reports
    return expected_taxful_total, expected_taxless_total, shop, order
示例#36
0
def test_personal_wishlists(rf, admin_user, regular_user):
    shop = get_default_shop()
    admin_person = get_person_contact(admin_user)
    person = get_person_contact(regular_user)
    product = get_default_product()
    shop_product = product.get_shop_instance(shop)

    wishlist = Wishlist.objects.create(shop=shop,
                                       customer=person,
                                       name='foo',
                                       privacy=WishlistPrivacy.PUBLIC)
    wishlist.products.add(shop_product)
    Wishlist.objects.create(shop=shop,
                            customer=admin_person,
                            name='foo',
                            privacy=WishlistPrivacy.PUBLIC)

    view_func = WishlistCustomerView.as_view()
    request = apply_request_middleware(rf.get("/"), user=person.user)
    response = view_func(request)

    assert response.status_code == 200
    assert 'customer_wishlists' in response.context_data
    assert response.context_data['customer_wishlists'].count() == 1
示例#37
0
def test_product_module_search(rf, admin_user):
    get_default_shop()
    request = apply_request_middleware(rf.get("/"), user=admin_user)

    with replace_modules([
            CategoryModule,
            ImportAdminModule,
            ProductModule,
            MediaModule,
            ProductTypeModule,
            ManufacturerModule,
            PaymentMethodModule,
            ShippingMethodModule,
    ]):
        with admin_only_urls():
            default_product = get_default_product()
            model_url = get_model_url(default_product, shop=get_shop(request))
            sku = default_product.sku
            assert any(sr.url == model_url for sr in get_search_results(
                request, query=sku))  # Queries work
            assert any(sr.is_action for sr in get_search_results(
                request, query=sku[:5]))  # Actions work
            assert empty_iterable(get_search_results(
                request, query=sku[:2]))  # Short queries don't
示例#38
0
def test_nonajax():
    product = get_default_product()
    commands = get_basket_command_dispatcher(get_request_with_basket())
    commands.ajax = False
    with pytest.raises(Exception):
        commands.handle("add", kwargs=dict(product_id=product.pk, quantity=-3))
示例#39
0
def random_order():
    # These are prerequisites for random orders
    contact = create_random_person()
    product = get_default_product()
    return create_random_order(contact, [product])
示例#40
0
def test_product_edit_view(rf, admin_user, settings):
    shop = get_default_shop()  # obvious prerequisite
    product = get_default_product()
    shop_product = product.get_shop_instance(shop)
    cat = CategoryFactory()

    assert not shop_product.categories.exists()
    assert not shop_product.primary_category

    view = ProductEditView.as_view()
    request = apply_request_middleware(rf.get("/"), user=admin_user)
    response = view(request, pk=product.pk)
    response.render()

    content = force_text(response.content)
    post = extract_form_fields(BeautifulSoup(content))

    # Needed for Django 1.8 tests to pass
    post.update({
        'shop1-default_price_value': '42',
        'images-TOTAL_FORMS': '0',
        'media-TOTAL_FORMS': '0',
        'base-name__fi': 'test',
        'base-name__it': 'test',
        'base-name__ja': 'test',
        'base-name__pt-br': 'test',
        'base-name__zh-hans': 'test',
    })

    post_data = {'shop1-primary_category': [], 'shop1-categories': []}
    post.update(post_data)
    request = apply_request_middleware(rf.post("/", post), user=admin_user)
    response = view(request, pk=product.pk)

    shop_product.refresh_from_db()
    assert not shop_product.categories.exists()
    assert not shop_product.primary_category

    post_data = {
        'shop1-default_price_value': 12,
        'shop1-primary_category': [cat.pk],
        'shop1-categories': []
    }
    post.update(post_data)
    usable_post = {}
    for k, v in six.iteritems(post):
        if not k:
            continue
        if not post[k]:
            continue
        usable_post[k] = v

    request = apply_request_middleware(rf.post("/", usable_post),
                                       user=admin_user)
    response = view(request, pk=product.pk)

    shop_product = ShopProduct.objects.first()
    if settings.SHUUP_AUTO_SHOP_PRODUCT_CATEGORIES:
        assert shop_product.categories.count() == 1
        assert shop_product.categories.first() == cat
    else:
        assert not shop_product.categories.count()

    assert shop_product.primary_category == cat

    post_data = {'shop1-primary_category': [], 'shop1-categories': []}
    usable_post.update(post_data)

    request = apply_request_middleware(rf.post("/", usable_post),
                                       user=admin_user)
    response = view(request, pk=product.pk)

    # empty again
    shop_product = ShopProduct.objects.first()
    assert not shop_product.categories.exists()
    assert not shop_product.primary_category

    post_data = {'shop1-primary_category': [], 'shop1-categories': [cat.pk]}
    usable_post.update(post_data)

    request = apply_request_middleware(rf.post("/", usable_post),
                                       user=admin_user)
    response = view(request, pk=product.pk)

    shop_product = ShopProduct.objects.first()
    assert shop_product.categories.count() == 1
    assert shop_product.categories.first() == cat
    if settings.SHUUP_AUTO_SHOP_PRODUCT_CATEGORIES:
        assert shop_product.primary_category == cat
    else:
        assert not shop_product.primary_category

    cat2 = CategoryFactory()

    post_data = {
        'shop1-primary_category': [],
        'shop1-categories': [cat.pk, cat2.pk]
    }
    usable_post.update(post_data)

    request = apply_request_middleware(rf.post("/", usable_post),
                                       user=admin_user)
    response = view(request, pk=product.pk)

    shop_product = ShopProduct.objects.first()
    assert shop_product.categories.count() == 2
    assert cat in shop_product.categories.all()
    assert cat2 in shop_product.categories.all()
    if settings.SHUUP_AUTO_SHOP_PRODUCT_CATEGORIES:
        assert shop_product.primary_category == cat
    else:
        assert not shop_product.primary_category
示例#41
0
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
示例#42
0
def create_success_order_with_boleto():
    # 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()

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

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

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

    c.get(process_payment_path)
    c.get(process_payment_return_path)
    c.get(order_complete_path)

    order.refresh_from_db()
    return order
def test_image_inheritance():
    shop = get_default_shop()
    product = get_default_product()
    shop_product = product.get_shop_instance(shop)
    assert product.primary_image_id
    assert shop_product.primary_image == product.primary_image
示例#44
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
示例#45
0
def test_product_tour(browser, admin_user, live_server, settings):
    shop = factories.get_default_shop()
    shop2 = factories.get_shop(identifier="shop2")
    admin_user_2 = factories.create_random_user(is_staff=True,
                                                is_superuser=True)
    admin_user_2.set_password("password")
    admin_user_2.save()
    product = factories.get_default_product()
    shop_product = product.get_shop_instance(shop)

    shop.staff_members.add(admin_user)
    shop.staff_members.add(admin_user_2)

    for user in [admin_user, admin_user_2]:
        initialize_admin_browser_test(browser,
                                      live_server,
                                      settings,
                                      username=user.username,
                                      tour_complete=False)
        wait_until_condition(browser, lambda x: x.is_text_present("Welcome!"))
        browser.visit(live_server + "/sa/products/%d/" % shop_product.pk)

        wait_until_condition(
            browser, lambda x: x.is_text_present(shop_product.product.name))
        # as this is added through javascript, add an extra timeout
        wait_until_condition(
            browser,
            lambda x: x.is_text_present("You are adding a product."),
            timeout=30)
        wait_until_condition(
            browser, lambda x: x.is_element_present_by_css(
                ".shepherd-button.btn-primary"))
        click_element(browser, ".shepherd-button.btn-primary")

        category_targets = [
            "a.shepherd-enabled[href='#basic-information-section']",
            "a.shepherd-enabled[href='#additional-details-section']",
            "a.shepherd-enabled[href='#manufacturer-section']",
            "a.shepherd-enabled[href*='-additional-section']",
            "a.shepherd-enabled[href='#product-media-section']",
            "a.shepherd-enabled[href='#product-images-section']",
            "a.shepherd-enabled[href='#contact-group-pricing-section']",
            "a.shepherd-enabled[href='#contact-group-discount-section']"
        ]
        for target in category_targets:
            wait_until_condition(browser,
                                 lambda x: x.is_element_present_by_css(target))
            move_to_element(browser, ".shepherd-button.btn-primary")
            browser.find_by_css(".shepherd-button.btn-primary").last.click()
        wait_until_condition(browser,
                             lambda x: is_tour_complete(shop, "product", user))

        # check whether the tour is shown again
        browser.visit(live_server + "/sa/products/%d/" % shop_product.pk)
        wait_until_condition(
            browser,
            lambda x: not x.is_text_present("You are adding a product."),
            timeout=20)

        assert is_tour_complete(shop2, "product", user) is False

        browser.visit(live_server + "/logout")
        browser.visit(live_server + "/sa")
示例#46
0
def test_product_tour(browser, admin_user, live_server, settings):
    shop = factories.get_default_shop()
    shop2 = factories.get_shop(identifier="shop2")
    admin_user_2 = factories.create_random_user(is_staff=True,
                                                is_superuser=True)
    admin_user_2.set_password("password")
    admin_user_2.save()
    product = factories.get_default_product()
    shop_product = product.get_shop_instance(shop)

    shop.staff_members.add(admin_user)
    shop.staff_members.add(admin_user_2)

    for user in [admin_user, admin_user_2]:
        initialize_admin_browser_test(browser,
                                      live_server,
                                      settings,
                                      username=user.username,
                                      tour_complete=False)
        wait_until_condition(browser, lambda x: x.is_text_present("Welcome!"))
        browser.visit(live_server + "/sa/products/%d/" % shop_product.pk)

        wait_until_condition(
            browser, lambda x: x.is_text_present(shop_product.product.name))
        # as this is added through javascript, add an extra timeout
        wait_until_condition(
            browser,
            lambda x: x.is_text_present("You are adding a product."),
            timeout=30)
        wait_until_condition(
            browser, lambda x: x.is_element_present_by_css(
                ".shepherd-button.btn-primary"))
        click_element(browser, ".shepherd-button.btn-primary")

        category_targets = [
            "a.shepherd-enabled[href='#basic-information-section']",
            "a.shepherd-enabled[href='#additional-details-section']",
            "a.shepherd-enabled[href='#manufacturer-section']",
            "a.shepherd-enabled[href*='-additional-section']",
            "a.shepherd-enabled[href='#product-media-section']",
            "a.shepherd-enabled[href='#product-images-section']",
            "a.shepherd-enabled[href='#contact-group-pricing-section']",
            "a.shepherd-enabled[href='#contact-group-discount-section']"
        ]

        # Scroll top before starting to click. For some reason the first
        # item is not found without this. For Firefox or Chrome the browser
        # does not do any extra scroll which could hide the first item.
        # Steps are scrollTo false on purpose since the scrollTo true is the
        # config which does not work in real world.
        browser.execute_script("window.scrollTo(0,0)")
        for target in category_targets:
            try:
                wait_until_condition(
                    browser, lambda x: x.is_element_present_by_css(target))
                browser.find_by_css(
                    ".shepherd-button.btn-primary").last.click()
            except ElementNotInteractableException:
                move_to_element(browser, ".shepherd-button.btn-primary")
                wait_until_condition(
                    browser, lambda x: x.is_element_present_by_css(target))
                browser.find_by_css(
                    ".shepherd-button.btn-primary").last.click()

        wait_until_condition(browser,
                             lambda x: is_tour_complete(shop, "product", user))

        # check whether the tour is shown again
        browser.visit(live_server + "/sa/products/%d/" % shop_product.pk)
        wait_until_condition(
            browser,
            lambda x: not x.is_text_present("You are adding a product."),
            timeout=20)

        assert is_tour_complete(shop2, "product", user) is False

        browser.visit(live_server + "/logout")
        browser.visit(live_server + "/sa")
示例#47
0
def test_contact_filters(rf, admin_user):
    shop = get_default_shop()
    products_per_order = 5

    request = rf.get('/')
    request.shop = shop
    apply_request_middleware(request)
    product = get_default_product()

    customer = get_person_contact(admin_user)
    create_order(request,
                 creator=admin_user,
                 customer=customer,
                 product=product)
    order_one = Order.objects.first()

    user = UserFactory()
    second_customer = get_person_contact(user)
    create_order(request,
                 creator=admin_user,
                 customer=second_customer,
                 product=product)
    order_two = Order.objects.first()

    user = UserFactory()
    user.is_staff = True
    user.save()

    create_order(request,
                 creator=user,
                 customer=second_customer,
                 product=product)
    order_three = Order.objects.first()
    order_three.orderer = customer
    order_three.save()

    # test that admin user gets two orders as he created two
    expected_taxful_total_price = order_one.taxful_total_price + order_two.taxful_total_price
    expected_taxless_total_price = order_one.taxless_total_price + order_two.taxless_total_price
    expected_order_count = 2
    test_info = initialize_simple_report(
        SalesReport, data_overrides={"creator": [admin_user.pk]})
    return_data = test_info.json_data.get("tables")[0].get("data")
    _assert_expected_values(expected_order_count, expected_taxful_total_price,
                            expected_taxless_total_price, products_per_order,
                            return_data)

    # test that new admin user gets one order
    expected_taxful_total_price = order_three.taxful_total_price
    expected_taxless_total_price = order_three.taxless_total_price
    expected_order_count = 1
    test_info = initialize_simple_report(SalesReport,
                                         data_overrides={"creator": [user.pk]})
    return_data = test_info.json_data.get("tables")[0].get("data")
    _assert_expected_values(expected_order_count, expected_taxful_total_price,
                            expected_taxless_total_price, products_per_order,
                            return_data)

    # test that new admin user and second_customer gets one order
    expected_taxful_total_price = order_three.taxful_total_price
    expected_taxless_total_price = order_three.taxless_total_price
    expected_order_count = 1
    test_info = initialize_simple_report(SalesReport,
                                         data_overrides={
                                             "creator": [user.pk],
                                             "customer": [second_customer.pk]
                                         })
    return_data = test_info.json_data.get("tables")[0].get("data")
    _assert_expected_values(expected_order_count, expected_taxful_total_price,
                            expected_taxless_total_price, products_per_order,
                            return_data)

    # test that second_customer gets two orders
    expected_taxful_total_price = order_three.taxful_total_price + order_two.taxful_total_price
    expected_taxless_total_price = order_three.taxless_total_price + order_two.taxless_total_price
    expected_order_count = 2
    test_info = initialize_simple_report(
        SalesReport, data_overrides={"customer": [second_customer.pk]})
    return_data = test_info.json_data.get("tables")[0].get("data")
    _assert_expected_values(expected_order_count, expected_taxful_total_price,
                            expected_taxless_total_price, products_per_order,
                            return_data)

    # test that second_customer gets two orders
    expected_taxful_total_price = order_three.taxful_total_price
    expected_taxless_total_price = order_three.taxless_total_price
    expected_order_count = 1
    test_info = initialize_simple_report(SalesReport,
                                         data_overrides={
                                             "customer": [second_customer.pk],
                                             "orderer": [customer.pk]
                                         })
    return_data = test_info.json_data.get("tables")[0].get("data")
    _assert_expected_values(expected_order_count, expected_taxful_total_price,
                            expected_taxless_total_price, products_per_order,
                            return_data)
def test_shop_overview_block(rf, data, admin_user):
    with override_settings(SHUUP_ENABLE_MULTIPLE_SHOPS=True):
        shop1 = get_default_shop()
        shop2 = get_shop(identifier="shop2",
                         status=ShopStatus.ENABLED,
                         name="Shop2")

        (today, expected_today, expected_mtd, expected_ytd) = data
        product = get_default_product()
        sp = product.get_shop_instance(shop1)
        sp.default_price_value = "10"
        sp.save()
        get_order_for_date(today, product)
        o = get_order_for_date(today, product)
        o.customer = None
        o.save()
        get_order_for_date(date(today.year - 1, 12, 31), product)
        get_order_for_date(date(today.year, 1, 1), product)
        get_order_for_date(date(today.year, today.month, 1), product)

        for shop in [shop1, shop2]:
            request = apply_request_middleware(rf.get("/"),
                                               user=admin_user,
                                               shop=shop)
            block = get_shop_overview_block(request,
                                            currency=DEFAULT_CURRENCY,
                                            for_date=today)
            soup = BeautifulSoup(block.content)
            _, today_sales, mtd, ytd, totals = soup.find_all("tr")

            if shop == shop1:
                assert today_sales.find_all("td")[
                    NUM_ORDERS_COLUMN_INDEX].string == str(expected_today)
                assert today_sales.find_all("td")[
                    NUM_CUSTOMERS_COLUMN_INDEX].string == str(expected_today)
                assert mtd.find_all(
                    "td")[NUM_ORDERS_COLUMN_INDEX].string == str(expected_mtd)
                assert mtd.find_all("td")[
                    NUM_CUSTOMERS_COLUMN_INDEX].string == str(expected_mtd)
                assert ytd.find_all(
                    "td")[NUM_ORDERS_COLUMN_INDEX].string == str(expected_ytd)
                assert ytd.find_all("td")[
                    NUM_CUSTOMERS_COLUMN_INDEX].string == str(expected_ytd)
                assert totals.find_all(
                    "td")[NUM_ORDERS_COLUMN_INDEX].string == "5"
                assert totals.find_all(
                    "td")[NUM_CUSTOMERS_COLUMN_INDEX].string == "5"
            else:
                assert today_sales.find_all(
                    "td")[NUM_ORDERS_COLUMN_INDEX].string == "0"
                assert today_sales.find_all(
                    "td")[NUM_CUSTOMERS_COLUMN_INDEX].string == "0"
                assert mtd.find_all(
                    "td")[NUM_ORDERS_COLUMN_INDEX].string == "0"
                assert mtd.find_all(
                    "td")[NUM_CUSTOMERS_COLUMN_INDEX].string == "0"
                assert ytd.find_all(
                    "td")[NUM_ORDERS_COLUMN_INDEX].string == "0"
                assert ytd.find_all(
                    "td")[NUM_CUSTOMERS_COLUMN_INDEX].string == "0"
                assert totals.find_all(
                    "td")[NUM_ORDERS_COLUMN_INDEX].string == "0"
                assert totals.find_all(
                    "td")[NUM_CUSTOMERS_COLUMN_INDEX].string == "0"
示例#49
0
def test_simple_product_works(rf):
    product = get_default_product()
    request = rf.get("/")
    assert product.get_child_price_range(request) == (None, None)
    assert product.get_cheapest_child_price_info(request) is None
    assert product.get_cheapest_child_price(request) is None
示例#50
0
def test_recent_orders_block(rf):
    order = create_random_order(customer=create_random_person(),
                                products=[get_default_product()])
    block = get_recent_orders_block(rf.get("/"), DEFAULT_CURRENCY)
    assert html.escape(order.customer.name) in block.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 test_thumbnail_cache():
    image1 = factories.get_random_filer_image()
    image2 = factories.get_random_filer_image()
    media = ProductMedia.objects.create(
        product=factories.get_default_product(), file=image2)

    cache_key, cached_url = _get_cached_thumbnail_url(image1,
                                                      alias=None,
                                                      generate=True)
    assert cache_key and not cached_url
    url = thumbnail(image1)
    cache_key, cached_url = _get_cached_thumbnail_url(image1,
                                                      alias=None,
                                                      generate=True)
    assert cache_key and cached_url == url

    cache_key, cached_url = _get_cached_thumbnail_url(media,
                                                      alias=None,
                                                      generate=True)
    assert cache_key and not cached_url
    url = thumbnail(media)
    cache_key, cached_url = _get_cached_thumbnail_url(media,
                                                      alias=None,
                                                      generate=True)
    assert cache_key and cached_url == url

    img_url = "http://www.shuup.com/logo.png"
    cache_key, cached_url = _get_cached_thumbnail_url(img_url,
                                                      alias=None,
                                                      generate=True)
    assert cache_key and not cached_url
    url = thumbnail(img_url)
    cache_key, cached_url = _get_cached_thumbnail_url(img_url,
                                                      alias=None,
                                                      generate=True)
    assert cache_key and cached_url == url

    source = Thumbnailer(file=BytesIO(TEST_PNG), name="logo.png")
    source.url = '/media/logo.png'
    cache_key, cached_url = _get_cached_thumbnail_url(source,
                                                      alias=None,
                                                      generate=True)
    assert cache_key and not cached_url
    url = thumbnail(source)
    cache_key, cached_url = _get_cached_thumbnail_url(source,
                                                      alias=None,
                                                      generate=True)
    assert cache_key and cached_url == url

    # check whether caches are bumped
    image1.save()
    cache_key, cached_url = _get_cached_thumbnail_url(image1,
                                                      alias=None,
                                                      generate=True)
    assert cache_key and not cached_url

    media.save()
    cache_key, cached_url = _get_cached_thumbnail_url(media,
                                                      alias=None,
                                                      generate=True)
    assert cache_key and not cached_url

    media.delete()
    image1.delete()
    image2.delete()
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
示例#54
0
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
示例#55
0
def test_product_price_range_filter(reindex_catalog):
    shop = factories.get_default_shop()
    product = factories.get_default_product()
    category = factories.get_default_category()
    shop_product = product.get_shop_instance(shop)
    shop_product.default_price_value = 10
    shop_product.save()
    shop_product.categories.add(category)
    reindex_catalog()

    client = SmartClient()
    config = {
        "filter_products_by_price": True,
        "filter_products_by_price_range_min": 5,
        "filter_products_by_price_range_max": 15,
        "filter_products_by_price_range_size": 5,
    }
    set_configuration(category=category, data=config)
    url = reverse("shuup:category",
                  kwargs={
                      "pk": category.pk,
                      "slug": category.slug
                  })
    response, soup = client.response_and_soup(url)
    assert response.status_code == 200
    assert soup.find(id="product-%d" % product.id)
    price_range_select = soup.find(id="id_price_range")
    # as the configuration is not set to override shop default configuration
    # this field shouldn't be there..
    assert price_range_select is None

    # make the category configuration override the shop's default config
    config.update({"override_default_configuration": True})
    set_configuration(category=category, data=config)
    url = reverse("shuup:category",
                  kwargs={
                      "pk": category.pk,
                      "slug": category.slug
                  })
    response, soup = client.response_and_soup(url)
    assert response.status_code == 200
    assert soup.find(id="product-%d" % product.id)
    price_range_select = soup.find(id="id_price_range")
    price_ranges = price_range_select.find_all("option")
    assert len(price_ranges) == 4

    # filter products with prices above $15
    filtered_url = "{}?price_range={}".format(url,
                                              price_ranges[-1].attrs["value"])
    response, soup = client.response_and_soup(filtered_url)
    assert response.status_code == 200
    assert not soup.find(id="product-%d" % product.id)

    # explicitly disable the override
    config.update({"override_default_configuration": False})
    set_configuration(category=category, data=config)
    url = reverse("shuup:category",
                  kwargs={
                      "pk": category.pk,
                      "slug": category.slug
                  })
    response, soup = client.response_and_soup(url)
    assert response.status_code == 200
    assert soup.find(id="product-%d" % product.id)
    price_range_select = soup.find(id="id_price_range")
    assert price_range_select is None
示例#56
0
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()
示例#57
0
def test_order_chart_works():
    order = create_random_order(customer=create_random_person(),
                                products=(get_default_product(), ))
    chart = OrderValueChartDashboardBlock("test", order.currency).get_chart()
    assert len(chart.series[0]) > 0
示例#58
0
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)
示例#59
0
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
示例#60
0
def test_order_received_variables(rf, with_shop_contact):
    activate("en")
    shop = get_shop(True)
    shop.contact_address = get_address(**SHOP_ADDRESS_DATA)
    shop.contact_address.save()
    shop.save()
    get_default_product()
    get_default_supplier()

    STEP_DATA = [{
        "cond_op":
        "all",
        "enabled":
        True,
        "next":
        "continue",
        "actions": [{
            "template_data": {
                "en": {
                    "body": "{{ customer_email }}",
                    "content_type": "plain",
                    "subject": "{{ customer_phone }}"
                }
            },
            "identifier": "send_email",
            "language": {
                "constant": "en"
            },
            "recipient": {
                "constant": "*****@*****.**"
            }
        }]
    }]

    if with_shop_contact:
        STEP_DATA[0]['actions'].insert(
            0, {
                "template_data": {
                    "en": {
                        "body": "{{ shop_email }}",
                        "content_type": "plain",
                        "subject": "{{ shop_phone }}"
                    }
                },
                "identifier": "send_email",
                "language": {
                    "constant": "en"
                },
                "recipient": {
                    "constant": "*****@*****.**"
                }
            })

    sc = Script.objects.create(name="variables script",
                               event_identifier="order_received",
                               enabled=True,
                               shop=shop)
    sc.set_serialized_steps(STEP_DATA)
    sc.save()

    n_outbox_pre = len(mail.outbox)
    customer = create_random_person(locale='en')
    customer.default_shipping_address = get_address(**DEFAULT_ADDRESS_DATA)
    customer.default_shipping_address.save()
    customer.save()

    create_random_order(customer, shop=shop)
    assert (len(mail.outbox) == n_outbox_pre +
            (2 if with_shop_contact else 1)), "Sending email failed"

    latest_mail = mail.outbox[-1]
    assert latest_mail.subject == customer.default_shipping_address.phone
    assert latest_mail.body == customer.default_shipping_address.email

    if with_shop_contact:
        # shop email is sent first - we use insert(0, shop_step_data)
        penult_mail = mail.outbox[-2]
        assert penult_mail.subject == shop.contact_address.phone
        assert penult_mail.body == shop.contact_address.email