def test_same_codes(): shop1 = factories.get_shop(True, "EUR") shop2 = factories.get_shop(True, "USD") dc1 = Coupon.objects.create(code="TEST") dc2 = Coupon.objects.create(code="TEST") BasketCampaign.objects.create(name="test1", active=True, shop_id=shop1.id, coupon_id=dc1.id) with pytest.raises(ValidationError): BasketCampaign.objects.create(name="test1", active=True, shop_id=shop1.id, coupon_id=dc2.id) BasketCampaign.objects.create(name="test2", active=True, shop_id=shop2.id, coupon_id=dc2.id) with pytest.raises(ValidationError): BasketCampaign.objects.create(name="test2", active=True, shop_id=shop2.id, coupon_id=dc1.id) # Disable one campaigns for dc1 and you should be able to set the code to different campaign again dc3 = Coupon.objects.create(code="TEST") BasketCampaign.objects.filter(coupon=dc1).update(active=False) BasketCampaign.objects.create(name="test1", active=True, shop_id=shop1.id, coupon_id=dc3.id) # Try to reactivate the campaign for shop1 c = BasketCampaign.objects.filter(coupon=dc1).first() assert c.active == False with pytest.raises(ValidationError): c.active = True c.save() # Try to sneak one duplicate code by saving the coupon dc4 = Coupon.objects.create(code="TEST1") BasketCampaign.objects.create(name="test4", active=True, shop_id=shop2.id, coupon_id=dc4.id) with pytest.raises(ValidationError): dc4.code = "TEST" dc4.save()
def test_happy_hours_admin_edit_view_over_midnight(rf, staff_user, admin_user): shop = factories.get_default_shop() shop.staff_members.add(staff_user) factories.get_shop(identifier="shop2", enabled=True) assert Shop.objects.count() == 2 # Staff user gets shop automatically from_hour = datetime.time(hour=21, minute=0) to_hour = datetime.time(hour=3, minute=0) data = { "name": "Happiest Hour 2pm", "weekdays": [1], # Tue "from_hour": from_hour, "to_hour": to_hour } request = apply_request_middleware(rf.post("/", data=data), user=staff_user, shop=shop) set_shop(request, shop) assert request.shop == shop view_func = HappyHourEditView.as_view() response = view_func(request) if hasattr(response, "render"): response.render() assert response.status_code == 302 happy_hour = HappyHour.objects.first() assert happy_hour is not None assert happy_hour.shops.first() == shop assert happy_hour.time_ranges.count() == 2 # Since happy hour starts and ends on different day assert happy_hour.time_ranges.filter(weekday=1).exists() assert happy_hour.time_ranges.filter(weekday=1, from_hour=from_hour, to_hour=datetime.time(23, 59)).exists() assert happy_hour.time_ranges.filter(weekday=2, from_hour=datetime.time(0), to_hour=to_hour).exists() _assert_view_get(rf, happy_hour, shop, staff_user) # Viewing the edit should also still work
def test_manufacturer_admin_multishop_shop(rf, staff_user, admin_user, superuser): with override_settings(SHUUP_ENABLE_MULTIPLE_SHOPS=True): shop1 = factories.get_shop(identifier="shop1", enabled=True) shop2 = factories.get_shop(identifier="shop2", enabled=True) shop1.staff_members.add(staff_user) shop2.staff_members.add(staff_user) assert Manufacturer.objects.count() == 0 user = admin_user if superuser else staff_user request = apply_request_middleware(rf.post("/", data=dict(name="Manuf shop2")), user=user, shop=shop2) set_shop(request, shop2) view_func = ManufacturerEditView.as_view() response = view_func(request) assert response.status_code == 302 if superuser: assert Manufacturer.objects.first().shops.count() == 0 else: assert Manufacturer.objects.first().shops.first() == shop2 for view_class in (ManufacturerEditView, ManufacturerListView): view_instance = view_class() view_instance.request= request assert view_instance.get_queryset().count() == 1 if superuser: assert view_instance.get_queryset().first().shops.count() == 0 else: assert view_instance.get_queryset().first().shops.count() == 1 assert view_instance.get_queryset().first().shops.first() == shop2 request = apply_request_middleware(rf.post("/", data=dict(name="Manuf shop1")), user=user, shop=shop1) set_shop(request, shop1) view_func = ManufacturerEditView.as_view() response = view_func(request) assert response.status_code == 302 if superuser: assert Manufacturer.objects.last().shops.count() == 0 else: assert Manufacturer.objects.last().shops.first() == shop1 for view_class in (ManufacturerEditView, ManufacturerListView): view_instance = view_class() view_instance.request= request assert view_instance.get_queryset().count() == (2 if superuser else 1) if superuser: assert view_instance.get_queryset().first().shops.count() == 0 assert view_instance.get_queryset().last().shops.count() == 0 else: assert view_instance.get_queryset().first().shops.count() == 1 assert view_instance.get_queryset().first().shops.first() == shop1
def test_get_shipments(admin_user): client = _get_client(admin_user) shop1 = get_shop(True) shop2 = get_shop(True) customer1 = create_random_person() customer2 = create_random_person() order1 = create_random_order(customer1, shop=shop1, completion_probability=1) order2 = create_random_order(customer2, shop=shop1, completion_probability=1) order3 = create_random_order(customer1, shop=shop2, completion_probability=1) order4 = create_random_order(customer2, shop=shop1, completion_probability=1) # list shipments response = client.get("/api/shuup/shipment/") assert response.status_code == status.HTTP_200_OK shipment_data = json.loads(response.content.decode("utf-8")) assert len(shipment_data) == 4 assert shipment_data[0]["id"] == order1.shipments.first().pk assert shipment_data[1]["id"] == order2.shipments.first().pk assert shipment_data[2]["id"] == order3.shipments.first().pk assert shipment_data[3]["id"] == order4.shipments.first().pk # get shipment by id response = client.get("/api/shuup/shipment/%s/" % order1.shipments.first().pk) assert response.status_code == status.HTTP_200_OK shipment_data = json.loads(response.content.decode("utf-8")) assert shipment_data["id"] == order1.shipments.first().pk assert shipment_data["order"] == order1.pk # get shipment by product product = order2.shipments.first().products.first() response = client.get("/api/shuup/shipment/?product=%s" % product.pk) assert response.status_code == status.HTTP_200_OK shipment_data = json.loads(response.content.decode("utf-8")) for ship in shipment_data: for ship_product in shipment_data["product"]: assert ship_product["id"] == product.pk assert ship_product["order"] == order2.pk # get shipment by order response = client.get("/api/shuup/shipment/?order=%s" % order3.pk) assert response.status_code == status.HTTP_200_OK shipment_data = json.loads(response.content.decode("utf-8")) for ship in shipment_data: assert ship["order"] == order3.pk # get shipment by shop response = client.get("/api/shuup/shipment/?shop=%s" % shop1.pk) assert response.status_code == status.HTTP_200_OK shipment_data = json.loads(response.content.decode("utf-8")) for ship in shipment_data: assert Shipment.objects.filter(pk=ship["id"], order__shop=shop1).exists()
def test_edit_shared_file(admin_user): with override_settings(SHUUP_ENABLE_MULTIPLE_SHOPS=True): shop1 = factories.get_shop(identifier="shop1", enabled=True) shop2 = factories.get_shop(identifier="shop2", enabled=True) folder1 = Folder.objects.create(name="folder1") folder2 = Folder.objects.create(name="folder2") file = File.objects.create(original_filename="test.jpg", folder=folder1) # Shared file file_count = File.objects.count() assert force_text(file) == "test.jpg" response = _mbv_command(shop1, admin_user, {"action": "rename_file", "id": file.pk, "name": "test.tiff"}) assert not response["success"] response = _mbv_command(shop1, admin_user, {"action": "move_file", "file_id": file.pk, "folder_id": folder2.pk}) assert not response["success"] assert File.objects.get(pk=file.pk).folder == folder1 response = _mbv_command(shop1, admin_user, {"action": "delete_file", "id": file.pk}) assert not response["success"] # Let's make sure rename works when only one shop owns the file media_file = MediaFile.objects.create(file=file) media_file.shops.add(shop1) response = _mbv_command(shop1, admin_user, {"action": "rename_file", "id": file.pk, "name": "test.tiff"}) assert response["success"] file = File.objects.get(pk=file.pk) assert force_text(file) == "test.tiff" # Let's move the file to different folder response = _mbv_command(shop1, admin_user, {"action": "move_file", "file_id": file.pk, "folder_id": folder2.pk}) assert response["success"] assert File.objects.get(pk=file.pk).folder == folder2 # Then add second shop for the file and let's check and # renaming should be disabled again. media_file.shops.add(shop2) response = _mbv_command(shop1, admin_user, {"action": "rename_file", "id": file.pk, "name": "test.tiff"}) assert not response["success"] response = _mbv_command(shop1, admin_user, {"action": "delete_file", "id": file.pk}) assert not response["success"] response = _mbv_command(shop2, admin_user, {"action": "rename_file", "id": file.pk, "name": "test.tiff"}) assert not response["success"] response = _mbv_command(shop2, admin_user, {"action": "delete_file", "id": file.pk}) assert not response["success"] # Finally remove the file as shop2 media_file.shops.remove(shop1) response = _mbv_command(shop1, admin_user, {"action": "delete_file", "id": file.pk}) assert response["error"] == "File matching query does not exist." response = _mbv_command(shop2, admin_user, {"action": "delete_file", "id": file.pk}) assert response["success"] assert File.objects.count() == file_count - 1
def test_happy_hours_admin_edit_view(rf, staff_user, admin_user): with override_settings(SHUUP_ENABLE_MULTIPLE_SHOPS=True): shop = factories.get_default_shop() shop.staff_members.add(staff_user) factories.get_shop(identifier="shop2", enabled=True) assert Shop.objects.count() == 2 # Staff user gets shop automatically data = { "name": "Happiest Hour 2pm", "weekdays": [6], # Sun "from_hour": datetime.time(hour=14, minute=0), "to_hour": datetime.time(hour=14, minute=0) } request = apply_request_middleware(rf.post("/", data=data), user=staff_user, shop=shop) set_shop(request, shop) assert request.shop == shop view_func = HappyHourEditView.as_view() response = view_func(request) if hasattr(response, "render"): response.render() assert response.status_code == 302 happy_hour1 = HappyHour.objects.first() assert happy_hour1 is not None assert happy_hour1.shops.first() == shop assert happy_hour1.time_ranges.count() == 1 # Since happy hour starts and ends on same day # Test with superuser and with different shop shop2 = factories.get_shop(enabled=True) request = apply_request_middleware(rf.post("/", data=data), user=admin_user, shop=shop2) set_shop(request, shop2) view_func = HappyHourEditView.as_view() response = view_func(request) assert response.status_code == 302 assert HappyHour.objects.count() == 2 happy_hour2 = HappyHour.objects.exclude(id=happy_hour1.pk).first() assert happy_hour1 != happy_hour2 assert happy_hour2.shops.count() == 1 assert happy_hour2.shops.filter(id=shop2.pk).first() # Staff user can only view coupon codes since that has the right shop _assert_view_get(rf, happy_hour1, shop, staff_user) _assert_view_get(rf, happy_hour2, shop, staff_user, True) # Superuser can see both if needed, but only when right shop is active _assert_view_get(rf, happy_hour1, shop, admin_user) _assert_view_get(rf, happy_hour2, shop, admin_user, True) _assert_view_get(rf, happy_hour2, shop2, admin_user)
def test_exceptions_admin_edit_view(rf, staff_user, admin_user): with override_settings(SHUUP_ENABLE_MULTIPLE_SHOPS=True): shop = factories.get_default_shop() shop.staff_members.add(staff_user) factories.get_shop(identifier="shop2", enabled=True) assert Shop.objects.count() == 2 # Staff user gets shop automatically data = { "name": "No deals in next 2 days!", "start_datetime": datetime.datetime(year=2018, month=11, day=9), "end_datetime": datetime.datetime(year=2018, month=11, day=11), } request = apply_request_middleware(rf.post("/", data=data), user=staff_user, shop=shop) set_shop(request, shop) assert request.shop == shop view_func = AvailabilityExceptionEditView.as_view() response = view_func(request) if hasattr(response, "render"): response.render() assert response.status_code == 302 exception1 = AvailabilityException.objects.first() assert exception1 is not None assert exception1.shops.first() == shop # Test with superuser and with different shop shop2 = factories.get_shop(enabled=True) request = apply_request_middleware(rf.post("/", data=data), user=admin_user, shop=shop2) set_shop(request, shop2) view_func = AvailabilityExceptionEditView.as_view() response = view_func(request) assert response.status_code == 302 assert AvailabilityException.objects.count() == 2 exception2 = AvailabilityException.objects.exclude(id=exception1.pk).first() assert exception1 != exception2 assert exception2.shops.count() == 1 assert exception2.shops.filter(id=shop2.pk).exists() # Staff user can only view coupon codes since that has the right shop _assert_view_get(rf, exception1, shop, staff_user) _assert_view_get(rf, exception2, shop, staff_user, True) # Superuser can see both if needed, but only when right shop is active _assert_view_get(rf, exception1, shop, admin_user) _assert_view_get(rf, exception2, shop, admin_user, True) _assert_view_get(rf, exception2, shop2, admin_user)
def test_module(address, expected_taxes): """ Test the DefaultTaxModule. """ # Create a product shop = get_shop(prices_include_tax=False, currency='USD') product = create_product('PROD', shop=shop, default_price=1000) price = product.get_shop_instance(shop).default_price # Put the tax rules into database for ruledef in shuffled(TAX_RULE_DEFS): rule = ruledef.get_tax_rule() rule.tax.save() rule.tax = rule.tax # refresh the id rule.save() rule.tax_classes.add(product.tax_class) assert TaxRule.objects.count() == len(TAX_RULE_DEFS) with override_settings(SHUUP_TAX_MODULE='default_tax'): module = get_tax_module() assert isinstance(module, DefaultTaxModule) context = TaxingContext(location=address) taxed_price = module.get_taxed_price_for(context, product, price) expected_codes = set(sum([x.split() for x in expected_taxes], [])) assert set(x.tax.code for x in taxed_price.taxes) == expected_codes expected_tax = Money(TAX_AMOUNTS[expected_taxes], 'USD') assert taxed_price.taxful.amount == price.amount + expected_tax # Clean-up the rules TaxRule.objects.all().delete()
def test_category_tour(browser, admin_user, live_server, settings): shop = factories.get_default_shop() shop2 = factories.get_shop(identifier="shop2") admin_user_2 = factories.create_random_user(is_staff=True, is_superuser=True) admin_user_2.set_password("password") admin_user_2.save() shop.staff_members.add(admin_user) shop.staff_members.add(admin_user_2) for user in [admin_user, admin_user_2]: initialize_admin_browser_test(browser, live_server, settings, username=user.username, tour_complete=False) wait_until_condition(browser, lambda x: x.is_text_present("Welcome!")) browser.visit(live_server + "/sa/categories/new") wait_until_condition(browser, lambda x: x.is_text_present("Add a new product category"), timeout=30) wait_until_condition(browser, lambda x: x.is_element_present_by_css(".shepherd-button.btn-primary")) click_element(browser, ".shepherd-button.btn-primary") wait_until_condition(browser, lambda x: not x.is_element_present_by_css(".shepherd-button")) wait_until_condition(browser, lambda x: is_tour_complete(shop, "category", user)) # check whether the tour is shown again browser.visit(live_server + "/sa/categories/new") wait_until_condition(browser, lambda x: not x.is_text_present("Add a new product category")) browser.visit(live_server + "/logout") browser.visit(live_server + "/sa") assert is_tour_complete(shop2, "category", user) is False
def test_order_creator_account_manager(): company = create_random_company() shop = get_shop(identifier="random-shop", enabled=True) source = seed_source(create_random_user(), shop) source.customer = company source.add_line( type=OrderLineType.PRODUCT, product=get_default_product(), supplier=get_default_supplier(), quantity=1, base_unit_price=source.create_price(10), ) creator = OrderCreator() order = creator.create_order(source) assert order.account_manager is None # Company contact doesn't have account manager field person = create_random_person() person.account_manager = create_random_person() person.save() source = seed_source(create_random_user(), shop) source.customer = person source.add_line( type=OrderLineType.PRODUCT, product=get_default_product(), supplier=get_default_supplier(), quantity=1, base_unit_price=source.create_price(10), ) creator = OrderCreator() order = creator.create_order(source) assert order.account_manager is not None assert order.account_manager == person.account_manager with pytest.raises(ProtectedError): person.account_manager.delete()
def _test_exception_delete_view(rf, index): shop = factories.get_shop(identifier="shop%s" % index, enabled=True) staff_user = factories.create_random_user(is_staff=True) shop.staff_members.add(staff_user) exception_name = "Exception %s" % index exception = AvailabilityException.objects.create( name=exception_name, start_datetime=now(), end_datetime=now()) exception.shops = [shop] extra_exception = AvailabilityException.objects.create( name="Extra Exception %s" % index, start_datetime=now(), end_datetime=now()) extra_exception.shops = [shop] assert AvailabilityException.objects.filter(name=exception_name).exists() view_func = AvailabilityExceptionDeleteView.as_view() request = apply_request_middleware(rf.post("/"), user=staff_user, shop=shop) set_shop(request, shop) response = view_func(request, pk=exception.pk) if hasattr(response, "render"): response.render() assert response.status_code == 302 assert not AvailabilityException.objects.filter(name=exception_name).exists() # Make sure that this staff can't remove other people discounts other_exceptions = AvailabilityException.objects.exclude(shops=shop) exception_count = other_exceptions.count() for coupon in other_exceptions: view_func = AvailabilityExceptionDeleteView.as_view() request = apply_request_middleware(rf.post("/"), user=staff_user, shop=shop) set_shop(request, shop) with pytest.raises(Http404): response = view_func(request, pk=coupon.pk) if hasattr(response, "render"): response.render() assert exception_count == AvailabilityException.objects.exclude(shops=shop).count()
def _test_happy_hours_delete_view(rf, index): shop = factories.get_shop(identifier="shop%s" % index, enabled=True) staff_user = factories.create_random_user(is_staff=True) shop.staff_members.add(staff_user) happy_hour_name = "The Hour %s" % index happy_hour = HappyHour.objects.create(name=happy_hour_name) happy_hour.shops = [shop] extra_happy_hour= HappyHour.objects.create(name="Extra Hour %s" % index) extra_happy_hour.shops = [shop] assert HappyHour.objects.filter(name=happy_hour_name).exists() view_func = HappyHourDeleteView.as_view() request = apply_request_middleware(rf.post("/"), user=staff_user, shop=shop) set_shop(request, shop) response = view_func(request, pk=happy_hour.pk) if hasattr(response, "render"): response.render() assert response.status_code == 302 assert not HappyHour.objects.filter(name=happy_hour_name).exists() # Make sure that this staff can't remove other people discounts other_exceptions = HappyHour.objects.exclude(shops=shop) exception_count = other_exceptions.count() for coupon in other_exceptions: view_func = HappyHourDeleteView.as_view() request = apply_request_middleware(rf.post("/"), user=staff_user, shop=shop) set_shop(request, shop) with pytest.raises(Http404): response = view_func(request, pk=coupon.pk) if hasattr(response, "render"): response.render() assert exception_count == HappyHour.objects.exclude(shops=shop).count()
def get_request_for_contact_tests(rf): activate("en") request = rf.get("/") request.shop = get_shop(prices_include_tax=True) get_payment_method(request.shop) apply_request_middleware(request) return request
def _get_source(user, prices_include_taxes, total_price_value): shop = get_shop(prices_include_taxes) payment_method = get_payment_method(shop) shipping_method = get_shipping_method(shop) source = _seed_source(shop, user) source.payment_method = payment_method source.shipping_method = shipping_method assert source.payment_method_id == payment_method.id assert source.shipping_method_id == shipping_method.id supplier = get_default_supplier() product = create_product( sku="test-%s--%s" % (prices_include_taxes, total_price_value), shop=source.shop, supplier=supplier, default_price=total_price_value ) source.add_line( type=OrderLineType.PRODUCT, product=product, supplier=supplier, quantity=1, base_unit_price=source.create_price(total_price_value), ) if prices_include_taxes: assert source.taxful_total_price.value == total_price_value else: assert source.taxless_total_price.value == total_price_value assert payment_method == source.payment_method assert shipping_method == source.shipping_method return source, shipping_method
def test_stacked_tax_taxful_price(): shop = get_shop(prices_include_tax=True, currency='EUR') source = OrderSource(shop) assert source.prices_include_tax source.add_line( type=OrderLineType.OTHER, quantity=1, base_unit_price=source.create_price(20) ) with override_provides("tax_module", TAX_MODULE_SPEC): with override_settings(SHUUP_TAX_MODULE="irvine"): source.shipping_address = MutableAddress( street="16215 Alton Pkwy", postal_code="92602", ) line = source.get_final_lines(with_taxes=True)[0] assert isinstance(line, SourceLine) assert line.taxes assert line.taxful_price == TaxfulPrice(20, 'EUR') assert_almost_equal(line.taxless_price, TaxlessPrice("18.52", 'EUR')) source.uncache() # Let's move out to a taxless location. source.shipping_address.postal_code = "11111" line = source.get_final_lines(with_taxes=True)[0] assert isinstance(line, SourceLine) assert not line.taxes assert line.taxful_price == TaxfulPrice(20, source.currency) assert line.taxless_price.value == Decimal("20")
def test_editing_sales_ranges_multi_shop(rf, admin_user): get_default_shop() another_shop = get_shop(prices_include_tax=True) another_shop.status = ShopStatus.ENABLED another_shop.save() group = get_default_customer_group() data = {} for shop in Shop.objects.all(): data.update(get_edit_view_data(shop, group, 0, 50)) assert ContactGroupSalesRange.objects.count() == 0 # To make this test work we need to mock members form_part since the extra # forms does not render correctly with patch.object(ContactGroupEditView, "base_form_part_classes", [ContactGroupBaseFormPart]): request = apply_request_middleware(rf.post("/", data=data), user=admin_user) view = ContactGroupEditView.as_view() response = view(request=request, pk=group.pk) if hasattr(response, "render"): response.render() assert response.status_code in [200, 302] assert ContactGroupSalesRange.objects.count() == 2 for shop in Shop.objects.all(): sales_range = ContactGroupSalesRange.objects.filter(group=group, shop=shop).first() assert sales_range.min_value == 0 assert sales_range.max_value == 50
def _get_source(user, shipping_country, billing_country): prices_include_taxes = True shop = get_shop(prices_include_taxes) payment_method = get_payment_method(shop) shipping_method = get_shipping_method(shop) source = _seed_source(shop, user, shipping_country, billing_country) source.payment_method = payment_method source.shipping_method = shipping_method assert source.payment_method_id == payment_method.id assert source.shipping_method_id == shipping_method.id supplier = get_default_supplier() product = create_product( sku="test-%s--%s" % (prices_include_taxes, 10), shop=source.shop, supplier=supplier, default_price=10 ) source.add_line( type=OrderLineType.PRODUCT, product=product, supplier=supplier, quantity=1, base_unit_price=source.create_price(10), ) assert payment_method == source.payment_method assert shipping_method == source.shipping_method return source
def _test_happy_hours_list_view(rf, index): shop = factories.get_shop(identifier="shop%s" % index, enabled=True) staff_user = factories.create_random_user(is_staff=True) shop.staff_members.add(staff_user) happy_hour = HappyHour.objects.create(name="After Work %s" % index) happy_hour.shops = [shop] view_func = HappyHourListView.as_view() request = apply_request_middleware( rf.get("/", { "jq": json.dumps({"perPage": 100, "page": 1}) }), user=staff_user, shop=shop) set_shop(request, shop) response = view_func(request) if hasattr(response, "render"): response.render() assert response.status_code == 200 view_instance = HappyHourListView() view_instance.request = request assert request.shop == shop assert view_instance.get_queryset().count() == 1 data = json.loads(view_instance.get(request).content.decode("UTF-8")) assert len(data["items"]) == 1
def test_rules_with_disabled_tax(): """ Test whether rules match when tax is disabled """ tax_class = TaxClass.objects.create(name="test") # Create a product shop = get_shop(prices_include_tax=False, currency='USD') product = create_product('PROD', shop=shop, default_price=1000) product.tax_class = tax_class product.save() price = product.get_shop_instance(shop).default_price # create disabled tax tax = Tax.objects.create(code="any", rate=0.1, name="Tax for any customer", enabled=False) tax_rule = TaxRule.objects.create(tax=tax) tax_rule.tax_classes.add(tax_class) with override_settings(SHUUP_TAX_MODULE='default_tax'): module = get_tax_module() assert isinstance(module, DefaultTaxModule) # 1) check the tax for anonymous anonymous_context = TaxingContext() taxed_price = module.get_taxed_price_for(anonymous_context, product, price) assert len(list(taxed_price.taxes)) == 0 # Clean-up the rules TaxRule.objects.all().delete()
def test_product_tour(browser, admin_user, live_server, settings): shop = factories.get_default_shop() shop2 = factories.get_shop(identifier="shop2") admin_user_2 = factories.create_random_user(is_staff=True, is_superuser=True) admin_user_2.set_password("password") admin_user_2.save() product = factories.get_default_product() shop_product = product.get_shop_instance(shop) shop.staff_members.add(admin_user) shop.staff_members.add(admin_user_2) for user in [admin_user, admin_user_2]: initialize_admin_browser_test(browser, live_server, settings, username=user.username, tour_complete=False) wait_until_condition(browser, lambda x: x.is_text_present("Welcome!")) browser.visit(live_server + "/sa/products/%d/" % shop_product.pk) wait_until_condition(browser, lambda x: x.is_text_present(shop_product.product.name)) # as this is added through javascript, add an extra timeout wait_until_condition(browser, lambda x: x.is_text_present("You are adding a product."), timeout=30) wait_until_condition(browser, lambda x: x.is_element_present_by_css(".shepherd-button.btn-primary")) click_element(browser, ".shepherd-button.btn-primary") category_targets = [ "a.shepherd-enabled[href='#basic-information-section']", "a.shepherd-enabled[href='#additional-details-section']", "a.shepherd-enabled[href='#manufacturer-section']", "a.shepherd-enabled[href*='-additional-section']", "a.shepherd-enabled[href='#product-media-section']", "a.shepherd-enabled[href='#product-images-section']", "a.shepherd-enabled[href='#contact-group-pricing-section']", "a.shepherd-enabled[href='#contact-group-discount-section']" ] # Scroll top before starting to click. For some reason the first # item is not found without this. For Firefox or Chrome the browser # does not do any extra scroll which could hide the first item. # Steps are scrollTo false on purpose since the scrollTo true is the # config which does not work in real world. browser.execute_script("window.scrollTo(0,0)") for target in category_targets: try: wait_until_condition(browser, lambda x: x.is_element_present_by_css(target)) browser.find_by_css(".shepherd-button.btn-primary").last.click() except ElementNotInteractableException: move_to_element(browser, ".shepherd-button.btn-primary") wait_until_condition(browser, lambda x: x.is_element_present_by_css(target)) browser.find_by_css(".shepherd-button.btn-primary").last.click() wait_until_condition(browser, lambda x: is_tour_complete(shop, "product", user)) # check whether the tour is shown again browser.visit(live_server + "/sa/products/%d/" % shop_product.pk) wait_until_condition(browser, lambda x: not x.is_text_present("You are adding a product."), timeout=20) assert is_tour_complete(shop2, "product", user) is False browser.visit(live_server + "/logout") browser.visit(live_server + "/sa")
def test_media_view_images(rf): with override_settings(SHUUP_ENABLE_MULTIPLE_SHOPS=True): shop1 = factories.get_shop(identifier="shop1", enabled=True) shop1_staff1 = _create_random_staff(shop1) shop1_staff2 = _create_random_staff(shop1) shop2 = factories.get_shop(identifier="shop2", enabled=True) shop2_staff = _create_random_staff(shop2) # Let's agree this folder is created by for example carousel # so it would be shared with all the shops. folder = Folder.objects.create(name="Root") assert MediaFolder.objects.count() == 0 path = "/%s" % folder.name File.objects.create(name="normalfile", folder=folder) # Shared between shops # Let's create 4 images for shop 1 _mbv_upload(shop1, shop1_staff1, path=path) _mbv_upload(shop1, shop1_staff1, path=path) _mbv_upload(shop1, shop1_staff2, path=path) _mbv_upload(shop1, shop1_staff2, path=path) assert MediaFile.objects.count() == 4 # Let's create 3 images for shop 2 _mbv_upload(shop2, shop2_staff, path=path) _mbv_upload(shop2, shop2_staff, path=path) _mbv_upload(shop2, shop2_staff, path=path) assert MediaFile.objects.count() == 7 # All files were created to same folder and while uploading # the each shop declared that they own the folder. assert Folder.objects.count() == 1 assert MediaFolder.objects.count() == 1 assert MediaFolder.objects.filter(shops=shop1).exists() assert shop1.media_folders.count() == 1 assert shop1.media_files.count() == 4 assert MediaFolder.objects.filter(shops=shop2).exists() assert shop2.media_folders.count() == 1 assert shop2.media_files.count() == 3 # Now let's make sure that each staff can view the folder # and all the files she should see. _check_that_staff_can_see_folder(rf, shop1, shop1_staff1, folder, 5) _check_that_staff_can_see_folder(rf, shop1, shop1_staff2, folder, 5) _check_that_staff_can_see_folder(rf, shop2, shop2_staff, folder, 4)
def test_page_different_shops(rf): shop1 = get_shop(status=ShopStatus.ENABLED, identifier="shop-1", name="Shop 1", domain="shop1") shop2 = get_shop(status=ShopStatus.ENABLED, identifier="shop-2", name="Shop 2", domain="shop2") # dreate page only for shop2 page = create_page(available_from=datetime.date(1988, 1, 1), shop=shop2) view_func = PageView.as_view() request = apply_request_middleware(rf.get("/", HTTP_HOST=shop1.domain)) with pytest.raises(Http404): response = view_func(request, url=page.url) request = apply_request_middleware(rf.get("/", HTTP_HOST=shop2.domain)) response = view_func(request, url=page.url) assert response.status_code == 200 response.render() assert "<h1>Bacon ipsum" in response.rendered_content
def test_rules_with_anonymous(): """ Test the DefaultTaxModule with anonymous customer. """ tax_class = TaxClass.objects.create(name="test") # Create a product shop = get_shop(prices_include_tax=False, currency='USD') product = create_product('PROD', shop=shop, default_price=1000) product.tax_class = tax_class product.save() price = product.get_shop_instance(shop).default_price # create taxes # When customer is company, it should pay additional taxes tax_for_anyone = Tax.objects.create(code="any", rate=0.1, name="Tax for any customer") tax_for_companies = Tax.objects.create(code="companies", rate=0.3, name="Additional tax for companies") # create tax group for companies companies_tax_group = CustomerTaxGroup.get_default_company_group() # create the tax rule as follows: # - 10% for any kind of customer, no matter what # - 30% only for companies any_tax_rule = TaxRule.objects.create(tax=tax_for_anyone) any_tax_rule.tax_classes.add(tax_class) company_tax_rule = TaxRule.objects.create(tax=tax_for_companies) company_tax_rule.tax_classes.add(tax_class) company_tax_rule.customer_tax_groups.add(companies_tax_group) with override_settings(SHUUP_TAX_MODULE='default_tax'): module = get_tax_module() assert isinstance(module, DefaultTaxModule) # 1) check the tax for anonymous anonymous_context = TaxingContext() taxed_price = module.get_taxed_price_for(anonymous_context, product, price) expected_anonymous_codes = set(["any"]) assert set(x.tax.code for x in taxed_price.taxes) == expected_anonymous_codes # 2) check the tax for comanies company_context = TaxingContext(customer_tax_group=companies_tax_group) taxed_price = module.get_taxed_price_for(company_context, product, price) expected_companies_codes = set(["any", "companies"]) assert set(x.tax.code for x in taxed_price.taxes) == expected_companies_codes # Clean-up the rules TaxRule.objects.all().delete()
def test_resource_injection(client): """ Test that the GDPR warning is injected into the front template when enabled """ activate("en") shop = factories.get_default_shop() client = SmartClient() index_url = reverse("shuup:index") response = client.get(index_url) assert "gdpr-consent-warn-bar" not in response.content.decode("utf-8") # create a GDPR setting for the shop shop_gdpr = GDPRSettings.get_for_shop(shop) shop_gdpr.cookie_banner_content = "my cookie banner content" shop_gdpr.cookie_privacy_excerpt = " my cookie privacyexcerpt" shop_gdpr.enabled = True shop_gdpr.save() # the contents should be injected in the html response = client.get(index_url) response_content = response.content.decode("utf-8") assert "gdpr-consent-warn-bar" in response_content assert shop_gdpr.cookie_banner_content in response_content assert shop_gdpr.cookie_privacy_excerpt in response_content # create cookie categories cookie_category = GDPRCookieCategory.objects.create( shop=shop, always_active=True, cookies="cookie1,cookie2,_cookie3", name="RequiredCookies", how_is_used="to make the site work") default_active_cookie_category = GDPRCookieCategory.objects.create( shop=shop, always_active=False, default_active=True, cookies="analyticsCookie", name="Analytics", how_is_used="to track users") response, soup = client.response_and_soup(index_url) response_content = response.content.decode("utf-8") assert "gdpr-consent-warn-bar" in response_content assert cookie_category.cookies in response_content assert cookie_category.name in response_content assert cookie_category.how_is_used in response_content default_active_input = soup.find( "input", {"name": "cookie_category_%d" % default_active_cookie_category.pk}) assert default_active_input.has_attr("checked") # make sure no other shop has this with override_settings(SHUUP_ENABLE_MULTIPLE_SHOPS=True): shop2 = factories.get_shop(identifier="shop2", status=ShopStatus.DISABLED, domain="shop2") response = client.get(index_url, HTTP_HOST=shop2.domain) response_content = response.content.decode("utf-8") assert "gdpr-consent-warn-bar" not in response_content
def test_discount_admin_edit_view(rf, staff_user, admin_user): with override_settings(SHUUP_ENABLE_MULTIPLE_SHOPS=True): shop = factories.get_default_shop() shop.staff_members.add(staff_user) factories.get_shop(identifier="shop2") assert Shop.objects.count() == 2 # Staff user gets shop automatically product = factories.create_product("test", shop=shop) discount_percentage = 20 data = {"product": product.pk, "discount_percentage": discount_percentage} request = apply_request_middleware(rf.post("/", data=data), user=staff_user, shop=shop) set_shop(request, shop) assert request.shop == shop view_func = DiscountEditView.as_view() response = view_func(request) if hasattr(response, "render"): response.render() assert response.status_code == 302 discount1 = Discount.objects.first() assert discount1.shops.first() == shop # Test with superuser and with different shop shop2 = factories.get_shop(enabled=True) request = apply_request_middleware(rf.post("/", data=data), user=admin_user, shop=shop2) set_shop(request, shop2) view_func = DiscountEditView.as_view() response = view_func(request) assert response.status_code == 302 assert Discount.objects.count() == 2 discount2 = Discount.objects.exclude(id=discount1.pk).first() assert discount1 != discount2 assert discount2.shops.count() == 1 assert discount2.shops.filter(id=shop2.pk).exists() # Staff user can only view discount1 since that has the right shop _assert_view_get(rf, discount1, shop, staff_user) _assert_view_get(rf, discount2, shop, staff_user, True) # Superuser can see both if needed, but only when right shop is active _assert_view_get(rf, discount1, shop, admin_user) _assert_view_get(rf, discount2, shop, admin_user, True) _assert_view_get(rf, discount2, shop2, admin_user)
def test_sample_import_all_match_all_shops(filename, rf): activate("en") shop1 = get_shop(identifier="shop1", domain="shop1", enabled=True) shop2 = get_shop(identifier="shop2", domain="shop2", enabled=True) Product.objects.all().delete() tax_class = get_default_tax_class() product_type = get_default_product_type() sales_unit = get_default_sales_unit() path = os.path.join(os.path.dirname(__file__), "data", "product", filename) transformed_data = transform_file(filename.split(".")[1], path) for shop in [shop1, shop2]: importer = ProductImporter( transformed_data, ProductImporter.get_importer_context(rf.get("/"), shop=shop, language="en")) importer.process_data() assert len(importer.unmatched_fields) == 0 importer.do_import(ImportMode.CREATE_UPDATE) products = importer.new_objects if shop == shop1: # products created assert len(products) == 2 else: # products already exist assert len(products) == 0 assert Product.objects.count() == 2 for product in Product.objects.all(): shop_product = product.get_shop_instance(shop) assert shop_product.pk assert shop_product.default_price_value == 150 assert shop_product.default_price == shop.create_price(150) assert product.type == product_type # product type comes from importer defaults assert product.sales_unit == sales_unit assert shop_product.primary_category.pk == 1 assert [c.pk for c in shop_product.categories.all()] == [1, 2] assert ShopProduct.objects.count() == 4
def test_product_tour(browser, admin_user, live_server, settings): shop = factories.get_default_shop() shop2 = factories.get_shop(identifier="shop2") admin_user_2 = factories.create_random_user(is_staff=True, is_superuser=True) admin_user_2.set_password("password") admin_user_2.save() product = factories.get_default_product() shop_product = product.get_shop_instance(shop) shop.staff_members.add(admin_user) shop.staff_members.add(admin_user_2) for user in [admin_user, admin_user_2]: initialize_admin_browser_test(browser, live_server, settings, username=user.username, tour_complete=False) wait_until_condition(browser, lambda x: x.is_text_present("Welcome!")) browser.visit(live_server + "/sa/products/%d/" % shop_product.pk) wait_until_condition( browser, lambda x: x.is_text_present("You are adding a product.")) wait_until_condition( browser, lambda x: x.is_element_present_by_css( ".shepherd-button.btn-primary")) click_element(browser, ".shepherd-button.btn-primary") category_targets = [ "a.shepherd-enabled[href='#basic-information-section']", "a.shepherd-enabled[href='#additional-details-section']", "a.shepherd-enabled[href='#manufacturer-section']", "a.shepherd-enabled[href*='-additional-section']", "a.shepherd-enabled[href='#product-media-section']", "a.shepherd-enabled[href='#product-images-section']", "a.shepherd-enabled[href='#contact-group-pricing-section']", "a.shepherd-enabled[href='#contact-group-discount-section']" ] for target in category_targets: wait_until_condition(browser, lambda x: x.is_element_present_by_css(target)) move_to_element(browser, ".shepherd-button.btn-primary") browser.find_by_css(".shepherd-button.btn-primary").last.click() wait_until_condition(browser, lambda x: is_tour_complete(shop, "product", user)) # check whether the tour is shown again browser.visit(live_server + "/sa/products/%d/" % shop_product.pk) wait_until_condition( browser, lambda x: not x.is_text_present("You are adding a product.")) assert is_tour_complete(shop2, "product", user) is False browser.visit(live_server + "/logout") browser.visit(live_server + "/sa")
def test_coupon_codes_admin_edit_view(rf, staff_user, admin_user): with override_settings(SHUUP_ENABLE_MULTIPLE_SHOPS=True): shop = factories.get_default_shop() shop.staff_members.add(staff_user) factories.get_shop(identifier="shop2", enabled=True) assert Shop.objects.count() == 2 # Staff user gets shop automatically data = {"code": "potus"} request = apply_request_middleware(rf.post("/", data=data), user=staff_user, shop=shop) set_shop(request, shop) assert request.shop == shop view_func = CouponCodeEditView.as_view() response = view_func(request) if hasattr(response, "render"): response.render() assert response.status_code == 302 coupon1 = CouponCode.objects.first() assert coupon1.shops.first() == shop # Test with superuser and with different shop shop2 = factories.get_shop(enabled=True) request = apply_request_middleware(rf.post("/", data=data), user=admin_user, shop=shop2) set_shop(request, shop2) assert request.shop == shop2 view_func = CouponCodeEditView.as_view() response = view_func(request) assert response.status_code == 302 assert CouponCode.objects.count() == 2 coupon2 = CouponCode.objects.exclude(id=coupon1.pk).first() assert coupon1 != coupon2 assert coupon2.shops.count() == 1 assert coupon2.shops.filter(id=shop2.pk).exists() # Staff user can only view coupon codes for his shop _assert_view_get(rf, coupon1, shop, staff_user) _assert_view_get(rf, coupon2, shop, staff_user, True) # Superuser can see both if needed, but only when right shop is active _assert_view_get(rf, coupon1, shop, admin_user) _assert_view_get(rf, coupon2, shop, admin_user, True) _assert_view_get(rf, coupon2, shop2, admin_user)
def initialize_test(rf, include_tax=False, customer=create_customer): shop = get_shop(prices_include_tax=include_tax) if callable(customer): customer = customer() request = apply_request_middleware(rf.get("/")) request.shop = shop request.customer = customer return request, shop, customer.groups.first()
def initialize_test(rf, include_tax=False, customer=create_customer): shop = get_shop(prices_include_tax=include_tax) if callable(customer): customer = customer() request = apply_request_middleware(rf.get("/")) request.shop = shop request.customer = customer return request, shop, customer.groups.first()
def test_contact_in_shops(regular_user): shop1 = get_default_shop() shop2 = get_shop(identifier="shop-2") shop3 = get_shop(identifier="shop-3") contact = get_person_contact(regular_user) all_shop_ids = [shop1.pk, shop2.pk, shop3.pk] contact.add_to_shops(shop1, [shop2, shop3]) assert contact.registered_in(shop1) assert not contact.registered_in(shop2) assert not contact.registered_in(shop3) assert contact.in_shop(shop1) assert contact.in_shop(shop2) assert contact.in_shop(shop3) assert contact.shops.filter( pk__in=all_shop_ids).count() == len(all_shop_ids) contact.add_to_shops(shop2, [shop1, shop3]) assert contact.registered_in(shop1) assert not contact.registered_in(shop2) assert not contact.registered_in(shop3) assert contact.in_shop(shop1) assert contact.in_shop(shop2) assert contact.in_shop(shop3) assert contact.shops.filter( pk__in=all_shop_ids).count() == len(all_shop_ids) contact.registration_shop = None contact.shops.clear() contact.save() contact.add_to_shops(shop2, [shop1, shop3]) assert not contact.registered_in(shop1) assert contact.registered_in(shop2) assert not contact.registered_in(shop3) assert contact.in_shop(shop1) assert contact.in_shop(shop2) assert contact.in_shop(shop3) assert contact.shops.filter( pk__in=all_shop_ids).count() == len(all_shop_ids)
def test_happy_hours_admin_edit_view_over_midnight(rf, staff_user, admin_user): shop = factories.get_default_shop() shop.staff_members.add(staff_user) factories.get_shop(identifier="shop2", enabled=True) assert Shop.objects.count() == 2 # Staff user gets shop automatically from_hour = datetime.time(hour=21, minute=0) to_hour = datetime.time(hour=3, minute=0) data = { "name": "Happiest Hour 2pm", "weekdays": [1], # Tue "from_hour": from_hour, "to_hour": to_hour } request = apply_request_middleware(rf.post("/", data=data), user=staff_user, shop=shop) set_shop(request, shop) assert request.shop == shop view_func = HappyHourEditView.as_view() response = view_func(request) if hasattr(response, "render"): response.render() assert response.status_code == 302 happy_hour = HappyHour.objects.first() assert happy_hour is not None assert happy_hour.shops.first() == shop assert happy_hour.time_ranges.count( ) == 2 # Since happy hour starts and ends on different day assert happy_hour.time_ranges.filter(weekday=1).exists() assert happy_hour.time_ranges.filter(weekday=1, from_hour=from_hour, to_hour=datetime.time(23, 59)).exists() assert happy_hour.time_ranges.filter(weekday=2, from_hour=datetime.time(0), to_hour=to_hour).exists() _assert_view_get(rf, happy_hour, shop, staff_user) # Viewing the edit should also still work
def test_can_complete_productless_order(rf, admin_user): shop = get_shop(prices_include_tax=False) supplier = get_default_supplier() request = rf.get('/') request.shop = shop apply_request_middleware(request) customer = get_person_contact(admin_user) order = create_simple_order(request, admin_user, customer) assert not order.has_products() assert order.can_set_complete() assert not order.is_fully_shipped()
def test_admin_script_list(rf, admin_user): with override_settings(SHUUP_ENABLE_MULTIPLE_SHOPS=True): shop1 = factories.get_shop(identifier="shop-1") shop2 = factories.get_shop(identifier="shop-2") shop1.staff_members.add(admin_user) shop2.staff_members.add(admin_user) script_shop1 = Script.objects.create(shop=shop1, event_identifier="order_received", name="SHOP 1", enabled=True) script_shop2 = Script.objects.create(shop=shop2, event_identifier="order_received", name="SHOP 2", enabled=True) view = ScriptEditView.as_view() request = apply_request_middleware(rf.get("/"), user=admin_user) set_shop(request, shop2) with pytest.raises(Http404): response = view(request, pk=script_shop1.id) response = view(request, pk=script_shop2.id) assert response.status_code == 200
def test_can_complete_productless_order(rf, admin_user): shop = get_shop(prices_include_tax=False) supplier = get_default_supplier() request = rf.get('/') request.shop = shop apply_request_middleware(request) customer = get_person_contact(admin_user) order = create_simple_order(request, admin_user, customer) assert not order.has_products() assert order.can_set_complete() assert not order.is_fully_shipped()
def test_admin_script_list(rf, admin_user): with override_settings(SHUUP_ENABLE_MULTIPLE_SHOPS=True): shop1 = factories.get_shop(identifier="shop-1", enabled=True) shop2 = factories.get_shop(identifier="shop-2", enabled=True) shop1.staff_members.add(admin_user) shop2.staff_members.add(admin_user) script_shop1 = Script.objects.create(shop=shop1, event_identifier="order_received", name="SHOP 1", enabled=True) script_shop2 = Script.objects.create(shop=shop2, event_identifier="order_received", name="SHOP 2", enabled=True) view = ScriptEditView.as_view() request = apply_request_middleware(rf.get("/"), user=admin_user) set_shop(request, shop2) with pytest.raises(Http404): response = view(request, pk=script_shop1.id) response = view(request, pk=script_shop2.id) assert response.status_code == 200
def test_wishlist_create_with_product(admin_user, rf): activate("en") shop1 = get_shop(identifier="shop1", domain="shop1", name="shop1") shop2 = get_shop(identifier="shop2", domain="shop2", name="shop2") person = get_person_contact(admin_user) product1_s1 = create_product("p1_s1", shop1, get_default_supplier()) product1_s2 = create_product("p1_s2", shop2, get_default_supplier()) product2_s1 = create_product("p2_s1", shop1, get_default_supplier()) product2_s2 = create_product("p2_s2", shop2, get_default_supplier()) shop1_product2 = product2_s1.get_shop_instance(shop1) view_func = WishlistCreateView.as_view() request = rf.post("/", {"name": "foo", "privacy": 0, "shop_product_id": shop1_product2.id}, HTTP_HOST=shop1.domain) assert_wishlist(request, shop1, person, view_func, 1) shop2_product2 = product2_s2.get_shop_instance(shop2) request = rf.post("/", {"name": "foo", "privacy": 0, "shop_product_id": shop2_product2.id}, HTTP_HOST=shop2.domain) assert_wishlist(request, shop2, person, view_func, 1)
def test_wishlist_create_with_product(admin_user, rf): activate("en") shop1 = get_shop(identifier="shop1", domain="shop1", name="shop1") shop2 = get_shop(identifier="shop2", domain="shop2", name="shop2") person = get_person_contact(admin_user) create_product("p1_s1", shop1, get_default_supplier()) create_product("p1_s2", shop2, get_default_supplier()) product2_s1 = create_product("p2_s1", shop1, get_default_supplier()) product2_s2 = create_product("p2_s2", shop2, get_default_supplier()) shop1_product2 = product2_s1.get_shop_instance(shop1) view_func = WishlistCreateView.as_view() request = rf.post("/", {"name": "foo", "privacy": 0, "shop_product_id": shop1_product2.id}, HTTP_HOST=shop1.domain) assert_wishlist(request, shop1, person, view_func, 1) shop2_product2 = product2_s2.get_shop_instance(shop2) request = rf.post("/", {"name": "foo", "privacy": 0, "shop_product_id": shop2_product2.id}, HTTP_HOST=shop2.domain) assert_wishlist(request, shop2, person, view_func, 1)
def test_sample_import_all_match_all_shops(filename): activate("en") shop1 = get_shop(identifier="shop1", domain="shop1", enabled=True) shop2 = get_shop(identifier="shop2", domain="shop2", enabled=True) Product.objects.all().delete() tax_class = get_default_tax_class() product_type = get_default_product_type() sales_unit = get_default_sales_unit() path = os.path.join(os.path.dirname(__file__), "data", "product", filename) transformed_data = transform_file(filename.split(".")[1], path) for shop in [shop1, shop2]: importer = ProductImporter(transformed_data, shop, "en") importer.process_data() assert len(importer.unmatched_fields) == 0 importer.do_import(ImportMode.CREATE_UPDATE) products = importer.new_objects if shop == shop1: # products created assert len(products) == 2 else: # products already exist assert len(products) == 0 assert Product.objects.count() == 2 for product in Product.objects.all(): shop_product = product.get_shop_instance(shop) assert shop_product.pk assert shop_product.default_price_value == 150 assert shop_product.default_price == shop.create_price(150) assert product.type == product_type # product type comes from importer defaults assert product.sales_unit == sales_unit assert shop_product.primary_category.pk == 1 assert [c.pk for c in shop_product.categories.all()] == [1, 2] assert ShopProduct.objects.count() == 4
def initialize_test(rf, include_tax=False, customer=create_customer): domain = "shop-domain" shop = get_shop(prices_include_tax=include_tax, domain=domain) if callable(customer): customer = customer() request = apply_request_middleware(rf.get("/"), shop=shop, customer=customer, META={"HTTP_HOST": "%s" % domain}) assert request.shop == shop assert request.customer == customer assert request.basket.shop == shop return request, shop, customer.groups.first()
def initialize_test(rf, include_tax=False): shop = get_shop(prices_include_tax=include_tax) group = get_default_customer_group() customer = create_random_person() customer.groups.add(group) customer.save() request = apply_request_middleware(rf.get("/")) request.shop = shop request.customer = customer return request, shop, group
def test_basic_order(rf, admin_user, mode): prices_include_tax = (mode == "taxful") shop = get_shop(prices_include_tax=prices_include_tax) request = rf.get('/') request.shop = shop apply_request_middleware(request) product = get_default_product() customer = get_person_contact(admin_user) for x in range(10): create_order(request, creator=admin_user, customer=customer, product=product) assert Order.objects.filter(customer=customer).count() == 10
def initialize_test(rf, include_tax=False): shop = get_shop(prices_include_tax=include_tax) group = get_default_customer_group() customer = create_random_person() customer.groups.add(group) customer.save() request = apply_request_middleware(rf.get("/")) request.shop = shop request.customer = customer return request, shop, group
def test_bump_caches_signal(rf): """ Test that caches are actually bumped also when calling bump function with id's """ initial_price = 10 shop1 = factories.get_default_shop() shop2 = factories.get_shop(identifier="shop2", domain="shop2") now = datetime(2018, 1, 1, 9, 0, tzinfo=pytz.UTC) # 01/01/2018 09:00 AM def assert_cache_bumped(prods): for sp in prods: key, val = context_cache.get_cached_value( identifier="is_orderable", item=sp, context={"customer": contact}, supplier=factories.get_default_supplier(), stock_managed=bool(factories.get_default_supplier() and factories.get_default_supplier().stock_managed), quantity=1, allow_cache=True, ) assert val == None with patch("django.utils.timezone.now", new=lambda: now): product1 = factories.create_product( "product", shop=shop1, supplier=factories.get_default_supplier(), default_price=initial_price ) product2 = factories.create_product( "product2", shop=shop2, supplier=factories.get_default_supplier(), default_price=20 ) user = factories.create_random_user() contact = get_person_contact(user) shop_product1 = product1.shop_products.filter(shop=shop1).first() shop_product2 = product2.shop_products.filter(shop=shop2).first() assert shop_product1.is_orderable(factories.get_default_supplier(shop1), contact, 1) is True assert shop_product2.is_orderable(factories.get_default_supplier(shop2), contact, 1) is True # Test single product id bumping context_cache.bump_cache_for_product(product2.id, shop=shop2) context_cache.bump_cache_for_product(product1.id, shop=shop1) assert_cache_bumped([shop_product1, shop_product2]) # Test list bumping context_cache.bump_cache_for_product([product2.id], shop=shop2) context_cache.bump_cache_for_product([product1.id], shop=shop1) assert_cache_bumped([shop_product1, shop_product2])
def test_basic_order(rf, admin_user, mode): prices_include_tax = (mode == "taxful") shop = get_shop(prices_include_tax=prices_include_tax) request = rf.get('/') request.shop = shop apply_request_middleware(request) product = get_default_product() customer = get_person_contact(admin_user) for x in range(10): create_order(request, creator=admin_user, customer=customer, product=product) assert Order.objects.filter(customer=customer).count() == 10
def test_home_tour(browser, admin_user, live_server, settings): shop = factories.get_default_shop() shop2 = factories.get_shop(identifier="shop2") admin_user_2 = factories.create_random_user(is_staff=True, is_superuser=True) admin_user_2.set_password("password") admin_user_2.save() shop.staff_members.add(admin_user) shop.staff_members.add(admin_user_2) for user in [admin_user, admin_user_2]: initialize_admin_browser_test(browser, live_server, settings, username=user.username, tour_complete=False) wait_until_condition(browser, lambda x: x.is_text_present("Welcome!")) browser.visit(live_server + "/sa/home") wait_until_condition(browser, lambda x: x.is_text_present("Hi, new shop owner!")) wait_until_condition(browser, lambda x: x.is_element_present_by_css(".shepherd-button.btn-primary")) click_element(browser, ".shepherd-button.btn-primary") category_targets = [ ".shepherd-enabled[data-target-id='category-1'", ".shepherd-enabled[data-target-id='category-2'", ".shepherd-enabled[data-target-id='category-3'", ".shepherd-enabled[data-target-id='category-5'", ".shepherd-enabled[data-target-id='category-9'", ".shepherd-enabled[data-target-id='category-4'", ".shepherd-enabled[data-target-id='category-6'", ".shepherd-enabled[data-target-id='category-7'", ".shepherd-enabled[data-target-id='category-8'", ".shepherd-enabled#site-search", ".shepherd-enabled.shop-btn.visit-store", ] for target in category_targets: wait_until_condition(browser, lambda x: x.is_element_present_by_css(target)) move_to_element(browser, ".shepherd-button.btn-primary") browser.find_by_css(".shepherd-button.btn-primary").last.click() wait_until_condition(browser, lambda x: x.is_text_present("We're done!")) move_to_element(browser, ".shepherd-button.btn-primary") browser.find_by_css(".shepherd-button.btn-primary").last.click() wait_until_condition(browser, lambda x: is_tour_complete(shop, "home", user)) # check whether the tour is shown again browser.visit(live_server + "/sa/home") wait_until_condition(browser, lambda x: not x.is_text_present("Hi, new shop owner!")) browser.visit(live_server + "/logout") browser.visit(live_server + "/sa") wait_until_condition(browser, lambda x: not x.is_text_present("Hi, new shop owner!")) assert is_tour_complete(shop2, "home", user) is False
def test_home_tour(browser, admin_user, live_server, settings): shop = factories.get_default_shop() shop2 = factories.get_shop(identifier="shop2") admin_user_2 = factories.create_random_user(is_staff=True, is_superuser=True) admin_user_2.set_password("password") admin_user_2.save() shop.staff_members.add(admin_user) shop.staff_members.add(admin_user_2) for user in [admin_user, admin_user_2]: initialize_admin_browser_test(browser, live_server, settings, username=user.username, tour_complete=False) wait_until_condition(browser, lambda x: x.is_text_present("Welcome!")) browser.visit(live_server + "/sa/home") wait_until_condition(browser, lambda x: x.is_text_present("Hi, new shop owner!"), timeout=30) wait_until_condition(browser, lambda x: x.is_element_present_by_css(".shepherd-button.btn-primary")) click_element(browser, ".shepherd-button.btn-primary") category_targets = [ ".shepherd-enabled[data-target-id='category-1'", ".shepherd-enabled[data-target-id='category-2'", ".shepherd-enabled[data-target-id='category-3'", ".shepherd-enabled[data-target-id='category-5'", ".shepherd-enabled[data-target-id='category-9'", ".shepherd-enabled[data-target-id='category-4'", ".shepherd-enabled[data-target-id='category-6'", ".shepherd-enabled[data-target-id='category-7'", ".shepherd-enabled[data-target-id='category-8'", ".shepherd-enabled#site-search", ".shepherd-enabled.shop-btn.visit-store", ] for target in category_targets: wait_until_condition(browser, lambda x: x.is_element_present_by_css(target)) move_to_element(browser, ".shepherd-button.btn-primary") browser.find_by_css(".shepherd-button.btn-primary").last.click() wait_until_condition(browser, lambda x: x.is_text_present("We're done!"), timeout=30) move_to_element(browser, ".shepherd-button.btn-primary") browser.find_by_css(".shepherd-button.btn-primary").last.click() wait_until_condition(browser, lambda x: is_tour_complete(shop, "home", user)) # check whether the tour is shown again browser.visit(live_server + "/sa/home") wait_until_condition(browser, lambda x: not x.is_text_present("Hi, new shop owner!")) browser.visit(live_server + "/logout") browser.visit(live_server + "/sa") wait_until_condition(browser, lambda x: not x.is_text_present("Hi, new shop owner!")) assert is_tour_complete(shop2, "home", user) is False
def test_manufacturer_admin_simple_shop(rf, staff_user, admin_user): with override_settings(SHUUP_ENABLE_MULTIPLE_SHOPS=False): shop1 = factories.get_default_shop() shop1.staff_members.add(staff_user) factories.get_shop(identifier="shop2") assert Manufacturer.objects.count() == 0 # staff user request = apply_request_middleware(rf.post("/", data=dict(name="Manuf 1")), user=staff_user) view_func = ManufacturerEditView.as_view() response = view_func(request) assert response.status_code == 302 assert Manufacturer.objects.first().shops.first() == shop1 # superuser request = apply_request_middleware(rf.post("/", data=dict(name="Manuf 2")), user=admin_user) view_func = ManufacturerEditView.as_view() response = view_func(request) assert response.status_code == 302 assert Manufacturer.objects.count() == 2 assert Manufacturer.objects.last().shops.first() == shop1
def test_contact_module_search_multishop(rf): with override_settings(SHUUP_MANAGE_CONTACTS_PER_SHOP=True, SHUUP_ENABLE_MULTIPLE_SHOPS=True): staff_user = create_random_user(is_staff=True) shop1 = get_shop(identifier="shop-1", enabled=True) shop2 = get_shop(identifier="shop-2", enabled=True) shop1.staff_members.add(staff_user) shop2.staff_members.add(staff_user) cm = ContactModule() contact = create_random_person(locale="en_US", minimum_name_comp_len=5) contact.add_to_shop(shop2) request = apply_request_middleware(rf.get("/"), user=staff_user, shop=shop2) # find the shop assert not empty_iterable(cm.get_search_results(request, query=contact.email)) assert not empty_iterable(cm.get_search_results(request, query=contact.first_name)) # no shop found request = apply_request_middleware(rf.get("/"), user=staff_user, shop=shop1) assert empty_iterable(cm.get_search_results(request, query=contact.email))
def test_slide_admin_form(rf, admin_user): translation.activate("en") shop = get_default_shop() category = get_default_category() assert category.shops.first() == shop page = create_page(**{"url": "test", "shop": shop}) assert page.shop == shop test_carousel = Carousel.objects.create(name="test") request = apply_request_middleware(rf.get("/")) request.user = admin_user request.shop = shop slide_form = SlideForm( carousel=test_carousel, languages=settings.LANGUAGES, default_language=settings.PARLER_DEFAULT_LANGUAGE_CODE, request=request, ) soup = BeautifulSoup(slide_form.as_table()) options = soup.find(id="id_category_link").find_all("option") assert len(options) == 2 assert options[0]["value"] == "" assert options[1]["value"] == "%s" % category.pk options = soup.find(id="id_cms_page_link").find_all("option") assert len(options) == 2 assert options[0]["value"] == "" assert options[1]["value"] == "%s" % page.pk new_shop = get_shop(identifier="second-shop") category.shops.set([new_shop]) page.shop = new_shop page.save() slide_form = SlideForm( carousel=test_carousel, languages=settings.LANGUAGES, default_language=settings.PARLER_DEFAULT_LANGUAGE_CODE, request=request, ) soup = BeautifulSoup(slide_form.as_table()) options = soup.find(id="id_category_link").find_all("option") assert len(options) == 1 assert options[0]["value"] == "" options = soup.find(id="id_cms_page_link").find_all("option") assert len(options) == 1 assert options[0]["value"] == ""
def test_page_different_shops(rf): shop1 = get_shop(status=ShopStatus.ENABLED, identifier="shop-1", name="Shop 1", domain="shop1") shop2 = get_shop(status=ShopStatus.ENABLED, identifier="shop-2", name="Shop 2", domain="shop2") # dreate page only for shop2 page = create_page(available_from=datetime.date(1988, 1, 1), shop=shop2) view_func = PageView.as_view() request = apply_request_middleware(rf.get("/", HTTP_HOST=shop1.domain)) with pytest.raises(Http404): response = view_func(request, url=page.url) request = apply_request_middleware(rf.get("/", HTTP_HOST=shop2.domain)) response = view_func(request, url=page.url) assert response.status_code == 200 response.render() assert "<h1>Bacon ipsum" in response.rendered_content
def test_contact_company_edit_multishop(rf): with override_settings(SHUUP_MANAGE_CONTACTS_PER_SHOP=True, SHUUP_ENABLE_MULTIPLE_SHOPS=True): staff_user = create_random_user(is_staff=True) shop1 = get_shop(identifier="shop-1", enabled=True) shop2 = get_shop(identifier="shop-2", enabled=True) shop1.staff_members.add(staff_user) shop2.staff_members.add(staff_user) # only available in shop2 contact = create_random_person(locale="en_US", minimum_name_comp_len=5) contact.shops.add(shop2) # only available in shop1 company = create_random_company() company.shops.add(shop1) view = ContactEditView.as_view() # permission denied for contact and shop1 request = apply_request_middleware(rf.get("/"), user=staff_user, shop=shop1) with pytest.raises(PermissionDenied): response = view(request, pk=contact.id) # permission granted for contact and shop2 request = apply_request_middleware(rf.get("/"), user=staff_user, shop=shop2) response = view(request, pk=contact.id) assert response.status_code == 200 # permission denied for company and shop2 request = apply_request_middleware(rf.get("/"), user=staff_user, shop=shop2) with pytest.raises(PermissionDenied): response = view(request, pk=company.id) # permission granted for company and shop1 request = apply_request_middleware(rf.get("/"), user=staff_user, shop=shop1) response = view(request, pk=company.id) assert response.status_code == 200
def test_edit_shared_folder(admin_user): with override_settings(SHUUP_ENABLE_MULTIPLE_SHOPS=True): shop1 = factories.get_shop(identifier="shop1", enabled=True) shop2 = factories.get_shop(identifier="shop2", enabled=True) folder = Folder.objects.create(name="Test folder") # Shared folder folder_count = Folder.objects.count() response = _mbv_command(shop1, admin_user, {"action": "rename_folder", "id": folder.pk, "name": "Space"}) assert not response["success"] response = _mbv_command(shop1, admin_user, {"action": "delete_folder", "id": folder.pk}) assert not response["success"] # Let's make sure rename works when only one shop owns the folder media_folder = MediaFolder.objects.create(folder=folder) media_folder.shops.add(shop1) response = _mbv_command(shop1, admin_user, {"action": "rename_folder", "id": folder.pk, "name": "Space"}) assert response["success"] assert Folder.objects.get(pk=folder.pk).name == "Space" # Then add second shop for the folder and let's check and # renaming should be disabled again. media_folder.shops.add(shop2) response = _mbv_command(shop1, admin_user, {"action": "rename_folder", "id": folder.pk, "name": "Space"}) assert not response["success"] response = _mbv_command(shop1, admin_user, {"action": "delete_folder", "id": folder.pk}) assert not response["success"] response = _mbv_command(shop2, admin_user, {"action": "delete_folder", "id": folder.pk}) assert not response["success"] # Finally remove the folder as shop2 media_folder.shops.remove(shop1) response = _mbv_command(shop1, admin_user, {"action": "delete_folder", "id": folder.pk}) assert response["error"] == "Folder matching query does not exist." response = _mbv_command(shop2, admin_user, {"action": "delete_folder", "id": folder.pk}) assert response["success"] assert Folder.objects.count() == folder_count - 1
def test_contact_edit_multishop(rf): with override_settings(SHUUP_MANAGE_CONTACTS_PER_SHOP=True, SHUUP_ENABLE_MULTIPLE_SHOPS=True): staff_user = create_random_user(is_staff=True) shop1 = get_shop(identifier="shop-1", enabled=True) shop2 = get_shop(identifier="shop-2", enabled=True) shop1.staff_members.add(staff_user) shop2.staff_members.add(staff_user) contact = create_random_person(locale="en_US", minimum_name_comp_len=5, shop=shop2) # only available in shop2 assert contact.registered_in(shop2) assert contact.in_shop(shop2) request = apply_request_middleware(rf.get("/"), user=staff_user, shop=shop1) view = ContactDetailView.as_view() # contact not found for this shop with pytest.raises(Http404): response = view(request, pk=contact.id) request = apply_request_middleware(rf.get("/"), user=staff_user, shop=shop2) response = view(request, pk=contact.id) assert response.status_code == 200 assert contact.registered_in(shop2) assert contact.in_shop(shop2) assert not contact.registered_in(shop1) assert not contact.in_shop(shop1)
def test_shop_and_supplier_info(): activate("en") shop = factories.get_shop(True, "USD", enabled=True, name="Shop.com") supplier = factories.get_default_supplier() staff_user = factories.create_random_user(is_staff=True) staff_user.set_password("randpw") staff_user.save() staff_user.groups.set([factories.get_default_permission_group()]) shop.staff_members.add(staff_user) assert staff_user in [staff for staff in shop.staff_members.all()] assert shop.status == ShopStatus.ENABLED client = SmartClient() with override_settings( SHUUP_ENABLE_MULTIPLE_SHOPS=True, SHUUP_ENABLE_MULTIPLE_SUPPLIERS=False, SHUUP_ADMIN_SUPPLIER_PROVIDER_SPEC= "shuup.testing.supplier_provider.FirstSupplierProvider", ): url = reverse("shuup_admin:dashboard") client.login(username=staff_user.username, password="******") response, soup = client.response_and_soup(url) assert response.status_code == 200 assert shop.name in soup.find("div", { "class": "active-shop-and-supplier-info" }).text assert supplier.name not in soup.find( "div", { "class": "active-shop-and-supplier-info" }).text with override_settings( SHUUP_ENABLE_MULTIPLE_SHOPS=True, SHUUP_ENABLE_MULTIPLE_SUPPLIERS=True, SHUUP_ADMIN_SUPPLIER_PROVIDER_SPEC= "shuup.testing.supplier_provider.FirstSupplierProvider", ): url = reverse("shuup_admin:dashboard") client.login(username=staff_user.username, password="******") response, soup = client.response_and_soup(url) assert response.status_code == 200 assert shop.name in soup.find("div", { "class": "active-shop-and-supplier-info" }).text assert supplier.name in soup.find( "div", { "class": "active-shop-and-supplier-info" }).text
def create_order_source(prices_include_tax, line_data, tax_rates): """ Get order source with some testing data. :rtype: OrderSource """ lines = [Line.from_text(x) for x in line_data] shop = get_shop(prices_include_tax, currency='USD') tax_classes = create_assigned_tax_classes(tax_rates) products = create_products(shop, lines, tax_classes) services = create_services(shop, lines, tax_classes) source = OrderSource(shop) fill_order_source(source, lines, products, services) return source
def test_company_contact_detail_multishop(rf): with override_settings(SHUUP_MANAGE_CONTACTS_PER_SHOP=True, SHUUP_ENABLE_MULTIPLE_SHOPS=True): staff_user = create_random_user(is_staff=True) shop1 = get_shop(identifier="shop-1", enabled=True) shop2 = get_shop(identifier="shop-2", enabled=True) shop1.staff_members.add(staff_user) shop2.staff_members.add(staff_user) company = create_random_company() # only available in shop1 company.shops.add(shop1) view = ContactDetailView.as_view() # company not found for this shop request = apply_request_middleware(rf.get("/"), user=staff_user, shop=shop2) with pytest.raises(PermissionDenied): response = view(request, pk=company.id) request = apply_request_middleware(rf.get("/"), user=staff_user, shop=shop1) response = view(request, pk=company.id) assert response.status_code == 200
def test_basket_with_custom_shop(rf): """ Set a different shop for basket """ with override_settings(**CORE_BASKET_SETTINGS): shop1 = factories.get_default_shop() shop2 = factories.get_shop(identifier="shop2") user = factories.create_random_user() request = apply_request_middleware(rf.get("/"), user=user, shop=shop1) basket_class = cached_load("SHUUP_BASKET_CLASS_SPEC") basket = basket_class(request, "basket", shop=shop2) assert basket.shop == shop2 product_shop2 = factories.create_product("product_shop2", shop2, factories.get_default_supplier(), 10) line = basket.add_product(factories.get_default_supplier(), shop2, product_shop2, 1) assert line.shop == shop2
def _get_custom_order(regular_user, **kwargs): prices_include_tax = kwargs.pop("prices_include_tax", False) include_basket_campaign = kwargs.pop("include_basket_campaign", False) include_catalog_campaign = kwargs.pop("include_catalog_campaign", False) shop = get_shop(prices_include_tax=prices_include_tax) supplier = get_simple_supplier() if include_basket_campaign: _add_basket_campaign(shop) if include_catalog_campaign: _add_catalog_campaign(shop) _add_taxes() contact = get_person_contact(regular_user) source = BasketishOrderSource(shop) source.status = get_initial_order_status() source.customer = contact ctx = get_pricing_module().get_context_from_data(shop, contact) for product_data in _get_product_data(): quantity = product_data.pop("quantity") product = create_product( sku=product_data.pop("sku"), shop=shop, supplier=supplier, stock_behavior=StockBehavior.STOCKED, tax_class=get_default_tax_class(), **product_data) shop_product = product.get_shop_instance(shop) shop_product.categories.add(get_default_category()) shop_product.save() supplier.adjust_stock(product.id, INITIAL_PRODUCT_QUANTITY) pi = product.get_price_info(ctx) source.add_line( type=OrderLineType.PRODUCT, product=product, supplier=supplier, quantity=quantity, base_unit_price=pi.base_unit_price, discount_amount=pi.discount_amount ) oc = OrderCreator() order = oc.create_order(source) return order
def test_contact_list_multiple_shop(rf): shop1 = get_default_shop() shop2 = get_shop(identifier="shop2", name="Shop 2") staff = create_random_user(is_staff=True) Contact.objects.all().delete() shop1.staff_members.add(staff) shop2.staff_members.add(staff) contact1 = create_random_person(locale="en_US") contact1.shops.add(shop1) contact2 = create_random_person(locale="en_US") contact2.shops.add(shop2) view_func = ContactListView.as_view() # do not send which shop.. it should return all contacts payload = {"jq": json.dumps({"perPage": 100, "page": 1})} request = apply_request_middleware(rf.get("/", data=payload), user=staff) response = view_func(request) assert response.status_code == 200 data = json.loads(response.content.decode("utf-8")) contacts = [contact["_id"] for contact in data["items"]] assert contact1.pk in contacts assert contact2.pk in contacts # request contacts from shop1 payload = {"jq": json.dumps({"perPage": 100, "page": 1}), "shop": shop1.pk} request = apply_request_middleware(rf.get("/", data=payload), user=staff) response = view_func(request) assert response.status_code == 200 data = json.loads(response.content.decode("utf-8")) contacts = [contact["_id"] for contact in data["items"]] assert contact1.pk in contacts assert contact2.pk not in contacts # request contacts from shop2 payload = {"jq": json.dumps({"perPage": 100, "page": 1}), "shop": shop2.pk} request = apply_request_middleware(rf.get("/", data=payload), user=staff) response = view_func(request) assert response.status_code == 200 data = json.loads(response.content.decode("utf-8")) contacts = [contact["_id"] for contact in data["items"]] assert contact1.pk not in contacts assert contact2.pk in contacts