def test_product_caching_object(): shop_product = get_default_shop_product() product = shop_product.product another_product = create_product("PCOTestProduct") pco = ProductCachingObject() pco.product = product assert pco.product is product assert pco.product_id == product.pk assert ProductCachingObject( ).product != pco.product # Assert PCOs are separate assert pco._product_cache == pco.product # This private property is courtesy of ModelCachingDescriptor pco = ProductCachingObject() pco.product_id = product.pk assert pco.product == product assert pco.product_id == product.pk # Not creating a new PCO here pco.product = another_product assert pco.product == another_product assert pco.product_id == another_product.pk # Nor here pco.product_id = product.pk assert pco.product == product assert pco.product_id == product.pk
def test_add_product_to_basket(admin_user, settings): configure(settings) shop = factories.get_default_shop() basket = factories.get_basket() factories.get_default_payment_method() factories.get_default_shipping_method() shop_product = factories.get_default_shop_product() shop_product.default_price = TaxfulPrice(1, shop.currency) shop_product.save() client = _get_client(admin_user) # add shop product payload = { 'shop_product': shop_product.id } response = client.post('/api/shuup/basket/{}-{}/add/'.format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) assert len(response_data["items"]) == 1 assert response_data["items"][0]["shop_product"] == shop_product.pk assert not response_data["validation_errors"] assert float(response_data["total_price"]) == 1 # add product payload = { 'product': shop_product.product.pk, 'shop': shop.pk } response = client.post('/api/shuup/basket/{}-{}/add/'.format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) assert len(response_data["items"]) == 1 assert not response_data["validation_errors"] assert float(response_data["total_price"]) == 2
def test_product_unsupplied(admin_user): shop_product = get_default_shop_product() fake_supplier = Supplier.objects.create(identifier="fake") admin_contact = get_person_contact(admin_user) with modify(shop_product, visibility_limit=ProductVisibility.VISIBLE_TO_ALL, orderable=True): assert any(ve.code == "invalid_supplier" for ve in shop_product.get_orderability_errors(supplier=fake_supplier, customer=admin_contact, quantity=1))
def test_add_product_to_basket(admin_user, settings): configure(settings) shop = factories.get_default_shop() basket = factories.get_basket() factories.get_default_payment_method() factories.get_default_shipping_method() shop_product = factories.get_default_shop_product() shop_product.default_price = TaxfulPrice(1, shop.currency) shop_product.save() client = _get_client(admin_user) # add shop product payload = {'shop_product': shop_product.id} response = client.post( '/api/shuup/basket/{}-{}/add/'.format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) assert len(response_data["items"]) == 1 assert response_data["items"][0]["shop_product"] == shop_product.pk assert not response_data["validation_errors"] assert float(response_data["total_price"]) == 1 # add product payload = {'product': shop_product.product.pk, 'shop': shop.pk} response = client.post( '/api/shuup/basket/{}-{}/add/'.format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) assert len(response_data["items"]) == 1 assert not response_data["validation_errors"] assert float(response_data["total_price"]) == 2
def test_default_supplier(): supplier = get_default_supplier() assert supplier.slug == supplier.name.lower() shop_product = get_default_shop_product() product = shop_product.product assert supplier.get_stock_statuses([product.id])[product.id].logical_count == 0 assert not list(supplier.get_orderability_errors(shop_product, 1, customer=None))
def test_product_visibility_available_until(rf, admin_user, regular_user): anon_contact = get_person_contact(AnonymousUser()) shop_product = get_default_shop_product() admin_contact = get_person_contact(admin_user) regular_contact = get_person_contact(regular_user) customer_group = get_default_customer_group() grouped_user = get_user_model().objects.create_user(username=printable_gibberish(20)) grouped_contact = get_person_contact(grouped_user) customer_group.members.add(grouped_contact) with modify(shop_product, available_until=(now() + timedelta(seconds=200))): assert error_does_not_exist(shop_product.get_visibility_errors(customer=anon_contact), "product_not_available") assert error_does_not_exist( shop_product.get_visibility_errors(customer=grouped_contact), "product_not_available" ) assert error_does_not_exist(shop_product.get_visibility_errors(customer=admin_contact), "product_not_available") assert error_does_not_exist( shop_product.get_visibility_errors(customer=regular_contact), "product_not_available" ) with modify(shop_product, available_until=(now() - timedelta(seconds=150))): assert error_exists(shop_product.get_visibility_errors(customer=anon_contact), "product_not_available") assert error_exists(shop_product.get_visibility_errors(customer=grouped_contact), "product_not_available") assert error_exists(shop_product.get_visibility_errors(customer=admin_contact), "product_not_available") assert error_exists(shop_product.get_visibility_errors(customer=regular_contact), "product_not_available")
def test_update_line_quantity(admin_user, settings): configure(settings) shop = factories.get_default_shop() basket = factories.get_basket() factories.get_default_payment_method() factories.get_default_shipping_method() shop_product = factories.get_default_shop_product() shop_product.default_price = TaxfulPrice(1, shop.currency) shop_product.save() client = _get_client(admin_user) # add shop product payload = {'shop_product': shop_product.id} response = client.post( '/api/shuup/basket/{}-{}/add/'.format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) assert len(response_data["items"]) == 1 payload = {"line_id": response_data["items"][0]["line_id"], "quantity": 5} response = client.post( '/api/shuup/basket/{}-{}/update_quantity/'.format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) assert len(response_data["items"]) == 1 assert response_data["items"][0]["shop_product"] == shop_product.pk assert float(response_data["items"][0]["quantity"]) == 5 assert float(response_data["total_price"]) == 5 basket.refresh_from_db() assert Basket.objects.first().data["lines"][0]["quantity"] == 5
def test_multiple_coupons_work_properly(admin_user, settings): configure(settings) shop = factories.get_default_shop() basket = factories.get_basket() shop_product = factories.get_default_shop_product() client = _get_client(admin_user) code_one = "DACODE" code_two = "DACODE1" coupon = Coupon.objects.create(code=code_one, active=True) get_default_campaign(coupon) payload = {'code': code_one} response = client.post( '/api/shuup/basket/{}-{}/add_code/'.format(shop.pk, basket.key), payload) basket_data = json.loads(response.content.decode("utf-8")) assert response.status_code == status.HTTP_200_OK assert code_one in basket_data['codes'] coupon1 = Coupon.objects.create(code=code_two, active=True) get_default_campaign(coupon1) payload = {'code': code_two} response = client.post( '/api/shuup/basket/{}-{}/add_code/'.format(shop.pk, basket.key), payload) basket_data = json.loads(response.content.decode("utf-8")) assert response.status_code == status.HTTP_200_OK assert code_two in basket_data['codes'] assert len(basket_data["codes"]) == 1
def test_can_delete_line(admin_user, settings): configure(settings) shop = factories.get_default_shop() basket = factories.get_basket() shop_product = factories.get_default_shop_product() client = _get_client(admin_user) payload = { 'shop_product': shop_product.id, } response = client.post('/api/shuup/basket/{}-{}/add/'.format(shop.id, basket.key), payload) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) basket.refresh_from_db() assert len(response_data["items"]) == 1 assert basket.product_count == 1 line_id = response_data["items"][0]["line_id"] payload = { 'line_id': line_id } response = client.post('/api/shuup/basket/{}-{}/remove/'.format(shop.id, basket.key), payload) response_data = json.loads(response.content.decode("utf-8")) assert response.status_code == status.HTTP_200_OK basket.refresh_from_db() assert basket.product_count == 0 assert len(response_data["items"]) == 0
def test_category_deletion(admin_user): admin = get_person_contact(admin_user) category = get_default_category() category.children.create(identifier="foo") shop_product = get_default_shop_product() shop_product.categories.add(category) shop_product.primary_category = category shop_product.save() configuration.set(None, get_all_seeing_key(admin), True) assert category.status == CategoryStatus.VISIBLE assert category.children.count() == 1 with pytest.raises(NotImplementedError): category.delete() category.soft_delete() shop_product.refresh_from_db() shop_product.product.refresh_from_db() assert shop_product.categories.count() == 0 assert shop_product.primary_category is None assert category.status == CategoryStatus.DELETED assert category.children.count() == 0 # the child category still exists assert Category.objects.all_visible(customer=admin).count() == 1 assert Category.objects.all_except_deleted().count() == 1 configuration.set(None, get_all_seeing_key(admin), False)
def test_can_delete_line(admin_user, settings): configure(settings) shop = factories.get_default_shop() basket = factories.get_basket() shop_product = factories.get_default_shop_product() client = _get_client(admin_user) payload = { 'shop_product': shop_product.id, } response = client.post( '/api/shuup/basket/{}-{}/add/'.format(shop.id, basket.key), payload) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) basket.refresh_from_db() assert len(response_data["items"]) == 1 assert basket.product_count == 1 line_id = response_data["items"][0]["line_id"] payload = {'line_id': line_id} response = client.post( '/api/shuup/basket/{}-{}/remove/'.format(shop.id, basket.key), payload) response_data = json.loads(response.content.decode("utf-8")) assert response.status_code == status.HTTP_200_OK basket.refresh_from_db() assert basket.product_count == 0 assert len(response_data["items"]) == 0
def test_update_line_quantity(admin_user, settings): configure(settings) shop = factories.get_default_shop() basket = factories.get_basket() factories.get_default_payment_method() factories.get_default_shipping_method() shop_product = factories.get_default_shop_product() shop_product.default_price = TaxfulPrice(1, shop.currency) shop_product.save() client = _get_client(admin_user) # add shop product payload = { 'shop_product': shop_product.id } response = client.post('/api/shuup/basket/{}-{}/add/'.format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) assert len(response_data["items"]) == 1 payload = { "line_id": response_data["items"][0]["line_id"], "quantity": 5 } response = client.post('/api/shuup/basket/{}-{}/update_quantity/'.format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) assert len(response_data["items"]) == 1 assert response_data["items"][0]["shop_product"] == shop_product.pk assert float(response_data["items"][0]["quantity"]) == 5 assert float(response_data["total_price"]) == 5 basket.refresh_from_db() assert Basket.objects.first().data["lines"][0]["quantity"] == 5
def test_get_suppliable_products(): customer = create_random_person() shop_product = get_default_shop_product() shop = get_default_shop() supplier = get_default_supplier() # Check for default orderable shop product with unstocked behavior assert len(list(supplier.get_suppliable_products(shop, customer=customer))) == 1 supplier.stock_managed = True supplier.save() # Make sure supplier now omits unorderable product assert not list(supplier.get_suppliable_products(shop, customer=customer)) assert len(list(supplier.get_orderability_errors(shop_product, quantity=1, customer=customer))) == 1 shop_product.backorder_maximum = 10 shop_product.save() assert len(list(supplier.get_suppliable_products(shop, customer=customer))) == 1 assert len(list(supplier.get_orderability_errors(shop_product, quantity=10, customer=customer))) == 0 assert len(list(supplier.get_orderability_errors(shop_product, quantity=11, customer=customer))) == 1 shop_product.backorder_maximum = None shop_product.save() assert len(list(supplier.get_suppliable_products(shop, customer=customer))) == 1 assert len(list(supplier.get_orderability_errors(shop_product, quantity=1000, customer=customer))) == 0
def test_multiple_coupons_work_properly(admin_user, settings): configure(settings) shop = factories.get_default_shop() basket = factories.get_basket() shop_product = factories.get_default_shop_product() client = _get_client(admin_user) code_one = "DACODE" code_two = "DACODE1" coupon = Coupon.objects.create(code=code_one, active=True) get_default_campaign(coupon) payload = { 'code': code_one } response = client.post('/api/shuup/basket/{}-{}/add_code/'.format(shop.pk, basket.key), payload) basket_data = json.loads(response.content.decode("utf-8")) assert response.status_code == status.HTTP_200_OK assert code_one in basket_data['codes'] coupon1 = Coupon.objects.create(code=code_two, active=True) get_default_campaign(coupon1) payload = { 'code': code_two } response = client.post('/api/shuup/basket/{}-{}/add_code/'.format(shop.pk, basket.key), payload) basket_data = json.loads(response.content.decode("utf-8")) assert response.status_code == status.HTTP_200_OK assert code_two in basket_data['codes'] assert len(basket_data["codes"]) == 1
def test_product_caching_object(): shop_product = get_default_shop_product() product = shop_product.product another_product = create_product("PCOTestProduct") pco = ProductCachingObject() pco.product = product assert pco.product is product assert pco.product_id == product.pk assert ProductCachingObject().product != pco.product # Assert PCOs are separate assert pco._product_cache == pco.product # This private property is courtesy of ModelCachingDescriptor pco = ProductCachingObject() pco.product_id = product.pk assert pco.product == product assert pco.product_id == product.pk # Not creating a new PCO here pco.product = another_product assert pco.product == another_product assert pco.product_id == another_product.pk # Nor here pco.product_id = product.pk assert pco.product == product assert pco.product_id == product.pk
def test_product_visibility(rf, admin_user, regular_user): anon_contact = get_person_contact(AnonymousUser()) shop_product = get_default_shop_product() admin_contact = get_person_contact(admin_user) regular_contact = get_person_contact(regular_user) with modify(shop_product.product, deleted=True): # NB: assigning to `product` here works because `get_shop_instance` populates `_product_cache` assert error_exists(shop_product.get_visibility_errors(customer=anon_contact), "product_deleted") assert error_exists(shop_product.get_visibility_errors(customer=admin_contact), "product_deleted") with pytest.raises(ProductNotVisibleProblem): shop_product.raise_if_not_visible(anon_contact) assert not shop_product.is_list_visible() with modify(shop_product, visibility_limit=ProductVisibility.VISIBLE_TO_ALL, visibility=ShopProductVisibility.NOT_VISIBLE): assert error_exists(shop_product.get_visibility_errors(customer=anon_contact), "product_not_visible") assert error_does_not_exist(shop_product.get_visibility_errors(customer=admin_contact), "product_not_visible") assert not shop_product.is_list_visible() with modify(shop_product, visibility_limit=ProductVisibility.VISIBLE_TO_LOGGED_IN, visibility=ShopProductVisibility.ALWAYS_VISIBLE): assert error_exists(shop_product.get_visibility_errors(customer=anon_contact), "product_not_visible_to_anonymous") assert error_does_not_exist(shop_product.get_visibility_errors(customer=admin_contact), "product_not_visible_to_anonymous") customer_group = get_default_customer_group() grouped_user = get_user_model().objects.create_user(username=printable_gibberish(20)) grouped_contact = get_person_contact(grouped_user) with modify(shop_product, visibility_limit=ProductVisibility.VISIBLE_TO_GROUPS, visibility=ShopProductVisibility.ALWAYS_VISIBLE): shop_product.visibility_groups.add(customer_group) customer_group.members.add(grouped_contact) customer_group.members.remove(get_person_contact(regular_user)) assert error_does_not_exist(shop_product.get_visibility_errors(customer=grouped_contact), "product_not_visible_to_group") assert error_does_not_exist(shop_product.get_visibility_errors(customer=admin_contact), "product_not_visible_to_group") assert error_exists(shop_product.get_visibility_errors(customer=regular_contact), "product_not_visible_to_group")
def test_product_query(admin_user, regular_user): anon_contact = AnonymousContact() shop_product = get_default_shop_product() shop = shop_product.shop product = shop_product.product regular_contact = get_person_contact(regular_user) admin_contact = get_person_contact(admin_user) with modify(shop_product, save=True, listed=True, visible=True, visibility_limit=ProductVisibility.VISIBLE_TO_ALL ): assert Product.objects.list_visible(shop=shop, customer=anon_contact).filter(pk=product.pk).exists() with modify(shop_product, save=True, listed=False, visible=True, visibility_limit=ProductVisibility.VISIBLE_TO_ALL ): assert not Product.objects.list_visible(shop=shop, customer=anon_contact).filter(pk=product.pk).exists() assert not Product.objects.list_visible(shop=shop, customer=regular_contact).filter(pk=product.pk).exists() assert Product.objects.list_visible(shop=shop, customer=admin_contact).filter(pk=product.pk).exists() with modify(shop_product, save=True, listed=True, visible=True, visibility_limit=ProductVisibility.VISIBLE_TO_LOGGED_IN ): assert not Product.objects.list_visible(shop=shop, customer=anon_contact).filter(pk=product.pk).exists() assert Product.objects.list_visible(shop=shop, customer=regular_contact).filter(pk=product.pk).exists() product.soft_delete() assert not Product.objects.all_except_deleted().filter(pk=product.pk).exists()
def test_get_safe_strings(key): activate("en") shop_product = get_default_shop_product() setattr(shop_product.product, key, "test") shop_product.product.save() shop_product.refresh_from_db() assert getattr(shop_product.product, key) if key == "name": with pytest.raises(TranslationDoesNotExist): assert not getattr(shop_product, key) else: assert not getattr(shop_product, key) func = getattr(shop_product, "get_" + key) assert getattr(shop_product.product, key) == func() # returns value from product # set value to shop_product new_value = "testing" setattr(shop_product, key, new_value) shop_product.save() shop_product.refresh_from_db() assert func() == new_value # returns value from shop product
def test_product_visibility(rf, admin_user, regular_user): anon_contact = get_person_contact(AnonymousUser()) shop_product = get_default_shop_product() admin_contact = get_person_contact(admin_user) regular_contact = get_person_contact(regular_user) with modify( shop_product.product, deleted=True ): # NB: assigning to `product` here works because `get_shop_instance` populates `_product_cache` assert error_exists( shop_product.get_visibility_errors(customer=anon_contact), "product_deleted") assert error_exists( shop_product.get_visibility_errors(customer=admin_contact), "product_deleted") with pytest.raises(ProductNotVisibleProblem): shop_product.raise_if_not_visible(anon_contact) assert not shop_product.is_list_visible() with modify(shop_product, visibility_limit=ProductVisibility.VISIBLE_TO_ALL, visibility=ShopProductVisibility.NOT_VISIBLE): assert error_exists( shop_product.get_visibility_errors(customer=anon_contact), "product_not_visible") assert error_does_not_exist( shop_product.get_visibility_errors(customer=admin_contact), "product_not_visible") assert not shop_product.is_list_visible() with modify(shop_product, visibility_limit=ProductVisibility.VISIBLE_TO_LOGGED_IN, visibility=ShopProductVisibility.ALWAYS_VISIBLE): assert error_exists( shop_product.get_visibility_errors(customer=anon_contact), "product_not_visible_to_anonymous") assert error_does_not_exist( shop_product.get_visibility_errors(customer=admin_contact), "product_not_visible_to_anonymous") customer_group = get_default_customer_group() grouped_user = get_user_model().objects.create_user( username=printable_gibberish(20)) grouped_contact = get_person_contact(grouped_user) with modify(shop_product, visibility_limit=ProductVisibility.VISIBLE_TO_GROUPS, visibility=ShopProductVisibility.ALWAYS_VISIBLE): shop_product.visibility_groups.add(customer_group) customer_group.members.add(grouped_contact) customer_group.members.remove(get_person_contact(regular_user)) assert error_does_not_exist( shop_product.get_visibility_errors(customer=grouped_contact), "product_not_visible_to_group") assert error_does_not_exist( shop_product.get_visibility_errors(customer=admin_contact), "product_not_visible_to_group") assert error_exists( shop_product.get_visibility_errors(customer=regular_contact), "product_not_visible_to_group")
def test_shopproduct_category_manytomany(): shop_product = get_default_shop_product() category = get_default_category() shop_product.categories = [category] category.shop_products = [shop_product] shop_product.save() assert shop_product.categories.first() == category assert category.shop_products.first() == shop_product
def test_product_minimum_order_quantity(admin_user): shop_product = get_default_shop_product() supplier = get_default_supplier() admin_contact = get_person_contact(admin_user) with modify(shop_product, visibility_limit=ProductVisibility.VISIBLE_TO_ALL, orderable=True, minimum_purchase_quantity=10): assert any(ve.code == "purchase_quantity_not_met" for ve in shop_product.get_orderability_errors(supplier=supplier, customer=admin_contact, quantity=1)) assert not any(ve.code == "purchase_quantity_not_met" for ve in shop_product.get_orderability_errors(supplier=supplier, customer=admin_contact, quantity=15))
def test_product_categories(settings): with override_settings(SHUUP_AUTO_SHOP_PRODUCT_CATEGORIES=True): shop_product = get_default_shop_product() shop_product.categories.clear() shop_product.primary_category = None shop_product.save() assert not shop_product.primary_category assert not shop_product.categories.count() category_one = CategoryFactory() category_two = CategoryFactory() shop_product.categories = Category.objects.all() assert shop_product.primary_category # this was automatically populated assert shop_product.primary_category.pk == category_one.pk # it's the first one also shop_product.categories.clear() shop_product.primary_category = category_one shop_product.save() assert shop_product.primary_category == category_one assert category_one in shop_product.categories.all() # test removing shop_product.categories.remove(category_one) shop_product.refresh_from_db() assert not shop_product.categories.exists() shop_product.categories.add(category_one) category_one.soft_delete() assert not shop_product.categories.exists() with override_settings(SHUUP_AUTO_SHOP_PRODUCT_CATEGORIES=False): shop_product.categories.clear() shop_product.primary_category = None shop_product.save() assert not shop_product.primary_category assert not shop_product.categories.count() category_one = CategoryFactory() category_two = CategoryFactory() shop_product.categories = Category.objects.all() assert not shop_product.primary_category # this was NOT automatically populated shop_product.categories.clear() shop_product.primary_category = category_one shop_product.save() assert shop_product.primary_category == category_one assert category_one not in shop_product.categories.all()
def test_product_order_multiple(admin_user): shop_product = get_default_shop_product() supplier = get_default_supplier() admin_contact = get_person_contact(admin_user) with modify(shop_product, visibility_limit=ProductVisibility.VISIBLE_TO_ALL, orderable=True, purchase_multiple=7): assert any(ve.code == "invalid_purchase_multiple" for ve in shop_product.get_orderability_errors(supplier=supplier, customer=admin_contact, quantity=4)) assert any(ve.code == "invalid_purchase_multiple" for ve in shop_product.get_orderability_errors(supplier=supplier, customer=admin_contact, quantity=25)) assert not any(ve.code == "invalid_purchase_multiple" for ve in shop_product.get_orderability_errors(supplier=supplier, customer=admin_contact, quantity=49))
def test_abandoned_baskets(admin_user, settings): configure(settings) shop = factories.get_default_shop() factories.get_default_payment_method() factories.get_default_shipping_method() basket1 = factories.get_basket() shop_product = factories.get_default_shop_product() shop_product.default_price = TaxfulPrice(1, shop.currency) shop_product.save() client = _get_client(admin_user) # add shop product payload = {'shop_product': shop_product.id} response = client.post( '/api/shuup/basket/{}-{}/add/'.format(shop.pk, basket1.key), payload) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) assert len(response_data["items"]) == 1 assert response_data["items"][0]["shop_product"] == shop_product.pk assert not response_data["validation_errors"] assert float(response_data["total_price"]) == 1 assert Basket.objects.count() == 1 response = client.get( "/api/shuup/basket/abandoned/?shop={}&days_ago=0¬_updated_in_hours=0" .format(shop.pk)) response_data = json.loads(response.content.decode("utf-8")) assert len(response_data) == 1 basket_data = response_data[0] assert basket_data["id"] == basket1.id basket2 = factories.get_basket() response = client.post( '/api/shuup/basket/{}-{}/add/'.format(shop.pk, basket2.key), payload) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) assert len(response_data["items"]) == 1 assert response_data["items"][0]["shop_product"] == shop_product.pk assert not response_data["validation_errors"] assert float(response_data["total_price"]) == 1 assert Basket.objects.count() == 2 response = client.get( "/api/shuup/basket/abandoned/?shop={}&days_ago=0¬_updated_in_hours=0" .format(shop.pk)) response_data = json.loads(response.content.decode("utf-8")) assert len(response_data) == 2 basket_data = response_data[1] assert basket_data["id"] == basket2.id # there is no shop with this id thus it should return 404 response = client.get( "/api/shuup/basket/abandoned/?shop=2&days_ago=0¬_updated_in_hours=0" ) assert response.status_code == status.HTTP_404_NOT_FOUND
def test_cant_add_a_dummy_campaign_code(admin_user, settings): configure(settings) shop = factories.get_default_shop() basket = factories.get_basket() shop_product = factories.get_default_shop_product() client = _get_client(admin_user) payload = {'code': 'ABCDE'} response = client.post( '/api/shuup/basket/{}-{}/add_code/'.format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_400_BAD_REQUEST
def test_cant_add_a_dummy_campaign_code(admin_user, settings): configure(settings) shop = factories.get_default_shop() basket = factories.get_basket() shop_product = factories.get_default_shop_product() client = _get_client(admin_user) payload = { 'code': 'ABCDE' } response = client.post('/api/shuup/basket/{}-{}/add_code/'.format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_400_BAD_REQUEST
def test_create_order(admin_user, settings, target_customer): configure(settings) shop = factories.get_default_shop() basket = factories.get_basket() factories.create_default_order_statuses() shop_product = factories.get_default_shop_product() shop_product.default_price = TaxfulPrice(1, shop.currency) shop_product.save() client = _get_client(admin_user) # add shop product payload = {'shop_product': shop_product.id} if target_customer == "other": target = factories.create_random_person() payload["customer_id"] = target.pk else: target = get_person_contact(admin_user) response = client.post( '/api/shuup/basket/{}-{}/add/'.format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) assert len(response_data["items"]) == 1 response = client.post( '/api/shuup/basket/{}-{}/create_order/'.format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_400_BAD_REQUEST response_data = json.loads(response.content.decode("utf-8")) assert "errors" in response_data factories.get_default_payment_method() factories.get_default_shipping_method() response = client.post( '/api/shuup/basket/{}-{}/create_order/'.format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_201_CREATED response_data = json.loads(response.content.decode("utf-8")) basket.refresh_from_db() assert basket.finished order = Order.objects.get( reference_number=response_data["reference_number"]) assert order.status == OrderStatus.objects.get_default_initial() assert order.payment_status == PaymentStatus.NOT_PAID assert order.shipping_status == ShippingStatus.NOT_SHIPPED assert not order.payment_method assert not order.shipping_method assert float(order.taxful_total_price_value) == 1 assert order.customer == target assert order.orderer == get_person_contact(admin_user) assert order.creator == admin_user assert not order.billing_address assert not order.shipping_address
def test_product_is_required_when_adding(admin_user, settings): configure(settings) shop = factories.get_default_shop() basket = factories.get_basket() shop_product = factories.get_default_shop_product() client = _get_client(admin_user) payload = { 'shop': shop.id, } response = client.post('/api/shuup/basket/{}-{}/add/'.format(shop.id, basket.key), payload) assert response.status_code == status.HTTP_400_BAD_REQUEST assert '"product"' in str(response.content)
def test_suppliers_disabled(): customer = create_random_person() shop_product = get_default_shop_product() shop = get_default_shop() supplier = get_default_supplier() assert shop_product.get_supplier() == supplier supplier.enabled = False supplier.save() assert shop_product.get_supplier() is None assert len(list(supplier.get_suppliable_products(shop, customer=customer))) == 0
def test_get_suppliable_products(): customer = create_random_person() shop_product = get_default_shop_product() shop = get_default_shop() supplier = get_default_supplier() # Check for default orderable shop product with unstocked behavior assert len(list(supplier.get_suppliable_products(shop, customer=customer))) == 1 product = shop_product.product product.stock_behavior = StockBehavior.STOCKED product.save() # Make sure supplier now omits unorderable product assert not list(supplier.get_suppliable_products(shop, customer=customer))
def test_wishlist_plugin_get_context(rf, admin_user): shop = get_default_shop() person = get_person_contact(admin_user) product = get_default_shop_product() wishlist = Wishlist.objects.create(shop=shop, customer=person, name='foo', privacy=WishlistPrivacy.PUBLIC) request = apply_request_middleware(rf.get("/"), shop=shop, user=person.user, shop_product=product) plugin = WishlistPlugin({}) context = plugin.get_context_data({'request': request}) assert 'wishlists' in context assert 'shop_product' in context assert context['wishlists'].count() == 1 assert context['wishlists'][0].name == wishlist.name
def test_purchasability(): anon_contact = AnonymousContact() shop_product = get_default_shop_product() supplier = get_default_supplier(shop_product.shop) assert shop_product.purchasable shop_product.raise_if_not_orderable(supplier=supplier, customer=anon_contact, quantity=1) assert shop_product.is_orderable(supplier=supplier, customer=anon_contact, quantity=1) with modify(shop_product, purchasable=False): with pytest.raises(ProductNotOrderableProblem): shop_product.raise_if_not_orderable(supplier=supplier, customer=anon_contact, quantity=1) assert not shop_product.is_orderable(supplier=supplier, customer=anon_contact, quantity=1)
def test_product_orderability(): anon_contact = AnonymousContact() shop_product = get_default_shop_product() supplier = get_default_supplier() with modify(shop_product, visibility_limit=ProductVisibility.VISIBLE_TO_ALL, orderable=True): shop_product.raise_if_not_orderable(supplier=supplier, customer=anon_contact, quantity=1) assert shop_product.is_orderable(supplier=supplier, customer=anon_contact, quantity=1) with modify(shop_product, visibility_limit=ProductVisibility.VISIBLE_TO_LOGGED_IN, orderable=True): with pytest.raises(ProductNotOrderableProblem): shop_product.raise_if_not_orderable(supplier=supplier, customer=anon_contact, quantity=1) assert not shop_product.is_orderable(supplier=supplier, customer=anon_contact, quantity=1)
def test_add_blank_code(admin_user, settings): configure(settings) configure(settings) shop = factories.get_default_shop() basket = factories.get_basket() shop_product = factories.get_default_shop_product() client = _get_client(admin_user) payload = { 'code': '' } response = client.post('/api/shuup/basket/{}-{}/add_code/'.format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_400_BAD_REQUEST response_data = json.loads(response.content.decode("utf-8")) assert 'code' in response_data
def test_add_blank_code(admin_user, settings): configure(settings) configure(settings) shop = factories.get_default_shop() basket = factories.get_basket() shop_product = factories.get_default_shop_product() client = _get_client(admin_user) payload = {'code': ''} response = client.post( '/api/shuup/basket/{}-{}/add_code/'.format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_400_BAD_REQUEST response_data = json.loads(response.content.decode("utf-8")) assert 'code' in response_data
def test_create_order(admin_user, settings, target_customer): configure(settings) shop = factories.get_default_shop() basket = factories.get_basket() factories.create_default_order_statuses() shop_product = factories.get_default_shop_product() shop_product.default_price = TaxfulPrice(1, shop.currency) shop_product.save() client = _get_client(admin_user) # add shop product payload = { 'shop_product': shop_product.id } if target_customer == "other": target = factories.create_random_person() payload["customer_id"] = target.pk else: target = get_person_contact(admin_user) response = client.post('/api/shuup/basket/{}-{}/add/'.format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) assert len(response_data["items"]) == 1 response = client.post('/api/shuup/basket/{}-{}/create_order/'.format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_400_BAD_REQUEST response_data = json.loads(response.content.decode("utf-8")) assert "errors" in response_data factories.get_default_payment_method() factories.get_default_shipping_method() response = client.post('/api/shuup/basket/{}-{}/create_order/'.format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_201_CREATED response_data = json.loads(response.content.decode("utf-8")) basket.refresh_from_db() assert basket.finished order = Order.objects.get(reference_number=response_data["reference_number"]) assert order.status == OrderStatus.objects.get_default_initial() assert order.payment_status == PaymentStatus.NOT_PAID assert order.shipping_status == ShippingStatus.NOT_SHIPPED assert not order.payment_method assert not order.shipping_method assert float(order.taxful_total_price_value) == 1 assert order.customer == target assert order.orderer == get_person_contact(admin_user) assert order.creator == admin_user assert not order.billing_address assert not order.shipping_address
def test_abandoned_baskets(admin_user, settings): configure(settings) shop = factories.get_default_shop() factories.get_default_payment_method() factories.get_default_shipping_method() basket1 = factories.get_basket() shop_product = factories.get_default_shop_product() shop_product.default_price = TaxfulPrice(1, shop.currency) shop_product.save() client = _get_client(admin_user) # add shop product payload = {'shop_product': shop_product.id} response = client.post('/api/shuup/basket/{}-{}/add/'.format(shop.pk, basket1.key), payload) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) assert len(response_data["items"]) == 1 assert response_data["items"][0]["shop_product"] == shop_product.pk assert not response_data["validation_errors"] assert float(response_data["total_price"]) == 1 assert Basket.objects.count() == 1 response = client.get("/api/shuup/basket/abandoned/?shop={}&days_ago=0¬_updated_in_hours=0".format(shop.pk)) response_data = json.loads(response.content.decode("utf-8")) assert len(response_data) == 1 basket_data = response_data[0] assert basket_data["id"] == basket1.id basket2 = factories.get_basket() response = client.post('/api/shuup/basket/{}-{}/add/'.format(shop.pk, basket2.key), payload) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) assert len(response_data["items"]) == 1 assert response_data["items"][0]["shop_product"] == shop_product.pk assert not response_data["validation_errors"] assert float(response_data["total_price"]) == 1 assert Basket.objects.count() == 2 response = client.get("/api/shuup/basket/abandoned/?shop={}&days_ago=0¬_updated_in_hours=0".format(shop.pk)) response_data = json.loads(response.content.decode("utf-8")) assert len(response_data) == 2 basket_data = response_data[1] assert basket_data["id"] == basket2.id # there is no shop with this id thus it should return 404 response = client.get("/api/shuup/basket/abandoned/?shop=2&days_ago=0¬_updated_in_hours=0") assert response.status_code == status.HTTP_404_NOT_FOUND
def test_can_add_a_valid_campaign_code(admin_user, settings): configure(settings) shop = factories.get_default_shop() basket = factories.get_basket() shop_product = factories.get_default_shop_product() client = _get_client(admin_user) coupon = Coupon.objects.create(code="DACODE", active=True) get_default_campaign(coupon) payload = {'code': 'DACODE'} response = client.post( '/api/shuup/basket/{}-{}/add_code/'.format(shop.pk, basket.key), payload) basket_data = json.loads(response.content.decode("utf-8")) assert response.status_code == status.HTTP_200_OK assert 'DACODE' in basket_data['codes']
def test_can_add_a_valid_campaign_code(admin_user, settings): configure(settings) shop = factories.get_default_shop() basket = factories.get_basket() shop_product = factories.get_default_shop_product() client = _get_client(admin_user) coupon = Coupon.objects.create(code="DACODE", active=True) get_default_campaign(coupon) payload = { 'code': 'DACODE' } response = client.post('/api/shuup/basket/{}-{}/add_code/'.format(shop.pk, basket.key), payload) basket_data = json.loads(response.content.decode("utf-8")) assert response.status_code == status.HTTP_200_OK assert 'DACODE' in basket_data['codes']
def test_product_query_with_group_visibility(regular_user): default_group = get_default_customer_group() shop_product = get_default_shop_product() shop_product.visibility_limit = 3 shop_product.save() shop = shop_product.shop product = shop_product.product shop_product.visibility_groups.add(default_group) regular_contact = get_person_contact(regular_user) assert not Product.objects.listed(shop=shop, customer=regular_contact).filter(pk=product.pk).exists() regular_contact.groups.add(default_group) assert Product.objects.listed(shop=shop, customer=regular_contact).filter(pk=product.pk).count() == 1 shop_product.visibility_groups.add(regular_contact.get_default_group()) # Multiple visibility groups for shop product shouldn't cause duplicate matches assert Product.objects.listed(shop=shop, customer=regular_contact).filter(pk=product.pk).count() == 1
def test_wishlist_plugin_get_context(rf, admin_user): shop = get_default_shop() person = get_person_contact(admin_user) product = get_default_shop_product() wishlist = Wishlist.objects.create(shop=shop, customer=person, name='foo', privacy=WishlistPrivacy.PUBLIC) request = apply_request_middleware(rf.get("/"), shop=shop, customer=person, shop_product=product) plugin = WishlistPlugin({}) context = plugin.get_context_data({'request': request}) assert 'wishlists' in context assert 'shop_product' in context assert context['wishlists'].count() == 1 assert context['wishlists'][0].name == wishlist.name
def test_add_product_to_basket_with_custom_shop_product_fields(admin_user, settings): product_name = "Product Name" shop_product_name = "SHOP Product Name" configure(settings) shop = factories.get_default_shop() basket = factories.get_basket() factories.get_default_payment_method() factories.get_default_shipping_method() shop_product = factories.get_default_shop_product() shop_product.default_price = TaxfulPrice(1, shop.currency) shop_product.save() shop_product.product.name = product_name shop_product.product.save() client = _get_client(admin_user) payload = { 'product': shop_product.product.pk, 'shop': shop.pk } response = client.post('/api/shuup/basket/{}-{}/add/'.format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) assert len(response_data["items"]) == 1 assert response_data["items"][0]["shop_product"] == shop_product.pk assert response_data["items"][0]["text"] == product_name # set shop product name shop_product.product.name = shop_product_name shop_product.product.save() # add product payload = { 'product': shop_product.product.pk, 'shop': shop.pk } response = client.post('/api/shuup/basket/{}-{}/add/'.format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) assert len(response_data["items"]) == 1 assert response_data["items"][0]["text"] == shop_product_name
def test_product_query(admin_user, regular_user): anon_contact = AnonymousContact() shop_product = get_default_shop_product() shop = shop_product.shop product = shop_product.product regular_contact = get_person_contact(regular_user) admin_contact = get_person_contact(admin_user) with modify(shop_product, save=True, listed=True, visible=True, visibility_limit=ProductVisibility.VISIBLE_TO_ALL): assert Product.objects.list_visible( shop=shop, customer=anon_contact).filter(pk=product.pk).exists() with modify(shop_product, save=True, listed=False, visible=True, visibility_limit=ProductVisibility.VISIBLE_TO_ALL): assert not Product.objects.list_visible( shop=shop, customer=anon_contact).filter(pk=product.pk).exists() assert not Product.objects.list_visible( shop=shop, customer=regular_contact).filter(pk=product.pk).exists() assert Product.objects.list_visible( shop=shop, customer=admin_contact).filter(pk=product.pk).exists() with modify(shop_product, save=True, listed=True, visible=True, visibility_limit=ProductVisibility.VISIBLE_TO_LOGGED_IN): assert not Product.objects.list_visible( shop=shop, customer=anon_contact).filter(pk=product.pk).exists() assert Product.objects.list_visible( shop=shop, customer=regular_contact).filter(pk=product.pk).exists() product.soft_delete() assert not Product.objects.all_except_deleted().filter( pk=product.pk).exists()
def test_basket_can_be_cleared(admin_user, settings): configure(settings) shop = factories.get_default_shop() basket = factories.get_basket() shop_product = factories.get_default_shop_product() client = _get_client(admin_user) payload = { 'shop': shop.id, 'product': shop_product.id, } response = client.post('/api/shuup/basket/{}-{}/add/'.format(shop.id, basket.key), payload) assert response.status_code == status.HTTP_200_OK basket = Basket.objects.get(key=basket.key) assert basket.product_count == 1 response = client.post('/api/shuup/basket/{}-{}/clear/'.format(shop.id, basket.key), payload) response_data = json.loads(response.content.decode("utf-8")) assert response.status_code == status.HTTP_200_OK basket.refresh_from_db() assert basket.product_count == 0 assert len(response_data["items"]) == 0
def test_create_order(admin_user, target_customer): with override_settings(**REQUIRED_SETTINGS): set_configuration() factories.create_default_order_statuses() shop = factories.get_default_shop() client = _get_client(admin_user) # Create basket for target customer payload = {"shop": shop.pk} target = orderer = get_person_contact(admin_user) if target_customer == "other_person": target = orderer = factories.create_random_person() payload["customer"] = target.pk elif target_customer == "company": target = factories.create_random_company() orderer = factories.create_random_person() payload.update({ "customer": target.pk, "orderer": orderer.pk }) target.members.add(orderer) response = client.post("/api/shuup/basket/new/", payload) assert response.status_code == status.HTTP_201_CREATED basket_data = json.loads(response.content.decode("utf-8")) basket = Basket.objects.first() assert basket.key == basket_data["uuid"].split("-")[1] assert basket.customer == target assert basket.orderer == orderer shop_product = factories.get_default_shop_product() shop_product.default_price = TaxfulPrice(1, shop.currency) shop_product.save() # Add shop product to basket payload = {"shop_product": shop_product.id} response = client.post("/api/shuup/basket/{}-{}/add/".format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) assert len(response_data["items"]) == 1 # Create order from basket response = client.post("/api/shuup/basket/{}-{}/create_order/".format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_400_BAD_REQUEST response_data = json.loads(response.content.decode("utf-8")) assert "errors" in response_data factories.get_default_payment_method() factories.get_default_shipping_method() response = client.post("/api/shuup/basket/{}-{}/create_order/".format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_201_CREATED response_data = json.loads(response.content.decode("utf-8")) basket.refresh_from_db() assert basket.finished order = Order.objects.get(reference_number=response_data["reference_number"]) assert order.status == OrderStatus.objects.get_default_initial() assert order.payment_status == PaymentStatus.NOT_PAID assert order.shipping_status == ShippingStatus.NOT_SHIPPED assert not order.payment_method assert not order.shipping_method assert float(order.taxful_total_price_value) == 1 assert order.customer == target assert order.orderer == orderer assert order.creator == admin_user assert not order.billing_address assert not order.shipping_address
def test_adjust_stock(admin_user): get_default_shop() sp = get_default_shop_product() sp.stock_behavior = StockBehavior.STOCKED sp.save() client = _get_client(admin_user) supplier = get_default_supplier() simple_supplier = get_simple_supplier() # invalid type response = client.post("/api/shuup/supplier/%s/stock/" % supplier.pk, data={ "product": sp.product.pk, "delta": 100, "type": 100 }) assert response.status_code == status.HTTP_400_BAD_REQUEST data = json.loads(response.content.decode("utf-8")) assert "type" in data # invalid supplier response = client.post("/api/shuup/supplier/%s/stock/" % 100, data={ "product": sp.product.pk, "delta": 100, "type": 100 }) assert response.status_code == status.HTTP_404_NOT_FOUND # invalid product response = client.post("/api/shuup/supplier/%s/stock/" % supplier.pk, data={ "product": 100, "delta": 100, "type": 1 }) assert response.status_code == status.HTTP_400_BAD_REQUEST data = json.loads(response.content.decode("utf-8")) assert "product" in data # invalid delta response = client.post("/api/shuup/supplier/%s/stock/" % supplier.pk, data={ "product": sp.product.pk, "delta": "not-a-number", "type": 1 }) assert response.status_code == status.HTTP_400_BAD_REQUEST data = json.loads(response.content.decode("utf-8")) assert "delta" in data # adjust stock not implemented response = client.post("/api/shuup/supplier/%s/stock/" % supplier.pk, data={ "product": sp.product.pk, "delta": 100, "type": 1 }) assert response.status_code == 400 # add 100 to inventory response = client.post("/api/shuup/supplier/%s/stock/" % simple_supplier.pk, data={ "product": sp.product.pk, "delta": 100, "type": 1 }) assert response.status_code == 201 stock = simple_supplier.get_stock_status(sp.product.pk) assert stock.logical_count == 100 assert stock.physical_count == 100
def test_default_supplier(): supplier = get_default_supplier() shop_product = get_default_shop_product() product = shop_product.product assert supplier.get_stock_statuses([product.id])[product.id].logical_count == 0 assert not list(supplier.get_orderability_errors(shop_product, 1, customer=None))