def get_frontend_order_state(contact, valid_lines=True): """ Get a dict structure mirroring what the frontend JavaScript would submit. :type contact: Contact|None """ translation.activate("en") shop = get_default_shop() tax = Tax.objects.create(code="test_code", rate=decimal.Decimal("0.20"), name="Default") tax_class = TaxClass.objects.create(identifier="test_tax_class", name="Default") rule = TaxRule.objects.create(tax=tax) rule.tax_classes.add(tax_class) rule.save() product = create_product( sku=printable_gibberish(), supplier=get_default_supplier(), shop=shop ) product.tax_class = tax_class product.save() if valid_lines: lines = [ {"id": "x", "type": "product", "product": {"id": product.id}, "quantity": "32", "baseUnitPrice": 50}, {"id": "y", "type": "other", "sku": "hello", "text": "A greeting", "quantity": 1, "unitPrice": "5.5"}, {"id": "z", "type": "text", "text": "This was an order!", "quantity": 0}, ] else: unshopped_product = create_product(sku=printable_gibberish(), supplier=get_default_supplier()) not_visible_product = create_product( sku=printable_gibberish(), supplier=get_default_supplier(), shop=shop ) not_visible_shop_product = not_visible_product.get_shop_instance(shop) not_visible_shop_product.visible = False not_visible_shop_product.save() lines = [ {"id": "x", "type": "product"}, # no product? {"id": "x", "type": "product", "product": {"id": unshopped_product.id}}, # not in this shop? {"id": "y", "type": "product", "product": {"id": -product.id}}, # invalid product? {"id": "z", "type": "other", "quantity": 1, "unitPrice": "q"}, # what's that price? {"id": "rr", "type": "product", "quantity": 1, "product": {"id": not_visible_product.id}} # not visible ] state = { "customer": {"id": contact.id if contact else None}, "lines": lines, "methods": { "shippingMethod": {"id": get_default_shipping_method().id}, "paymentMethod": {"id": get_default_payment_method().id}, }, "shop": { "selected": { "id": shop.id, "name": shop.name, "currency": shop.currency, "priceIncludeTaxes": shop.prices_include_tax } } } return state
def test_editor_view_unknown_command(): with initialize_editor_view(printable_gibberish(), printable_gibberish()) as view_obj: view_obj.request.method = "POST" view_obj.request.POST = {"command": printable_gibberish()} with pytest.raises(Problem): view_obj.dispatch(view_obj.request)
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", discount_amount_value=discount_amount_value, active=True) campaign.conditions.add(rule) campaign.save() 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 test_draft_reversion(): view_name = printable_gibberish() theme = TestTheme() placeholder_name = "test_ph" vc = ViewConfig(theme=theme, 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, 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, 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_draft_reversion(): view_name = printable_gibberish() theme = TestTheme() placeholder_name = "test_ph" vc = ViewConfig(theme=theme, 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, 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, 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_basket_shipping_error(rf): StoredBasket.objects.all().delete() shop = get_default_shop() supplier = get_default_supplier() shipped_product = create_product( printable_gibberish(), shop=shop, supplier=supplier, default_price=50, shipping_mode=ShippingMode.SHIPPED ) unshipped_product = create_product( printable_gibberish(), shop=shop, supplier=supplier, default_price=50, shipping_mode=ShippingMode.NOT_SHIPPED ) request = rf.get("/") request.session = {} request.shop = shop apply_request_middleware(request) basket = get_basket(request) # With a shipped product but no shipping methods, we oughta get an error basket.add_product(supplier=supplier, shop=shop, product=shipped_product, quantity=1) assert any(ve.code == "no_common_shipping" for ve in basket.get_validation_errors()) basket.clear_all() # But with an unshipped product, we should not basket.add_product(supplier=supplier, shop=shop, product=unshipped_product, quantity=1) assert not any(ve.code == "no_common_shipping" for ve in basket.get_validation_errors())
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_move_file(): folder1 = Folder.objects.create(name=printable_gibberish()) folder2 = Folder.objects.create(name=printable_gibberish()) file = File.objects.create(folder=folder1) mbv_command({"action": "move_file", "file_id": file.pk, "folder_id": folder2.pk}) assert File.objects.get(pk=file.pk).folder == folder2 mbv_command({"action": "move_file", "file_id": file.pk, "folder_id": 0}) assert File.objects.get(pk=file.pk).folder is None
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_basket_free_product_coupon(rf): request, shop, group = initialize_test(rf, False) price = shop.create_price basket = get_basket(request) supplier = get_default_supplier() single_product_price = "50" discount_amount_value = "10" # 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.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) == 2 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 == OrderLineType.PRODUCT if line.product != product: assert line.product == second_product
def test_get_folder(): folder1 = Folder.objects.create(name=printable_gibberish()) folder2 = Folder.objects.create(name=printable_gibberish(), parent=folder1) root_resp = mbv_command({"action": "folder"}, "GET") assert any(f["id"] == folder1.pk for f in root_resp["folder"]["folders"]) f1_resp = mbv_command({"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({"action": "folder", "id": -1}, "GET")["error"]
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): 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({"action": "folders"}, "GET")) assert tree[folder1.pk] == {folder2.pk: {folder3.pk: {}}} mbv_command({"action": "delete_folder", "id": folder2.pk}) tree = get_id_tree(mbv_command({"action": "folders"}, "GET")) assert tree[folder1.pk] == {folder3.pk: {}} folder1 = Folder.objects.get(pk=folder1.pk) assert list(folder1.get_children()) == [folder3]
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_move_file(): folder1 = Folder.objects.create(name=printable_gibberish()) folder2 = Folder.objects.create(name=printable_gibberish()) file = File.objects.create(folder=folder1) mbv_command({ "action": "move_file", "file_id": file.pk, "folder_id": folder2.pk }) assert File.objects.get(pk=file.pk).folder == folder2 mbv_command({"action": "move_file", "file_id": file.pk, "folder_id": 0}) assert File.objects.get(pk=file.pk).folder is None
def test_get_folders(rf): # 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({"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_product_not_in_normal_mode(): FormSet = formset_factory(PackageChildForm, PackageChildFormSet, extra=5, can_delete=True) parent = create_product(printable_gibberish()) child_1 = create_product(printable_gibberish()) child_1.link_to_parent(parent) child_2 = create_product(printable_gibberish()) parent.verify_mode() assert parent.mode == ProductMode.SIMPLE_VARIATION_PARENT # Trying to create a package from a non-normal mode product with pytest.raises(Problem): formset = FormSet(parent_product=parent) data = dict(get_form_data(formset, True), **{"form-0-child": child_2.pk, "form-0-quantity": 2}) formset = FormSet(parent_product=parent, data=data) formset.save()
def test_form_populate_initial_data(rf, admin_user): shop = get_default_shop() supplier = get_default_supplier() campaign = BasketCampaign(discount_percentage=0.1, shop=shop) campaign.save() # Test that correct initial value is returned for non-many-to-many field product_amount_initial = 10 product_amount_condition = BasketTotalProductAmountCondition(product_count=product_amount_initial) product_amount_condition.save() campaign.conditions.add(product_amount_condition) products_count_initial = 5 for i in range(products_count_initial): create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price="20") products_initial = Product.objects.all()[:products_count_initial] assert len(products_initial) == products_count_initial # Test that correct initial value is returned for many-to-many field products_in_basket_condition = ProductsInBasketCondition.objects.create() products_in_basket_condition.values = products_initial products_in_basket_condition.save() campaign.conditions.add(products_in_basket_condition) assert len(campaign.conditions.all()) == 2 request=apply_request_middleware(rf.get("/"), user=admin_user) form = BasketCampaignForm(request=request, instance=campaign) assert form.fields["basket_product_condition"].initial == product_amount_initial assert set(form.fields["basket_products_condition"].initial) == set([p.pk for p in products_initial])
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 = OrderCreateView.as_view()(request) assert_contains(response, "unknown command", status_code=400)
def test_protected_fields(): activate("en") shop = Shop.objects.create( name="testshop", identifier="testshop", status=ShopStatus.ENABLED, public_name="test shop", domain="derp", currency="EUR" ) assert shop.name == "testshop" assert shop.currency == "EUR" shop_form = ShopBaseForm(instance=shop, languages=settings.LANGUAGES) assert not shop_form._get_protected_fields() # No protected fields just yet, right? data = get_form_data(shop_form, prepared=True) shop_form = ShopBaseForm(data=data, instance=shop, languages=settings.LANGUAGES) _test_cleanliness(shop_form) shop_form.save() # Now let's make it protected! create_product(printable_gibberish(), shop=shop, supplier=get_default_supplier()) order = create_random_order(customer=create_random_person(), shop=shop) assert order.shop == shop # And try again... data["currency"] = "XBT" # Bitcoins! shop_form = ShopBaseForm(data=data, instance=shop, languages=settings.LANGUAGES) assert shop_form._get_protected_fields() # So protected! _test_cleanliness(shop_form) shop = shop_form.save() assert shop.currency == "EUR" # But the shop form ignored the change . . .
def test_form_populate_initial_data(rf, admin_user): shop = get_default_shop() supplier = get_default_supplier() initial_discount_amount = 20 campaign = BasketCampaign.objects.create(shop=shop) BasketDiscountAmount.objects.create(campaign=campaign, discount_amount=initial_discount_amount) # Test that correct initial value is returned for non-many-to-many field product_amount_initial = 10 product_amount_condition = BasketTotalProductAmountCondition(product_count=product_amount_initial) product_amount_condition.save() campaign.conditions.add(product_amount_condition) products_count_initial = 5 for i in range(products_count_initial): create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price="20") products_initial = Product.objects.all()[:products_count_initial] assert len(products_initial) == products_count_initial # Test that correct initial value is returned for many-to-many field products_in_basket_condition = ProductsInBasketCondition.objects.create() products_in_basket_condition.values = products_initial products_in_basket_condition.save() campaign.conditions.add(products_in_basket_condition) assert len(campaign.conditions.all()) == 2 assert campaign.effects.count() == 1 request=apply_request_middleware(rf.get("/"), user=admin_user) form = BasketCampaignForm(request=request, instance=campaign) assert form.fields["basket_product_condition"].initial == product_amount_initial assert set(form.fields["basket_products_condition"].initial) == set([p.pk for p in products_initial]) assert form.fields["discount_amount_effect"].initial == initial_discount_amount
def test_missing_plugin_render(): plugin_id = printable_gibberish() cell = LayoutCell(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_campaign_module_case1(rf): request, shop, group = initialize_test(rf, False) price = shop.create_price basket = get_basket(request) supplier = get_default_supplier() single_product_price = "50" discount_amount_value = "10" # create basket rule that requires 2 products in basket basket_rule1 = BasketTotalProductAmountCondition.objects.create(value="2") 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.save() assert basket.product_count == 1 campaign = BasketCampaign.objects.create( shop=shop, public_name="test", name="test", discount_amount_value=discount_amount_value, active=True) campaign.conditions.add(basket_rule1) campaign.save() assert len(basket.get_final_lines()) == 1 # case 1 assert basket.total_price == price(single_product_price) # case 1 basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1) basket.save() assert len(basket.get_final_lines()) == 2 # case 1 assert basket.product_count == 2 assert basket.total_price == (price(single_product_price) * basket.product_count - price(discount_amount_value)) assert OrderLineType.DISCOUNT in [l.type for l in basket.get_final_lines()]
def test_editor_save(rf): layout, svc = get_test_layout_and_svc() with initialize_editor_view(svc.view_name, layout.placeholder_name) as view_obj: view_obj.request.GET.update({"x": 0, "y": 0}) view_obj.dispatch(view_obj.request) assert view_obj.current_cell assert view_obj.form assert "general" in view_obj.form.forms assert "plugin" in view_obj.form.forms form_data = get_form_data(view_obj.form, prepared=True) new_text = printable_gibberish() form_data["plugin-text_%s" % FALLBACK_LANGUAGE_CODE] = new_text form_data["save"] = "1" request = rf.post("/pepe/", data=form_data) # sort of rare pepe request.GET = dict(request.GET, x=0, y=0) with initialize_editor_view(svc.view_name, layout.placeholder_name, request) as view_obj: view_obj.dispatch(request) assert view_obj.form assert not view_obj.form.errors assert view_obj.current_cell.config["text"] == { FALLBACK_LANGUAGE_CODE: new_text }
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) campaign = BasketCampaign.objects.create( shop=shop, public_name="test", name="test", discount_amount_value=discount1, active=True ) campaign.conditions.add(rule) campaign.save() campaign = BasketCampaign.objects.create( shop=shop, public_name="test", name="test", discount_amount_value=discount2, active=True ) campaign.conditions.add(rule) campaign.save() assert len(basket.get_final_lines()) == 2 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_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 atleast 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) campaign = BasketCampaign.objects.create( shop=shop, public_name="test", name="test", discount_percentage=discount_percentage, active=True ) campaign.conditions.add(rule) campaign.save() assert len(basket.get_final_lines()) == 2 assert basket.product_count == 1 assert basket.total_price == expected_discounted_price
def test_admin_catalog_campaign_edit_view(rf, admin_user): shop = get_default_shop() view = CatalogCampaignEditView(request=apply_request_middleware(rf.get("/"), user=admin_user)) form_class = view.get_form_class() form_kwargs = view.get_form_kwargs() form = form_class(**form_kwargs) assert not form.is_bound data = get_form_data(form) data.update({ "shop": shop.pk, "name": "test", }) form = form_class(**dict(form_kwargs, data=data)) form.full_clean() assert "You must define discount percentage or amount" in form.errors["__all__"][0] data.update({"discount_amount_value": "20"}) form = form_class(**dict(form_kwargs, data=data)) form.full_clean() # atleast 1 rule is required assert "You must set at least one rule for this campaign" in form.errors["__all__"][0] supplier = get_default_supplier() product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price="20") data.update({"product_filter": [1]}) form = form_class(**dict(form_kwargs, data=data)) form.full_clean() assert not form.errors campaign = form.save() assert campaign.filters.count() == 1
def _get_frontend_order_state(shop, contact): tax = Tax.objects.create(code="test_code", rate=decimal.Decimal("0.20"), name="Default") tax_class = TaxClass.objects.create(identifier="test_tax_class", name="Default") rule = TaxRule.objects.create(tax=tax) rule.tax_classes.add(tax_class) rule.save() product = create_product( sku=printable_gibberish(), supplier=get_default_supplier(), shop=shop ) product.tax_class = tax_class product.save() lines = [ {"id": "x", "type": "product", "product": {"id": product.id}, "quantity": "32", "baseUnitPrice": 50} ] state = { "customer": {"id": contact.id if contact else None}, "lines": lines, "methods": { "shippingMethod": {"id": get_shipping_method(shop=shop).id}, "paymentMethod": {"id": get_payment_method(shop=shop).id}, }, "shop": { "selected": { "id": shop.id, "name": shop.safe_translation_getter("name"), "currency": shop.currency, "priceIncludeTaxes": shop.prices_include_tax } } } return state
def _get_order_with_coupon(request, initial_status, condition_product_count=1): shop = request.shop basket = get_basket(request) supplier = get_default_supplier() product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price="50") basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1) dc = Coupon.objects.create(code="TEST", 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=1) campaign.conditions.add(rule) campaign.save() basket.add_code(dc.code) basket.save() basket.status = initial_status creator = OrderCreator(request) order = creator.create_order(basket) assert order.lines.count() == 2 assert OrderLineType.DISCOUNT in [l.type for l in order.lines.all()] return order
def _get_order_with_coupon(request, initial_status, condition_product_count=1): shop = request.shop basket = get_basket(request) supplier = get_default_supplier() product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price="50") basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1) dc = Coupon.objects.create(code="TEST", active=True) campaign = BasketCampaign.objects.create( shop=shop, name="test", public_name="test", coupon=dc, discount_amount_value=shop.create_price("20"), active=True ) rule = BasketTotalProductAmountCondition.objects.create(value=1) campaign.conditions.add(rule) campaign.save() basket.add_code(dc.code) basket.save() basket.status = initial_status creator = OrderCreator(request) order = creator.create_order(basket) assert order.lines.count() == 2 assert OrderLineType.DISCOUNT in [l.type for l in order.lines.all()] return order
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 atleast value of 200 rule = BasketTotalAmountCondition.objects.create(value="200") single_product_price = "50" discount_amount_value = "10" unique_shipping_method = ShippingMethod(tax_class=get_default_tax_class(), module_data={"price": 50}) unique_shipping_method.save() 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", discount_amount_value=discount_amount_value, active=True ) campaign.conditions.add(rule) campaign.save() 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 test_user_detail_works_at_all(rf, admin_user): get_default_shop() user = get_user_model().objects.create( username=printable_gibberish(20), first_name=printable_gibberish(10), last_name=printable_gibberish(10), password="******" ) view_func = UserDetailView.as_view() response = view_func(apply_request_middleware(rf.get("/"), user=admin_user), pk=user.pk) assert response.status_code == 200 response.render() assert force_text(user) in force_text(response.content) response = view_func(apply_request_middleware(rf.post("/", {"set_is_active": "0"}), user=admin_user), pk=user.pk) assert response.status_code < 500 and not get_user_model().objects.get(pk=user.pk).is_active with pytest.raises(Problem): view_func(apply_request_middleware(rf.post("/", {"set_is_active": "0"}), user=admin_user), pk=admin_user.pk)
def test_translatable_field_initial(): dummy = printable_gibberish() tf = Form() assert str(tf).count(dummy) == 0 tf = Form(initial={"field": dummy}) assert str(tf).count(dummy) == 1 # Should only exist in the untranslated field tf = Form(initial={"field": {"en": dummy, "fi": dummy}}) assert str(tf).count(dummy) == 2 # Should exist in two fields
def test_contact_edit_form(): user = get_user_model().objects.create_user( username=printable_gibberish(), first_name=printable_gibberish(), last_name=printable_gibberish(), ) contact_base_form = ContactBaseForm(bind_user=user, data={ "name": "herf durr", "gender": Gender.UNDISCLOSED.value }) assert contact_base_form.bind_user == user assert contact_base_form.contact_class == PersonContact assert contact_base_form.is_valid(), contact_base_form.errors contact = contact_base_form.save() assert isinstance(contact, PersonContact) assert contact.user == user assert get_person_contact(user) == contact
def test_translatable_field_initial(): dummy = printable_gibberish() tf = Form() assert str(tf).count(dummy) == 0 tf = Form(initial={"field": dummy}) assert str(tf).count( dummy) == 1 # Should only exist in the untranslated field tf = Form(initial={"field": {"en": dummy, "fi": dummy}}) assert str(tf).count(dummy) == 2 # Should exist in two fields
def test_multiple_campaigns_match_with_coupon(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" product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price=product_price) basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1) campaign = BasketCampaign.objects.create(shop=shop, public_name="test", name="test", active=True) campaign.conditions.add(rule) campaign.save() BasketDiscountAmount.objects.create(discount_amount=discount1, campaign=campaign) dc = Coupon.objects.create(code="TEST", active=True) campaign2 = BasketCampaign.objects.create(shop=shop, public_name="test", name="test", coupon=dc, active=True) BasketDiscountAmount.objects.create(discount_amount=discount2, campaign=campaign2) basket.add_product(supplier=supplier, shop=shop, product=product, quantity=1) resp = handle_add_campaign_code(request, basket, dc.code) assert resp.get("ok") discount_lines_values = [ line.discount_amount for line in basket.get_final_lines() ] assert price(discount1) in discount_lines_values assert price(discount2) in discount_lines_values assert basket.total_price == (price(product_price) * basket.product_count - price(discount1) - price(discount2))
def test_package_child_formset(): FormSet = formset_factory(PackageChildForm, PackageChildFormSet, extra=5, can_delete=True) parent = create_product(printable_gibberish()) child = create_product(printable_gibberish()) # No products in the package formset = FormSet(parent_product=parent) assert formset.initial_form_count() == 0 # No children yet assert not parent.get_all_package_children() data = dict(get_form_data(formset, True), **{"form-0-child": child.pk, "form-0-quantity": 2}) formset = FormSet(parent_product=parent, data=data) formset.save() assert parent.get_all_package_children() clear_existing_package(parent) assert not parent.get_all_package_children()
def test_admin_catalog_campaign_edit_view(rf, admin_user): shop = get_default_shop() view = CatalogCampaignEditView( request=apply_request_middleware(rf.get("/"), user=admin_user)) form_class = view.get_form_class() form_kwargs = view.get_form_kwargs() form = form_class(**form_kwargs) assert not form.is_bound data = get_form_data(form) data.update({ "shop": shop.pk, "name": "test", }) form = form_class(**dict(form_kwargs, data=data)) form.full_clean() assert "At least one effect must be defined." in form.errors["__all__"][0] data.update({"discount_amount_effect": "20"}) form = form_class(**dict(form_kwargs, data=data)) form.full_clean() # at least 1 rule is required assert "You must set at least one rule for this campaign" in form.errors[ "__all__"][0] supplier = get_default_supplier() product = create_product(printable_gibberish(), shop=shop, supplier=supplier, default_price="20") data.update({"product_filter": [product.id]}) form = form_class(**dict(form_kwargs, data=data)) form.full_clean() assert not form.errors data.update({ "start_datetime": datetime.datetime.now() + datetime.timedelta(days=1), "end_datetime": datetime.datetime.now() }) form = form_class(**dict(form_kwargs, data=data)) form.full_clean() assert "Campaign end date can't be before start date" in form.errors[ "__all__"][0] data.update({"start_datetime": None}) form = form_class(**dict(form_kwargs, data=data)) form.full_clean() assert not form.errors campaign = form.save() assert campaign.filters.count() == 1
def test_basket(rf, storage): 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)) is_database = ( storage == "shoop.front.basket.storage:DatabaseBasketStorage") with override_settings(SHOOP_BASKET_STORAGE_CLASS_SPEC=storage): 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) 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 if is_database: product_ids = set( StoredBasket.objects.last().products.values_list( "id", flat=True)) assert product_ids == set([product.pk]) if is_database: 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_layout_and_svc(): svc = SavedViewConfig(theme_identifier=FauxTheme.identifier, view_name=printable_gibberish(), status=SavedViewConfigStatus.CURRENT_DRAFT) layout = Layout("ph") layout.add_plugin("text", {"text": "hello"}) svc.set_layout_data(layout.placeholder_name, layout) svc.save() return layout, svc
def get_frontend_order_state(contact, valid_lines=True): """ Get a dict structure mirroring what the frontend JavaScript would submit. :type contact: Contact|None """ shop = get_default_shop() product = create_product( sku=printable_gibberish(), supplier=get_default_supplier(), shop=shop ) if valid_lines: lines = [ {"id": "x", "type": "product", "product": {"id": product.id}, "quantity": "32", "baseUnitPrice": 50}, {"id": "y", "type": "other", "sku": "hello", "text": "A greeting", "quantity": 1, "unitPrice": "5.5"}, {"id": "z", "type": "text", "text": "This was an order!", "quantity": 0}, ] else: unshopped_product = create_product(sku=printable_gibberish(), supplier=get_default_supplier()) lines = [ {"id": "x", "type": "product"}, # no product? {"id": "x", "type": "product", "product": {"id": unshopped_product.id}}, # not in this shop? {"id": "y", "type": "product", "product": {"id": -product.id}}, # invalid product? {"id": "z", "type": "other", "quantity": 1, "unitPrice": "q"}, # what's that price? ] state = { "customer": {"id": contact.id if contact else None}, "lines": lines, "methods": { "shippingMethod": {"id": get_default_shipping_method().id}, "paymentMethod": {"id": get_default_payment_method().id}, }, "shop": { "selected": { "id": shop.id, "name": shop.name, "currency": shop.currency, "priceIncludeTaxes": shop.prices_include_tax } } } return state
def test_impossible_simple_variation(): FormSet = formset_factory(SimpleVariationChildForm, SimpleVariationChildFormSet, extra=5, can_delete=True) parent = create_product(printable_gibberish()) child = create_product(printable_gibberish()) grandchild = create_product(printable_gibberish()) grandchild.link_to_parent(child) assert child.variation_children.exists() formset = FormSet(parent_product=parent) data = dict(get_form_data(formset, True), **{"form-0-child": child.pk}) formset = FormSet(parent_product=parent, data=data) assert formset.is_valid() # It's technically valid, but... with pytest.raises(Problem) as ei: formset.save() if six.PY3: # Can only test inner exceptions on Py3. Ah well. inner_exc = ei.value.__context__ assert isinstance(inner_exc, ImpossibleProductModeException) assert inner_exc.code == "multilevel"
def test_translatable_field_data(): dummy = printable_gibberish() tf = Form(data={"field_en": dummy, "field_fi": dummy, "field_*": "oops"}) assert str(tf).count(dummy) == 2 assert str(tf).count("oops") == 1 tf.full_clean() assert tf.cleaned_data["field"] == {"en": dummy, "fi": dummy, "*": "oops"} tf = Form(data={"field_en": dummy}) assert str(tf).count(dummy) == 1 tf.full_clean() assert tf.cleaned_data["field"] == {"en": dummy}
def get_test_layout_and_svc(): svc = SavedViewConfig( theme_identifier=FauxTheme.identifier, view_name=printable_gibberish(), status=SavedViewConfigStatus.CURRENT_DRAFT ) layout = Layout("ph") layout.add_plugin("text", {"text": "hello"}) svc.set_layout_data(layout.placeholder_name, layout) svc.save() return layout, svc
def test_campaign_with_coupons(rf): 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) dc = Coupon.objects.create(code="TEST", 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() assert len(basket.get_final_lines() ) == 2 # no discount was applied because coupon is required basket.add_code(dc.code) assert len(basket.get_final_lines() ) == 3 # now basket has codes so they will be applied too assert OrderLineType.DISCOUNT in [l.type for l in basket.get_final_lines()] # Ensure codes persist between requests, so do what the middleware would, i.e. basket.save() # and then reload the basket: del request.basket basket = get_basket(request) assert basket.codes == [dc.code] assert len(basket.get_final_lines() ) == 3 # now basket has codes so they will be applied too assert OrderLineType.DISCOUNT in [l.type for l in basket.get_final_lines()] basket.status = status creator = OrderCreator(request) order = creator.create_order(basket) assert CouponUsage.objects.filter(order=order).count() == 1 assert CouponUsage.objects.filter(order=order, coupon__code=dc.code).count() == 1
def get_test_template_bits(request, pass_view=True, **extra_ctx): layout = Layout("test") gibberish = printable_gibberish() layout.begin_column({"md": 12, "xs": 0}) layout.add_plugin("text", {"text": 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)
def test_creating_contact(): persons_count = PersonContact.objects.count() contact_base_form = ContactBaseForm(data={ "type": "PersonContact", "name": printable_gibberish(), "gender": Gender.UNDISCLOSED.value }) assert contact_base_form.is_valid(), contact_base_form.errors contact = contact_base_form.save() assert isinstance(contact, PersonContact) assert contact.pk is not None assert PersonContact.objects.count() == (persons_count + 1)
def test_order_creator_product_data(rf, admin_user): shop = get_default_shop() product = create_product(sku=printable_gibberish(), supplier=get_default_supplier(), shop=shop) request = apply_request_middleware(rf.get("/", { "command": "product_data", "shop_id": shop.id, "id": product.id, }), user=admin_user) response = OrderCreateView.as_view()(request) assert_contains(response, "taxClass") assert_contains(response, "sku") assert_contains(response, product.sku)
def test_new_folder(): folder1 = Folder.objects.create(name=printable_gibberish()) child_folder_data = mbv_command({ "action": "new_folder", "name": "y", "parent": folder1.id })["folder"] assert Folder.objects.get(pk=child_folder_data["id"]).parent == folder1 root_folder_data = mbv_command({ "action": "new_folder", "name": "y" })["folder"] assert not Folder.objects.get(pk=root_folder_data["id"]).parent_id