def second_category_sort_with_price_filter(browser, category): set_configuration( category=category, data={ "override_default_configuration": True, "filter_products_by_price": True, "filter_products_by_price_range_min": 5, "filter_products_by_price_range_max": 12, "filter_products_by_price_range_size": 3, }, ) browser.reload() wait_until_condition(browser, lambda x: len(x.find_by_css("#id_price_range option")) == 5) # 5 products and let's filter all products with price less than 5 click_element(browser, "button[data-id='id_price_range']") click_element(browser, "button[data-id='id_price_range'] + .dropdown-menu li[data-original-index='1'] a") # 4 products and let's filter products with price +12 wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 4) click_element(browser, "button[data-id='id_price_range']") click_element(browser, "button[data-id='id_price_range'] + .dropdown-menu li[data-original-index='4'] a") # Now 2 products left and now filter with price 8-11 wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 2) click_element(browser, "button[data-id='id_price_range']") click_element(browser, "button[data-id='id_price_range'] + .dropdown-menu li[data-original-index='3'] a") wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 3)
def test_category_product_filters_2(browser, live_server, settings): cache.clear() # Avoid cache from past tests shop, first_cat, second_cat, third_cat, first_manufacturer = initialize_db() # Activate limit page size changer for the shop set_configuration( shop=shop, data={ "sort_products_by_name": True, "sort_products_by_name_ordering": 1, "sort_products_by_price": True, "sort_products_by_price_ordering": 2, "limit_product_list_page_size": True, }, ) # initialize test and go to front page browser = initialize_front_browser_test(browser, live_server) # check that front page actually loaded wait_until_condition(browser, lambda x: x.is_text_present("Welcome to Default!")) url = reverse("shuup:category", kwargs={"pk": first_cat.pk, "slug": first_cat.slug}) browser.visit("%s%s" % (live_server, url)) wait_until_condition(browser, lambda x: x.is_text_present("First Category")) wait_until_condition(browser, lambda x: x.is_text_present("Sort")) assert not browser.is_text_present("Manufacturers") # Since not in default configuration second_category_sort_test(browser, live_server, shop, second_cat) second_category_sort_with_price_filter(browser, second_cat)
def categories_filter_test(browser, first_cat, second_cat, third_cat): # Add all products in second category to also in first category for shop_product in ShopProduct.objects.filter(primary_category=second_cat): shop_product.categories.add(first_cat) # Add one product including first_cat also to third_cat shop_product = ShopProduct.objects.filter(primary_category=first_cat).last() shop_product.categories.add(third_cat) # Activate categories filter for current category which is the first one set_configuration( category=first_cat, data={ "override_default_configuration": True, "sort_products_by_name": True, "sort_products_by_name_ordering": 1, "sort_products_by_price": True, "sort_products_by_price_ordering": 2, "filter_products_by_category": True, }, ) browser.reload() wait_until_condition(browser, lambda x: x.is_element_present_by_id("categories-%s" % third_cat.id)) browser.execute_script("$('#categories-%s').click();" % third_cat.id) wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 1) browser.execute_script("$('#categories-%s').click();" % second_cat.id) wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 1) browser.execute_script("$('#categories-%s').click();" % third_cat.id) wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 12)
def test_category_product_filters_2(browser, live_server, settings): cache.clear() # Avoid cache from past tests shop, first_cat, second_cat, third_cat, first_manufacturer = initialize_db() # Activate limit page size changer for the shop set_configuration( shop=shop, data={ "sort_products_by_name": True, "sort_products_by_name_ordering": 1, "sort_products_by_price": True, "sort_products_by_price_ordering": 2, "limit_product_list_page_size": True } ) # initialize test and go to front page browser = initialize_front_browser_test(browser, live_server) # check that front page actually loaded wait_until_condition(browser, lambda x: x.is_text_present("Welcome to Default!")) url = reverse("shuup:category", kwargs={"pk": first_cat.pk, "slug": first_cat.slug}) browser.visit("%s%s" % (live_server, url)) wait_until_condition(browser, lambda x: x.is_text_present("First Category")) wait_until_condition(browser, lambda x: x.is_text_present("Sort")) assert not browser.is_text_present("Manufacturers") # Since not in default configuration second_category_sort_test(browser, live_server, shop, second_cat) second_category_sort_with_price_filter(browser, second_cat)
def second_category_sort_test(browser, live_server, shop, category): url = reverse("shuup:category", kwargs={"pk": category.pk, "slug": category.slug}) browser.visit("%s%s" % (live_server, url)) assert not browser.is_text_present("Sort") # Sort shouldn't be available since default configurations wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 12) click_element(browser, "#next_page a") wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 1, timeout=30) click_element(browser, "#previous_page a") wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 12, timeout=30) # Activate limit page size changer set_configuration( shop=shop, data={ "sort_products_by_name": True, "sort_products_by_name_ordering": 1, "sort_products_by_price": True, "sort_products_by_price_ordering": 2, "limit_product_list_page_size": True } ) browser.reload() # Set limit to 24 click_element(browser, "button[data-id='id_limit']") click_element(browser, "button[data-id='id_limit'] + .dropdown-menu li[data-original-index='1'] a") wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 13)
def second_category_sort_with_price_filter(browser, category): set_configuration( category=category, data={ "override_default_configuration": True, "filter_products_by_price": True, "filter_products_by_price_range_min": 5, "filter_products_by_price_range_max": 12, "filter_products_by_price_range_size": 3 } ) browser.reload() wait_until_condition(browser, lambda x: len(x.find_by_css("#id_price_range option")) == 5) # 5 products and let's filter all products with price less than 5 click_element(browser, "button[data-id='id_price_range']") click_element(browser, "button[data-id='id_price_range'] + .dropdown-menu li[data-original-index='1'] a") # 4 products and let's filter products with price +12 wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 4) click_element(browser, "button[data-id='id_price_range']") click_element(browser, "button[data-id='id_price_range'] + .dropdown-menu li[data-original-index='4'] a") # Now 2 products left and now filter with price 8-11 wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 2) click_element(browser, "button[data-id='id_price_range']") click_element(browser, "button[data-id='id_price_range'] + .dropdown-menu li[data-original-index='3'] a") wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 3)
def second_category_sort_test(browser, live_server, shop, category): url = reverse("shuup:category", kwargs={ "pk": category.pk, "slug": category.slug }) browser.visit("%s%s" % (live_server, url)) assert not browser.is_text_present( "Sort") # Sort shouldn't be available since default configurations wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 12) click_element(browser, "#next_page a") wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 1, timeout=30) click_element(browser, "#previous_page a") wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 12, timeout=30) # Activate limit page size changer set_configuration(shop=shop, data={ "sort_products_by_name": True, "sort_products_by_name_ordering": 1, "sort_products_by_price": True, "sort_products_by_price_ordering": 2, "limit_product_list_page_size": True }) browser.reload() wait_until_condition( browser, lambda x: x.is_element_present_by_css("button[data-id='id_limit']")) # Set limit to 24 click_element(browser, "button[data-id='id_limit']") click_element( browser, "button[data-id='id_limit'] + .dropdown-menu li[data-original-index='1'] a" ) wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 13) # Check that visibility change affects the product count shop_products = ShopProduct.objects.filter( primary_category_id=category.id)[:3] for sp in shop_products: sp.visibility = ShopProductVisibility.NOT_VISIBLE sp.save() browser.reload() wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 10) for sp in shop_products: sp.visibility = ShopProductVisibility.ALWAYS_VISIBLE sp.save() browser.reload() wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 13)
def second_category_sort_test(browser, live_server, shop, category): url = reverse("shuup:category", kwargs={"pk": category.pk, "slug": category.slug}) browser.visit("%s%s" % (live_server, url)) assert not browser.is_text_present("Sort") # Sort shouldn't be available since default configurations wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 12) click_element(browser, "#next_page a") wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 1, timeout=30) click_element(browser, "#previous_page a") wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 12, timeout=30) # Activate limit page size changer set_configuration( shop=shop, data={ "sort_products_by_name": True, "sort_products_by_name_ordering": 1, "sort_products_by_price": True, "sort_products_by_price_ordering": 2, "limit_product_list_page_size": True } ) browser.reload() # Set limit to 24 click_element(browser, "button[data-id='id_limit']") click_element(browser, "button[data-id='id_limit'] + .dropdown-menu li[data-original-index='1'] a") wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 13)
def categories_filter_test(browser, first_cat, second_cat, third_cat): # Add all products in second category to also in first category for shop_product in ShopProduct.objects.filter(primary_category=second_cat): shop_product.categories.add(first_cat) # Add one product including first_cat also to third_cat shop_product = ShopProduct.objects.filter(primary_category=first_cat).last() shop_product.categories.add(third_cat) # Activate categories filter for current category which is the first one set_configuration( category=first_cat, data={ "override_default_configuration": True, "sort_products_by_name": True, "sort_products_by_name_ordering": 1, "sort_products_by_price": True, "sort_products_by_price_ordering": 2, "filter_products_by_category": True } ) browser.reload() wait_until_condition(browser, lambda x: x.is_element_present_by_id("categories-%s" % third_cat.id)) browser.execute_script("$('#categories-%s').click();" % third_cat.id) wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 1) browser.execute_script("$('#categories-%s').click();" % second_cat.id) wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 1) browser.execute_script("$('#categories-%s').click();" % third_cat.id) wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 12)
def hide_sorts_for_shop(browser, shop): set_configuration(shop=shop, data={ "sort_products_by_name": False, "sort_products_by_price": False }) browser.reload() assert not browser.is_text_present("Sort")
def test_category_detail_multiselect_supplier_filters(client): shop = factories.get_default_shop() # Activate show supplier info for front assert ThemeSettings.objects.count() == 1 theme_settings = ThemeSettings.objects.first() theme_settings.update_settings({"show_supplier_info": True}) category = factories.get_default_category() # Important! Activate supplier filter. set_configuration( shop=shop, data={ "filter_products_by_supplier": True, "filter_products_by_supplier_ordering": 1, "filter_products_by_supplier_multiselect_enabled": True, }, ) supplier_data = [ ("Johnny Inc", 0.5), ("Mike Inc", 0.9), ("Simon Inc", 0.8), ] for name, percentage_from_original_price in supplier_data: supplier = Supplier.objects.create(name=name) supplier.shops.add(shop) sku = name price_value = 10 product = factories.create_product(sku, shop=shop, default_price=price_value) shop_product = product.get_shop_instance(shop) shop_product.suppliers.add(supplier) shop_product.primary_category = category shop_product.categories.add(category) shop_product.save() supplier_price = percentage_from_original_price * price_value SupplierPrice.objects.create(supplier=supplier, shop=shop, product=product, amount_value=supplier_price) strategy = "shuup.testing.supplier_pricing.supplier_strategy:CheapestSupplierPriceSupplierStrategy" with override_settings(SHUUP_PRICING_MODULE="supplier_pricing", SHUUP_SHOP_PRODUCT_SUPPLIERS_STRATEGY=strategy): with override_current_theme_class(ClassicGrayTheme, shop): # Ensure settings is refreshed from DB johnny_supplier = Supplier.objects.filter(name="Johnny Inc").first() mike_supplier = Supplier.objects.filter(name="Mike Inc").first() simon_supplier = Supplier.objects.filter(name="Simon Inc").first() soup = _get_category_detail_soup_multiselect(client, category, [johnny_supplier.pk]) assert len(soup.findAll("div", {"class": "single-product"})) == 1 soup = _get_category_detail_soup_multiselect(client, category, [johnny_supplier.pk, mike_supplier.pk]) assert len(soup.findAll("div", {"class": "single-product"})) == 2 soup = _get_category_detail_soup_multiselect( client, category, [johnny_supplier.pk, mike_supplier.pk, simon_supplier.pk] ) assert len(soup.findAll("div", {"class": "single-product"})) == 3
def test_category_product_filters_4(browser, live_server, settings): """ Do not show manufacturer option if there is any product """ cache.clear() # Avoid cache from past tests shop, first_cat, second_cat, third_cat, first_manufacturer = initialize_db( ) # remove manufacturers from all products Product.objects.all().update(manufacturer=None) # show manufacturer filter set_configuration( category=first_cat, data={ "override_default_configuration": True, "sort_products_by_name": True, "sort_products_by_name_ordering": 1, "sort_products_by_price": True, "sort_products_by_price_ordering": 2, "filter_products_by_manufacturer": True, }, ) # initialize test and go to front page browser = initialize_front_browser_test(browser, live_server) # check that front page actually loaded wait_until_condition(browser, lambda x: x.is_text_present("Welcome to Default!")) url = reverse("shuup:category", kwargs={ "pk": first_cat.pk, "slug": first_cat.slug }) browser.visit("%s%s" % (live_server, url)) wait_until_condition(browser, lambda x: x.is_text_present("First Category")) wait_until_condition(browser, lambda x: x.is_text_present("Sort")) assert not browser.is_text_present( "Manufacturers") # Since there is no product with manufacturer # add the manufacturer to the last product so the manufacturer filter is show last_product = Product.objects.last() last_product.manufacturer = first_manufacturer last_product.save() browser.visit("%s%s" % (live_server, url)) assert browser.is_text_present("Manufacturers") # set the shop product hidden shop_product = last_product.get_shop_instance(shop) shop_product.visibility = ShopProductVisibility.NOT_VISIBLE shop_product.save() # the manufacturer filter is removed browser.visit("%s%s" % (live_server, url)) assert not browser.is_text_present("Manufacturers")
def hide_sorts_for_shop(browser, shop): set_configuration(shop=shop, data={ "sort_products_by_name": False, "sort_products_by_price": False }) browser.reload() wait_until_condition(browser, lambda x: not x.is_text_present("sort"), timeout=20)
def variations_filter_test(browser, category): wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 1) # Activate categories filter for current category which is the first one set_configuration(category=category, data={ "sort_products_by_name": True, "sort_products_by_name_ordering": 1, "sort_products_by_price": True, "sort_products_by_price_ordering": 2, "filter_products_by_variation_value": True, "filter_products_by_variation_value_ordering": 1 }) browser.reload() wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 3) # Two brown products browser.execute_script("$('#variation_color-brown').click();") wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 2) # Two brown L sized products browser.execute_script("$('#variation_size-l').click();") wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 2) # One brown big browser.execute_script("$('#variation_size-big').click();") browser.execute_script("$('#variation_size-l').click();") wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 1) browser.execute_script( "$('#variation_color-brown').click();") # unselect brown # Two Big or Black products browser.execute_script("$('#variation_color-black').click();") wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 2) browser.execute_script( "$('#variation_color-black').click();") # unselect black # Three Big or Pink products browser.execute_script("$('#variation_color-pink').click();") wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 0) # One pink product browser.execute_script("$('#variation_size-big').click();") wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 1)
def variations_filter_test(browser, category): wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 1) # Activate categories filter for current category which is the first one set_configuration( category=category, data={ "override_default_configuration": True, "sort_products_by_name": True, "sort_products_by_name_ordering": 1, "sort_products_by_price": True, "sort_products_by_price_ordering": 2, "filter_products_by_variation_value": True, "filter_products_by_variation_value_ordering": 1 } ) def get_var_id(value): return value.replace(" ", "*") browser.reload() wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 3) # Two brown products browser.execute_script("$('#variation_color-%s').click();" % get_var_id("Brown")) wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 2) # Two brown L sized products browser.execute_script("$('#variation_size-%s').click();" % get_var_id("L")) wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 2) # One brown big browser.execute_script("$('#variation_size-%s').click();" % get_var_id("Big")) browser.execute_script("$('#variation_size-%s').click();" % get_var_id("L")) wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 1) browser.execute_script("$('#variation_color-%s').click();" % get_var_id("Brown")) # unselect brown # Two Big or Black products browser.execute_script("$('#variation_color-%s').click();"% get_var_id("Black")) wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 2) browser.execute_script("$('#variation_color-%s').click();" % get_var_id("Black")) # unselect black # Three Big or Pink products browser.execute_script("$('#variation_color-%s').click();" % get_var_id("Pink")) wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 0) # One pink product browser.execute_script("$('#variation_size-%s').click();" % get_var_id("Big")) browser.execute_script("$('#variation_size-%s').click();" % get_var_id("Brown")) wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 1)
def variations_filter_test(browser, category): wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 1) # Activate categories filter for current category which is the first one set_configuration( category=category, data={ "override_default_configuration": True, "sort_products_by_name": True, "sort_products_by_name_ordering": 1, "sort_products_by_price": True, "sort_products_by_price_ordering": 2, "filter_products_by_variation_value": True, "filter_products_by_variation_value_ordering": 1, }, ) def get_var_id(value): return value.replace(" ", "*") browser.reload() wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 3) # Two brown products browser.execute_script("$('#variation_color-%s').click();" % get_var_id("Brown")) wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 2) # Two brown L sized products browser.execute_script("$('#variation_size-%s').click();" % get_var_id("L")) wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 2) # One brown big browser.execute_script("$('#variation_size-%s').click();" % get_var_id("Big")) browser.execute_script("$('#variation_size-%s').click();" % get_var_id("L")) wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 1) browser.execute_script("$('#variation_color-%s').click();" % get_var_id("Brown")) # unselect brown # Two Big or Black products browser.execute_script("$('#variation_color-%s').click();" % get_var_id("Black")) wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 2) browser.execute_script("$('#variation_color-%s').click();" % get_var_id("Black")) # unselect black # Three Big or Pink products browser.execute_script("$('#variation_color-%s').click();" % get_var_id("Pink")) wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 0) # One pink product browser.execute_script("$('#variation_size-%s').click();" % get_var_id("Big")) browser.execute_script("$('#variation_size-%s').click();" % get_var_id("Brown")) wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 1)
def test_category_filter(reindex_catalog): 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) reindex_catalog() client = SmartClient() config = {"filter_products_by_category": True} set_configuration(shop=shop, data=config) url = reverse("shuup: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_suppliers_filter_get_fields(rf): cache.clear() shop = factories.get_default_shop() request = apply_request_middleware(rf.get("/")) assert SupplierProductListFilter().get_fields(request, None) is None supplier = Supplier.objects.create(name="Favorite brands dot com") supplier.shops.add(shop) assert Supplier.objects.enabled().exists() assert SupplierProductListFilter().get_fields(request, None) is None category = factories.get_default_category() product = factories.create_product("sku", shop=shop) shop_product = product.get_shop_instance(shop=shop) shop_product.primary_category = category shop_product.save() assert SupplierProductListFilter().get_fields(request, category) is None # Now once we link supplier to product we should get # form field for manufacturer shop_product.suppliers.add(supplier) form_field = SupplierProductListFilter().get_fields(request, category)[0][1] assert form_field is not None assert form_field.label == "Suppliers" with override_settings( SHUUP_FRONT_OVERRIDE_SORTS_AND_FILTERS_LABELS_LOGIC={ "supplier": "Filter by suppliers" }): form_field = SupplierProductListFilter().get_fields(request, category)[0][1] assert form_field is not None assert form_field.label == "Filter by suppliers" assert isinstance(form_field, forms.ModelChoiceField) configuration = get_configuration(shop, category) configuration.update( {SupplierProductListFilter.enable_multiselect_key: True}) set_configuration(shop, category, configuration) form_field = SupplierProductListFilter().get_fields(request, category)[0][1] assert form_field is not None assert form_field.label == "Filter by suppliers" assert isinstance(form_field, CommaSeparatedListField) cache.clear()
def test_category_product_filters_4(browser, live_server, settings): """ Do not show manufacturer option if there is any product """ cache.clear() # Avoid cache from past tests shop, first_cat, second_cat, third_cat, first_manufacturer = initialize_db() # remove manufacturers from all products Product.objects.all().update(manufacturer=None) # show manufacturer filter set_configuration( category=first_cat, data={ "override_default_configuration": True, "sort_products_by_name": True, "sort_products_by_name_ordering": 1, "sort_products_by_price": True, "sort_products_by_price_ordering": 2, "filter_products_by_manufacturer": True } ) # initialize test and go to front page browser = initialize_front_browser_test(browser, live_server) # check that front page actually loaded wait_until_condition(browser, lambda x: x.is_text_present("Welcome to Default!")) url = reverse("shuup:category", kwargs={"pk": first_cat.pk, "slug": first_cat.slug}) browser.visit("%s%s" % (live_server, url)) wait_until_condition(browser, lambda x: x.is_text_present("First Category")) wait_until_condition(browser, lambda x: x.is_text_present("Sort")) assert not browser.is_text_present("Manufacturers") # Since there is no product with manufacturer # add the manufacturer to the last product so the manufacturer filter is show last_product = Product.objects.last() last_product.manufacturer = first_manufacturer last_product.save() browser.visit("%s%s" % (live_server, url)) assert browser.is_text_present("Manufacturers") # set the shop product hidden shop_product = last_product.get_shop_instance(shop) shop_product.visibility = ShopProductVisibility.NOT_VISIBLE shop_product.save() # the manufacturer filter is removed browser.visit("%s%s" % (live_server, url)) assert not browser.is_text_present("Manufacturers")
def manufacturer_filter_test(browser, category, manufacturer): wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 3) set_configuration(category=category, data={ "sort_products_by_name": True, "sort_products_by_name_ordering": 1, "sort_products_by_price": True, "sort_products_by_price_ordering": 2, "filter_products_by_manufacturer": True }) browser.reload() wait_until_condition(browser, lambda x: x.is_text_present("Manufacturers")) browser.execute_script("$('#manufacturers-%s').click();" % manufacturer.id) wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 1)
def manufacturer_filter_test(browser, category, manufacturer): wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 3) set_configuration( category=category, data={ "sort_products_by_name": True, "sort_products_by_name_ordering": 1, "sort_products_by_price": True, "sort_products_by_price_ordering": 2, "filter_products_by_manufacturer": True } ) browser.reload() wait_until_condition(browser, lambda x: x.is_text_present("Manufacturers")) browser.execute_script("$('#manufacturers-%s').click();" % manufacturer.id) wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 1)
def variations_filter_test(browser, category): wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 1) # Activate categories filter for current category which is the first one set_configuration( category=category, data={ "sort_products_by_name": True, "sort_products_by_name_ordering": 1, "sort_products_by_price": True, "sort_products_by_price_ordering": 2, "filter_products_by_variation_value": True, "filter_products_by_variation_value_ordering": 1 } ) browser.reload() wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 3) # Two brown products browser.execute_script("$('#variation_color-brown').click();") wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 2) # Two brown L sized products browser.execute_script("$('#variation_size-l').click();") wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 2) # One brown big browser.execute_script("$('#variation_size-big').click();") browser.execute_script("$('#variation_size-l').click();") wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 1) browser.execute_script("$('#variation_color-brown').click();") # unselect brown # Two Big or Black products browser.execute_script("$('#variation_color-black').click();") wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 2) browser.execute_script("$('#variation_color-black').click();") # unselect black # Three Big or Pink products browser.execute_script("$('#variation_color-pink').click();") wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 0) # One pink product browser.execute_script("$('#variation_size-big').click();") wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 1)
def second_category_sort_with_price_filter(browser, category): set_configuration( category=category, data={ "filter_products_by_price": True, "filter_products_by_price_range_min": 5, "filter_products_by_price_range_max": 12, "filter_products_by_price_range_size": 3 } ) browser.reload() wait_until_condition(browser, lambda x: len(x.find_by_css("#id_price_range option")) == 5) browser.select("price_range", "-5") wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 4) browser.select("price_range", "12-") wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 2) browser.select("price_range", "8-11") wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 3)
def second_category_sort_with_price_filter(browser, category): set_configuration( category=category, data={ "filter_products_by_price": True, "filter_products_by_price_range_min": 5, "filter_products_by_price_range_max": 12, "filter_products_by_price_range_size": 3 } ) browser.reload() wait_until_condition(browser, lambda x: len(x.find_by_css("#id_price_range option")) == 5) browser.select("price_range", "-5") wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 4) browser.select("price_range", "12-") wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 2) browser.select("price_range", "8-11") wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 3)
def second_category_sort_test(browser, live_server, shop, category): url = reverse("shuup:category", kwargs={"pk": category.pk, "slug": category.slug}) browser.visit("%s%s" % (live_server, url)) assert not browser.is_text_present("Sort") # Sort shouldn't be available since default configurations wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 12) click_element(browser, "#next_page a") wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 1, timeout=30) click_element(browser, "#previous_page a") wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 12, timeout=30) # Activate limit page size changer set_configuration( shop=shop, data={ "sort_products_by_name": True, "sort_products_by_name_ordering": 1, "sort_products_by_price": True, "sort_products_by_price_ordering": 2, "limit_product_list_page_size": True } ) browser.reload() wait_until_condition(browser, lambda x: x.is_element_present_by_css("button[data-id='id_limit']")) # Set limit to 24 click_element(browser, "button[data-id='id_limit']") click_element(browser, "button[data-id='id_limit'] + .dropdown-menu li[data-original-index='1'] a") wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 13) # Check that visibility change affects the product count shop_products = ShopProduct.objects.filter(primary_category_id=category.id)[:3] for sp in shop_products: sp.visibility = ShopProductVisibility.NOT_VISIBLE sp.save() browser.reload() wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 10) for sp in shop_products: sp.visibility = ShopProductVisibility.ALWAYS_VISIBLE sp.save() browser.reload() wait_until_condition(browser, lambda x: len(x.find_by_css(".product-card")) == 13)
def show_sorts_for_the_category_only(browser, category): set_configuration(category=category, data={"sort_products_by_name": True}) browser.reload() wait_until_condition(browser, lambda x: x.is_text_present("Sort")) wait_until_condition(browser, lambda x: len(x.find_by_css("#id_sort option")) == 2) click_element(browser, "button[data-id='id_sort']") set_configuration( category=category, data={ "sort_products_by_name": True, "sort_products_by_name_ordering": 1, "sort_products_by_price": True, "sort_products_by_price_ordering": 2, "sort_products_by_date_created": True, "sort_products_by_date_created_ordering": 3 } ) browser.reload() wait_until_condition(browser, lambda x: len(x.find_by_css("#id_sort option")) == 5)
def show_sorts_for_the_category_only(browser, category): set_configuration(category=category, data={"sort_products_by_name": True}) browser.reload() wait_until_condition(browser, lambda x: x.is_text_present("Sort")) wait_until_condition(browser, lambda x: len(x.find_by_css("#id_sort option")) == 2) click_element(browser, "button[data-id='id_sort']") set_configuration(category=category, data={ "sort_products_by_name": True, "sort_products_by_name_ordering": 1, "sort_products_by_price": True, "sort_products_by_price_ordering": 2, "sort_products_by_date_created": True, "sort_products_by_date_created_ordering": 3 }) browser.reload() wait_until_condition(browser, lambda x: len(x.find_by_css("#id_sort option")) == 5)
def test_product_price_range_filter(): shop = factories.get_default_shop() product = factories.get_default_product() category = factories.get_default_category() shop_product = product.get_shop_instance(shop) shop_product.default_price_value = 10 shop_product.categories.add(category) shop_product.save() client = SmartClient() config = { "filter_products_by_price": True, "filter_products_by_price_range_min": 5, "filter_products_by_price_range_max": 15, "filter_products_by_price_range_size": 5 } set_configuration(category=category, data=config) url = reverse('shuup:category', kwargs={'pk': category.pk, 'slug': category.slug}) response, soup = client.response_and_soup(url) assert response.status_code == 200 assert soup.find(id="product-%d" % product.id) price_range_select = soup.find(id="id_price_range") # as the configuration is not set to override shop default configuration # this field shouldn't be there.. assert price_range_select is None # make the category configuration override the shop's default config config.update({"override_default_configuration": True}) set_configuration(category=category, data=config) url = reverse('shuup:category', kwargs={'pk': category.pk, 'slug': category.slug}) response, soup = client.response_and_soup(url) assert response.status_code == 200 assert soup.find(id="product-%d" % product.id) price_range_select = soup.find(id="id_price_range") price_ranges = price_range_select.find_all("option") assert len(price_ranges) == 4 # filter products with prices above $15 filtered_url = "{}?price_range={}".format(url, price_ranges[-1].attrs["value"]) response, soup = client.response_and_soup(filtered_url) assert response.status_code == 200 assert not soup.find(id="product-%d" % product.id) # explicitly disable the override config.update({"override_default_configuration": False}) set_configuration(category=category, data=config) url = reverse('shuup:category', kwargs={'pk': category.pk, 'slug': category.slug}) response, soup = client.response_and_soup(url) assert response.status_code == 200 assert soup.find(id="product-%d" % product.id) price_range_select = soup.find(id="id_price_range") assert price_range_select is None
def test_product_attributes_filter(reindex_catalog): shop = factories.get_default_shop() category1 = Category.objects.create(name="Category 1") category1.shops.add(shop) product_type = ProductType.objects.create(name="Default Product Type") options_attribute = create_attribute_with_options("attribute1", ["A", "B", "C"], 1, 3) product_type.attributes.add(options_attribute) choices = list( options_attribute.choices.all().order_by("translations__name")) option_a, option_b, option_c = choices product1 = factories.create_product("p1", shop, factories.get_default_supplier(), "10", type=product_type) shop_product1 = product1.get_shop_instance(shop) shop_product1.categories.add(category1) product1.set_attribute_value("attribute1", [option_a.pk, option_c.pk]) product2 = factories.create_product("p2", shop, factories.get_default_supplier(), "10", type=product_type) shop_product2 = product2.get_shop_instance(shop) shop_product2.categories.add(category1) product2.set_attribute_value("attribute1", [option_c.pk]) reindex_catalog() client = SmartClient() config = { "filter_products_by_products_attribute": True, "override_default_configuration": True } set_configuration(category=category1, data=config) url = reverse("shuup:category", kwargs={ "pk": category1.pk, "slug": category1.slug }) filtered_url = "{}?attribute1={}".format(url, option_c.pk) response, soup = client.response_and_soup(filtered_url) assert response.status_code == 200 assert soup.find(id="product-%d" % product1.id) assert soup.find(id="product-%d" % product2.id) url = reverse("shuup:category", kwargs={ "pk": category1.pk, "slug": category1.slug }) filtered_url = "{}?attribute1={}".format(url, option_a.pk) response, soup = client.response_and_soup(filtered_url) assert response.status_code == 200 assert soup.find(id="product-%d" % product1.id) assert not soup.find(id="product-%d" % product2.id) url = reverse("shuup:category", kwargs={ "pk": category1.pk, "slug": category1.slug }) filtered_url = "{}?attribute1={}".format(url, option_b.pk) response, soup = client.response_and_soup(filtered_url) assert response.status_code == 200 assert not soup.find(id="product-%d" % product1.id) assert not soup.find(id="product-%d" % product2.id) # Check category setting doesn't override config = { "filter_products_by_products_attribute": True, "override_default_configuration": False } set_configuration(category=category1, data=config) url = reverse("shuup:category", kwargs={ "pk": category1.pk, "slug": category1.slug }) filtered_url = "{}?attribute1={}".format(url, option_a.pk) response, soup = client.response_and_soup(filtered_url) assert response.status_code == 200 assert soup.find(id="product-%d" % product2.id) # Check shop setting is working config = { "filter_products_by_products_attribute": True, } set_configuration(shop=shop, data=config) url = reverse("shuup:category", kwargs={ "pk": category1.pk, "slug": category1.slug }) filtered_url = "{}?attribute1={}".format(url, option_a.pk) response, soup = client.response_and_soup(filtered_url) assert response.status_code == 200 assert not soup.find(id="product-%d" % product2.id)
def test_category_detail(client): shop = factories.get_default_shop() # Activate show supplier info for front assert ThemeSettings.objects.count() == 1 theme_settings = ThemeSettings.objects.first() theme_settings.update_settings({"show_supplier_info": True}) # Activate supplier filters to prove they don't effect results # without actually filtering something. There is separate tests # to do the more closer tests. set_configuration( shop=shop, data={ "filter_products_by_supplier": True, "filter_products_by_supplier_ordering": 1, } ) category = factories.get_default_category() product_data = [ ("laptop", 1500), ("keyboard", 150), ("mouse", 150) ] products = [] for sku, price_value in product_data: products.append(factories.create_product(sku, shop=shop, default_price=price_value)) supplier_data = [ ("Johnny Inc", 0.5), ("Mike Inc", 0.9), ("Simon Inc", 0.8), ] for name, percentage_from_original_price in supplier_data: supplier = Supplier.objects.create(name=name) for product in products: shop_product = product.get_shop_instance(shop) shop_product.suppliers.add(supplier) shop_product.primary_category = category shop_product.save() supplier_price = ( percentage_from_original_price * [price for sku, price in product_data if product.sku == sku][0]) SupplierPrice.objects.create(supplier=supplier, shop=shop, product=product, amount_value=supplier_price) strategy = "shuup.testing.supplier_pricing.supplier_strategy:CheapestSupplierPriceSupplierStrategy" with override_settings(SHUUP_PRICING_MODULE="supplier_pricing", SHUUP_SHOP_PRODUCT_SUPPLIERS_STRATEGY=strategy): with override_current_theme_class(ClassicGrayTheme, shop): # Ensure settings is refreshed from DB soup = _get_category_detail_soup(client, category) # Johnny Inc has the best prices for everything laptop = [product for product in products if product.sku == "laptop"][0] laptop_product_box = soup.find("div", {"id": "product-%s" % laptop.pk}) _assert_supplier_info(laptop_product_box, "Johnny Inc") _assert_product_price(laptop_product_box, 750) keyboard = [product for product in products if product.sku == "keyboard"][0] keyboard_product_box = soup.find("div", {"id": "product-%s" % keyboard.pk}) _assert_supplier_info(keyboard_product_box, "Johnny Inc") _assert_product_price(keyboard_product_box, 75) mouse = [product for product in products if product.sku == "mouse"][0] mouse_product_box = soup.find("div", {"id": "product-%s" % mouse.pk}) _assert_supplier_info(mouse_product_box, "Johnny Inc") _assert_product_price(mouse_product_box, 75) # Ok competition has done it job and the other suppliers # has to start adjust their prices. # Let's say Mike has the cheapest laptop mike_supplier = Supplier.objects.filter(name="Mike Inc") SupplierPrice.objects.filter(supplier=mike_supplier, shop=shop, product=laptop).update(amount_value=333) soup = _get_category_detail_soup(client, category) laptop_product_box = soup.find("div", {"id": "product-%s" % laptop.pk}) _assert_supplier_info(laptop_product_box, "Mike Inc") _assert_product_price(laptop_product_box, 333) # Just to make sure Simon takes over the mouse biz simon_supplier = Supplier.objects.filter(name="Simon Inc") SupplierPrice.objects.filter(supplier=simon_supplier, shop=shop, product=mouse).update(amount_value=1) soup = _get_category_detail_soup(client, category) mouse_product_box = soup.find("div", {"id": "product-%s" % mouse.pk}) _assert_supplier_info(mouse_product_box, "Simon Inc") _assert_product_price(mouse_product_box, 1)
def hide_sorts_for_shop(browser, shop): set_configuration( shop=shop, data={"sort_products_by_name": False, "sort_products_by_price": False}) browser.reload() wait_until_condition(browser, lambda x: not x.is_text_present("sort"), timeout=20)
def form_valid(self, form): if self.name in form.forms and form[self.name].has_changed(): set_configuration(shop=self.object, data=form[self.name].cleaned_data)
def test_category_detail_filters(client): shop = factories.get_default_shop() # Activate show supplier info for front assert ThemeSettings.objects.count() == 1 theme_settings = ThemeSettings.objects.first() theme_settings.update_settings({"show_supplier_info": True}) category = factories.get_default_category() # Important! Activate supplier filter. set_configuration( shop=shop, data={ "filter_products_by_supplier": True, "filter_products_by_supplier_ordering": 1, } ) product_data = [ ("laptop", 1500), ("keyboard", 150), ("mouse", 150) ] products = [] for sku, price_value in product_data: products.append(factories.create_product(sku, shop=shop, default_price=price_value)) supplier_data = [ ("Johnny Inc", 0.5), ("Mike Inc", 0.9), ("Simon Inc", 0.8), ] for name, percentage_from_original_price in supplier_data: supplier = Supplier.objects.create(name=name) supplier.shops.add(shop) for product in products: shop_product = product.get_shop_instance(shop) shop_product.suppliers.add(supplier) shop_product.primary_category = category shop_product.categories.add(category) shop_product.save() supplier_price = ( percentage_from_original_price * [price for sku, price in product_data if product.sku == sku][0]) SupplierPrice.objects.create(supplier=supplier, shop=shop, product=product, amount_value=supplier_price) strategy = "shuup.testing.supplier_pricing.supplier_strategy:CheapestSupplierPriceSupplierStrategy" with override_settings(SHUUP_PRICING_MODULE="supplier_pricing", SHUUP_SHOP_PRODUCT_SUPPLIERS_STRATEGY=strategy): with override_current_theme_class(ClassicGrayTheme, shop): # Ensure settings is refreshed from DB laptop = [product for product in products if product.sku == "laptop"][0] keyboard = [product for product in products if product.sku == "keyboard"][0] mouse = [product for product in products if product.sku == "mouse"][0] # Let's get products for Johnny supplier_johnny = Supplier.objects.filter(name="Johnny Inc").first() soup = _get_category_detail_soup(client, category, supplier_johnny.pk) laptop_product_box = soup.find("div", {"id": "product-%s" % laptop.pk}) _assert_supplier_info(laptop_product_box, "Johnny Inc") _assert_product_price(laptop_product_box, 750) # Now here when the category view is filtered based on supplier # the product urls should lead to supplier product url so we # can show details and prices for correct supplier. _assert_product_url(laptop_product_box, supplier_johnny, laptop) # Let's test rest of the products and suppliers keyboard_product_box = soup.find("div", {"id": "product-%s" % keyboard.pk}) _assert_supplier_info(keyboard_product_box, "Johnny Inc") _assert_product_price(keyboard_product_box, 75) _assert_product_url(keyboard_product_box, supplier_johnny, keyboard) mike_supplier = Supplier.objects.filter(name="Mike Inc").first() soup = _get_category_detail_soup(client, category, mike_supplier.pk) keyboard_product_box = soup.find("div", {"id": "product-%s" % keyboard.pk}) _assert_supplier_info(keyboard_product_box, "Mike Inc") _assert_product_price(keyboard_product_box, 135) _assert_product_url(keyboard_product_box, mike_supplier, keyboard) simon_supplier = Supplier.objects.filter(name="Simon Inc").first() soup = _get_category_detail_soup(client, category, simon_supplier.pk) mouse_product_box = soup.find("div", {"id": "product-%s" % mouse.pk}) _assert_supplier_info(mouse_product_box, "Simon Inc") _assert_product_price(mouse_product_box, 120) _assert_product_url(mouse_product_box, simon_supplier, mouse)
def test_category_detail_filters(client): shop = factories.get_default_shop() # Activate show supplier info for front assert ThemeSettings.objects.count() == 1 theme_settings = ThemeSettings.objects.first() theme_settings.update_settings({"show_supplier_info": True}) category = factories.get_default_category() # Important! Activate supplier filter. set_configuration( shop=shop, data={ "filter_products_by_supplier": True, "filter_products_by_supplier_ordering": 1, }, ) product_data = [("laptop", 1500), ("keyboard", 150), ("mouse", 150)] products = [] for sku, price_value in product_data: products.append(factories.create_product(sku, shop=shop, default_price=price_value)) supplier_data = [ ("Johnny Inc", 0.5), ("Mike Inc", 0.9), ("Simon Inc", 0.8), ] for name, percentage_from_original_price in supplier_data: supplier = Supplier.objects.create(name=name) supplier.shops.add(shop) for product in products: shop_product = product.get_shop_instance(shop) shop_product.suppliers.add(supplier) shop_product.primary_category = category shop_product.categories.add(category) shop_product.save() supplier_price = ( percentage_from_original_price * [price for sku, price in product_data if product.sku == sku][0] ) SupplierPrice.objects.create(supplier=supplier, shop=shop, product=product, amount_value=supplier_price) strategy = "shuup.testing.supplier_pricing.supplier_strategy:CheapestSupplierPriceSupplierStrategy" with override_settings(SHUUP_PRICING_MODULE="supplier_pricing", SHUUP_SHOP_PRODUCT_SUPPLIERS_STRATEGY=strategy): with override_current_theme_class(ClassicGrayTheme, shop): # Ensure settings is refreshed from DB laptop = [product for product in products if product.sku == "laptop"][0] keyboard = [product for product in products if product.sku == "keyboard"][0] mouse = [product for product in products if product.sku == "mouse"][0] # Let's get products for Johnny supplier_johnny = Supplier.objects.filter(name="Johnny Inc").first() soup = _get_category_detail_soup(client, category, supplier_johnny.pk) laptop_product_box = soup.find("div", {"id": "product-%s" % laptop.pk}) _assert_supplier_info(laptop_product_box, "Johnny Inc") _assert_product_price(laptop_product_box, 750) # Now here when the category view is filtered based on supplier # the product urls should lead to supplier product url so we # can show details and prices for correct supplier. _assert_product_url(laptop_product_box, supplier_johnny, laptop) # Let's test rest of the products and suppliers keyboard_product_box = soup.find("div", {"id": "product-%s" % keyboard.pk}) _assert_supplier_info(keyboard_product_box, "Johnny Inc") _assert_product_price(keyboard_product_box, 75) _assert_product_url(keyboard_product_box, supplier_johnny, keyboard) mike_supplier = Supplier.objects.filter(name="Mike Inc").first() soup = _get_category_detail_soup(client, category, mike_supplier.pk) keyboard_product_box = soup.find("div", {"id": "product-%s" % keyboard.pk}) _assert_supplier_info(keyboard_product_box, "Mike Inc") _assert_product_price(keyboard_product_box, 135) _assert_product_url(keyboard_product_box, mike_supplier, keyboard) simon_supplier = Supplier.objects.filter(name="Simon Inc").first() soup = _get_category_detail_soup(client, category, simon_supplier.pk) mouse_product_box = soup.find("div", {"id": "product-%s" % mouse.pk}) _assert_supplier_info(mouse_product_box, "Simon Inc") _assert_product_price(mouse_product_box, 120) _assert_product_url(mouse_product_box, simon_supplier, mouse)
def form_valid(self, form): if self.name in form.forms: set_configuration(category=self.object, data=form[self.name].cleaned_data)