Пример #1
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_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
Пример #3
0
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))
Пример #4
0
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))
Пример #5
0
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))
Пример #6
0
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))
Пример #7
0
def test_product_categories(settings):
    with override_settings(WSHOP_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(WSHOP_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()
Пример #8
0
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)
Пример #9
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))
    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
Пример #10
0
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
Пример #11
0
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)

    configuration.set(None, get_all_seeing_key(admin_contact), True)

    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")

    configuration.set(None, get_all_seeing_key(admin_contact), False)
Пример #12
0
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)
    supplier1 = get_simple_supplier()
    supplier2 = get_default_supplier()
    # invalid type
    response = client.post("/api/wshop/supplier/%s/adjust_stock/" % supplier1.pk, format="json", data={
        "product": sp.product.pk,
        "delta": 100,
        "type": 200
    })
    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/wshop/supplier/%s/adjust_stock/" % 100, format="json", data={
        "product": sp.product.pk,
        "delta": 100,
        "type": StockAdjustmentType.INVENTORY.value
    })
    assert response.status_code == status.HTTP_404_NOT_FOUND

    # invalid product
    response = client.post("/api/wshop/supplier/%s/adjust_stock/" % supplier1.pk, format="json", data={
        "product": 100,
        "delta": 100,
        "type": StockAdjustmentType.INVENTORY.value
    })
    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/wshop/supplier/%s/adjust_stock/" % supplier1.pk, format="json", data={
        "product": sp.product.pk,
        "delta": "not-a-number",
        "type": StockAdjustmentType.INVENTORY.value
    })
    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/wshop/supplier/%s/adjust_stock/" % supplier2.pk, format="json", data={
        "product": sp.product.pk,
        "delta": 100,
        "type": StockAdjustmentType.INVENTORY.value
    })
    assert response.status_code == status.HTTP_400_BAD_REQUEST

    # add 100 to inventory
    response = client.post("/api/wshop/supplier/%s/adjust_stock/" % supplier1.pk, format="json", data={
        "product": sp.product.pk,
        "delta": 100,
        "type": StockAdjustmentType.RESTOCK.value
    })
    assert response.status_code == status.HTTP_200_OK
    stock = supplier1.get_stock_status(sp.product.pk)
    assert stock.logical_count == 100
    assert stock.physical_count == 100

    # remove the stocks adjustments and calculate the stock again
    StockAdjustment.objects.all().delete()

    # update the stock,
    response = client.post("/api/wshop/supplier/%s/update_stocks/" % supplier1.pk, format="json", data={
        "products": [sp.product.pk]
    })
    assert response.status_code == status.HTTP_200_OK
    # everything should be zero
    stock = supplier1.get_stock_status(sp.product.pk)
    assert stock.logical_count == 0
    assert stock.physical_count == 0
Пример #13
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/wshop/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/wshop/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/wshop/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/wshop/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