Beispiel #1
0
def test_matching_product_discount_with_contact(rf):
    default_price = 10
    request, product = _init_test_for_product(rf, default_price)

    product_discount_amount = 4
    discount = Discount.objects.create(active=True, product=product, discount_amount_value=product_discount_amount)
    discount.shops.add(request.shop)
    assert product.get_price_info(request).price == request.shop.create_price(default_price - product_discount_amount)

    # Adding contact condition to the discount should make
    # the discount go away.
    random_contact = factories.create_random_person()
    discount.contact = random_contact
    discount.save()
    assert request.customer != random_contact
    assert product.get_price_info(request).price == request.shop.create_price(default_price)

    # Let's set the new contact as request customer and we
    # should get the discount back.
    request.customer = random_contact
    assert product.get_price_info(request).price == request.shop.create_price(default_price - product_discount_amount)

    # Another contact should still only get the price without discount
    another_contact = factories.create_random_person()
    request.customer = another_contact
    assert product.get_price_info(request).price == request.shop.create_price(default_price)
Beispiel #2
0
def test_customer_usage_limit(rf):
    default_price = 10
    request, product = _init_test_for_product_without_basket(rf, default_price)
    shop = request.shop
    customers = []
    for x in range(3):
        customers.append(factories.create_random_company(shop=shop))

    discount_percentage = 0.20
    coupon = CouponCode.objects.create(code="sUpErAle", active=True, usage_limit_customer=2)
    coupon.shops = [request.shop]
    discount = Discount.objects.create(
        active=True, product=product, coupon_code=coupon, discount_percentage=discount_percentage)
    discount.shops.add(request.shop)

    # Order product twice for each customer
    for customer in customers:
        for y in range(2):
            _create_order(request, customer, coupon, product, request.shop.create_price(8))

    assert coupon.usages.count() == 6  # Each customer 2 orders

    # Any of the customers created shouldn't be allowed to
    # order more with this coupon code.
    for customer in customers:
        assert not CouponCode.is_usable(shop, coupon, customer)

    # New customer should still be able to order some
    new_customer = factories.create_random_person()
    assert CouponCode.is_usable(shop, coupon, new_customer)
    _create_order(request, new_customer, coupon, product, request.shop.create_price(8))

    assert coupon.usages.count() == 7

    # Set usage limit and the new customer shouldn't be able to use the code
    coupon.usage_limit = 7
    coupon.save()
    assert not CouponCode.is_usable(request.shop, coupon, new_customer)
    _create_order(request, new_customer, coupon, product, request.shop.create_price(default_price))
    assert coupon.usages.count() == 7

    # One of the customer got refund
    refunded_customer = customers[0]
    order = refunded_customer.customer_orders.first()
    coupon_code_modifier = CouponCodeModule()
    coupon_code_modifier.clear_codes(order)

    assert coupon.usages.count() == 6

    # New customer still doesn't  able to create coupon
    new_customer = factories.create_random_person()
    assert CouponCode.is_usable(shop, coupon, new_customer)
    _create_order(request, new_customer, coupon, product, request.shop.create_price(8))
    assert coupon.usages.count() == 7
Beispiel #3
0
def test_category_product_discount_with_contact_group(rf):
    default_price = 10
    request, product = _init_test_for_product(rf, default_price)

    category = factories.get_default_category()
    product.get_shop_instance(request.shop).categories.add(category)
    product_discount_amount = 4
    discount = Discount.objects.create(active=True, category=category, discount_amount_value=product_discount_amount)
    discount.shops.add(request.shop)
    assert product.get_price_info(request).price == request.shop.create_price(default_price - product_discount_amount)

    # Adding contact group limitation to the discount should
    # make the discount go away
    contact_group = factories.get_default_customer_group()
    discount.contact_group = contact_group
    discount.save()
    assert product.get_price_info(request).price == request.shop.create_price(default_price)

    # Let's set contact for request with the group created
    # and let's see the discount coming back
    random_contact = factories.create_random_person()
    request.customer = random_contact
    assert product.get_price_info(request).price == request.shop.create_price(default_price)
    random_contact.groups.add(contact_group)
    assert request.customer == random_contact
    assert product.get_price_info(request).price == request.shop.create_price(default_price - product_discount_amount)
Beispiel #4
0
def test_create_new_basket(admin_user):
    with override_settings(**REQUIRED_SETTINGS):
        shop = factories.get_default_shop()
        shop2 = create_shop("foobar")
        client = _get_client(admin_user)
        response = client.post("/api/E-Commerce/basket/new/", {
            "shop": shop2.pk
        })
        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.shop == shop2
        admin_contact = get_person_contact(admin_user)
        assert basket.customer == admin_contact
        assert basket.orderer == admin_contact
        assert basket.creator == admin_user

        # invalid shop
        response = client.post("/api/E-Commerce/basket/new/", data={"shop": 1000})
        assert response.status_code == status.HTTP_400_BAD_REQUEST

        # no shop in multishop mode
        response = client.post("/api/E-Commerce/basket/new/")
        assert response.status_code == status.HTTP_400_BAD_REQUEST

        # no shop in single shop mode
        with override_settings(E-Commerce_ENABLE_MULTIPLE_SHOPS=False):
            response = client.post("/api/E-Commerce/basket/new/")
            assert response.status_code == status.HTTP_201_CREATED
            basket_data = json.loads(response.content.decode("utf-8"))
            basket = Basket.objects.all()[1]
            assert basket.key == basket_data['uuid'].split("-")[1]
            assert basket.shop == shop
            assert basket.customer == admin_contact
            assert basket.orderer == admin_contact
            assert basket.creator == admin_user

            person = factories.create_random_person()

            response = client.post("/api/E-Commerce/basket/new/", data={"customer": person.pk})
            assert response.status_code == status.HTTP_201_CREATED
            basket_data = json.loads(response.content.decode("utf-8"))
            basket = Basket.objects.all()[2]
            assert basket.key == basket_data['uuid'].split("-")[1]
            assert basket.shop == shop
            assert basket.creator == admin_user
            assert basket.customer.pk == person.pk
            assert basket.orderer.pk == person.pk
            assert basket.creator.pk == admin_user.pk

            # Try to fetch the basket as the customer
            user = factories.UserFactory()
            person.user = user
            person.save()
            response = client.get("/api/E-Commerce/basket/{}/".format(basket_data['uuid']))
            assert response.status_code == 200
            customer_basket_data = json.loads(response.content.decode("utf-8"))
            assert basket.key == customer_basket_data['key']  # Still same basket as before
            assert customer_basket_data['customer']['id'] == person.pk  # Still same customer as before
def test_class_refunded():
    shop = factories.get_default_shop()
    supplier = factories.get_default_supplier()
    customer = factories.create_random_person("en")
    OrderStatusManager().ensure_default_statuses()

    product = factories.create_product("p", shop, supplier, 1.0)
    order = factories.create_order_with_product(product, supplier, 1, 1, shop=shop)

    # make sure to have some script enabled
    Script.objects.create(shop=shop, event_identifier="order_status_changed", name="Script", enabled=True)

    def get_mocked_cls():
        return mock.MagicMock(identifier="order_status_changed")

    with mock.patch("E-Commerce.front.notify_events.OrderStatusChanged", new_callable=get_mocked_cls) as mocked:
        order.status = OrderStatus.objects.get_default_processing()
        order.save()
        mocked.assert_called()
        order.refresh_from_db()
        assert mocked.call_args.kwargs["order"] == order
        assert mocked.call_args.kwargs["old_status"] == OrderStatus.objects.get_default_initial()
        assert mocked.call_args.kwargs["new_status"] == OrderStatus.objects.get_default_processing()
        assert order.status == OrderStatus.objects.get_default_processing()

    # nothing changes
    with mock.patch("E-Commerce.front.notify_events.OrderStatusChanged", new_callable=get_mocked_cls) as mocked:
        order.status = OrderStatus.objects.get_default_processing()
        order.save()
        mocked.assert_not_called()
Beispiel #6
0
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
Beispiel #7
0
def test_set_non_shop_member_customer(rf):
    """
    Set some customer to the basket that is not member of the shop
    """
    with override_settings(**CORE_BASKET_SETTINGS):
        shop = factories.get_shop(False)
        assert shop != factories.get_default_shop()

        user = factories.create_random_user()
        request = apply_request_middleware(rf.get("/"), user=user)
        basket = get_basket(request, "basket")
        basket.customer = get_person_contact(user)
        assert basket.shop == factories.get_default_shop()

        person = factories.create_random_person()
        person.shops.add(shop)

        company = factories.create_random_company()
        company.add_to_shop(shop)

        for customer in [person, company]:
            with pytest.raises(ValidationError) as exc:
                basket_commands.handle_set_customer(request, basket, customer)
            assert exc.value.code == "invalid_customer_shop"
            assert basket.customer == get_person_contact(user)
def test_person_contact_layout():
    vc = _get_basic_view_config()
    person = factories.create_random_person()

    placeholder_name = "kissa"
    request = get_request()
    request.customer = person
    context = {"request": request}
    layout = vc.get_placeholder_layout(PersonContactLayout, placeholder_name, context=context)
    assert isinstance(layout, PersonContactLayout)
    help_text = layout.get_help_text({})  # Same help text with or without the context
    assert layout.get_help_text(context) == help_text

    # Invalid contexts for anon and company layouts
    assert vc.get_placeholder_layout(AnonymousContactLayout, placeholder_name, context=context) is None
    assert vc.get_placeholder_layout(CompanyContactLayout, placeholder_name, context=context) is None

    # Valid contexts for contact layout
    assert vc.get_placeholder_layout(ContactLayout, placeholder_name, context=context) is not None

    _add_plugin_and_test_save(vc, layout, placeholder_name, context)

    # Ok here we want to check that the plugin doesn't end up to the
    # contact placeholders
    contact_layout = vc.get_placeholder_layout(ContactLayout, placeholder_name, context=context)
    _assert_empty_layout(contact_layout, placeholder_name)
Beispiel #9
0
def test_basket_with_staff_user():
    with override_settings(**REQUIRED_SETTINGS):
        set_configuration()
        shop = factories.get_default_shop()
        staff_user = User.objects.create(username="******", is_staff=True)

        client = _get_client(staff_user)
        person = factories.create_random_person()
        response = client.post("/api/E-Commerce/basket/new/", data={"shop": shop.pk, "customer": person.pk})
        # Only stuff linked to shop can create baskets for someone else
        assert response.status_code == status.HTTP_403_FORBIDDEN

        # Can still add personal baskets
        staff_person = get_person_contact(staff_user)
        response = client.post(
            "/api/E-Commerce/basket/new/", data={"shop": shop.pk, "customer": staff_person.pk})
        assert response.status_code == status.HTTP_201_CREATED
        basket_data = json.loads(response.content.decode("utf-8"))
        basket = Basket.objects.filter(key=basket_data["uuid"].split("-")[1]).first()
        assert basket.shop == shop
        assert basket.creator == staff_user
        assert basket.customer.pk == staff_person.pk
        response = client.get("/api/E-Commerce/basket/{}/".format(basket_data["uuid"]))
        assert response.status_code == 200

        basket_uuid = basket_data["uuid"]
        assert basket_data['customer']['id'] == staff_person.pk
        assert basket_data['customer']['user'] == staff_user.pk

        # retrieve the basket
        response = client.get("/api/E-Commerce/basket/{}/".format(basket_uuid))
        basket_data = json.loads(response.content.decode("utf-8"))
        assert basket_data['customer']['id'] == staff_person.pk
        assert basket_data['customer']['user'] == staff_user.pk

        # Ok let's link the staff member to the shop and
        # the basket create for random person should work
        shop.staff_members.add(staff_user)
        response = client.post(
            "/api/E-Commerce/basket/new/", data={"shop": shop.pk, "customer": person.pk})
        assert response.status_code == status.HTTP_201_CREATED
        basket_data = json.loads(response.content.decode("utf-8"))
        basket = Basket.objects.filter(key=basket_data["uuid"].split("-")[1]).first()
        assert basket.shop == shop
        assert basket.creator == staff_user
        assert basket.customer.pk == person.pk
        response = client.get("/api/E-Commerce/basket/{}/".format(basket_data["uuid"]))
        assert response.status_code == 200

        basket_uuid = basket_data["uuid"]
        assert basket_data['customer']['id'] == person.pk
        assert basket_data['customer']['user'] is None

        # retrieve the basket
        response = client.get("/api/E-Commerce/basket/{}/".format(basket_uuid))
        basket_data = json.loads(response.content.decode("utf-8"))
        assert basket_data['customer']['id'] == person.pk
        assert basket_data['customer']['user'] is None
Beispiel #10
0
def test_basic_tasks(admin_user):
    shop = factories.get_default_shop()
    contact = factories.create_random_person(shop=shop)
    # task gets created
    text = "derpy hooves"
    task_type = TaskType.objects.create(name="Request", shop=shop)
    task = create_task(shop, contact, task_type, "my task", comment=text)

    assert Task.objects.count() == 1
    assert TaskComment.objects.count() == 1
    assert TaskComment.objects.first().author == contact
    assert contact.task_comments.count() == 1
    assert not task.assigned_to
    assert task.status == TaskStatus.NEW

    # someone handles it
    admin_contact = factories.create_random_person()
    admin_contact.user = admin_user
    admin_contact.save()
    task.assign(admin_contact)
    task.refresh_from_db()

    assert task.assigned_to == admin_contact
    assert task.status == TaskStatus.IN_PROGRESS

    comment_text = "this being handled now"
    task.comment(admin_contact, comment_text)

    task.refresh_from_db()

    assert task.comments.count() == 2
    assert task.comments.last().body == comment_text

    assert TaskComment.objects.count() == 2

    task.set_in_progress()
    task.refresh_from_db()
    assert task.status == TaskStatus.IN_PROGRESS

    task.set_completed(admin_contact)
    task.refresh_from_db()
    assert task.status == TaskStatus.COMPLETED

    assert task.completed_on
    assert task.completed_by == admin_contact
Beispiel #11
0
def test_set_different_customer(rf):
    """
    Set some customer to the basket that is not the request one
    """
    with override_settings(**CORE_BASKET_SETTINGS):
        user = factories.create_random_user()
        request = apply_request_middleware(rf.get("/"), user=user)
        basket = get_basket(request, "basket")
        basket.customer = get_person_contact(user)
        person1 = factories.create_random_person()

        with pytest.raises(ValidationError) as exc:
            basket_commands.handle_set_customer(request, basket, person1)
        assert exc.value.code == "no_permission"
        assert basket.customer == get_person_contact(user)

        # with superuser
        person2 = factories.create_random_person()
        superuser = factories.create_random_user(is_superuser=True)
        request = apply_request_middleware(rf.get("/"), user=superuser)
        assert basket_commands.handle_set_customer(request, basket, person2)["ok"] is True
        assert basket.customer == person2
        assert basket.orderer == person2

        # with staff user not member of the shop
        person3 = factories.create_random_person()
        staff = factories.create_random_user(is_staff=True)
        request = apply_request_middleware(rf.get("/"), user=staff)
        with pytest.raises(ValidationError) as exc:
            basket_commands.handle_set_customer(request, basket, person3)
        assert exc.value.code == "no_permission"
        assert basket.customer == person2
        assert basket.orderer == person2

        # with staff user member of the shop
        person4 = factories.create_random_person()
        staff_member = factories.create_random_user(is_staff=True)
        basket.shop.staff_members.add(staff_member)
        request = apply_request_middleware(rf.get("/"), user=staff_member)
        assert basket_commands.handle_set_customer(request, basket, person4)["ok"] is True
        assert basket.customer == person4
        assert basket.orderer == person4
Beispiel #12
0
def test_discount_for_person_contacts(rf):
    default_price = 10
    request, product = _init_test_for_product(rf, default_price)
    assert request.customer == AnonymousContact()

    random_person = factories.create_random_person()
    person_contact_group = random_person.get_default_group()
    product_discount_amount = 2
    discount = Discount.objects.create(
        active=True, contact_group=person_contact_group, discount_amount_value=product_discount_amount)
    discount.shops.add(request.shop)
    assert product.get_price_info(request).price == request.shop.create_price(default_price)

    # Setting customer to request activates the discount
    request.customer = factories.create_random_person()
    assert product.get_price_info(request).price == request.shop.create_price(default_price - product_discount_amount)

    # Using company contact as customer means no discount
    request.customer = factories.create_random_company()
    assert product.get_price_info(request).price == request.shop.create_price(default_price)
Beispiel #13
0
def test_set_from_anonymous_to_customer_not_auth(rf):
    """
    Set some customer to the basket when not authenticated
    """
    with override_settings(**CORE_BASKET_SETTINGS):
        request = apply_request_middleware(rf.get("/"))
        basket = get_basket(request, "basket")
        basket.customer = AnonymousContact()

        customer = factories.create_random_person()
        assert basket_commands.handle_set_customer(request, basket, customer)["ok"] is True
        assert basket.customer == customer
Beispiel #14
0
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()
Beispiel #15
0
def test_serialize_data():
    """
    Test contact dashboard views
    """
    activate("en")
    shop = factories.get_default_shop()

    customer = factories.create_random_person("en")
    user = factories.create_random_user("en")
    user.set_password("1234")
    user.save()
    customer.user = user
    customer.default_billing_address = factories.create_random_address()
    customer.default_shipping_address = factories.create_random_address()
    customer.save()

    company = factories.create_random_company()
    company.default_billing_address = factories.create_random_address()
    company.default_shipping_address = factories.create_random_address()
    company.save()
    company.members.add(customer)

    product = factories.create_product("p1", shop, factories.get_default_supplier())
    for basket_customer in [customer, company]:
        [factories.create_random_order(basket_customer, [product]) for order in range(3)]

    client = SmartClient()
    client.login(username=user.username, password="******")

    response = client.get(reverse("E-Commerce:gdpr_customer_dashboard"))
    assert response.status_code == 200
    assert "My Data" in response.content.decode("utf-8")

    response = client.post(reverse("E-Commerce:gdpr_download_data"))
    assert response._headers["content-disposition"][0] == "Content-Disposition"
    assert response.status_code == 200

    from E-Commerce.tasks.models import Task, TaskType
    from E-Commerce.gdpr.models import GDPR_ANONYMIZE_TASK_TYPE_IDENTIFIER
    response = client.post(reverse("E-Commerce:gdpr_anonymize_account"))
    assert response.status_code == 302
    assert response.url.endswith(reverse("E-Commerce:index"))
    task_type = TaskType.objects.get(identifier=GDPR_ANONYMIZE_TASK_TYPE_IDENTIFIER, shop=shop)
    assert Task.objects.get(type=task_type, shop=shop)

    user.refresh_from_db()
    assert user.is_active is False

    refreshed_customer = PersonContact.objects.get(id=customer.id)
    assert refreshed_customer.is_active is False
    assert refreshed_customer.name == customer.name     # nothing changed yet
Beispiel #16
0
def test_discount_for_anons(rf):
    default_price = 10
    request, product = _init_test_for_product(rf, default_price)
    assert request.customer == AnonymousContact()

    anon_default_group = AnonymousContact().get_default_group()
    product_discount_amount = 2
    discount = Discount.objects.create(
        active=True, contact_group=anon_default_group, discount_amount_value=product_discount_amount)
    discount.shops.add(request.shop)
    assert product.get_price_info(request).price == request.shop.create_price(default_price - product_discount_amount)

    # Setting customer to request takes out the discount
    request.customer = factories.create_random_person()
    assert product.get_price_info(request).price == request.shop.create_price(default_price)
Beispiel #17
0
def _init_test_for_product_without_basket(rf, default_price):
    shop = factories.get_default_shop()
    supplier = factories.get_default_supplier()
    random_customer = factories.create_random_person()
    request = rf.get("/")
    apply_request_middleware(request, shop=shop, customer=random_customer)
    assert request.shop == shop
    assert request.customer == random_customer

    sku = "test"
    product = Product.objects.filter(sku=sku).first()
    if not product:
        product = factories.create_product(sku, shop=shop, supplier=supplier, default_price=default_price)

    assert product.get_price_info(request).price == shop.create_price(default_price)
    return request, product
Beispiel #18
0
def test_set_company_customer(rf):
    """
    Set a company as the basket customer
    """
    with override_settings(**CORE_BASKET_SETTINGS):
        user = factories.create_random_user()
        request = apply_request_middleware(rf.get("/"), user=user)
        basket = get_basket(request, "basket")
        basket.customer = get_person_contact(user)

        person = factories.create_random_person()
        company = factories.create_random_company()

        # no orderer provided
        with pytest.raises(ValidationError) as exc:
            basket_commands.handle_set_customer(request, basket, company)
        assert exc.value.code == "invalid_orderer"
        assert basket.customer == get_person_contact(user)

        # orderer provided but not member of the company
        with pytest.raises(ValidationError) as exc:
            basket_commands.handle_set_customer(request, basket, company, person)
        assert exc.value.code == "orderer_not_company_member"
        assert basket.customer == get_person_contact(user)

        # orderer provided but user not member of the company
        company.members.add(person)
        with pytest.raises(ValidationError) as exc:
            basket_commands.handle_set_customer(request, basket, company, person)
        assert exc.value.code == "not_company_member"
        assert basket.customer == get_person_contact(user)

        # staff and admin can add any the company and orderer without being member of the company
        superuser = factories.create_random_user(is_superuser=True)
        staff = factories.create_random_user(is_staff=True)
        basket.shop.staff_members.add(staff)

        for user in [superuser, staff]:
            basket.customer = None
            basket.orderer = None

            request = apply_request_middleware(rf.get("/"), user=user)
            assert basket_commands.handle_set_customer(request, basket, company, person)["ok"] is True
            assert basket.customer == company
            assert basket.orderer == person
Beispiel #19
0
def test_set_from_anonymous_to_customer_auth(rf):
    """
    Set some random customer to the basket when authenticated
    """
    with override_settings(**CORE_BASKET_SETTINGS):
        user = factories.create_random_user()
        request = apply_request_middleware(rf.get("/"), user=user)
        basket = get_basket(request, "basket")
        basket.customer = AnonymousContact()

        # can not set the customer for something different as the request customer
        with pytest.raises(ValidationError) as exc:
            basket_commands.handle_set_customer(request, basket, factories.create_random_person())
        assert exc.value.code == "no_permission"
        assert basket.customer == AnonymousContact()

        assert basket_commands.handle_set_customer(request, basket, get_person_contact(user))["ok"] is True
        assert basket.customer == get_person_contact(user)
Beispiel #20
0
def test_anonymous_set_company_customer(rf):
    """
    Set a company as the basket customer
    """
    with override_settings(**CORE_BASKET_SETTINGS):
        user = factories.create_random_user()
        request = apply_request_middleware(rf.get("/"), user=user)
        basket = get_basket(request, "basket")
        basket.customer = AnonymousContact()

        person = factories.create_random_person()
        company = factories.create_random_company()
        company.members.add(person)

        with pytest.raises(ValidationError) as exc:
            basket_commands.handle_set_customer(request, basket, company, person)
        assert exc.value.code == "not_company_member"
        assert basket.customer == AnonymousContact()
Beispiel #21
0
def test_gdpr_admin_download_data(client, admin_user):
    """
    Test that admin user can download customer data
    """
    activate("en")
    shop = factories.get_default_shop()
    customer = factories.create_random_person("en")
    product = factories.create_product("p1", shop, factories.get_default_supplier())
    [factories.create_random_order(customer, [product]) for order in range(3)]

    client = SmartClient()
    admin_user.set_password("admin")
    admin_user.save()
    client.login(username=admin_user.username, password="******")
    admin_download_url = reverse("E-Commerce_admin:gdpr.download_data", kwargs=dict(pk=customer.pk))
    response = client.post(admin_download_url)
    assert response.status_code == 200
    assert response._headers["content-disposition"][0] == "Content-Disposition"
    assert response._headers["content-disposition"][1].startswith("attachment; filename=user_data_")
def test_copy_order_to_basket_for_staff(admin_user):
    with override_settings(**REQUIRED_SETTINGS):
        set_configuration()
        shop = factories.get_default_shop()
        customer = factories.create_random_person()
        order = _create_order(shop, customer)

        client = get_client(admin_user)
        basket = factories.get_basket(shop)
        uuid = "%s-%s" % (shop.pk, basket.key)
        response = client.post(
            '/api/E-Commerce/basket/%s/set_customer/' % uuid, format="json", data={"customer": customer.id}
        )
        assert response.status_code == status.HTTP_200_OK

        response = client.post('/api/E-Commerce/basket/%s/add_from_order/' % uuid, {"order": order.pk})
        assert response.status_code == status.HTTP_404_NOT_FOUND  # admin user is not staff

        shop.staff_members.add(admin_user)
        _fill_new_basket_from_order(client, basket, customer, order)
Beispiel #23
0
def test_gdpr_admin_anonymize(client, admin_user):
    """
    Test that admin user can anonymize contact
    """
    activate("en")
    factories.get_default_shop()
    person = factories.create_random_person("en")
    person.user = factories.create_random_user("en")
    person.save()

    client = SmartClient()
    admin_user.set_password("admin")
    admin_user.save()
    client.login(username=admin_user.username, password="******")
    admin_anonymize_url = reverse("E-Commerce_admin:gdpr.anonymize", kwargs=dict(pk=person.pk))
    response = client.post(admin_anonymize_url)
    assert response.status_code == 302
    assert response.url.endswith(reverse("E-Commerce_admin:contact.detail", kwargs=dict(pk=person.pk)))

    anonymized_person = PersonContact.objects.get(id=person.id)
    assert anonymized_person.name != person.name
    assert anonymized_person.user.username != person.user.username
Beispiel #24
0
def test_set_not_active_customer(rf):
    """
    Set a not active customer to the basket
    """
    with override_settings(**CORE_BASKET_SETTINGS):
        user = factories.create_random_user()
        request = apply_request_middleware(rf.get("/"), user=user)
        basket = get_basket(request, "basket")
        basket.customer = get_person_contact(user)

        person = factories.create_random_person()
        person.is_active = False
        person.save()

        company = factories.create_random_company()
        company.is_active = False
        company.save()

        for customer in [person, company]:
            with pytest.raises(ValidationError) as exc:
                basket_commands.handle_set_customer(request, basket, customer)
            assert exc.value.code == "invalid_customer"
            assert basket.customer == get_person_contact(user)
Beispiel #25
0

def _get_edit_object_view(rf, view, model_name, object_id, user, shop, mode=None):
    data = {
        "model": model_name,
        "id": object_id
    }
    if mode:
        data["mode"] = mode
    request = apply_request_middleware(rf.get(reverse("E-Commerce_admin:edit"), data), user=user, shop=shop)
    return view(request)


@pytest.mark.parametrize("creator_fn", [
    lambda: factories.create_product("sku", factories.get_default_shop(), factories.get_default_supplier()),
    lambda: factories.create_random_person(),
    lambda: factories.create_random_company(),
    lambda: factories.create_random_order(customer=factories.create_random_person(), products=[
        factories.create_product("p", factories.get_default_shop(), factories.get_default_supplier())
    ]),
    lambda: factories.create_random_user(),
])
@pytest.mark.django_db
def test_edit_object_view(rf, admin_user, creator_fn):
    shop = factories.get_default_shop()
    view = EditObjectView.as_view()
    object_instance = creator_fn()
    model = ".".join(ContentType.objects.get_for_model(object_instance).natural_key())

    # correct shop
    response = _get_edit_object_view(rf, view, model, object_instance.id, admin_user, shop)
def test_catalog_campaign_sync():
    shop = factories.get_default_shop()
    supplier = factories.get_default_supplier()
    default_price = 100
    product1 = factories.create_product("test1", shop=shop, supplier=supplier, default_price=default_price)
    product2 = factories.create_product("test2", shop=shop, supplier=supplier, default_price=default_price)
    product3 = factories.create_product("test3", shop=shop, supplier=supplier, default_price=default_price)
    category = factories.get_default_category()
    shop_product = product1.get_shop_instance(shop)
    shop_product.primary_category = category
    shop_product.save()
    shop_product.categories.add(category)

    contact1 = factories.create_random_person()

    contact2 = factories.create_random_person()
    contact_group = factories.get_default_customer_group()
    contact2.groups.add(contact_group)

    happy_hour1_weekdays = "0,1"  # Mon, Tue
    happy_hour1_start = datetime.time(21)
    happy_hour1_end = datetime.time(3)
    happy_hour1_condition = HourCondition.objects.create(
        days=happy_hour1_weekdays, hour_start=happy_hour1_start, hour_end=happy_hour1_end)

    happy_hour2_weekdays = "2,6"  # Wed, Sun
    happy_hour2_start = datetime.time(14)
    happy_hour2_end = datetime.time(16)
    happy_hour2_condition = HourCondition.objects.create(
        days=happy_hour2_weekdays, hour_start=happy_hour2_start, hour_end=happy_hour2_end)

    discount_amount_value = 50
    discount_percentage = decimal.Decimal("0.35")
    _create_catalog_campaign_for_products(
        shop, [product1], discount_amount_value, happy_hour1_condition)
    _create_catalog_campaign_for_products(
        shop, [product2, product3], discount_amount_value)
    _create_catalog_campaign_for_category(
        shop, category, discount_percentage)
    _create_catalog_campaign_for_contact(
        shop, product1, contact1, discount_amount_value)
    _create_catalog_campaign_for_contact_group(
        shop, [product1, product2, product3], contact_group, discount_percentage, happy_hour2_condition)

    call_command("import_catalog_campaigns", *[], **{})

    # From first campaign we should get 1 discount with happy hour
    # From second campaign we should get 2 discounts
    # From third campaign we should get 1 discount
    # From fourth campaign we should get also 1 discount
    # From last campaign we should get 3 discounts with happy hour
    assert Discount.objects.count() == 8

    # There should be 2 happy hours in total
    assert HappyHour.objects.count() == 2

    # From first happy hour there should be 4 ranges
    # Mon 21-23, Tue 0-3, Tue 21-23, Wed 0-3
    # From second happy hour there should be 2 ranges
    # Wed 14-16 and Sun 14-16
    assert TimeRange.objects.count() == 6

    # Let's go through all our 8 discounts to make sure all is good
    first_discount = Discount.objects.filter(
        product=product1, category__isnull=True, contact__isnull=True, contact_group__isnull=True).first()
    assert first_discount.happy_hours.count() == 1
    assert first_discount.discount_amount_value == discount_amount_value

    second_discount = Discount.objects.filter(
        product=product2, category__isnull=True, contact__isnull=True, contact_group__isnull=True).first()
    assert second_discount.happy_hours.count() == 0
    assert second_discount.discount_amount_value == discount_amount_value

    third_discount = Discount.objects.filter(
        product=product3, category__isnull=True, contact__isnull=True, contact_group__isnull=True).first()
    assert third_discount.happy_hours.count() == 0
    assert third_discount.discount_amount_value == discount_amount_value

    category_discount = Discount.objects.filter(
        product__isnull=True, category=category, contact__isnull=True, contact_group__isnull=True).first()
    assert category_discount.happy_hours.count() == 0
    assert category_discount.discount_percentage == discount_percentage

    contact_discount = Discount.objects.filter(
        product=product1, category__isnull=True, contact=contact1, contact_group__isnull=True).first()
    assert contact_discount.discount_amount_value == discount_amount_value

    product1_contact_group_discount = Discount.objects.filter(
        product=product1, category__isnull=True, contact__isnull=True, contact_group=contact_group).first()
    assert product1_contact_group_discount.happy_hours.count() == 1
    assert product1_contact_group_discount.discount_percentage == discount_percentage

    product2_contact_group_discount = Discount.objects.filter(
        product=product2, category__isnull=True, contact__isnull=True, contact_group=contact_group).first()
    assert product2_contact_group_discount.happy_hours.count() == 1
    assert product2_contact_group_discount.discount_percentage == discount_percentage

    product3_contact_group_discount = Discount.objects.filter(
        product=product3, category__isnull=True, contact__isnull=True, contact_group=contact_group).first()
    assert product3_contact_group_discount.happy_hours.count() == 1
    assert product3_contact_group_discount.discount_percentage == discount_percentage
Beispiel #27
0
def test_reorder_view():
    shop = factories.get_default_shop()
    factories.get_default_shipping_method()
    factories.get_default_payment_method()

    supplier1 = factories.get_supplier(SimpleSupplierModule.identifier, shop=shop)
    supplier2 = factories.get_supplier(SimpleSupplierModule.identifier, shop=shop)
    assert supplier1.pk != supplier2.pk

    product_supplier1 = factories.create_product(
        "product_supplier1",
        shop=shop,
        supplier=supplier1,
        default_price=10,
        shipping_mode=ShippingMode.NOT_SHIPPED
    )
    product_supplier2 = factories.create_product(
        "product_supplier2",
        shop=shop,
        supplier=supplier2,
        default_price=20,
        shipping_mode=ShippingMode.NOT_SHIPPED
    )

    user = factories.create_random_user("en")
    user.set_password("user")
    user.save()

    customer = factories.create_random_person("en")
    customer.user = user
    customer.save()

    order = factories.create_random_order(
        customer=customer,
        shop=shop,
        products=[product_supplier1, product_supplier2],
        completion_probability=0,
        random_products=False
    )
    suppliers = [line.supplier for line in order.lines.products()]
    assert supplier1 in suppliers
    assert supplier2 in suppliers

    client = Client()
    client.login(username=user.username, password="******")

    # list orders
    response = client.get(reverse("E-Commerce:personal-orders"))
    assert response.status_code == 200
    content = response.content.decode("utf-8")
    assert "<td>%d</td>" % order.id in content
    assert "<td>Received</td>" in content

    # go to order detail
    response = client.get(reverse("E-Commerce:show-order", kwargs=dict(pk=order.pk)))
    assert response.status_code == 200
    content = response.content.decode("utf-8")
    assert "Add all products to cart" in content
    reorder_url = reverse("E-Commerce:reorder-order", kwargs=dict(pk=order.pk))
    assert reorder_url in content

    # reorder products
    response = client.get(reorder_url)
    assert response.status_code == 302
    assert response.url.endswith(reverse("E-Commerce:basket"))

    # go to basket
    response = client.get(response.url)
    assert response.status_code == 200
    content = response.content.decode("utf-8")

    # ensure the basket contain those products and suppliers
    basket_key = client.session["basket_basket_key"]["key"]
    from E-Commerce.front.models import StoredBasket
    basket = StoredBasket.objects.get(key=basket_key)
    lines = basket.data["lines"]
    product_supplier = [(line["product_id"], line["supplier_id"]) for line in lines]
    assert (product_supplier1.pk, supplier1.pk) in product_supplier
    assert (product_supplier2.pk, supplier2.pk) in product_supplier

    assert product_supplier1.name in content
    assert product_supplier2.name in content
    assert "You are unable to proceed to checkout!" not in content
def test_index_view_with_contact_limitatons():
    shop = factories.get_default_shop()
    password = "******"

    # Person 1 to test contact and person contact layouts
    person1 = factories.create_random_person(shop=shop)
    person1.user = factories.create_random_user()
    person1.user.set_password(password)
    person1.user.save()
    person1.save()

    # Person 2 to test company layout
    person2 = factories.create_random_person(shop=shop)
    person2.user = factories.create_random_user()
    person2.user.set_password(password)
    person2.user.save()
    person2.save()
    company = factories.create_random_company(shop=shop)
    company.members.add(person2)

    placeholder_name = "front_content"
    request = get_request()
    context = {"request": request}

    # Add plugin for anons
    vc = _get_basic_view_config(view_name="IndexView")
    anon_plugin_text = "This content is only for guests"
    layout = vc.get_placeholder_layout(AnonymousContactLayout, placeholder_name, context=context)
    _add_plugin_and_test_save(vc, layout, placeholder_name, context, anon_plugin_text)

    # Add plugin for contact
    vc = _get_basic_view_config(view_name="IndexView")
    context["request"].customer = person1
    contact_plugin_text = "This content is only for users logged in"
    layout = vc.get_placeholder_layout(ContactLayout, placeholder_name, context=context)
    _add_plugin_and_test_save(vc, layout, placeholder_name, context, contact_plugin_text)

    # Add plugin for person contacts
    vc = _get_basic_view_config(view_name="IndexView")
    person_contact_plugin_text = "This content is only for person contacts"
    layout = vc.get_placeholder_layout(PersonContactLayout, placeholder_name, context=context)
    _add_plugin_and_test_save(vc, layout, placeholder_name, context, person_contact_plugin_text)

    # Add plugin for companies
    vc = _get_basic_view_config(view_name="IndexView")
    context["request"].customer = company
    company_plugin_text = "This content is only for companies"
    layout = vc.get_placeholder_layout(CompanyContactLayout, placeholder_name, context=context)
    _add_plugin_and_test_save(vc, layout, placeholder_name, context, company_plugin_text)

    c = SmartClient()  # By default there is no user logged in
    soup = c.soup(reverse("E-Commerce:index"))
    page_content = soup.find("div", {"class": "page-content"})
    page_content_text = page_content.text
    assert anon_plugin_text in page_content_text
    assert contact_plugin_text not in page_content_text
    assert person_contact_plugin_text not in page_content_text
    assert company_plugin_text not in page_content_text

    # Login as person1 user
    c = SmartClient()
    c.login(username=person1.user.username, password=password)
    soup = c.soup(reverse("E-Commerce:index"))
    page_content = soup.find("div", {"class": "page-content"})
    page_content_text = page_content.text
    assert anon_plugin_text not in page_content_text
    assert contact_plugin_text in page_content_text
    assert person_contact_plugin_text in page_content_text
    assert company_plugin_text not in page_content_text

    # Login as person2 user which is linked to company
    c = SmartClient()
    c.login(username=person2.user.username, password=password)
    soup = c.soup(reverse("E-Commerce:index"))
    page_content = soup.find("div", {"class": "page-content"})
    page_content_text = page_content.text
    assert anon_plugin_text not in page_content_text
    assert contact_plugin_text in page_content_text
    assert person_contact_plugin_text not in page_content_text
    assert company_plugin_text in page_content_text
Beispiel #29
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/E-Commerce/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/E-Commerce/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/E-Commerce/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/E-Commerce/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
Beispiel #30
0
def test_basket_reorder_staff_user():
    with override_settings(**REQUIRED_SETTINGS):
        set_configuration()
        shop = factories.get_default_shop()
        factories.get_default_payment_method()
        factories.get_default_shipping_method()
        staff_user = User.objects.create(username="******", is_staff=True)

        client = _get_client(staff_user)
        person = factories.create_random_person()

        # create an order for the person
        product = create_product("product", shop=shop, supplier=get_default_supplier(), default_price='12.4')
        order = create_random_order(customer=person, products=[product], completion_probability=1, shop=shop)

        # create the basket
        response = client.post("/api/E-Commerce/basket/new/", data={"shop": shop.pk, "customer": person.pk}, format="json")
        # Only stuff linked to shop can create baskets for someone else
        assert response.status_code == status.HTTP_403_FORBIDDEN

        # Can still add personal baskets
        staff_person = get_person_contact(staff_user)
        response = client.post("/api/E-Commerce/basket/new/", data={"shop": shop.pk, "customer": staff_person.pk}, format="json")
        assert response.status_code == status.HTTP_201_CREATED
        basket_data = json.loads(response.content.decode("utf-8"))
        basket = Basket.objects.filter(key=basket_data["uuid"].split("-")[1]).first()
        assert basket.shop == shop
        assert basket.creator == staff_user
        assert basket.customer.pk == staff_person.pk
        response = client.get("/api/E-Commerce/basket/{}/".format(basket_data["uuid"]))
        assert response.status_code == 200

        # Ok let's link the staff member to the shop and
        # the basket create for random person should work
        shop.staff_members.add(staff_user)
        response = client.post("/api/E-Commerce/basket/new/", data={"shop": shop.pk, "customer": person.pk}, format="json")
        assert response.status_code == status.HTTP_201_CREATED
        basket_data = json.loads(response.content.decode("utf-8"))
        basket = Basket.objects.filter(key=basket_data["uuid"].split("-")[1]).first()
        assert basket.shop == shop
        assert basket.creator == staff_user
        assert basket.customer.pk == person.pk
        response = client.get("/api/E-Commerce/basket/{}/".format(basket_data["uuid"]))
        assert response.status_code == 200
        assert basket.creator == staff_user
        assert basket.customer.pk == person.pk

        # add contents to the basket from a customer order
        response = client.post('/api/E-Commerce/basket/{}-{}/add_from_order/'.format(shop.pk, basket.key), data={"order": order.pk}, format="json")
        assert response.status_code == status.HTTP_200_OK
        basket_data = json.loads(response.content.decode("utf-8"))
        assert len(basket_data['items']) > 0
        assert Decimal(basket_data['taxful_total_price']) == order.taxful_total_price_value

        # finally create the order
        response = client.post('/api/E-Commerce/basket/{}-{}/create_order/'.format(shop.pk, basket.key))
        assert response.status_code == status.HTTP_201_CREATED
        response_data = json.loads(response.content.decode("utf-8"))
        created_order = Order.objects.get(id=response_data['id'])
        assert created_order.creator == staff_user
        assert created_order.customer == person

        # create a second customer
        person2 = factories.create_random_person()
        # create a basket for customer 2 and try to fill with contents of customer 1 order - it should not be possible
        response = client.post("/api/E-Commerce/basket/new/", data={"shop": shop.pk, "customer": person2.pk}, format="json")
        assert response.status_code == status.HTTP_201_CREATED
        basket_data = json.loads(response.content.decode("utf-8"))
        basket = Basket.objects.filter(key=basket_data["uuid"].split("-")[1]).first()
        assert basket.shop == shop
        assert basket.creator == staff_user
        assert basket.customer.pk == person2.pk

        # add contents to the basket from customer 1 order - error
        response = client.post('/api/E-Commerce/basket/{}-{}/add_from_order/'.format(shop.pk, basket.key), data={"order": order.pk}, format="json")
        assert response.status_code == status.HTTP_404_NOT_FOUND
        assert 'invalid order' in response.content.decode("utf-8")