def test_simple_children_formset(): FormSet = formset_factory(SimpleVariationChildForm, SimpleVariationChildFormSet, extra=5, can_delete=True) parent = create_product(printable_gibberish()) child = create_product(printable_gibberish()) # No links yet formset = FormSet(parent_product=parent) assert formset.initial_form_count() == 0 # No children yet # Save a link data = dict(get_form_data(formset, True), **{"form-0-child": child.pk}) formset = FormSet(parent_product=parent, data=data) formset.save() assert parent.variation_children.filter( pk=child.pk).exists() # Got link'd! # Remove the link formset = FormSet(parent_product=parent) assert formset.initial_form_count() == 1 # Got the child here data = dict(get_form_data(formset, True), **{"form-0-DELETE": "1"}) formset = FormSet(parent_product=parent, data=data) formset.save() assert not parent.variation_children.exists() # Got unlinked
def test_mass_edit_orders2(rf, admin_user): shop = get_default_shop() supplier = get_default_supplier() contact1 = create_random_person() product1 = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price="50") product2 = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price="501") order = create_random_order(customer=contact1, products=[product1, product2], completion_probability=0) assert order.status.role != OrderStatusRole.CANCELED payload = { "action": OrderConfirmationPdfAction().identifier, "values": [order.pk] } request = apply_request_middleware(rf.post( "/", user=admin_user, )) request._body = json.dumps(payload).encode("UTF-8") view = OrderListView.as_view() response = view(request=request) assert response.status_code == 200 if weasyprint: assert response[ 'Content-Disposition'] == 'attachment; filename=order_%s_confirmation.pdf' % order.pk else: assert response["content-type"] == "application/json"
def test_mass_edit_products(rf, admin_user): shop = get_default_shop() supplier = get_default_supplier() product1 = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price="50") product2 = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price="501") category = get_default_category() shop_product1 = product1.get_shop_instance(shop) shop_product2 = product2.get_shop_instance(shop) # ensure no categories set assert shop_product1.primary_category is None assert shop_product2.primary_category is None request = apply_request_middleware(rf.post( "/", data={"primary_category": category.pk}), user=admin_user) request.session["mass_action_ids"] = [product1.pk, product2.pk] view = ProductMassEditView.as_view() response = view(request=request) assert response.status_code == 302 for product in Product.objects.all(): assert product.get_shop_instance(shop).primary_category == category
def test_draft_reversion(): view_name = printable_gibberish() shop = get_default_shop() theme = ATestTheme(shop=shop) placeholder_name = "test_ph" vc = ViewConfig(theme=theme, shop=shop, view_name=view_name, draft=True) def get_layout_data(draft): # shorthand -- we're going to be doing this a lot in this test case return ViewConfig(theme=theme, shop=shop, view_name=view_name, draft=draft).saved_view_config.get_layout_data(placeholder_name) data1 = {printable_gibberish(): True} data2 = {printable_gibberish(): True} vc.save_placeholder_layout(placeholder_name, data1) vc.publish() assert get_layout_data(draft=False) == data1 assert get_layout_data(draft=True) == data1 vc = ViewConfig(theme=theme, shop=shop, view_name=view_name, draft=True) svc = vc.saved_view_config assert svc.draft assert svc.get_layout_data(placeholder_name) == data1 # Make changes over the last published version svc.set_layout_data(placeholder_name, data2) svc.save() # Still all good in public? assert get_layout_data(draft=False) == data1 # Still got it in draft? assert get_layout_data(draft=True) == data2 # Actually revert those draft changes now! vc.revert() # So in draft we're back to the published version, right? assert get_layout_data(draft=True) == data1
def test_mass_edit_products2(rf, admin_user): shop = get_default_shop() supplier = get_default_supplier() product1 = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price="50") product2 = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price="501") shop_product1 = product1.get_shop_instance(shop) shop_product2 = product2.get_shop_instance(shop) # ensure no categories set assert shop_product1.primary_category is None assert shop_product2.primary_category is None payload = { "action": InvisibleMassAction().identifier, "values": [product1.pk, product2.pk] } request = apply_request_middleware(rf.post( "/", user=admin_user, )) request._body = json.dumps(payload).encode("UTF-8") view = ProductListView.as_view() response = view(request=request) assert response.status_code == 200 for product in Product.objects.all(): assert product.get_shop_instance( shop).visibility == ShopProductVisibility.NOT_VISIBLE
def test_mass_edit_orders(rf, admin_user): shop = get_default_shop() supplier = get_default_supplier() contact1 = create_random_person() product1 = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price="50") product2 = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price="501") order = create_random_order(customer=contact1, products=[product1, product2], completion_probability=0) assert order.status.role != OrderStatusRole.CANCELED payload = {"action": CancelOrderAction().identifier, "values": [order.pk]} request = apply_request_middleware(rf.post( "/", user=admin_user, )) request._body = json.dumps(payload).encode("UTF-8") view = OrderListView.as_view() response = view(request=request) assert response.status_code == 200 for order in Order.objects.all(): assert order.status.role == OrderStatusRole.CANCELED
def test_basket_free_product_coupon(rf): request, shop, _ = initialize_test(rf, False) basket = get_basket(request) supplier = get_default_supplier() single_product_price = "50" # create basket rule that requires 2 products in basket product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price=single_product_price) basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1) basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1) basket.shipping_method = get_shipping_method(shop=shop) basket.save() second_product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price=single_product_price) rule = BasketTotalProductAmountCondition.objects.create(value="2") coupon = Coupon.objects.create(code="TEST", active=True) campaign = BasketCampaign.objects.create(active=True, shop=shop, name="test", public_name="test", coupon=coupon) campaign.conditions.add(rule) effect = FreeProductLine.objects.create(campaign=campaign) effect.products.add(second_product) basket.add_code(coupon.code) basket.uncache() final_lines = basket.get_final_lines() assert len(final_lines) == 3 line_types = [l.type for l in final_lines] assert OrderLineType.DISCOUNT not in line_types for line in basket.get_final_lines(): assert line.type in [OrderLineType.PRODUCT, OrderLineType.SHIPPING] if line.type == OrderLineType.SHIPPING: continue if line.product != product: assert line.product == second_product
def test_editor_view_commands(): with initialize_editor_view(printable_gibberish(), printable_gibberish()) as view_obj: view_obj.request.method = "POST" view_obj.request.POST = {"command": "add_row"} view_obj._populate_vars() # don't tell anyone we're calling a private method here assert len(view_obj.layout) == 0 view_obj.dispatch(view_obj.request) assert len(view_obj.layout) == 1
def test_deleting_mid_folder(rf, admin_user): folder1 = Folder.objects.create(name=printable_gibberish()) folder2 = Folder.objects.create(name=printable_gibberish(), parent=folder1) folder3 = Folder.objects.create(name=printable_gibberish(), parent=folder2) tree = get_id_tree(mbv_command(admin_user, {"action": "folders"}, "GET")) assert tree[folder1.pk] == {folder2.pk: {folder3.pk: {}}} mbv_command(admin_user, {"action": "delete_folder", "id": folder2.pk}) tree = get_id_tree(mbv_command(admin_user, {"action": "folders"}, "GET")) assert tree[folder1.pk] == {folder3.pk: {}} folder1 = Folder.objects.get(pk=folder1.pk) assert list(folder1.get_children()) == [folder3]
def test_get_folders(rf, admin_user): # Create a structure and retrieve it folder1 = Folder.objects.create(name=printable_gibberish()) folder2 = Folder.objects.create(name=printable_gibberish()) folder3 = Folder.objects.create(name=printable_gibberish()) folder4 = Folder.objects.create(name=printable_gibberish(), parent=folder2) folder5 = Folder.objects.create(name=printable_gibberish(), parent=folder3) tree = get_id_tree(mbv_command(admin_user, {"action": "folders"}, "GET")) assert set((folder1.id, folder2.id, folder3.id)) <= set(tree.keys()) assert folder4.pk in tree[folder2.pk] assert folder5.pk in tree[folder3.pk]
def test_variable_variation_form(): var1 = printable_gibberish() var2 = printable_gibberish() parent = create_product(printable_gibberish()) for a in range(4): for b in range(3): child = create_product(printable_gibberish()) child.link_to_parent(parent, variables={var1: a, var2: b}) assert parent.variation_children.count() == 4 * 3 form = VariableVariationChildrenForm(parent_product=parent) assert len(form.fields) == 12
def test_mass_actions(rf, admin_user): shop = get_default_shop() supplier = get_default_supplier() product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price=50) product2 = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price=50) ids = [product.id, product2.id] request = apply_request_middleware(rf.get("/"), user=admin_user) TestPicotableMassAction().process(request, ids) for product in Product.objects.all(): assert product.cost_center == "test" mass_action_response = TestPicotableFileMassAction().process(request, ids) assert mass_action_response["Content-disposition"] == 'attachment; filename="products.csv"'
def test_productfilter_works(rf): request, shop, group = initialize_test(rf, False) price = shop.create_price product_price = "100" discount_percentage = "0.30" supplier = get_default_supplier() product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price=product_price) shop_product = product.get_shop_instance(shop) # create catalog campaign catalog_filter = ProductFilter.objects.create() catalog_filter.products.add(product) assert catalog_filter.matches(shop_product) catalog_campaign = CatalogCampaign.objects.create(shop=shop, active=True, name="test") catalog_campaign.filters.add(catalog_filter) cdp = ProductDiscountPercentage.objects.create(campaign=catalog_campaign, discount_percentage=discount_percentage) # add product to basket basket = get_basket(request) basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1) basket.shipping_method = get_shipping_method(shop=shop) basket.save() expected_total = price(product_price) - (Decimal(discount_percentage) * price(product_price)) assert basket.total_price == expected_total
def test_order_creator_view_invalid_command(rf, admin_user): get_default_shop() request = apply_request_middleware(rf.get( "/", {"command": printable_gibberish()}), user=admin_user) response = OrderEditView.as_view()(request) assert_contains(response, "unknown command", status_code=400)
def test_missing_plugin_render(): plugin_id = printable_gibberish() cell = LayoutCell(FauxTheme, plugin_identifier=plugin_id) assert not cell.plugin_class assert not cell.instantiate_plugin() assert ("%s?" % plugin_id) in cell.render( None) # Should render a "whut?" comment
def test_basket_orderability_change_shop_product(rf): StoredBasket.objects.all().delete() shop = get_default_shop() supplier = get_default_supplier() product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price=50) request = rf.get("/") request.session = {} request.shop = shop apply_request_middleware(request) basket = get_basket(request) line = basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1, force_new_line=True, extra={"foo": "foo"}) assert len(basket.get_lines()) == 1 assert len(basket.get_unorderable_lines()) == 0 product.get_shop_instance(shop).delete() basket.uncache() assert basket.dirty assert len(basket.get_lines()) == 0 assert len(basket.get_unorderable_lines()) == 1
def test_basket_clearing(rf): StoredBasket.objects.all().delete() shop = get_default_shop() supplier = get_default_supplier() product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price=50) request = rf.get("/") request.session = {} request.shop = shop apply_request_middleware(request) basket = get_basket(request) pm = get_default_payment_method() sm = get_default_shipping_method() basket.shipping_method = sm basket.payment_method = pm basket.save() assert basket.shipping_method assert basket.payment_method basket.clear_all() assert not basket.shipping_method assert not basket.payment_method
def test_percentage_campaign(rf): request, shop, group = initialize_test(rf, False) price = shop.create_price basket = get_basket(request) supplier = get_default_supplier() # create a basket rule that requires at least value of 200 rule = BasketTotalAmountCondition.objects.create(value="200") product_price = "200" discount_percentage = "0.1" expected_discounted_price = price(product_price) - (price(product_price) * Decimal(discount_percentage)) product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price=product_price) basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1) basket.shipping_method = get_shipping_method(shop=shop) campaign = BasketCampaign.objects.create( shop=shop, public_name="test", name="test", active=True) campaign.conditions.add(rule) campaign.save() BasketDiscountPercentage.objects.create(campaign=campaign, discount_percentage=discount_percentage) assert len(basket.get_final_lines()) == 3 assert basket.product_count == 1 assert basket.total_price == expected_discounted_price
def _init_basket_coupon_test(rf, code="TEST"): status = get_initial_order_status() request, shop, group = initialize_test(rf, False) basket = get_basket(request) supplier = get_default_supplier() for x in range(2): product = create_product(printable_gibberish(), shop, supplier=supplier, default_price="50") basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1) basket.shipping_method = get_shipping_method( shop=shop) # For shippable products dc = Coupon.objects.create(code=code, active=True) campaign = BasketCampaign.objects.create(shop=shop, name="test", public_name="test", coupon=dc, active=True) BasketDiscountAmount.objects.create( discount_amount=shop.create_price("20"), campaign=campaign) rule = BasketTotalProductAmountCondition.objects.create(value=2) campaign.conditions.add(rule) campaign.save() return basket, dc, request, status
def test_only_cheapest_price_is_selected(rf): request, shop, group = initialize_test(rf, False) price = shop.create_price basket = get_basket(request) supplier = get_default_supplier() # create a basket rule that requires atleast value of 200 rule = BasketTotalAmountCondition.objects.create(value="200") product_price = "200" discount1 = "10" discount2 = "20" # should be selected product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price=product_price) basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1) basket.shipping_method = get_shipping_method(shop=shop) campaign1 = BasketCampaign.objects.create(shop=shop, public_name="test", name="test", active=True) campaign1.conditions.add(rule) campaign1.save() BasketDiscountAmount.objects.create(discount_amount=discount1, campaign=campaign1) campaign2 = BasketCampaign.objects.create(shop=shop, public_name="test", name="test", active=True) campaign2.conditions.add(rule) campaign2.save() BasketDiscountAmount.objects.create(discount_amount=discount2, campaign=campaign2) assert len(basket.get_final_lines()) == 3 line_types = [l.type for l in basket.get_final_lines()] assert OrderLineType.DISCOUNT in line_types for line in basket.get_final_lines(): if line.type == OrderLineType.DISCOUNT: assert line.discount_amount == price(discount2)
def test_move_file(admin_user): folder1 = Folder.objects.create(name=printable_gibberish()) folder2 = Folder.objects.create(name=printable_gibberish()) file = File.objects.create(folder=folder1) mbv_command(admin_user, { "action": "move_file", "file_id": file.pk, "folder_id": folder2.pk }) assert File.objects.get(pk=file.pk).folder == folder2 mbv_command(admin_user, { "action": "move_file", "file_id": file.pk, "folder_id": 0 }) assert File.objects.get(pk=file.pk).folder is None
def test_get_folder(admin_user): folder1 = Folder.objects.create(name=printable_gibberish()) folder2 = Folder.objects.create(name=printable_gibberish(), parent=folder1) root_resp = mbv_command(admin_user, {"action": "folder"}, "GET") assert any(f["id"] == folder1.pk for f in root_resp["folder"]["folders"]) f1_resp = mbv_command(admin_user, { "action": "folder", "id": folder1.pk }, "GET") assert f1_resp["folder"]["folders"][0]["id"] == folder2.pk assert not f1_resp["folder"]["files"] assert f1_resp["folder"]["name"] == folder1.name assert mbv_command(admin_user, { "action": "folder", "id": -1 }, "GET")["error"]
def test_rename_folder(admin_user): folder = Folder.objects.create(name=printable_gibberish()) mbv_command(admin_user, { "action": "rename_folder", "id": folder.pk, "name": "Space" }) assert Folder.objects.get(pk=folder.pk).name == "Space"
def test_product_category_discount_percentage_greater_then_products( rf, include_tax): # Buy X amount of Y get Z discount from Y request, shop, _ = initialize_test(rf, include_tax) basket = get_basket(request) supplier = get_default_supplier() single_product_price = "50" discount_percentage = Decimal(1.9) # 190% quantity = 2 # the expected discount amount should not be greater than the products expected_discount_amount = basket.create_price( single_product_price) * quantity category = CategoryFactory() # create basket rule that requires 2 products in basket product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price=single_product_price) ShopProduct.objects.get(shop=shop, product=product).categories.add(category) basket.add_product(supplier=supplier, shop=shop, product=product, quantity=quantity) basket.shipping_method = get_shipping_method(shop=shop) basket.save() rule = ProductsInBasketCondition.objects.create(quantity=2) rule.products.add(product) rule.save() campaign = BasketCampaign.objects.create(active=True, shop=shop, name="test", public_name="test") campaign.conditions.add(rule) DiscountFromCategoryProducts.objects.create( campaign=campaign, discount_percentage=discount_percentage, category=category) assert rule.matches(basket, []) basket.uncache() final_lines = basket.get_final_lines() assert len(final_lines ) == 2 # no new lines since the effect touches original lines original_price = basket.create_price(single_product_price) * quantity line = final_lines[0] assert line.discount_amount == expected_discount_amount assert basket.total_price == original_price - expected_discount_amount
def test_basket_campaign_case2(rf): request, shop, group = initialize_test(rf, False) price = shop.create_price basket = get_basket(request) supplier = get_default_supplier() # create a basket rule that requires at least value of 200 rule = BasketTotalAmountCondition.objects.create(value="200") single_product_price = "50" discount_amount_value = "10" unique_shipping_method = get_shipping_method(shop, price=50) for x in range(3): product = create_product( printable_gibberish(), shop=shop, supplier=supplier, default_price=single_product_price) basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1) assert basket.product_count == 3 campaign = BasketCampaign.objects.create( shop=shop, public_name="test", name="test", active=True) campaign.conditions.add(rule) campaign.save() BasketDiscountAmount.objects.create(discount_amount=discount_amount_value, campaign=campaign) assert len(basket.get_final_lines()) == 3 assert basket.total_price == price(single_product_price) * basket.product_count # check that shipping method affects campaign basket.shipping_method = unique_shipping_method basket.save() basket.uncache() assert len(basket.get_final_lines()) == 4 # Shipping should not affect the rule being triggered line_types = [l.type for l in basket.get_final_lines()] assert OrderLineType.DISCOUNT not in line_types product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price=single_product_price) basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1) assert len(basket.get_final_lines()) == 6 # Discount included assert OrderLineType.DISCOUNT in [l.type for l in basket.get_final_lines()]
def create_category_product(category): product = create_product(printable_gibberish(), shop, supplier, single_product_price) product.primary_category = category sp = ShopProduct.objects.get(product=product, shop=shop) sp.primary_category = category sp.categories.add(category) return product
def test_productdiscountamount_with_minimum_price(rf, per_line_discount): # Buy X amount of Y get Z discount from Y request, shop, _ = initialize_test(rf, False) basket = get_basket(request) supplier = get_default_supplier() single_product_price = Decimal("50") single_product_min_price = Decimal("40") discount_amount_value = Decimal("200") # will exceed the minimum price quantity = 2 # create basket rule that requires 2 products in basket product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price=single_product_price) shop_product = ShopProduct.objects.get(product=product, shop=shop) shop_product.minimum_price_value = single_product_min_price shop_product.save() basket.add_product(supplier=supplier, shop=shop, product=product, quantity=quantity) basket.shipping_method = get_shipping_method(shop=shop) basket.save() rule = ProductsInBasketCondition.objects.create(quantity=2) rule.products.add(product) rule.save() campaign = BasketCampaign.objects.create(active=True, shop=shop, name="test", public_name="test") campaign.conditions.add(rule) effect = DiscountFromProduct.objects.create( campaign=campaign, discount_amount=discount_amount_value, per_line_discount=per_line_discount) effect.products.add(product) assert rule.matches(basket, []) basket.uncache() # the discount amount should not exceed the minimum price. as the configued discount # will exceed, it should limit the discount amount final_lines = basket.get_final_lines() expected_discount_amount = basket.create_price( (single_product_price - single_product_min_price) * quantity) original_price = basket.create_price(single_product_price) * quantity line = final_lines[0] assert line.discount_amount == expected_discount_amount assert basket.total_price == original_price - expected_discount_amount
def test_edit_view_with_anonymous_contact(rf, admin_user): shop = get_default_shop() supplier = get_default_supplier() product = create_product(sku=printable_gibberish(), supplier=supplier, shop=shop) order = create_order_with_product(product, supplier, 1, 10, shop=shop) order.save() assert not order.customer request = apply_request_middleware(rf.get("/"), user=admin_user) response = OrderEditView.as_view()(request=request, pk=order.pk) assert response.status_code == 200
def test_basket(rf): StoredBasket.objects.all().delete() quantities = [3, 12, 44, 23, 65] shop = get_default_shop() get_default_payment_method( ) # Can't create baskets without payment methods supplier = get_default_supplier() products_and_quantities = [] for quantity in quantities: product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price=50) products_and_quantities.append((product, quantity)) for product, q in products_and_quantities: request = rf.get("/") request.session = {} request.shop = shop apply_request_middleware(request) basket = get_basket(request) assert basket == request.basket assert basket.product_count == 0 line = basket.add_product(supplier=supplier, shop=shop, product=product, quantity=q) basket.shipping_method = get_shipping_method( shop=shop) # For shippable product assert line.quantity == q assert basket.get_lines() assert basket.get_product_ids_and_quantities().get(product.pk) == q assert basket.product_count == q basket.save() delattr(request, "basket") basket = get_basket(request) assert basket.get_product_ids_and_quantities().get(product.pk) == q product_ids = set(StoredBasket.objects.last().products.values_list( "id", flat=True)) assert product_ids == set([product.pk]) stats = StoredBasket.objects.all().aggregate( n=Sum("product_count"), tfs=Sum("taxful_total_price_value"), tls=Sum("taxless_total_price_value"), ) assert stats["n"] == sum(quantities) if shop.prices_include_tax: assert stats["tfs"] == sum(quantities) * 50 else: assert stats["tls"] == sum(quantities) * 50 basket.finalize()
def get_test_template_bits(request, pass_view=True, **extra_ctx): layout = Layout(FauxTheme, "test") gibberish = printable_gibberish() layout.begin_column({"md": 12, "xs": 0}) layout.add_plugin("text", {"text": "<p>%s</p>" % gibberish}) jeng = get_jinja2_engine() template = jeng.from_string("") template.template.name = "test" vars = {"view": pass_view and FauxView(), "request": request} vars.update(extra_ctx) ctx = template.template.new_context(vars) return (template, layout, gibberish, ctx)