def test_company_edit_form_links_company(regular_user, allow_company_registration): get_default_shop() configuration.set(None, "allow_company_registration", allow_company_registration) person = get_person_contact(regular_user) assert not get_company_contact(regular_user) client = SmartClient() client.login(username=REGULAR_USER_USERNAME, password=REGULAR_USER_PASSWORD) data = default_company_data() data.update(default_address_data("billing")) data.update(default_address_data("shipping")) company_edit_url = reverse("wshop:company_edit") if allow_company_registration: soup = client.soup(company_edit_url) response, soup = client.response_and_soup(company_edit_url, data, "post") assert response.status_code == 302 assert get_company_contact(regular_user) else: response = client.get(company_edit_url) assert response.status_code == 404 response = client.post(company_edit_url, data) assert response.status_code == 404
def test_category_links_plugin_with_customer(rf, show_all_categories): """ Test plugin for categories that is visible for certain group """ shop = get_default_shop() group = get_default_customer_group() customer = create_random_person() customer.groups.add(group) customer.save() request = rf.get("/") request.shop = get_default_shop() apply_request_middleware(request) request.customer = customer category = get_default_category() category.status = CategoryStatus.VISIBLE category.visibility = CategoryVisibility.VISIBLE_TO_GROUPS category.visibility_groups.add(group) category.shops.add(shop) category.save() vars = {"request": request} context = get_jinja_context(**vars) plugin = CategoryLinksPlugin({"categories": [category.pk], "show_all_categories": show_all_categories}) assert category.is_visible(customer) assert category in plugin.get_context_data(context)["categories"] customer_without_groups = create_random_person() customer_without_groups.groups.clear() assert not category.is_visible(customer_without_groups) request.customer = customer_without_groups context = get_jinja_context(**vars) assert category not in plugin.get_context_data(context)["categories"]
def test_refund_without_shipment(restock): shop = get_default_shop() supplier = get_simple_supplier() product = create_product( "test-sku", shop=get_default_shop(), default_price=10, stock_behavior=StockBehavior.STOCKED ) # Start out with a supplier with quantity of 10 of a product supplier.adjust_stock(product.id, 10) check_stock_counts(supplier, product, physical=10, logical=10) order = create_order_with_product(product, supplier, 2, 200, shop=shop) order.cache_prices() check_stock_counts(supplier, product, physical=10, logical=8) # Restock value shouldn't matter if we don't have any shipments product_line = order.lines.first() order.create_refund([ {"line": product_line, "quantity": 2, "amount": Money(400, order.currency), "restock_products": restock}]) if restock: check_stock_counts(supplier, product, physical=10, logical=10) else: check_stock_counts(supplier, product, physical=10, logical=8) assert product_line.refunded_quantity == 2 assert order.get_total_tax_amount() == Money( order.taxful_total_price_value - order.taxless_total_price_value, order.currency)
def test_register_bad_data(): get_default_shop() client = _get_client() # no username or email register_data = { "password": "******" } response = client.post("/api/wshop/front/user/", content_type="application/json", data=json.dumps(register_data)) assert response.status_code == status.HTTP_400_BAD_REQUEST assert "username and/or email is required" in response.content.decode("utf-8") # invalid email register_data = { "email": "invalidemail", "password": "******" } response = client.post("/api/wshop/front/user/", content_type="application/json", data=json.dumps(register_data)) assert response.status_code == status.HTTP_400_BAD_REQUEST assert "Enter a valid email address" in response.content.decode("utf-8") # no password register_data = { "email": "*****@*****.**", } response = client.post("/api/wshop/front/user/", content_type="application/json", data=json.dumps(register_data)) assert response.status_code == status.HTTP_400_BAD_REQUEST assert "password" in json.loads(response.content.decode("utf-8"))
def test_refund_entire_order_with_restock(admin_user): shop = get_default_shop() supplier = get_simple_supplier() product = create_product("test-sku", shop=get_default_shop(), default_price=10, stock_behavior=StockBehavior.STOCKED) supplier.adjust_stock(product.id, 5) _check_stock_counts(supplier, product, 5, 5) order = create_order_with_product(product, supplier, 2, 200, shop=shop) order.payment_status = PaymentStatus.DEFERRED order.cache_prices() order.save() _check_stock_counts(supplier, product, 5, 3) assert not StockAdjustment.objects.filter(created_by=admin_user).exists() client = _get_client(admin_user) refund_url = "/api/wshop/order/%s/create_full_refund/" % order.id data = {"restock_products": True} response = client.post(refund_url, data, format="json") assert response.status_code == status.HTTP_201_CREATED order.refresh_from_db() # restock logical count _check_stock_counts(supplier, product, 5, 5) assert StockAdjustment.objects.filter(created_by=admin_user).exists()
def test_processor_orderability(admin_user): source = OrderSource(Shop()) processor = OrderProcessor() line = source.add_line( type=OrderLineType.PRODUCT, product=get_default_product(), supplier=get_default_supplier(), quantity=1, shop=get_default_shop(), base_unit_price=source.create_price(10), ) line.order = Order(shop=get_default_shop()) assert processor._check_orderability(line) is None unorderable_line = source.add_line( type=OrderLineType.PRODUCT, product=create_product("no-shop"), supplier=get_default_supplier(), quantity=1, shop=get_default_shop(), base_unit_price=source.create_price(20), ) unorderable_line.order = Order(shop=get_default_shop()) with pytest.raises(ValidationError) as exc: processor._check_orderability(unorderable_line) assert "Not available in" in exc.value.message
def test_order_chart_works(rf, admin_user): get_default_shop() order = create_random_order(customer=create_random_person(), products=(get_default_product(), )) request = apply_request_middleware(rf.get("/"), user=admin_user) chart = OrderValueChartDashboardBlock("test", request=request).get_chart() assert len(chart.datasets[0]) > 0
def test_xtheme_extra_view_exceptions(rf): with override_current_theme_class(H2G2Theme, get_default_shop()): request = rf.get("/") request.shop = get_default_shop() assert extra_view_dispatch(request, "vogons").status_code == 404 with pytest.raises(ImproperlyConfigured): assert extra_view_dispatch(request, "true")
def test_contact_details_view_with_many_groups(rf, admin_user): get_default_shop() person = create_random_person() person.groups.add( ContactGroup.objects.create(name="Czz Group"), ContactGroup.objects.create(name="Azz Group"), ContactGroup.objects.create(name="Bzz Group"), ContactGroup.objects.language('fi').create(name="Dzz ryhmä"), ) # Group with name in two languages grp_e = ContactGroup.objects.language('en').create(name="Ezz Group") grp_e.set_current_language('fi') grp_e.name = "Ezz ryhmä" grp_e.save() person.groups.add(grp_e) request = apply_request_middleware(rf.get("/"), user=admin_user) with translation.override('en'): view_func = ContactDetailView.as_view() response = view_func(request, pk=person.pk) content = response.render().content.decode('utf-8') assert "Azz Group" in content assert "Bzz Group" in content assert "Czz Group" in content assert "Dzz ryhmä" in content, "no name in active language, still present" assert "Ezz Group" in content, "rendered with active language" positions = [content.index(x + "zz ") for x in 'ABCDE'] assert positions == sorted(positions), "Groups are sorted" assert response.status_code == 200
def get_products_by_id_sku(admin_user): client = _get_client(admin_user) get_default_shop() products = [ create_product("product 1"), create_product("product 2"), create_product("product 3") ] client = _get_client(admin_user) # get by ID response = client.get("/api/wshop/product/?id=%d" % products[2].id) assert response.status_code == status.HTTP_200_OK product_data = json.loads(response.content.decode("utf-8")) assert len(product_data) == 1 assert product_data[0]["product"] == products[2].id assert product_data[0]["sku"] == products[2].id # get by SKU response = client.get("/api/wshop/product/?sku=%s" % products[1].sku) assert response.status_code == status.HTTP_200_OK product_data = json.loads(response.content.decode("utf-8")) assert len(product_data) == 1 assert product_data[0]["product"] == products[1].id assert product_data[0]["sku"] == products[1].id
def test_service_provide_edit_view(rf, admin_user, sp_model, extra_inputs): """ Test that ``ServiceProvideEditView`` works with existing ``ServiceProvider`` subclasses To make things little bit more simple let's use only english as an language. """ with override_settings(LANGUAGES=[("en", "en")]): base_inputs = ["csrfmiddlewaretoken", "name__en", "enabled", "logo"] get_default_shop() view = ServiceProviderEditView.as_view() provider_name = "some name" service_provider = sp_model.objects.create(name=provider_name) soup = get_bs_object_for_view(rf.get("/"), view, admin_user, object=service_provider) provider_form = soup.find("form", attrs={"id": "service_provider_form"}) rendered_fields = [] for input_field in provider_form.findAll("input"): rendered_fields.append(input_field["name"]) assert rendered_fields == (base_inputs + extra_inputs) assert provider_form.find("input", attrs={"name": "name__en"})["value"] == provider_name
def test_delete_product(admin_user): get_default_shop() client = _get_client(admin_user) assert Product.objects.count() == 0 data = _get_product_sample_data() response = client.post("/api/wshop/product/", content_type="application/json", data=json.dumps(data)) assert response.status_code == status.HTTP_201_CREATED assert Product.objects.count() == 1 product = Product.objects.first() # actually, we do not remove it from db, just "soft delete" response = client.delete("/api/wshop/product/%d/" % product.pk, content_type="application/json") assert response.status_code == status.HTTP_204_NO_CONTENT assert Product.objects.count() == 1 # check whether the info was changed for lang in ("en", "pt-br"): activate(lang) product = Product.objects.first() _check_product_basic_data(product, data, lang) assert product.deleted is True
def test_login_as_user_errors(rf, admin_user, regular_user): get_default_shop() view_func = LoginAsUserView.as_view() request = apply_request_middleware(rf.post("/"), user=regular_user) # log in as self with pytest.raises(Problem): view_func(request, pk=regular_user.pk) user = UserFactory() get_person_contact(user) # non superuser trying to login as someone else with pytest.raises(PermissionDenied): view_func(request, pk=user.pk) request = apply_request_middleware(rf.post("/"), user=admin_user) user.is_superuser = True user.save() # user is trying to login as another superuser with pytest.raises(PermissionDenied): view_func(request, pk=user.pk) user.is_superuser = False user.is_staff = True user.save() # user is trying to login as a staff user with pytest.raises(PermissionDenied): view_func(request, pk=user.pk) user.is_staff = False user.is_active = False user.save() # user is trying to login as an inactive user with pytest.raises(Problem): view_func(request, pk=user.pk)
def test_sales_unit_api(admin_user): activate("en") get_default_shop() client = APIClient() client.force_authenticate(user=admin_user) sales_unit_data = { "translations": { "en": {"name": "Kilo", "symbol": "KG"} }, "decimals": 2 } response = client.post("/api/wshop/sales_unit/", content_type="application/json", data=json.dumps(sales_unit_data)) assert response.status_code == status.HTTP_201_CREATED sales_unit = SalesUnit.objects.first() assert sales_unit.name == sales_unit_data["translations"]["en"]["name"] assert sales_unit.symbol == sales_unit_data["translations"]["en"]["symbol"] assert sales_unit.decimals == sales_unit_data["decimals"] sales_unit_data["translations"]["en"]["name"] = "Pound" sales_unit_data["translations"]["en"]["symbol"] = "PD" sales_unit_data["decimals"] = 3 response = client.put("/api/wshop/sales_unit/%d/" % sales_unit.id, content_type="application/json", data=json.dumps(sales_unit_data)) assert response.status_code == status.HTTP_200_OK sales_unit = SalesUnit.objects.first() assert sales_unit.name == sales_unit_data["translations"]["en"]["name"] assert sales_unit.symbol == sales_unit_data["translations"]["en"]["symbol"] assert sales_unit.decimals == sales_unit_data["decimals"] response = client.get("/api/wshop/sales_unit/%d/" % sales_unit.id) assert response.status_code == status.HTTP_200_OK data = json.loads(response.content.decode("utf-8")) assert sales_unit.name == data["translations"]["en"]["name"] assert sales_unit.symbol == data["translations"]["en"]["symbol"] assert sales_unit.decimals == data["decimals"] response = client.get("/api/wshop/sales_unit/") assert response.status_code == status.HTTP_200_OK data = json.loads(response.content.decode("utf-8")) assert sales_unit.name == data[0]["translations"]["en"]["name"] assert sales_unit.symbol == data[0]["translations"]["en"]["symbol"] assert sales_unit.decimals == data[0]["decimals"] response = client.delete("/api/wshop/sales_unit/%d/" % sales_unit.id) assert response.status_code == status.HTTP_204_NO_CONTENT assert SalesUnit.objects.count() == 0 # create a product and relate it to a sales unit sales_unit = SalesUnit.objects.create(name="Kilo", symbol="KG") product = create_product("product with sales unit", sales_unit=sales_unit) # shouldn't be possible to delete a sales_unit with a related product response = client.delete("/api/wshop/sales_unit/%d/" % sales_unit.id) assert response.status_code == status.HTTP_400_BAD_REQUEST assert "This object can not be deleted because it is referenced by" in response.content.decode("utf-8")
def test_campaign_new_mode_view_formsets(rf, admin_user): view = BasketCampaignEditView get_default_shop() request = apply_request_middleware(rf.get("/"), user=admin_user) form_parts = get_form_parts(request, view, view.model()) assert len(form_parts) == 1 assert issubclass(form_parts[0].__class__, BasketBaseFormPart)
def test_behavior_delete_save(rf, admin_user, view, model, get_object, service_provider_attr): """ Only testing one initial behavior component """ get_default_shop() with override_settings(LANGUAGES=[("en", "en")]): object = get_object() view = view.as_view() service_provider_attr_field = "base-%s" % service_provider_attr component = WeightLimitsBehaviorComponent.objects.create(min_weight=0, max_weight=1) object.behavior_components.add(component) components_before = object.behavior_components.count() assert components_before == 1 data = get_default_data(object, service_provider_attr, service_provider_attr_field, delete=True) data["weightlimitsbehaviorcomponent-0-id"] = component.id data["weightlimitsbehaviorcomponent-INITIAL_FORMS"] = 1 data["weightlimitsbehaviorcomponent-TOTAL_FORMS"] = 2 request = apply_request_middleware(rf.post("/", data=data), user=admin_user) response = view(request, pk=object.pk) if hasattr(response, "render"): response.render() components_after = object.behavior_components.count() assert not components_after assert not WaivingCostBehaviorComponent.objects.first()
def test_permission_group_edit_view(rf, admin_user): get_default_shop() group = get_default_permission_group() view_func = PermissionGroupEditView.as_view() response = view_func( apply_request_middleware(rf.get("/", user=admin_user), pk=group.pk)) assert response.status_code == 200
def test_none_dates_page_not_visible(): # create page that is not anymore visible page = create_page(shop=get_default_shop()) assert not Page.objects.visible( get_default_shop()).filter(pk=page.pk).exists() assert not page.is_visible()
def test_single_page_checkout_with_login_and_register(browser, live_server, settings): cache.clear() # Avoid caches from past tests # initialize product_name = "Test Product" get_default_shop() get_default_payment_method() get_default_shipping_method() product = create_orderable_product(product_name, "test-123", price=100) OrderStatus.objects.create(identifier="initial", role=OrderStatusRole.INITIAL, name="initial", default=True) # Initialize test and go to front page browser = initialize_front_browser_test(browser, live_server) wait_until_condition(browser, lambda x: x.is_text_present("Welcome to Default!")) navigate_to_checkout(browser, product) # Let's assume that after addresses the checkout is normal wait_until_condition(browser, lambda x: x.is_text_present("Checkout Method")) test_username = "******" test_email = "*****@*****.**" test_password = "******" register_test(browser, live_server, test_username, test_email, test_password) login_and_finish_up_the_checkout(browser, live_server, test_username, test_email, test_password)
def get_pico(rf, model=None, columns=None): get_default_shop() model = model or get_user_model() columns = columns or [ Column("id", "Id", filter_config=Filter(), display=instance_id), Column("username", "Username", sortable=False, filter_config=MultiFieldTextFilter( filter_fields=("username", "email"), operator="iregex")), Column("email", "Email", sortable=False, filter_config=TextFilter()), Column("is_superuser", "Is Superuser", display="superuser_display", filter_config=ChoicesFilter(choices=false_and_true())), Column("is_active", "Is Active", filter_config=ChoicesFilter( choices=false_and_true)), # `choices` callable Column("date_joined", "Date Joined", filter_config=DateRangeFilter()) ] request = apply_request_middleware(rf.get("/")) return Picotable(request=request, columns=columns, mass_actions=[], queryset=model.objects.all(), context=PicoContext(request))
def test_register_api(): get_default_shop() configuration.set(None, "api_permission_FrontUserViewSet", PermissionLevel.PUBLIC_WRITE) client = _get_client() register_data = { "username": "******", "password": "******" } response = client.post("/api/wshop/front/user/", content_type="application/json", data=json.dumps(register_data)) assert response.status_code == status.HTTP_201_CREATED response_json = json.loads(response.content.decode("utf-8")) assert "token" in response_json assert get_user_model().objects.count() == 1 # Try to register with same username register_data = { "username": "******", "password": "******" } response = client.post("/api/wshop/front/user/", content_type="application/json", data=json.dumps(register_data)) assert response.status_code == status.HTTP_400_BAD_REQUEST assert "User already exists" in response.content.decode("utf-8")
def test_list_no_orders(admin_user): get_default_shop() client = _get_client(admin_user) response = client.get("/api/wshop/front/orders/") response_data = json.loads(response.content.decode("utf-8")) assert response.status_code == status.HTTP_200_OK assert len(response_data) == 0
def test_set_non_shop_member_customer(rf): """ Set some customer to the basket that is not member of the shop """ with override_settings(**CORE_BASKET_SETTINGS): shop = factories.get_shop(False) assert shop != factories.get_default_shop() user = factories.create_random_user() request = apply_request_middleware(rf.get("/"), user=user) basket = get_basket(request, "basket") basket.customer = get_person_contact(user) assert basket.shop == factories.get_default_shop() person = factories.create_random_person() person.shops.add(shop) company = factories.create_random_company() company.shops.add(shop) for customer in [person, company]: with pytest.raises(ValidationError) as exc: basket_commands.handle_set_customer(request, basket, customer) assert exc.value.code == "invalid_customer_shop" assert basket.customer == get_person_contact(user)
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_edit_view_adding_messages_to_form_group(rf, admin_user): get_default_shop() # obvious prerequisite product = get_default_product() view = ProductEditView.as_view() request = apply_request_middleware(rf.get("/"), user=admin_user) response = view(request, pk=product.pk) response.render() assert 200 <= response.status_code < 300 assert ProductEditView.add_form_errors_as_messages content = force_text(response.content) post = extract_form_fields(BeautifulSoup(content)) post_data = { # Error in the base form part "base-name__en": "", } post.update(post_data) request = apply_request_middleware(rf.post("/", post), user=admin_user) response = view(request, pk=product.pk) errors = response.context_data["form"].errors assert "base" in errors assert "name__en" in errors["base"]
def test_campaign_edit_save(rf, admin_user): """ To make things little bit more simple let's use only english as a language. """ with override_settings(LANGUAGES=[("en", "en")]): shop = get_default_shop() object = BasketCampaign.objects.create(name="test campaign", active=True, shop=shop) object.save() view = BasketCampaignEditView.as_view() new_name = "Test Campaign" assert object.name != new_name data = { "base-name": new_name, "base-public_name__en": "Test Campaign", "base-shop": get_default_shop().id, "base-active": True, "base-basket_line_text": "Test campaign activated!" } methods_before = BasketCampaign.objects.count() # Conditions and effects is tested separately with override_provides("campaign_basket_condition", []): with override_provides("campaign_basket_discount_effect_form", []): with override_provides("campaign_basket_line_effect_form", []): request = apply_request_middleware(rf.post("/", data=data), user=admin_user) response = view(request, pk=object.pk) assert response.status_code in [200, 302] assert BasketCampaign.objects.count() == methods_before assert BasketCampaign.objects.get(pk=object.pk).name == new_name
def test_refund_entire_order(): shop = get_default_shop() supplier = get_simple_supplier() product = create_product( "test-sku", shop=get_default_shop(), default_price=10, stock_behavior=StockBehavior.STOCKED ) supplier.adjust_stock(product.id, 5) check_stock_counts(supplier, product, 5, 5) order = create_order_with_product(product, supplier, 2, 200, Decimal("0.24"), shop=shop) order.cache_prices() original_total_price = order.taxful_total_price check_stock_counts(supplier, product, 5, 3) # Create a full refund with `restock_products` set to False order.create_full_refund(restock_products=False) # Confirm the refund was created with correct amount assert order.taxless_total_price.amount.value == 0 assert order.taxful_total_price.amount.value == 0 refund_line = order.lines.order_by("ordering").last() assert refund_line.type == OrderLineType.REFUND assert refund_line.taxful_price == -original_total_price # Make sure logical count reflects refunded products check_stock_counts(supplier, product, 5, 3)
def test_rules_and_effects(rf, admin_user): """ To make things little bit more simple let's use only english as a language. """ get_default_shop() with override_settings(LANGUAGES=[("en", "en")]): shop = get_default_shop() object = BasketCampaign.objects.create(name="test campaign", active=True, shop=shop) assert object.conditions.count() == 0 assert object.discount_effects.count() == 0 view = BasketCampaignEditView.as_view() data = { "base-name": "test campaign", "base-public_name__en": "Test Campaign", "base-shop": get_default_shop().id, "base-active": True, "base-basket_line_text": "Test campaign activated!" } with override_provides( "campaign_basket_condition", ["wshop.campaigns.admin_module.forms:BasketTotalProductAmountConditionForm"]): with override_provides( "campaign_basket_discount_effect_form", ["wshop.campaigns.admin_module.forms:BasketDiscountAmountForm"]): with override_provides("campaign_basket_line_effect_form", []): data.update(get_products_in_basket_data()) data.update(get_free_product_data(object)) request = apply_request_middleware(rf.post("/", data=data), user=admin_user) view(request, pk=object.pk) object.refresh_from_db() assert object.conditions.count() == 1 assert object.discount_effects.count() == 1
def test_login_with_email_3(client, regular_user, rf): new_user_password = "******" new_user = get_user_model().objects.create_user( username=regular_user.email, password=new_user_password, email=regular_user.email ) get_default_shop() prepare_user(regular_user) redirect_target = "/redirect-success/" # Login with new_user username should work even if there is users with same email response = client.post(reverse("wshop_admin:login"), data={ "username": regular_user.email, "password": new_user_password, REDIRECT_FIELD_NAME: redirect_target }) assert response.get("location") assert response.get("location").endswith(redirect_target) request = rf.get("/") request.session = client.session assert get_user(request) == new_user, "User is logged in"
def test_customer_edit_redirects_to_login_if_not_logged_in(): get_default_shop() # Front middleware needs a Shop to exists urls = ["wshop:customer_edit", "wshop:company_edit"] for url in urls: response = SmartClient().get(reverse(url), follow=False) assert response.status_code == 302 # Redirection ("Found") assert resolve_url(settings.LOGIN_URL) in response.url