def _get_shop_product_sample_data(): return { "shop": get_default_shop().id, "suppliers": [ get_default_supplier().id ], "visibility": ShopProductVisibility.ALWAYS_VISIBLE.value, "purchasable": False, "visibility_limit": ProductVisibility.VISIBLE_TO_ALL.value, "visibility_groups": [ create_random_contact_group().id, create_random_contact_group().id, ], "backorder_maximum": 0, "purchase_multiple": 1, "minimum_purchase_quantity": 1, "limit_shipping_methods": False, "limit_payment_methods": False, "shipping_methods": [], "payment_methods": [], "primary_category": get_default_category().id, "categories": [ get_default_category().id, CategoryFactory().id ], "default_price_value": 12.45, "minimum_price_value": 5.35 }
def test_product_pricing_cache(admin_user): shop = get_default_shop() group = create_random_contact_group() group2 = create_random_contact_group() product = create_product("Just-A-Product", shop, default_price=200) CgpPrice.objects.create(product=product, shop=shop, group=group, price_value=175) CgpPrice.objects.create(product=product, shop=shop, group=group2, price_value=150) client = _get_client(admin_user) response = client.get("/api/shuup/front/shop_products/") products_data = json.loads(response.content.decode("utf-8")) assert products_data[0]["price"] == 200 user = get_user_model().objects.first() user.pk = None user.username = "******" user.save() customer = create_random_person() customer.groups.add(group) customer.user = user customer.save() client = _get_client(user) response = client.get("/api/shuup/front/shop_products/") products_data = json.loads(response.content.decode("utf-8")) assert products_data[0]["price"] == 175 client = _get_client(admin_user) response = client.get("/api/shuup/front/shop_products/") products_data = json.loads(response.content.decode("utf-8")) assert products_data[0]["price"] == 200
def test_get_items_from_obj_context(): shop = factories.get_default_shop() customer = factories.create_random_person() contact_group = factories.create_random_contact_group() contact_group.members.add(customer) context = Context() context.customer = customer items = _get_items_from_context(context) groups = context_cache._get_val(customer.groups.all()) # check whether items were cached assert cache.get("_ctx_cache:customer_%d" % customer.pk) == groups assert context._ctx_cache_customer == groups assert items["customer_groups"] == groups assert "customer" not in items get_val_mock = mock.Mock(wraps=context_cache._get_val) with mock.patch.object(context_cache, "_get_val", new=get_val_mock): # get items again from the context, it shouldn't invoke _gel_val again for the customer get_val_mock.assert_not_called() items = _get_items_from_context(context) get_val_mock.assert_not_called() assert items["customer_groups"] == groups assert "customer" not in items
def test_order_customer_groups(rf, admin_user): customer = create_random_person() default_group = get_default_customer_group() default_group.members.add(customer) source = seed_source(admin_user) source.customer=customer source.add_line( type=OrderLineType.PRODUCT, product=get_default_product(), supplier=get_default_supplier(), quantity=1, base_unit_price=source.create_price(10), ) source.add_line( type=OrderLineType.OTHER, quantity=1, base_unit_price=source.create_price(10), require_verification=True, ) creator = OrderCreator() order = creator.create_order(source) assert get_data_dict(source.billing_address) == get_data_dict(order.billing_address) assert get_data_dict(source.shipping_address) == get_data_dict(order.shipping_address) customer = source.customer assert customer == order.customer assert customer.groups.count() == 2 assert order.customer_groups.filter(id=default_group.id).exists() with pytest.raises(ProtectedError): default_group.delete() assert customer.tax_group is not None assert customer.tax_group == order.tax_group with pytest.raises(ProtectedError): customer.tax_group.delete() new_group = create_random_contact_group() new_group.members.add(customer) order.phone = "911" order.save() assert order.customer_groups.filter(id=default_group.id).exists() assert not order.customer_groups.filter(id=new_group.id).exists()
def test_get_items_from_dict_context(): customer = factories.create_random_person() new_customer = factories.create_random_person() contact_group = factories.create_random_contact_group() contact_group.members.add(customer) context = { "customer": customer } items = _get_items_from_context(context) groups = context_cache._get_val(customer.groups.all()) assert items["customer_groups"] == groups assert "customer" not in items # check whether items were cached assert cache.get("_ctx_cache:customer_%d" % customer.pk) == groups get_val_mock = mock.Mock(wraps=context_cache._get_val) with mock.patch.object(context_cache, "_get_val", new=get_val_mock): # get items again from the context, it shouldn't invoke _gel_val again for the customer get_val_mock.assert_not_called() items = _get_items_from_context(context) get_val_mock.assert_not_called() # check whether cache is bumped after changing contact get_val_mock = mock.Mock(wraps=context_cache._get_val) with mock.patch.object(context_cache, "_get_val", new=get_val_mock): customer.save() items = _get_items_from_context(context) get_val_mock.assert_called() # check whether cache is bumped after changing members of contact group get_val_mock = mock.Mock(wraps=context_cache._get_val) with mock.patch.object(context_cache, "_get_val", new=get_val_mock): items = _get_items_from_context(context) get_val_mock.assert_not_called() contact_group.members.add(new_customer) items = _get_items_from_context(context) get_val_mock.assert_called()
def mock_customer_group(self, **kwargs): """ Create a random contact group """ return create_random_contact_group()
def test_get_products(admin_user): shop1 = get_default_shop() person1 = create_random_person() person1.user = admin_user person1.save() person2 = create_random_person() person2.save() client = _get_client(admin_user) client.customer = person1 client.shop = shop1 # list all orderable products request = get_request("/api/shuup/front/products/", admin_user, shop1, person1) response = FrontProductViewSet.as_view({"get": "list"})(request) response.render() assert response.status_code == status.HTTP_200_OK products_data = json.loads(response.content.decode("utf-8")) assert len(products_data) == 0 shop2 = Shop.objects.create() supplier1 = create_simple_supplier("supplier1") supplier2 = create_simple_supplier("supplier2") # create 2 products for shop2 product1 = create_product("product1", shop=shop2, supplier=supplier1) product2 = create_product("product2", shop=shop2, supplier=supplier2) # add images for products 1 and 2 add_product_image(product1) add_product_image(product2) # list all orderable products - None, since the 2 just created are for shop2 request = get_request("/api/shuup/front/products/", admin_user, shop1, person1) response = FrontProductViewSet.as_view({"get": "list"})(request) response.render() products_data = json.loads(response.content.decode("utf-8")) assert len(products_data) == 0 # create the product for shop1 but set it as not visible product3 = create_product("product3", shop=shop1, supplier=supplier1) shop1_product3 = ShopProduct.objects.get(shop=shop1, product=product3) shop1_product3.visibility = ShopProductVisibility.NOT_VISIBLE shop1_product3.save() # list all orderable products - No one yet request = get_request("/api/shuup/front/products/", admin_user, shop1, person1) response = FrontProductViewSet.as_view({"get": "list"})(request) response.render() products_data = json.loads(response.content.decode("utf-8")) assert len(products_data) == 0 # now product3 becomes visible shop1_product3.visibility = ShopProductVisibility.ALWAYS_VISIBLE shop1_product3.save() request = get_request("/api/shuup/front/products/", admin_user, shop1, person1) response = FrontProductViewSet.as_view({"get": "list"})(request) response.render() products_data = json.loads(response.content.decode("utf-8")) assert len(products_data) == 1 assert products_data[0]["shop_products"][0]["orderable"] is True # product should be visible only for some groups group = create_random_contact_group() group.members.add(person2) product3.visibility = ProductVisibility.VISIBLE_TO_GROUPS product3.save() shop1_product3.visibility_limit = ProductVisibility.VISIBLE_TO_GROUPS shop1_product3.visibility_groups.add(group) shop1_product3.save() request = get_request("/api/shuup/front/products/", admin_user, shop1, person1) response = FrontProductViewSet.as_view({"get": "list"})(request) response.render() products_data = json.loads(response.content.decode("utf-8")) assert len(products_data) == 0 # visible for person2 which is in the same group request = get_request("/api/shuup/front/products/", admin_user, shop1, person2) response = FrontProductViewSet.as_view({"get": "list"})(request) response.render() products_data = json.loads(response.content.decode("utf-8")) assert len(products_data) == 1 # product1 and product2 are visible in shop2 request = get_request("/api/shuup/front/products/", admin_user, shop2, person1) response = FrontProductViewSet.as_view({"get": "list"})(request) response.render() products_data = json.loads(response.content.decode("utf-8")) products = sorted(products_data, key=lambda p: p["id"]) assert products[0]["id"] == product1.id assert products[0]["shop_products"][0]["orderable"] is True assert products[1]["id"] == product2.id assert products[1]["shop_products"][0]["orderable"] is True # check for medias assert products[0]["primary_image"]["file"] == request.build_absolute_uri(product1.primary_image.url) assert products[0]["media"][0]["file"] == request.build_absolute_uri(product1.media.first().url) assert products[0]["media"][1]["file"] == request.build_absolute_uri(product1.media.all()[1].url) assert products[1]["primary_image"]["file"] == request.build_absolute_uri(product2.primary_image.url) assert products[1]["media"][0]["file"] == request.build_absolute_uri(product2.media.first().url) assert products[1]["media"][1]["file"] == request.build_absolute_uri(product2.media.all()[1].url) # ordering by -id request = get_request("/api/shuup/front/products/?ordering=-id", admin_user, shop2, person1) response = FrontProductViewSet.as_view({"get": "list"})(request) response.render() products_data = json.loads(response.content.decode("utf-8")) assert products_data[0]["id"] == product2.id assert products_data[0]["shop_products"][0]["orderable"] is True assert products_data[1]["id"] == product1.id assert products_data[1]["shop_products"][0]["orderable"] is True # add categories to products category1 = Category.objects.create(parent=None, identifier="category1", name="category1") shop2_product1 = ShopProduct.objects.get(shop=shop2, product=product1) shop2_product1.primary_category = category1 shop2_product1.categories.add(category1) shop2_product1.save() category2 = Category.objects.create(parent=None, identifier="category2", name="category2") shop2_product2 = ShopProduct.objects.get(shop=shop2, product=product2) shop2_product2.primary_category = category2 shop2_product2.categories.add(category2) shop2_product2.save() # fetch by category1 request = get_request("/api/shuup/front/products/?category=%d" % category1.id, admin_user, shop2, person1) response = FrontProductViewSet.as_view({"get": "list"})(request) response.render() products_data = json.loads(response.content.decode("utf-8")) assert len(products_data) == 1 assert products_data[0]["id"] == product1.id # fetch by category2 request = get_request("/api/shuup/front/products/?category=%d" % category2.id, admin_user, shop2, person1) response = FrontProductViewSet.as_view({"get": "list"})(request) response.render() products_data = json.loads(response.content.decode("utf-8")) assert len(products_data) == 1 assert products_data[0]["id"] == product2.id # create a package product product4 = create_package_product("product4", shop=shop1, supplier=supplier1) # make product3 orderable again product3.visibility = ProductVisibility.VISIBLE_TO_ALL product3.save() shop1_product3.visibility_limit = ProductVisibility.VISIBLE_TO_ALL shop1_product3.visibility_groups.all().delete() shop1_product3.save() # product3 and product4 are visible in shop1 request = get_request("/api/shuup/front/products/", admin_user, shop1, person1) response = FrontProductViewSet.as_view({"get": "list"})(request) response.render() products_data = json.loads(response.content.decode("utf-8")) products = sorted(products_data, key=lambda p: p["id"]) assert products[0]["id"] == product3.id assert products[0]["shop_products"][0]["orderable"] is True assert products[1]["id"] == product4.id assert products[1]["shop_products"][0]["orderable"] is True # change the shop of the first child product to make the package not orderable sp = product4.get_all_package_children()[0].shop_products.first() sp.shop = shop2 sp.save() # product3 is orderable and product4 doesn't request = get_request("/api/shuup/front/products/", admin_user, shop1, person1) response = FrontProductViewSet.as_view({"get": "list"})(request) response.render() products_data = json.loads(response.content.decode("utf-8")) products = sorted(products_data, key=lambda p: p["id"]) assert products[0]["id"] == product3.id assert products[0]["shop_products"][0]["orderable"] is True assert products[1]["id"] == product4.id assert products[1]["shop_products"][0]["orderable"] is False # assign cross sell of product1 and product2 ProductCrossSell.objects.create(product1=product1, product2=product2, type=ProductCrossSellType.RECOMMENDED) ProductCrossSell.objects.create(product1=product1, product2=product2, type=ProductCrossSellType.RELATED) ProductCrossSell.objects.create(product1=product1, product2=product2, type=ProductCrossSellType.COMPUTED) ProductCrossSell.objects.create(product1=product1, product2=product2, type=ProductCrossSellType.BOUGHT_WITH) # product1 must have cross shell of product2 request = get_request("/api/shuup/front/products/", admin_user, shop2, person1) response = FrontProductViewSet.as_view({"get": "list"})(request) response.render() products_data = json.loads(response.content.decode("utf-8")) products = sorted(products_data, key=lambda p: p["id"]) assert products[0]["id"] == product1.id assert products[0]["cross_sell"]["recommended"] == [product2.id] assert products[0]["cross_sell"]["related"] == [product2.id] assert products[0]["cross_sell"]["computed"] == [product2.id] assert products[0]["cross_sell"]["bought_with"] == [product2.id] assert products[1]["id"] == product2.id assert products[1]["cross_sell"]["recommended"] == [] assert products[1]["cross_sell"]["related"] == [] assert products[1]["cross_sell"]["computed"] == [] assert products[1]["cross_sell"]["bought_with"] == []
def test_get_products(admin_user): shop1 = get_default_shop() person1 = create_random_person() person1.user = admin_user person1.save() person2 = create_random_person() person2.save() client = _get_client(admin_user) client.customer = person1 client.shop = shop1 # list all orderable products request = get_request("/api/shuup/front/products/", admin_user, shop1, person1) response = FrontProductViewSet.as_view({"get": "list"})(request) response.render() assert response.status_code == status.HTTP_200_OK products_data = json.loads(response.content.decode("utf-8")) assert len(products_data) == 0 shop2 = Shop.objects.create() supplier1 = create_simple_supplier("supplier1") supplier2 = create_simple_supplier("supplier2") # create 2 products for shop2 product1 = create_product("product1", shop=shop2, supplier=supplier1) product2 = create_product("product2", shop=shop2, supplier=supplier2) # add images for products 1 and 2 add_product_image(product1) add_product_image(product2) # list all orderable products - None, since the 2 just created are for shop2 request = get_request("/api/shuup/front/products/", admin_user, shop1, person1) response = FrontProductViewSet.as_view({"get": "list"})(request) response.render() products_data = json.loads(response.content.decode("utf-8")) assert len(products_data) == 0 # create the product for shop1 but set it as not visible product3 = create_product("product3", shop=shop1, supplier=supplier1) shop1_product3 = ShopProduct.objects.get(shop=shop1, product=product3) shop1_product3.visibility = ShopProductVisibility.NOT_VISIBLE shop1_product3.save() # list all orderable products - No one yet request = get_request("/api/shuup/front/products/", admin_user, shop1, person1) response = FrontProductViewSet.as_view({"get": "list"})(request) response.render() products_data = json.loads(response.content.decode("utf-8")) assert len(products_data) == 0 # now product3 becomes visible shop1_product3.visibility = ShopProductVisibility.ALWAYS_VISIBLE shop1_product3.save() request = get_request("/api/shuup/front/products/", admin_user, shop1, person1) response = FrontProductViewSet.as_view({"get": "list"})(request) response.render() products_data = json.loads(response.content.decode("utf-8")) assert len(products_data) == 1 assert products_data[0]["shop_products"][0]["orderable"] is True # product should be visible only for some groups group = create_random_contact_group() group.members.add(person2) product3.visibility = ProductVisibility.VISIBLE_TO_GROUPS product3.save() shop1_product3.visibility_limit = ProductVisibility.VISIBLE_TO_GROUPS shop1_product3.visibility_groups.add(group) shop1_product3.save() request = get_request("/api/shuup/front/products/", admin_user, shop1, person1) response = FrontProductViewSet.as_view({"get": "list"})(request) response.render() products_data = json.loads(response.content.decode("utf-8")) assert len(products_data) == 0 # visible for person2 which is in the same group request = get_request("/api/shuup/front/products/", admin_user, shop1, person2) response = FrontProductViewSet.as_view({"get": "list"})(request) response.render() products_data = json.loads(response.content.decode("utf-8")) assert len(products_data) == 1 # product1 and product2 are visible in shop2 request = get_request("/api/shuup/front/products/", admin_user, shop2, person1) response = FrontProductViewSet.as_view({"get": "list"})(request) response.render() products_data = json.loads(response.content.decode("utf-8")) products = sorted(products_data, key=lambda p: p["id"]) assert products[0]["id"] == product1.id assert products[0]["shop_products"][0]["orderable"] is True assert products[1]["id"] == product2.id assert products[1]["shop_products"][0]["orderable"] is True # check for medias assert products[0]["primary_image"]["file"] == request.build_absolute_uri( product1.primary_image.url) assert products[0]["media"][0]["file"] == request.build_absolute_uri( product1.media.first().url) assert products[0]["media"][1]["file"] == request.build_absolute_uri( product1.media.all()[1].url) assert products[1]["primary_image"]["file"] == request.build_absolute_uri( product2.primary_image.url) assert products[1]["media"][0]["file"] == request.build_absolute_uri( product2.media.first().url) assert products[1]["media"][1]["file"] == request.build_absolute_uri( product2.media.all()[1].url) # ordering by -id request = get_request("/api/shuup/front/products/?ordering=-id", admin_user, shop2, person1) response = FrontProductViewSet.as_view({"get": "list"})(request) response.render() products_data = json.loads(response.content.decode("utf-8")) assert products_data[0]["id"] == product2.id assert products_data[0]["shop_products"][0]["orderable"] is True assert products_data[1]["id"] == product1.id assert products_data[1]["shop_products"][0]["orderable"] is True # add categories to products category1 = Category.objects.create(parent=None, identifier="category1", name="category1") shop2_product1 = ShopProduct.objects.get(shop=shop2, product=product1) shop2_product1.primary_category = category1 shop2_product1.categories.add(category1) shop2_product1.save() category2 = Category.objects.create(parent=None, identifier="category2", name="category2") shop2_product2 = ShopProduct.objects.get(shop=shop2, product=product2) shop2_product2.primary_category = category2 shop2_product2.categories.add(category2) shop2_product2.save() # fetch by category1 request = get_request( "/api/shuup/front/products/?category=%d" % category1.id, admin_user, shop2, person1) response = FrontProductViewSet.as_view({"get": "list"})(request) response.render() products_data = json.loads(response.content.decode("utf-8")) assert len(products_data) == 1 assert products_data[0]["id"] == product1.id # fetch by category2 request = get_request( "/api/shuup/front/products/?category=%d" % category2.id, admin_user, shop2, person1) response = FrontProductViewSet.as_view({"get": "list"})(request) response.render() products_data = json.loads(response.content.decode("utf-8")) assert len(products_data) == 1 assert products_data[0]["id"] == product2.id # create a package product product4 = create_package_product("product4", shop=shop1, supplier=supplier1) # make product3 orderable again product3.visibility = ProductVisibility.VISIBLE_TO_ALL product3.save() shop1_product3.visibility_limit = ProductVisibility.VISIBLE_TO_ALL shop1_product3.visibility_groups.all().delete() shop1_product3.save() # product3 and product4 are visible in shop1 request = get_request("/api/shuup/front/products/", admin_user, shop1, person1) response = FrontProductViewSet.as_view({"get": "list"})(request) response.render() products_data = json.loads(response.content.decode("utf-8")) products = sorted(products_data, key=lambda p: p["id"]) assert products[0]["id"] == product3.id assert products[0]["shop_products"][0]["orderable"] is True assert products[1]["id"] == product4.id assert products[1]["shop_products"][0]["orderable"] is True # change the shop of the first child product to make the package not orderable sp = product4.get_all_package_children()[0].shop_products.first() sp.shop = shop2 sp.save() # product3 is orderable and product4 doesn't request = get_request("/api/shuup/front/products/", admin_user, shop1, person1) response = FrontProductViewSet.as_view({"get": "list"})(request) response.render() products_data = json.loads(response.content.decode("utf-8")) products = sorted(products_data, key=lambda p: p["id"]) assert products[0]["id"] == product3.id assert products[0]["shop_products"][0]["orderable"] is True assert products[1]["id"] == product4.id assert products[1]["shop_products"][0]["orderable"] is False # assign cross sell of product1 and product2 ProductCrossSell.objects.create(product1=product1, product2=product2, type=ProductCrossSellType.RECOMMENDED) ProductCrossSell.objects.create(product1=product1, product2=product2, type=ProductCrossSellType.RELATED) ProductCrossSell.objects.create(product1=product1, product2=product2, type=ProductCrossSellType.COMPUTED) ProductCrossSell.objects.create(product1=product1, product2=product2, type=ProductCrossSellType.BOUGHT_WITH) # product1 must have cross shell of product2 request = get_request("/api/shuup/front/products/", admin_user, shop2, person1) response = FrontProductViewSet.as_view({"get": "list"})(request) response.render() products_data = json.loads(response.content.decode("utf-8")) products = sorted(products_data, key=lambda p: p["id"]) assert products[0]["id"] == product1.id assert products[0]["cross_sell"]["recommended"] == [product2.id] assert products[0]["cross_sell"]["related"] == [product2.id] assert products[0]["cross_sell"]["computed"] == [product2.id] assert products[0]["cross_sell"]["bought_with"] == [product2.id] assert products[1]["id"] == product2.id assert products[1]["cross_sell"]["recommended"] == [] assert products[1]["cross_sell"]["related"] == [] assert products[1]["cross_sell"]["computed"] == [] assert products[1]["cross_sell"]["bought_with"] == []
def mock_customer_group(self): """ Create a random contact group """ return create_random_contact_group()
def mock_customer_group(self, **kwargs): """ Create a random contact group. """ return create_random_contact_group()