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
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
Esempio n. 3
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()
Esempio n. 4
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)
Esempio n. 5
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
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)
Esempio n. 7
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
Esempio n. 8
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)
Esempio n. 9
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
Esempio n. 10
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
Esempio n. 11
0
def _init_test_for_product_with_basket(rf, default_price):
    request, product = _init_test_for_product_without_basket(rf, default_price)
    shop = factories.get_default_shop()
    supplier = factories.get_default_supplier()
    basket = get_basket(request)
    basket.status = factories.get_initial_order_status()
    basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1)
    basket.shipping_method = factories.get_shipping_method(shop=shop)
    basket.payment_method = factories.get_payment_method(shop=shop)
    assert basket.shop == request.shop
    assert basket.customer == request.customer
    return request, product, basket
Esempio n. 12
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()
Esempio n. 13
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)
Esempio n. 14
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
Esempio n. 15
0
def _create_order(request, customer, coupon, product, expected_product_price):
    creator = OrderCreator(request)
    shop = request.shop
    request.basket = None
    request.customer = customer
    basket = get_basket(request)
    basket.status = factories.get_initial_order_status()
    basket.add_product(supplier=factories.get_default_supplier(), shop=shop, product=product, quantity=1)
    basket.shipping_method = factories.get_shipping_method(shop=shop)
    basket.payment_method = factories.get_payment_method(shop=shop)
    basket.add_code(coupon)
    assert basket.shop == request.shop
    assert basket.customer == request.customer
    assert product.get_price_info(request).price == expected_product_price
    creator.create_order(basket)
Esempio n. 16
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
Esempio n. 17
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
Esempio n. 18
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
Esempio n. 19
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_")
def test_product_view_prices_and_basket_visibility(rf):
    activate("en")
    product_sku = "test-123"
    shop = factories.get_default_shop()
    supplier = factories.get_default_supplier()
    default_price = 11
    product = factories.create_product(product_sku, shop=shop, supplier=supplier, default_price=default_price)

    assert ThemeSettings.objects.count() == 1
    theme_settings = ThemeSettings.objects.first()
    assert theme_settings.shop == shop
    assert theme_settings.theme_identifier == ClassicGrayTheme.identifier

    assert not theme_settings.get_setting("hide_prices")
    assert not theme_settings.get_setting("catalog_mode")

    with override_current_theme_class(ClassicGrayTheme, shop):  # Ensure settings is refreshed from DB
        c = SmartClient()
        soup = c.soup(reverse("E-Commerce:product", kwargs={"pk": product.pk, "slug": product.slug}))
        assert _is_basket_in_soup(soup)
        assert _is_price_in_soup(soup, default_price)
        assert _is_add_to_basket_button_in_soup(soup)

    theme_settings.update_settings({"catalog_mode": True})
    with override_current_theme_class(ClassicGrayTheme, shop):  # Ensure settings is refreshed from DB
        c = SmartClient()
        soup = c.soup(reverse("E-Commerce:product", kwargs={"pk": product.pk, "slug": product.slug}))
        assert not _is_basket_in_soup(soup)
        assert not _is_add_to_basket_button_in_soup(soup)
        assert _is_price_in_soup(soup, default_price)

    theme_settings.update_settings({"hide_prices": True, "catalog_mode": False})
    with override_current_theme_class(ClassicGrayTheme, shop):  # Ensure settings is refreshed from DB
        c = SmartClient()
        soup = c.soup(reverse("E-Commerce:product", kwargs={"pk": product.pk, "slug": product.slug}))
        assert not _is_add_to_basket_button_in_soup(soup)
        assert not _is_basket_in_soup(soup)
        assert not _is_price_in_soup(soup, default_price)
Esempio n. 21
0
def test_resolve_product_url():
    shop = factories.get_default_shop()
    product = factories.create_product("product", shop, factories.get_default_supplier(), "10")
    from E-Commerce.front.template_helpers.urls import model_url
    assert model_url({}, product) == reverse("E-Commerce:product", kwargs=dict(pk=product.pk, slug=product.slug))
Esempio n. 22
0
from E-Commerce.utils.excs import Problem


def _get_edit_object_view(rf, view, model_name, object_id, user, shop, mode=None):
    data = {
        "model": model_name,
        "id": object_id
    }
    if mode:
        data["mode"] = mode
    request = apply_request_middleware(rf.get(reverse("E-Commerce_admin:edit"), data), user=user, shop=shop)
    return view(request)


@pytest.mark.parametrize("creator_fn", [
    lambda: factories.create_product("sku", factories.get_default_shop(), factories.get_default_supplier()),
    lambda: factories.create_random_person(),
    lambda: factories.create_random_company(),
    lambda: factories.create_random_order(customer=factories.create_random_person(), products=[
        factories.create_product("p", factories.get_default_shop(), factories.get_default_supplier())
    ]),
    lambda: factories.create_random_user(),
])
@pytest.mark.django_db
def test_edit_object_view(rf, admin_user, creator_fn):
    shop = factories.get_default_shop()
    view = EditObjectView.as_view()
    object_instance = creator_fn()
    model = ".".join(ContentType.objects.get_for_model(object_instance).natural_key())

    # correct shop
Esempio n. 23
0
def test_product_selection_plugin(rf):
    shop = factories.get_default_shop()
    category1 = factories.CategoryFactory(status=CategoryStatus.VISIBLE)
    category2 = factories.CategoryFactory(status=CategoryStatus.VISIBLE)

    p1 = factories.create_product("p1", shop, factories.get_default_supplier(), "10")
    p2 = factories.create_product("p2", shop, factories.get_default_supplier(), "20")
    p3 = factories.create_product("p3", shop, factories.get_default_supplier(), "30")
    p4 = factories.create_product("p4", shop, factories.get_default_supplier(), "40")
    p5 = factories.create_product("p5", shop, factories.get_default_supplier(), "50")

    sp1 = p1.get_shop_instance(shop)
    sp2 = p2.get_shop_instance(shop)
    sp3 = p3.get_shop_instance(shop)
    sp4 = p4.get_shop_instance(shop)

    sp1.categories.add(category1, category2)
    sp2.categories.add(category1)
    sp3.categories.add(category2)
    sp4.categories.add(category2)

    # this discount should show products: p1, p2 and p5
    discount1 = Discount.objects.create(
        name="discount1",
        active=True,
        start_datetime=now() - timedelta(days=10),
        end_datetime=now() + timedelta(days=1),
        product=p5,
        category=category1
    )
    discount1.shops = [shop]

    # this discount should show products: p1, p3 and p4
    discount2 = Discount.objects.create(
        name="discount2",
        active=True,
        start_datetime=now() - timedelta(days=10),
        end_datetime=now() + timedelta(days=1),
        category=category2
    )
    discount2.shops = [shop]

    # this discount shouldn't be available for this shop
    discount3 = Discount.objects.create(
        name="discount3",
        active=True,
        start_datetime=now() - timedelta(days=10),
        end_datetime=now() + timedelta(days=1),
        category=category2
    )

    context = get_context(rf)

    # test only discount1
    plugin = DiscountedProductsPlugin({"discounts": [discount1.pk], "count": 10})
    context_products = plugin.get_context_data(context)["products"]
    assert p1 in context_products
    assert p2 in context_products
    assert p3 not in context_products
    assert p4 not in context_products
    assert p5 in context_products

    for status in range(2):
        if status == 1:
            discount2.active = False
            discount2.save()

        # test only discount2
        plugin = DiscountedProductsPlugin({"discounts": [discount2.pk], "count": 10})
        context_products = plugin.get_context_data(context)["products"]

        if status == 1:
            assert context_products == []
        else:
            assert p1 in context_products
            assert p2 not in context_products
            assert p3 in context_products
            assert p4 in context_products
            assert p5 not in context_products

    # test discount3
    plugin = DiscountedProductsPlugin({"discounts": [discount3.pk], "count": 10})
    assert plugin.get_context_data(context)["products"] == []

    discount2.active = True
    discount2.save()

    # test both discount1 and discount2
    plugin = DiscountedProductsPlugin({"discounts": [discount1.pk, discount2.pk], "count": 10})
    context_products = plugin.get_context_data(context)["products"]
    assert p1 in context_products
    assert p2 in context_products
    assert p3 in context_products
    assert p4 in context_products
    assert p5 in context_products

    # test the plugin form
    with override_current_theme_class(None):
        theme = get_current_theme(shop)
        cell = LayoutCell(theme, DiscountedProductsPlugin.identifier, sizes={"md": 8})
        lcfg = LayoutCellFormGroup(layout_cell=cell, theme=theme, request=apply_request_middleware(rf.get("/")))
        # not valid, products are required
        assert not lcfg.is_valid()

        lcfg = LayoutCellFormGroup(
            data={
                "general-cell_width": "8",
                "general-cell_align": "pull-right",
                "plugin-discounts": [discount1.pk, discount2.pk],
                "plugin-count": 6
            },
            layout_cell=cell,
            theme=theme,
            request=apply_request_middleware(rf.get("/"))
        )
        assert lcfg.is_valid()
        lcfg.save()
        assert cell.config["discounts"] == [discount1.pk, discount2.pk]
Esempio n. 24
0
def test_xtheme_edit_product(admin_user, browser, live_server, settings):
    shop = factories.get_default_shop()
    supplier = factories.get_default_supplier()
    products = []
    for x in range(3):
        products.append(factories.create_product("test%s" % x, shop=shop, supplier=supplier, default_price=10))

    browser = initialize_admin_browser_test(browser, live_server, settings)  # Login to admin as admin user

    browser.visit(live_server + "/")
    wait_until_condition(browser, lambda x: x.is_text_present("Welcome to Default!"))

    # Start edit
    click_element(browser, ".xt-edit-toggle button[type='submit']")

    # Visit first product and edit the layout with custom text
    first_product = products.pop()
    first_product_url = "%s%s" % (
        live_server, reverse("E-Commerce:product", kwargs={"pk": first_product.pk, "slug": first_product.slug})
    )
    browser.visit(first_product_url)

    first_product_text_content = "This text is only visible for product %s." % first_product.name
    _edit_layout(
        browser,
        "product_extra_1",
        "#xt-ph-product_extra_1-xtheme-product-layout-%s" % first_product.pk,
        first_product_text_content
    )

    # Visit second product and edit the layout with custom text
    second_product = products.pop()
    second_product_url = "%s%s" % (
        live_server, reverse("E-Commerce:product", kwargs={"pk": second_product.pk, "slug": second_product.slug})
    )
    browser.visit(second_product_url)

    second_product_text_content = "This text is only visible for product %s." % second_product.name
    _edit_layout(
        browser,
        "product_extra_1",
        "#xt-ph-product_extra_1-xtheme-product-layout-%s" % second_product.pk,
        second_product_text_content
    )

    # Visit third product and edit common layout with text
    third_product = products.pop()
    third_product_url = "%s%s" % (
        live_server, reverse("E-Commerce:product", kwargs={"pk": third_product.pk, "slug": third_product.slug})
    )
    browser.visit(third_product_url)

    common_text_content = "This text is visible for all products."
    _edit_layout(
        browser, "product_extra_1", "#xt-ph-product_extra_1", common_text_content)

    # Close edit
    click_element(browser, ".xt-edit-toggle button[type='submit']")

    # Logout
    click_element(browser, "div.top-nav i.menu-icon.fa.fa-user")
    click_element(browser, "a[href='/logout/']")

    # Let's revisit the product details as anonymous and check the placeholder content
    browser.visit(first_product_url)
    wait_until_condition(browser, lambda x: x.is_text_present(common_text_content))
    wait_until_condition(browser, lambda x: x.is_text_present(first_product_text_content))
    wait_until_condition(browser, lambda x: not x.is_text_present(second_product_text_content))

    browser.visit(second_product_url)
    wait_until_condition(browser, lambda x: x.is_text_present(common_text_content))
    wait_until_condition(browser, lambda x: not x.is_text_present(first_product_text_content))
    wait_until_condition(browser, lambda x: x.is_text_present(second_product_text_content))

    browser.visit(third_product_url)
    wait_until_condition(browser, lambda x: x.is_text_present(common_text_content))
    wait_until_condition(browser, lambda x: not x.is_text_present(first_product_text_content))
    wait_until_condition(browser, lambda x: not x.is_text_present(second_product_text_content))
Esempio n. 25
0
def test_many_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
    )
    child1 = factories.create_product(
        "child1",
        shop=shop,
        supplier=factories.get_default_supplier(),
        default_price=5
    )
    child2 = factories.create_product(
        "child2",
        shop=shop,
        supplier=factories.get_default_supplier(),
        default_price=9
    )
    child1.link_to_parent(product, variables={"color": "red"})
    child2.link_to_parent(product, variables={"color": "blue"})

    request = apply_request_middleware(rf.get("/"))
    child1_pi = child1.get_price_info(request)
    child2_pi = child1.get_price_info(request)

    def assert_cache_products():
        cache_many_price_info(request, product, 1, [child1_pi, child2_pi])
        assert get_many_cached_price_info(request, product, 1)[0].price == child1_pi.price
        assert get_many_cached_price_info(request, product, 1)[1].price == child2_pi.price

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

    # cache the item
    assert_nothing_is_cached()
    assert_cache_products()

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

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

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

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

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

    # cache bumped - the cache should be dropped - then, cache again
    supplier = shop_product.suppliers.first()
    supplier.enabled = False
    supplier.save()
    assert_nothing_is_cached()
    assert_cache_products()
Esempio n. 26
0
def test_anonymize_contact():
    """
    Test that contact are anonymized
    """
    activate("en")
    shop = factories.get_default_shop()
    anonymizer = Anonymizer()

    customer = factories.create_random_person("en")
    user = factories.create_random_user("en")
    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())

    orders = []
    core_baskets = []
    front_baskets = []

    for basket_customer in [customer, company]:
        orders.extend([factories.create_random_order(basket_customer, [product]) for order in range(3)])

        front_baskets.append(
            StoredBasket.objects.create(
                key=uuid4().hex,
                shop=shop,
                customer=basket_customer,
                orderer=customer,
                creator=customer.user,
                currency=shop.currency,
                data={"items": []},
                prices_include_tax=shop.prices_include_tax
            )
        )
        core_baskets.append(
            Basket.objects.create(
                key=uuid4().hex,
                shop=shop,
                customer=basket_customer,
                orderer=customer,
                creator=customer.user,
                currency=shop.currency,
                data={"items": []},
                prices_include_tax=shop.prices_include_tax
            )
        )

    anonymized_person = PersonContact.objects.get(id=customer.id)
    anonymizer.anonymize_person(anonymized_person)
    anonymized_person.refresh_from_db()
    assert anonymized_person.first_name != customer.first_name
    assert anonymized_person.last_name != customer.last_name
    assert anonymized_person.email != customer.email
    assert anonymized_person.phone != customer.phone
    assert anonymized_person.default_billing_address.street != customer.default_billing_address.street
    assert anonymized_person.default_billing_address.city != customer.default_billing_address.city

    anonymized_company = CompanyContact.objects.get(id=company.id)
    anonymizer.anonymize_company(anonymized_company)
    anonymized_company.refresh_from_db()
    assert anonymized_company.tax_number != company.tax_number
    assert anonymized_company.email != company.email
    assert anonymized_company.phone != company.phone
    assert anonymized_company.default_billing_address.street != company.default_billing_address.street
    assert anonymized_company.default_billing_address.city != company.default_billing_address.city

    for created_order in orders:
        order = Order.objects.get(id=created_order.id)
        assert order.phone != created_order.phone
        assert order.ip_address != created_order.ip_address
        assert order.shipping_address.street != created_order.shipping_address.street
        assert order.billing_address.street != created_order.billing_address.street

    for front_basket in front_baskets:
        stored_basket = StoredBasket.objects.get(id=front_basket.id)
        assert stored_basket.data is None

    for core_basket in core_baskets:
        basket = Basket.objects.get(id=core_basket.id)
        assert basket.data is None

    anonymized_user = get_user_model().objects.get(id=user.id)
    anonymizer.anonymize_user(anonymized_user)
    anonymized_user.refresh_from_db()
    assert user.username != anonymized_user.username
    assert user.first_name != anonymized_user.first_name
    assert user.last_name != anonymized_user.last_name
Esempio n. 27
0
def test_serialize_data():
    """
    Test that contact data is serialized
    """
    activate("en")
    shop = factories.get_default_shop()

    customer = factories.create_random_person("en")
    user = factories.create_random_user("en")
    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())

    orders = []
    core_baskets = []
    front_baskets = []

    for basket_customer in [customer, company]:
        orders.extend([factories.create_random_order(basket_customer, [product]) for order in range(3)])

        front_baskets.append(
            StoredBasket.objects.create(
                key=uuid4().hex,
                shop=shop,
                customer=basket_customer,
                orderer=customer,
                creator=customer.user,
                currency=shop.currency,
                data={"items": []},
                prices_include_tax=shop.prices_include_tax
            )
        )
        core_baskets.append(
            Basket.objects.create(
                key=uuid4().hex,
                shop=shop,
                customer=basket_customer,
                orderer=customer,
                creator=customer.user,
                currency=shop.currency,
                data={"items": []},
                prices_include_tax=shop.prices_include_tax
            )
        )

    person_data = GDPRPersonContactSerializer(customer).data
    assert person_data["name"] == customer.name
    assert person_data["phone"] == customer.phone
    assert person_data["default_billing_address"]["street"] == customer.default_billing_address.street
    assert person_data["default_shipping_address"]["street"] == customer.default_shipping_address.street
    assert person_data["user"]["id"] == customer.user.id
    assert person_data["user"]["username"] == customer.user.username
    assert person_data["company_memberships"][0]["name"] == company.name
    assert person_data["company_memberships"][0]["id"] == company.id
    assert len(person_data["orders"]) == 3
    assert len(person_data["saved_baskets"]) == 1
    assert len(person_data["baskets"]) == 1
Esempio n. 28
0
def test_bump_caches_signal(rf):
    """
    Test that prices are bumped when discount objects changes
    """
    initial_price = 10
    discounted_price = 5

    shop1 = factories.get_default_shop()
    shop2 = factories.get_shop(identifier="shop2", domain="shop2")

    product1 = factories.create_product(
        "product",
        shop=shop1,
        supplier=factories.get_default_supplier(),
        default_price=initial_price
    )

    product2 = factories.create_product(
        "product2",
        shop=shop2,
        supplier=factories.get_default_supplier(),
        default_price=20
    )

    now = datetime(2018, 1, 1, 9, 0, tzinfo=pytz.UTC)   # 01/01/2018 09:00 AM

    with patch("django.utils.timezone.now", new=lambda: now):
        discount = Discount.objects.create(
            name="discount",
            active=True,
            start_datetime=now-timedelta(days=10),
            end_datetime=now+timedelta(days=10),
            discounted_price_value=discounted_price
        )

        request = apply_request_middleware(rf.get("/"))
        request_shop2 = apply_request_middleware(rf.get("/", HTTP_HOST=shop2.domain))

        def assert_cache_product1(discounted=False):
            cache_price_info(request, product1, 1, product1.get_price_info(request))
            if discounted:
                assert get_cached_price_info(request, product1, 1).price == shop1.create_price(discounted_price)
            else:
                assert get_cached_price_info(request, product1, 1).price == shop1.create_price(initial_price)

        def assert_product1_is_not_cached():
            assert get_cached_price_info(request, product1) is None

        def assert_product2_is_cached():
            assert get_cached_price_info(request_shop2, product2) is not None

        assert_product1_is_not_cached()
        assert_cache_product1()

        # cache bumped - the cache should be dropped - then, cache again
        discount.save()
        assert_product1_is_not_cached()
        assert_cache_product1()

        discount.shops.add(shop1)
        assert_product1_is_not_cached()
        assert_cache_product1(True)

        # cache product 2.. from now on, shop2 cache should never be bumped
        cache_price_info(request_shop2, product2, 1, product2.get_price_info(request_shop2))
        assert_product2_is_cached()

        discount.product = product1
        discount.save()

        assert_product1_is_not_cached()
        assert_cache_product1(True)
        assert_product2_is_cached()

        availability_exception = AvailabilityException.objects.create(
            name="ae1",
            start_datetime=now+timedelta(days=20),
            end_datetime=now+timedelta(days=30),
        )
        availability_exception.discounts.add(discount)
        assert_product1_is_not_cached()
        assert_cache_product1(True)
        assert_product2_is_cached()

        availability_exception.save()
        assert_product1_is_not_cached()
        assert_cache_product1(True)
        assert_product2_is_cached()

        happy_hour = HappyHour.objects.create(name="hh 1")
        happy_hour.discounts.add(discount)
        assert_product1_is_not_cached()
        assert_cache_product1(True)
        assert_product2_is_cached()

        happy_hour.save()
        assert_product1_is_not_cached()
        assert_cache_product1(True)
        assert_product2_is_cached()

        time_range = TimeRange.objects.create(
            happy_hour=happy_hour,
            from_hour=(now - timedelta(hours=1)).time(),
            to_hour=(now + timedelta(hours=1)).time(),
            weekday=now.weekday()
        )
        assert_product1_is_not_cached()
        assert_cache_product1(True)
        assert_product2_is_cached()

        time_range.save()
        assert_product1_is_not_cached()
        assert_cache_product1(True)
        assert_product2_is_cached()

        time_range.delete()
        assert_product1_is_not_cached()
        assert_cache_product1(True)
        assert_product2_is_cached()

        with pytest.raises(DiscountM2MChangeError):
            handle_generic_m2m_changed("test", time_range)
def test_catalog_campaign_sync():
    shop = factories.get_default_shop()
    supplier = factories.get_default_supplier()
    default_price = 100
    product1 = factories.create_product("test1", shop=shop, supplier=supplier, default_price=default_price)
    product2 = factories.create_product("test2", shop=shop, supplier=supplier, default_price=default_price)
    product3 = factories.create_product("test3", shop=shop, supplier=supplier, default_price=default_price)
    category = factories.get_default_category()
    shop_product = product1.get_shop_instance(shop)
    shop_product.primary_category = category
    shop_product.save()
    shop_product.categories.add(category)

    contact1 = factories.create_random_person()

    contact2 = factories.create_random_person()
    contact_group = factories.get_default_customer_group()
    contact2.groups.add(contact_group)

    happy_hour1_weekdays = "0,1"  # Mon, Tue
    happy_hour1_start = datetime.time(21)
    happy_hour1_end = datetime.time(3)
    happy_hour1_condition = HourCondition.objects.create(
        days=happy_hour1_weekdays, hour_start=happy_hour1_start, hour_end=happy_hour1_end)

    happy_hour2_weekdays = "2,6"  # Wed, Sun
    happy_hour2_start = datetime.time(14)
    happy_hour2_end = datetime.time(16)
    happy_hour2_condition = HourCondition.objects.create(
        days=happy_hour2_weekdays, hour_start=happy_hour2_start, hour_end=happy_hour2_end)

    discount_amount_value = 50
    discount_percentage = decimal.Decimal("0.35")
    _create_catalog_campaign_for_products(
        shop, [product1], discount_amount_value, happy_hour1_condition)
    _create_catalog_campaign_for_products(
        shop, [product2, product3], discount_amount_value)
    _create_catalog_campaign_for_category(
        shop, category, discount_percentage)
    _create_catalog_campaign_for_contact(
        shop, product1, contact1, discount_amount_value)
    _create_catalog_campaign_for_contact_group(
        shop, [product1, product2, product3], contact_group, discount_percentage, happy_hour2_condition)

    call_command("import_catalog_campaigns", *[], **{})

    # From first campaign we should get 1 discount with happy hour
    # From second campaign we should get 2 discounts
    # From third campaign we should get 1 discount
    # From fourth campaign we should get also 1 discount
    # From last campaign we should get 3 discounts with happy hour
    assert Discount.objects.count() == 8

    # There should be 2 happy hours in total
    assert HappyHour.objects.count() == 2

    # From first happy hour there should be 4 ranges
    # Mon 21-23, Tue 0-3, Tue 21-23, Wed 0-3
    # From second happy hour there should be 2 ranges
    # Wed 14-16 and Sun 14-16
    assert TimeRange.objects.count() == 6

    # Let's go through all our 8 discounts to make sure all is good
    first_discount = Discount.objects.filter(
        product=product1, category__isnull=True, contact__isnull=True, contact_group__isnull=True).first()
    assert first_discount.happy_hours.count() == 1
    assert first_discount.discount_amount_value == discount_amount_value

    second_discount = Discount.objects.filter(
        product=product2, category__isnull=True, contact__isnull=True, contact_group__isnull=True).first()
    assert second_discount.happy_hours.count() == 0
    assert second_discount.discount_amount_value == discount_amount_value

    third_discount = Discount.objects.filter(
        product=product3, category__isnull=True, contact__isnull=True, contact_group__isnull=True).first()
    assert third_discount.happy_hours.count() == 0
    assert third_discount.discount_amount_value == discount_amount_value

    category_discount = Discount.objects.filter(
        product__isnull=True, category=category, contact__isnull=True, contact_group__isnull=True).first()
    assert category_discount.happy_hours.count() == 0
    assert category_discount.discount_percentage == discount_percentage

    contact_discount = Discount.objects.filter(
        product=product1, category__isnull=True, contact=contact1, contact_group__isnull=True).first()
    assert contact_discount.discount_amount_value == discount_amount_value

    product1_contact_group_discount = Discount.objects.filter(
        product=product1, category__isnull=True, contact__isnull=True, contact_group=contact_group).first()
    assert product1_contact_group_discount.happy_hours.count() == 1
    assert product1_contact_group_discount.discount_percentage == discount_percentage

    product2_contact_group_discount = Discount.objects.filter(
        product=product2, category__isnull=True, contact__isnull=True, contact_group=contact_group).first()
    assert product2_contact_group_discount.happy_hours.count() == 1
    assert product2_contact_group_discount.discount_percentage == discount_percentage

    product3_contact_group_discount = Discount.objects.filter(
        product=product3, category__isnull=True, contact__isnull=True, contact_group=contact_group).first()
    assert product3_contact_group_discount.happy_hours.count() == 1
    assert product3_contact_group_discount.discount_percentage == discount_percentage