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
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()
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)
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)
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
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)
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 _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
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
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()
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)
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
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)
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
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
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
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)
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))
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
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]
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))
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()
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
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
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