Ejemplo n.º 1
0
def test_list_view_with_multiple_suppliers(rf, admin_user):
    shop = factories.get_default_shop()

    product = factories.create_product(sku="test", shop=shop)
    shop_product = product.get_shop_instance(shop)
    shop_product.primary_category = factories.get_default_category()
    shop_product.save()
    shop_product.categories.add(shop_product.primary_category)

    # Also one product with supplier
    supplier = factories.get_default_supplier()
    product2 = factories.create_product(sku="test2", shop=shop, supplier=supplier)
    shop_product2 = product2.get_shop_instance(shop)
    shop_product2.primary_category = factories.get_default_category()
    shop_product2.save()
    shop_product2.categories.add(shop_product.primary_category)

    with override_settings(E-Commerce_ENABLE_MULTIPLE_SUPPLIERS=True):
        view = load("E-Commerce.admin.modules.products.views:ProductListView").as_view()
        request = apply_request_middleware(rf.get("/", {
            "jq": json.dumps({"perPage": 100, "page": 1})
        }), user=admin_user)
        response = view(request)
        assert 200 <= response.status_code < 300

        data = json.loads(response.content.decode("utf-8"))
        product_data = [item for item in data["items"] if item["_id"] == shop_product.pk][0]
        assert product_data["primary_category"] == factories.get_default_category().name
        assert product_data["categories"] == factories.get_default_category().name
        assert product_data["categories"] == factories.get_default_category().name
        assert product_data["suppliers"] == ""

        product_data2 = [item for item in data["items"] if item["_id"] == shop_product2.pk][0]
        assert product_data2["suppliers"] == factories.get_default_supplier().name
Ejemplo n.º 2
0
def test_product_campaigns_section_no_shop_product(rf, admin_user):
    shop = factories.get_default_shop()
    supplier = factories.get_default_supplier()

    request = apply_request_middleware(rf.get("/"), user=admin_user)
    request.shop = shop
    context = ProductCampaignsSection.get_context_data(factories.create_product("test1"), request)
    assert not context
    context = ProductCampaignsSection.get_context_data(factories.create_product("test2", shop=shop), request)
    assert context[shop]["basket_campaigns"].count() == 0
def test_supplier_filter_get_fields(rf):
    shop = factories.get_default_shop()
    request = apply_request_middleware(rf.get("/"))
    category = factories.get_default_category()

    supplier = Supplier.objects.create(name="Mike Inc")
    supplier.shops.add(shop)
    assert SupplierProductListFilter().get_fields(request, None) is None

    product = factories.create_product("sku", shop=shop)
    shop_product = product.get_shop_instance(shop=shop)
    shop_product.primary_category = category
    shop_product.save()

    assert SupplierProductListFilter().get_fields(request, category) is None

    # Now once we link manufacturer to product we should get
    # form field for manufacturer
    shop_product.suppliers.add(supplier)
    form_field = SupplierProductListFilter().get_fields(request, category)[0][1]
    assert form_field is not None
    assert form_field.label == "Suppliers"
    assert len(form_field.widget.choices) == 1

    # Add second supplier for new product
    supplier2 = Supplier.objects.create(name="K Inc")
    supplier2.shops.add(shop)
    new_product = factories.create_product("sku1", shop=shop)
    new_shop_product = new_product.get_shop_instance(shop=shop)
    new_shop_product.suppliers.add(supplier2)

    # Still one with category since shop product not linked to category
    form_field = SupplierProductListFilter().get_fields(request, category)[0][1]
    assert form_field is not None
    assert len(form_field.widget.choices) == 1

    # Without category we get two results
    form_field = SupplierProductListFilter().get_fields(request, None)[0][1]
    assert form_field is not None
    assert len(form_field.widget.choices) == 2

    new_shop_product.categories.add(category)  # primary category shouldn't be required

    # Now with or without category we get 2 results
    form_field = SupplierProductListFilter().get_fields(request, category)[0][1]
    assert form_field is not None
    assert len(form_field.widget.choices) == 2

    form_field = SupplierProductListFilter().get_fields(request, None)[0][1]
    assert form_field is not None
    assert len(form_field.widget.choices) == 2
Ejemplo n.º 4
0
def test_class_refunded():
    shop = factories.get_default_shop()
    supplier = factories.get_default_supplier()
    customer = factories.create_random_person("en")
    OrderStatusManager().ensure_default_statuses()

    product = factories.create_product("p", shop, supplier, 1.0)
    order = factories.create_order_with_product(product, supplier, 1, 1, shop=shop)

    # make sure to have some script enabled
    Script.objects.create(shop=shop, event_identifier="order_status_changed", name="Script", enabled=True)

    def get_mocked_cls():
        return mock.MagicMock(identifier="order_status_changed")

    with mock.patch("E-Commerce.front.notify_events.OrderStatusChanged", new_callable=get_mocked_cls) as mocked:
        order.status = OrderStatus.objects.get_default_processing()
        order.save()
        mocked.assert_called()
        order.refresh_from_db()
        assert mocked.call_args.kwargs["order"] == order
        assert mocked.call_args.kwargs["old_status"] == OrderStatus.objects.get_default_initial()
        assert mocked.call_args.kwargs["new_status"] == OrderStatus.objects.get_default_processing()
        assert order.status == OrderStatus.objects.get_default_processing()

    # nothing changes
    with mock.patch("E-Commerce.front.notify_events.OrderStatusChanged", new_callable=get_mocked_cls) as mocked:
        order.status = OrderStatus.objects.get_default_processing()
        order.save()
        mocked.assert_not_called()
Ejemplo n.º 5
0
def test_product_price(client):
    shop = factories.get_default_shop()
    product = factories.create_product("sku", shop=shop, default_price=30)
    shop_product = product.get_shop_instance(shop)

    supplier_data = [
        ("Johnny Inc", 30),
        ("Mike Inc", 20),
        ("Simon Inc", 10),
    ]
    for name, product_price in supplier_data:
        supplier = Supplier.objects.create(name=name)
        shop_product.suppliers.add(supplier)
        SupplierPrice.objects.create(supplier=supplier, shop=shop, product=product, amount_value=product_price)

    strategy = "E-Commerce.testing.supplier_pricing.supplier_strategy:CheapestSupplierPriceSupplierStrategy"
    with override_settings(E-Commerce_PRICING_MODULE="supplier_pricing", E-Commerce_SHOP_PRODUCT_SUPPLIERS_STRATEGY=strategy):
        for name, price in supplier_data:
            supplier = Supplier.objects.get(name=name)
            response = client.get(
                reverse('E-Commerce:xtheme_extra_view', kwargs={
                        'view': 'product_price'
                    }
                ) + "?id=%s&quantity=%s&supplier=%s" % (product.pk, 1, supplier.pk)
            )
            soup = BeautifulSoup(response.content)
            price_span = soup.find("span", {"class": "product-price"})
            assert "%s" % price in price_span.text
Ejemplo n.º 6
0
def test_add_product_with_extra_parent_line(rf):
    """
    Add product to basket with extra info and parent line
    """
    with override_settings(**CORE_BASKET_SETTINGS):
        shop = factories.get_default_shop()
        user = factories.create_random_user()
        product = factories.create_product("product", shop, factories.get_default_supplier(), 10)
        request = apply_request_middleware(rf.get("/"), user=user)
        basket = get_basket(request, "basket")
        basket.customer = get_person_contact(user)

        cmd_response = basket_commands.handle_add(request, basket, product.id, 1, extra={"more": "stuff"})
        line_id1 = cmd_response["line_id"]
        assert cmd_response["ok"]
        line1 = basket.get_basket_line(line_id1)
        assert line1._data["more"] == "stuff"

        cmd_response = basket_commands.handle_add(
            request, basket, product.id, 1, parent_line=line1, force_new_line=True)
        line_id2 = cmd_response["line_id"]
        assert cmd_response["ok"]
        line2 = basket.get_basket_line(line_id2)
        assert not line2._data

        assert line_id1 != line_id2
        assert line2.parent_line.line_id == line_id1
Ejemplo n.º 7
0
def test_manufacturer_filter_get_fields(rf):
    cache.clear()

    shop = factories.get_default_shop()

    request = apply_request_middleware(rf.get("/"))
    assert ManufacturerProductListFilter().get_fields(request, None) is None

    manufacturer = Manufacturer.objects.create(name="Random Brand Inc")
    assert ManufacturerProductListFilter().get_fields(request, None) is None

    category = factories.get_default_category()
    product = factories.create_product("sku", shop=shop)
    shop_product = product.get_shop_instance(shop=shop)
    shop_product.primary_category = category
    shop_product.save()

    assert ManufacturerProductListFilter().get_fields(request, category) is None

    # Now once we link manufacturer to product we should get
    # form field for manufacturer
    product.manufacturer = manufacturer
    product.save()
    form_field = ManufacturerProductListFilter().get_fields(request, category)[0][1]
    assert form_field is not None
    assert form_field.label == "Manufacturers"

    with override_settings(E-Commerce_FRONT_OVERRIDE_SORTS_AND_FILTERS_LABELS_LOGIC={"manufacturers": "Brands"}):
        form_field = ManufacturerProductListFilter().get_fields(request, category)[0][1]
        assert form_field is not None
        assert form_field.label == "Brands"
Ejemplo n.º 8
0
def test_contact_group_discount(rf):
    default_price = 10
    request, product = _init_test_for_product(rf, default_price)

    # Just to demonstrate that discounts can be created without products
    # and categories. This contact group gets $2 off from every product.
    product_discount_amount = 2
    random_company = factories.create_random_company()
    contact_group = factories.get_default_customer_group()
    random_company.groups.add(contact_group)
    request.customer = random_company

    discount = Discount.objects.create(
        active=True, contact_group=contact_group, discount_amount_value=product_discount_amount)
    discount.shops.add(request.shop)
    assert product.get_price_info(request).price == request.shop.create_price(default_price - product_discount_amount)

    new_product_price = 7
    new_product = factories.create_product("test1", shop=request.shop, default_price=new_product_price)
    assert new_product.get_price_info(request).price == (
        request.shop.create_price(new_product_price - product_discount_amount))

    # Changing the request customer drops the $2 discount
    request.customer = factories.create_random_company()
    assert not request.customer.groups.filter(id=contact_group.pk).exists()
    assert product.get_price_info(request).price == request.shop.create_price(default_price)
    assert new_product.get_price_info(request).price == request.shop.create_price(new_product_price)
Ejemplo n.º 9
0
def test_discounted_price(rf):
    shop = factories.get_default_shop()
    supplier = factories.get_default_supplier()
    request = rf.get("/")
    request.shop = shop
    apply_request_middleware(request)
    assert request.shop == shop

    original_price = 10
    product = factories.create_product("test1", shop=shop, supplier=supplier, default_price=original_price)
    shop_product = product.get_shop_instance(shop)

    # Set discount with discount amount for $2
    discount_amount = 2
    discount = Discount.objects.create(
        active=True, product=product, supplier=supplier, discount_amount_value=discount_amount)
    discount.shops = [shop]

    # Even though the supplier is matching with the product there is no discount
    # since the supplier is not in pricing context.
    assert not hasattr(request, "supplier")
    assert supplier in shop_product.suppliers.all()
    assert product.get_price_info(request).price == request.shop.create_price(10)

    setattr(request, "supplier", supplier)
    assert product.get_price_info(request).price == request.shop.create_price(8)

    # No discount once we change the discount supplier
    new_supplier = Supplier.objects.create(identifier="*")
    discount.supplier = new_supplier
    discount.save()
    assert product.get_price_info(request).price == request.shop.create_price(10)
Ejemplo n.º 10
0
def test_edit_object_view_errors(rf, admin_user):
    shop = factories.get_default_shop()
    view = EditObjectView.as_view()

    # missing params
    response = view(apply_request_middleware(rf.get(reverse("E-Commerce_admin:edit")), user=admin_user, shop=shop))
    assert response.status_code == 400
    assert "Invalid object" in response.content.decode("utf-8")

    # invalid model
    response = _get_edit_object_view(rf, view, ".", None, admin_user, shop)
    assert response.status_code == 400
    assert "Invalid model" in response.content.decode("utf-8")

    # invalid object ID
    product = factories.create_product("p1", shop, factories.get_default_supplier())
    model = ".".join(ContentType.objects.get_for_model(product).natural_key())
    with pytest.raises(Http404) as error:
        _get_edit_object_view(rf, view, model, product.id + 10, admin_user, shop)
    assert "Object not found" in str(error)

    # object has no admin url
    from E-Commerce.core.models import ConfigurationItem
    config = ConfigurationItem.objects.create(shop=shop, key="test", value={"value": 123})
    model = ".".join(ContentType.objects.get_for_model(config).natural_key())
    with pytest.raises(Http404) as error:
        _get_edit_object_view(rf, view, model, config.id, admin_user, shop)
    assert "Object not found" in str(error)
Ejemplo n.º 11
0
def _create_order(shop, customer):
    p1 = factories.create_product("test", shop=shop, supplier=factories.get_default_supplier())
    order = factories.create_order_with_product(factories.get_default_product(), factories.get_default_supplier(), 2,
                                                10, shop=shop)
    factories.add_product_to_order(order, factories.get_default_supplier(), p1, 2, 5)
    order.customer = customer
    order.save()
    return order
Ejemplo n.º 12
0
def test_category_filter():
    shop = factories.get_default_shop()

    category1 = Category.objects.create(name="Category 1")
    category1.shops.add(shop)
    product1 = factories.create_product("p1", shop, factories.get_default_supplier(), "10")
    shop_product1 = product1.get_shop_instance(shop)
    shop_product1.categories.add(category1)

    category2 = Category.objects.create(name="Category 2")
    category2.shops.add(shop)
    product2 = factories.create_product("p2", shop, factories.get_default_supplier(), "20")
    shop_product2 = product2.get_shop_instance(shop)
    shop_product2.categories.add(category2)

    client = SmartClient()
    config = {"filter_products_by_category": True}
    set_configuration(shop=shop, data=config)

    url = reverse('E-Commerce:all-categories')

    # 1) go to all categories view and list products
    # no filters being applied should list all products
    response, soup = client.response_and_soup(url)
    assert response.status_code == 200
    assert soup.find(id="product-%d" % product1.id)
    assert soup.find(id="product-%d" % product2.id)

    # 2) filter by category2 id only
    response, soup = client.response_and_soup("{}?categories={}".format(url, category2.pk))
    assert response.status_code == 200
    assert not soup.find(id="product-%d" % product1.id)
    assert soup.find(id="product-%d" % product2.id)

    # 3) filter by category1 and category2 id
    response, soup = client.response_and_soup("{}?categories={},{}".format(url, category1.pk, category2.pk))
    assert response.status_code == 200
    assert soup.find(id="product-%d" % product1.id)
    assert soup.find(id="product-%d" % product2.id)

    # 4) filter by blank value, it shouldn't break
    response, soup = client.response_and_soup("{}?categories=".format(url))
    assert response.status_code == 200
    assert soup.find(id="product-%d" % product1.id)
    assert soup.find(id="product-%d" % product2.id)
Ejemplo n.º 13
0
def init_test():
    shop = factories.get_default_shop()
    product = factories.create_product("test", shop=shop, default_price=10)
    discount = Discount.objects.create(active=True, product=product, discounted_price_value=6)
    discount.shops = [shop]
    happy_hour = HappyHour.objects.create(name="Happy")
    happy_hour.shops = [shop]
    discount.happy_hours = [happy_hour]
    return happy_hour
Ejemplo n.º 14
0
def test_product_detail_view():
    vc = _get_basic_view_config(view_name="ProductDetailView")
    product = factories.create_product("test", shop=factories.get_default_shop(), name="Test product name")
    product2 = factories.create_product("test2", shop=factories.get_default_shop(), name="Test product name 2")
    placeholder_name = "product_extra_1"
    context = {"product": product}
    layout = vc.get_placeholder_layout(ProductLayout, placeholder_name, context=context)
    plugin_text = printable_gibberish()
    _add_plugin_and_test_save(vc, layout, placeholder_name, context, plugin_text)

    # Also let's confirm that the plugin visibility works with smart client
    c = SmartClient()
    soup = c.soup(reverse("E-Commerce:product", kwargs={"pk": product.id, "slug": product.slug}))
    product_details = soup.find("div", {"class": "product-basic-details"})
    assert plugin_text in product_details.text

    c = SmartClient()
    soup = c.soup(reverse("E-Commerce:product", kwargs={"pk": product2.id, "slug": product2.slug}))
    product_details = soup.find("div", {"class": "product-basic-details"})
    assert plugin_text not in product_details.text
Ejemplo n.º 15
0
def _init_test_for_product(rf, default_price):
    shop = factories.get_default_shop()
    supplier = factories.get_default_supplier()
    request = rf.get("/")
    request.shop = shop
    apply_request_middleware(request)
    assert request.shop == shop

    product = factories.create_product("test", shop=shop, supplier=supplier, default_price=default_price)
    assert product.get_price_info(request).price == shop.create_price(default_price)
    return request, product
Ejemplo n.º 16
0
def test_price_info_cache_bump(rf):
    initial_price = 10
    shop = factories.get_default_shop()
    tax = factories.get_default_tax()
    tax_class = factories.get_default_tax_class()
    product = factories.create_product(
        "product",
        shop=shop,
        supplier=factories.get_default_supplier(),
        default_price=initial_price
    )
    request = apply_request_middleware(rf.get("/"))

    def assert_cache_product():
        cache_price_info(request, product, 1, product.get_price_info(request))
        assert get_cached_price_info(request, product, 1).price == shop.create_price(initial_price)

    def assert_nothing_is_cached():
        # nothing is cached
        assert get_cached_price_info(request, product, 1) is None

    # cache the item
    assert_nothing_is_cached()
    assert_cache_product()

    # cache bumped - the cache should be dropped - then, cache again
    tax.save()
    assert_nothing_is_cached()
    assert_cache_product()

    # cache bumped - the cache should be dropped - then, cache again
    tax_class.save()
    assert_nothing_is_cached()
    assert_cache_product()

    # cache bumped - the cache should be dropped - then, cache again
    product.save()
    assert_nothing_is_cached()
    assert_cache_product()

    shop_product = product.get_shop_instance(shop)

    # cache bumped - the cache should be dropped - then, cache again
    shop_product.save()
    assert_nothing_is_cached()
    assert_cache_product()

    category = factories.get_default_category()

    # cache bumped - the cache should be dropped - then, cache again
    shop_product.categories.add(category)
    assert_nothing_is_cached()
    assert_cache_product()
Ejemplo n.º 17
0
def test_default_layout():
    vc = _get_basic_view_config()
    product = factories.create_product("test", name="Test product name")
    category = factories.get_default_category()

    placeholder_name = "wildhorse"
    context = {"request": get_request(), "product": product, "category": category}
    layout = vc.get_placeholder_layout(Layout, placeholder_name)
    assert isinstance(layout, Layout)
    assert layout.get_help_text({}) == layout.get_help_text(context)

    _add_plugin_and_test_save(vc, layout, placeholder_name, context)
Ejemplo n.º 18
0
def test_edit_object_view_no_permissions(rf):
    user = factories.create_random_user("en", is_staff=True)
    shop = factories.get_default_shop()
    shop.staff_members.add(user)

    view = EditObjectView.as_view()
    product = factories.create_product("p1", shop, factories.get_default_supplier())
    model = ".".join(ContentType.objects.get_for_model(product).natural_key())

    # no permission
    with pytest.raises(Problem) as error:
        _get_edit_object_view(rf, view, model, product.id, user, shop)
    assert "You do not have the required permission" in str(error)
Ejemplo n.º 19
0
def test_product_layout():
    vc = _get_basic_view_config()
    product = factories.create_product("test", shop=factories.get_default_shop(), name="Test product name")

    placeholder_name = "wow"
    # Context doesn't validate with the product layout
    assert vc.get_placeholder_layout(ProductLayout, placeholder_name) is None

    context = {"product": product}
    layout = vc.get_placeholder_layout(ProductLayout, placeholder_name, context=context)
    assert isinstance(layout, ProductLayout)
    assert layout.get_help_text({}) == ""  # Invalid context for help text
    assert product.name in layout.get_help_text(context)
    _assert_empty_layout(layout, placeholder_name)

    _add_plugin_and_test_save(vc, layout, placeholder_name, context)
    
    # Make sure layout only available for this one product
    new_product = factories.create_product("new_test")
    context = {"product": new_product}
    layout = vc.get_placeholder_layout(ProductLayout, placeholder_name, context=context)
    _assert_empty_layout(layout, placeholder_name)
Ejemplo n.º 20
0
def test_serialize_data():
    """
    Test contact dashboard views
    """
    activate("en")
    shop = factories.get_default_shop()

    customer = factories.create_random_person("en")
    user = factories.create_random_user("en")
    user.set_password("1234")
    user.save()
    customer.user = user
    customer.default_billing_address = factories.create_random_address()
    customer.default_shipping_address = factories.create_random_address()
    customer.save()

    company = factories.create_random_company()
    company.default_billing_address = factories.create_random_address()
    company.default_shipping_address = factories.create_random_address()
    company.save()
    company.members.add(customer)

    product = factories.create_product("p1", shop, factories.get_default_supplier())
    for basket_customer in [customer, company]:
        [factories.create_random_order(basket_customer, [product]) for order in range(3)]

    client = SmartClient()
    client.login(username=user.username, password="******")

    response = client.get(reverse("E-Commerce:gdpr_customer_dashboard"))
    assert response.status_code == 200
    assert "My Data" in response.content.decode("utf-8")

    response = client.post(reverse("E-Commerce:gdpr_download_data"))
    assert response._headers["content-disposition"][0] == "Content-Disposition"
    assert response.status_code == 200

    from E-Commerce.tasks.models import Task, TaskType
    from E-Commerce.gdpr.models import GDPR_ANONYMIZE_TASK_TYPE_IDENTIFIER
    response = client.post(reverse("E-Commerce:gdpr_anonymize_account"))
    assert response.status_code == 302
    assert response.url.endswith(reverse("E-Commerce:index"))
    task_type = TaskType.objects.get(identifier=GDPR_ANONYMIZE_TASK_TYPE_IDENTIFIER, shop=shop)
    assert Task.objects.get(type=task_type, shop=shop)

    user.refresh_from_db()
    assert user.is_active is False

    refreshed_customer = PersonContact.objects.get(id=customer.id)
    assert refreshed_customer.is_active is False
    assert refreshed_customer.name == customer.name     # nothing changed yet
Ejemplo n.º 21
0
def test_add_product(rf):
    """
    Add product to basket
    """
    with override_settings(**CORE_BASKET_SETTINGS):
        shop = factories.get_default_shop()
        user = factories.create_random_user()
        product = factories.create_product("product", shop, factories.get_default_supplier(), 10)
        request = apply_request_middleware(rf.get("/"), user=user)
        basket = get_basket(request, "basket")
        basket.customer = get_person_contact(user)
        cmd_response = basket_commands.handle_add(request, basket, product.id, 1)
        assert cmd_response["ok"]
        assert cmd_response["line_id"]
        assert cmd_response["added"] == 1
        assert len(basket.get_lines()) == 1
Ejemplo n.º 22
0
def _init_test_for_product_without_basket(rf, default_price):
    shop = factories.get_default_shop()
    supplier = factories.get_default_supplier()
    random_customer = factories.create_random_person()
    request = rf.get("/")
    apply_request_middleware(request, shop=shop, customer=random_customer)
    assert request.shop == shop
    assert request.customer == random_customer

    sku = "test"
    product = Product.objects.filter(sku=sku).first()
    if not product:
        product = factories.create_product(sku, shop=shop, supplier=supplier, default_price=default_price)

    assert product.get_price_info(request).price == shop.create_price(default_price)
    return request, product
Ejemplo n.º 23
0
def test_basket_with_custom_shop(rf):
    """
    Set a different shop for basket
    """
    with override_settings(**CORE_BASKET_SETTINGS):
        shop1 = factories.get_default_shop()
        shop2 = factories.get_shop(identifier="shop2")
        user = factories.create_random_user()
        request = apply_request_middleware(rf.get("/"), user=user, shop=shop1)
        basket_class = cached_load("E-Commerce_BASKET_CLASS_SPEC")
        basket = basket_class(request, "basket", shop=shop2)
        assert basket.shop == shop2

        product_shop2 = factories.create_product("product_shop2", shop2, factories.get_default_supplier(), 10)
        line = basket.add_product(factories.get_default_supplier(), shop2, product_shop2, 1)
        assert line.shop == shop2
Ejemplo n.º 24
0
def test_discount_amount(rf):
    shop = factories.get_default_shop()
    request = rf.get("/")
    request.shop = shop
    apply_request_middleware(request)
    assert request.shop == shop

    original_price = 10
    product = factories.create_product("test1", shop=shop, default_price=original_price)

    # Set discount percentage to 20% which means $2
    discount_percentage = 0.20
    discount = Discount.objects.create(active=True, product=product, discount_percentage=discount_percentage)
    discount.shops = [shop]
    assert product.get_price_info(request).price == request.shop.create_price(8)

    # Let's set discounted price to let's say $5
    discounted_price = 5
    discount = Discount.objects.create(active=True, product=product, discounted_price_value=discounted_price)
    discount.shops = [shop]
    assert product.get_price_info(request).price == request.shop.create_price(5)

    # All discount amount values up to $5 shouldn't change the product price
    for x in range(0, 5):
        discount_amount = decimal.Decimal(random.randrange(1, 501))/100
        discount = Discount.objects.create(active=True, product=product, discount_amount_value=discount_amount)
        discount.shops = [shop]
        assert product.get_price_info(request).price == request.shop.create_price(5)

    # Finally let's set discount amount value higher than all other discounts
    discount_amount = decimal.Decimal(random.randrange(500, 1000))/100
    discount = Discount.objects.create(active=True, product=product, discount_amount_value=discount_amount)
    discount.shops = [shop]
    assert product.get_price_info(request).price == request.shop.create_price(original_price - discount_amount)

    # Let's make sure price doesn't go below zero
    discount_amount = decimal.Decimal(random.randrange(1000, 25000))/100
    discount = Discount.objects.create(active=True, product=product, discount_amount_value=discount_amount)
    discount.shops = [shop]
    assert product.get_price_info(request).price == request.shop.create_price(0)

    # Finally let's make sure the minimum price value for shop product is honored
    shop_product = product.get_shop_instance(shop)
    min_price = decimal.Decimal(random.randrange(1, 501))/100
    shop_product.minimum_price_value = min_price
    shop_product.save()
    assert product.get_price_info(request).price == request.shop.create_price(min_price)
Ejemplo n.º 25
0
def test_suppliers_filter_get_fields(rf):
    cache.clear()
    shop = factories.get_default_shop()

    request = apply_request_middleware(rf.get("/"))
    assert SupplierProductListFilter().get_fields(request, None) is None

    supplier = Supplier.objects.create(name="Favorite brands dot com")
    supplier.shops.add(shop)
    assert Supplier.objects.enabled().exists()
    assert SupplierProductListFilter().get_fields(request, None) is None

    category = factories.get_default_category()
    product = factories.create_product("sku", shop=shop)
    shop_product = product.get_shop_instance(shop=shop)
    shop_product.primary_category = category
    shop_product.save()

    assert SupplierProductListFilter().get_fields(request, category) is None

    # Now once we link supplier to product we should get
    # form field for manufacturer
    shop_product.suppliers.add(supplier)
    form_field = SupplierProductListFilter().get_fields(request, category)[0][1]
    assert form_field is not None
    assert form_field.label == "Suppliers"

    with override_settings(E-Commerce_FRONT_OVERRIDE_SORTS_AND_FILTERS_LABELS_LOGIC={"supplier": "Filter by suppliers"}):
        form_field = SupplierProductListFilter().get_fields(request, category)[0][1]
        assert form_field is not None
        assert form_field.label == "Filter by suppliers"
        assert isinstance(form_field, forms.ModelChoiceField)

        configuration = get_configuration(shop, category)
        configuration.update({
            SupplierProductListFilter.enable_multiselect_key: True
        })

        set_configuration(shop, category, configuration)
        form_field = SupplierProductListFilter().get_fields(request, category)[0][1]
        assert form_field is not None
        assert form_field.label == "Filter by suppliers"
        assert isinstance(form_field, CommaSeparatedListField)

        cache.clear()
Ejemplo n.º 26
0
def test_discount_admin_edit_view(rf, staff_user, admin_user):
    with override_settings(E-Commerce_ENABLE_MULTIPLE_SHOPS=True):
        shop = factories.get_default_shop()
        shop.staff_members.add(staff_user)
        factories.get_shop(identifier="shop2")
        assert Shop.objects.count() == 2

        # Staff user gets shop automatically
        product = factories.create_product("test", shop=shop)
        discount_percentage = 20
        data = {"product": product.pk, "discount_percentage": discount_percentage}
        request = apply_request_middleware(rf.post("/", data=data), user=staff_user, shop=shop)
        set_shop(request, shop)
        assert request.shop == shop
        view_func = DiscountEditView.as_view()
        response = view_func(request)
        if hasattr(response, "render"):
            response.render()

        assert response.status_code == 302
        discount1 = Discount.objects.first()
        assert discount1.shops.first() == shop

        # Test with superuser and with different shop
        shop2 = factories.get_shop(enabled=True)
        request = apply_request_middleware(rf.post("/", data=data), user=admin_user, shop=shop2)
        set_shop(request, shop2)
        view_func = DiscountEditView.as_view()
        response = view_func(request)
        assert response.status_code == 302
        assert Discount.objects.count() == 2

        discount2 = Discount.objects.exclude(id=discount1.pk).first()
        assert discount1 != discount2
        assert discount2.shops.count() == 1
        assert discount2.shops.filter(id=shop2.pk).exists()

        # Staff user can only view discount1 since that has the right shop
        _assert_view_get(rf, discount1, shop, staff_user)
        _assert_view_get(rf, discount2, shop, staff_user, True)

        # Superuser can see both if needed, but only when right shop is active
        _assert_view_get(rf, discount1, shop, admin_user)
        _assert_view_get(rf, discount2, shop, admin_user, True)
        _assert_view_get(rf, discount2, shop2, admin_user)
Ejemplo n.º 27
0
def test_product_campaigns_section(rf, admin_user):
    shop = factories.get_default_shop()
    supplier = factories.get_default_supplier()

    product = factories.create_product("test", shop=shop, supplier=supplier, default_price=10)
    campaign1 = _create_active_campaign(shop, supplier, product)
    campaign2 = _create_active_campaign(shop, None, product)

    shop_staff_user = factories.create_random_user(is_staff=True)
    shop.staff_members.add(shop_staff_user)

    supplier_staff_user = factories.create_random_user(username=supplier.identifier, is_staff=True)
    shop.staff_members.add(supplier_staff_user)

    supplier_provider = "E-Commerce.testing.supplier_provider.UsernameSupplierProvider"
    with override_settings(E-Commerce_ADMIN_SUPPLIER_PROVIDER_SPEC=supplier_provider):
        request = apply_request_middleware(rf.get("/"), user=admin_user)
        request.shop = shop
        assert get_supplier(request) is None
        context = ProductCampaignsSection.get_context_data(product, request)
        assert context[shop]["basket_campaigns"].count() == 2

        request = apply_request_middleware(rf.get("/"), user=shop_staff_user)
        request.shop = shop
        assert get_supplier(request) is None
        context = ProductCampaignsSection.get_context_data(product, request)
        assert context[shop]["basket_campaigns"].count() == 2

        request = apply_request_middleware(rf.get("/"), user=supplier_staff_user)
        request.shop = shop
        assert get_supplier(request) == supplier
        context = ProductCampaignsSection.get_context_data(product, request)
        assert context[shop]["basket_campaigns"].count() == 1

        campaign1.supplier = None
        campaign1.save()

        context = ProductCampaignsSection.get_context_data(product, request)
        assert context[shop]["basket_campaigns"].count() == 0

        BasketCampaign.objects.update(supplier=supplier)

        context = ProductCampaignsSection.get_context_data(product, request)
        assert context[shop]["basket_campaigns"].count() == 2
Ejemplo n.º 28
0
def test_product_detail(client):
    shop = factories.get_default_shop()
    product = factories.create_product("sku", shop=shop, default_price=30)
    shop_product = product.get_shop_instance(shop)

    # Activate show supplier info for front
    assert ThemeSettings.objects.count() == 1
    theme_settings = ThemeSettings.objects.first()
    theme_settings.update_settings({"show_supplier_info": True})

    supplier_data = [
        ("Johnny Inc", 30),
        ("Mike Inc", 20),
        ("Simon Inc", 10),
    ]
    for name, product_price in supplier_data:
        supplier = Supplier.objects.create(name=name)
        shop_product.suppliers.add(supplier)
        SupplierPrice.objects.create(supplier=supplier, shop=shop, product=product, amount_value=product_price)

    strategy = "E-Commerce.testing.supplier_pricing.supplier_strategy:CheapestSupplierPriceSupplierStrategy"
    with override_settings(E-Commerce_PRICING_MODULE="supplier_pricing", E-Commerce_SHOP_PRODUCT_SUPPLIERS_STRATEGY=strategy):

        # Ok so cheapest price should be default supplier
        expected_supplier = shop_product.get_supplier()
        assert expected_supplier.name == "Simon Inc"
        with override_current_theme_class(ClassicGrayTheme, shop):  # Ensure settings is refreshed from DB
            soup = _get_product_detail_soup(client, product)

            _assert_supplier_subtitle(soup, expected_supplier)
            _assert_add_to_basket_form(soup, expected_supplier, 10)

            # Bonus! Let's say Johnny gets mad and starts to supply this product for 5 euros
            johnny_the_supplier = Supplier.objects.filter(name="Johnny Inc").first()
            SupplierPrice.objects.filter(
                supplier=johnny_the_supplier, shop=shop, product=product
            ).update(amount_value=5)

            # This means that product detail get new default supplier and new price
            assert shop_product.get_supplier() == johnny_the_supplier
            soup = _get_product_detail_soup(client, product)

            _assert_supplier_subtitle(soup, johnny_the_supplier)
            _assert_add_to_basket_form(soup, johnny_the_supplier, 5)
Ejemplo n.º 29
0
def test_gdpr_admin_download_data(client, admin_user):
    """
    Test that admin user can download customer data
    """
    activate("en")
    shop = factories.get_default_shop()
    customer = factories.create_random_person("en")
    product = factories.create_product("p1", shop, factories.get_default_supplier())
    [factories.create_random_order(customer, [product]) for order in range(3)]

    client = SmartClient()
    admin_user.set_password("admin")
    admin_user.save()
    client.login(username=admin_user.username, password="******")
    admin_download_url = reverse("E-Commerce_admin:gdpr.download_data", kwargs=dict(pk=customer.pk))
    response = client.post(admin_download_url)
    assert response.status_code == 200
    assert response._headers["content-disposition"][0] == "Content-Disposition"
    assert response._headers["content-disposition"][1].startswith("attachment; filename=user_data_")
Ejemplo n.º 30
0
def test_supplier_product_detail(client):
    shop = factories.get_default_shop()
    product = factories.create_product("sku", shop=shop, default_price=30)
    shop_product = product.get_shop_instance(shop)

    # Activate show supplier info for front
    assert ThemeSettings.objects.count() == 1
    theme_settings = ThemeSettings.objects.first()
    theme_settings.update_settings({"show_supplier_info": True})

    supplier_data = [
        ("Johnny Inc", 30),
        ("Mike Inc", 20),
        ("Simon Inc", 10),
    ]
    for name, product_price in supplier_data:
        supplier = Supplier.objects.create(name=name)
        supplier.shops.add(shop)
        shop_product.suppliers.add(supplier)
        SupplierPrice.objects.create(supplier=supplier, shop=shop, product=product, amount_value=product_price)

    strategy = "E-Commerce.testing.supplier_pricing.supplier_strategy:CheapestSupplierPriceSupplierStrategy"
    with override_settings(E-Commerce_PRICING_MODULE="supplier_pricing", E-Commerce_SHOP_PRODUCT_SUPPLIERS_STRATEGY=strategy):

        # Ok so cheapest price should be default supplier
        expected_supplier = shop_product.get_supplier()
        assert expected_supplier.name == "Simon Inc"
        with override_current_theme_class(ClassicGrayTheme, shop):  # Ensure settings is refreshed from DB
            johnny = Supplier.objects.filter(name="Johnny Inc").first()
            soup = _get_supplier_product_detail_soup(client, product, johnny)
            _assert_supplier_subtitle(soup, johnny)
            _assert_add_to_basket_form(soup, johnny, 30)

            mike = Supplier.objects.filter(name="Mike Inc").first()
            soup = _get_supplier_product_detail_soup(client, product, mike)
            _assert_supplier_subtitle(soup, mike)
            _assert_add_to_basket_form(soup, mike, 20)

            simon = Supplier.objects.filter(name="Simon Inc").first()
            soup = _get_supplier_product_detail_soup(client, product, simon)
            _assert_supplier_subtitle(soup, simon)
            _assert_add_to_basket_form(soup, simon, 10)