Beispiel #1
0
def test_same_codes():
    shop1 = factories.get_shop(True, "EUR")
    shop2 = factories.get_shop(True, "USD")

    dc1 = Coupon.objects.create(code="TEST")
    dc2 = Coupon.objects.create(code="TEST")


    BasketCampaign.objects.create(name="test1", active=True, shop_id=shop1.id, coupon_id=dc1.id)
    with pytest.raises(ValidationError):
        BasketCampaign.objects.create(name="test1", active=True, shop_id=shop1.id, coupon_id=dc2.id)

    BasketCampaign.objects.create(name="test2", active=True, shop_id=shop2.id, coupon_id=dc2.id)
    with pytest.raises(ValidationError):
        BasketCampaign.objects.create(name="test2", active=True, shop_id=shop2.id, coupon_id=dc1.id)

    # Disable one campaigns for dc1 and you should be able to set the code to different campaign again
    dc3 = Coupon.objects.create(code="TEST")
    BasketCampaign.objects.filter(coupon=dc1).update(active=False)
    BasketCampaign.objects.create(name="test1", active=True, shop_id=shop1.id, coupon_id=dc3.id)

    # Try to reactivate the campaign for shop1
    c = BasketCampaign.objects.filter(coupon=dc1).first()
    assert c.active == False
    with pytest.raises(ValidationError):
        c.active = True
        c.save()

    # Try to sneak one duplicate code by saving the coupon
    dc4 = Coupon.objects.create(code="TEST1")
    BasketCampaign.objects.create(name="test4", active=True, shop_id=shop2.id, coupon_id=dc4.id)
    with pytest.raises(ValidationError):
        dc4.code = "TEST"
        dc4.save()
def test_happy_hours_admin_edit_view_over_midnight(rf, staff_user, admin_user):
    shop = factories.get_default_shop()
    shop.staff_members.add(staff_user)
    factories.get_shop(identifier="shop2", enabled=True)
    assert Shop.objects.count() == 2

    # Staff user gets shop automatically
    from_hour = datetime.time(hour=21, minute=0)
    to_hour = datetime.time(hour=3, minute=0)
    data = {
        "name": "Happiest Hour 2pm",
        "weekdays": [1],  # Tue
        "from_hour": from_hour,
        "to_hour": to_hour
    }
    request = apply_request_middleware(rf.post("/", data=data), user=staff_user, shop=shop)
    set_shop(request, shop)
    assert request.shop == shop
    view_func = HappyHourEditView.as_view()
    response = view_func(request)
    if hasattr(response, "render"):
        response.render()

    assert response.status_code == 302

    happy_hour = HappyHour.objects.first()
    assert happy_hour is not None
    assert happy_hour.shops.first() == shop
    assert happy_hour.time_ranges.count() == 2  # Since happy hour starts and ends on different day
    assert happy_hour.time_ranges.filter(weekday=1).exists()
    assert happy_hour.time_ranges.filter(weekday=1, from_hour=from_hour, to_hour=datetime.time(23, 59)).exists()
    assert happy_hour.time_ranges.filter(weekday=2, from_hour=datetime.time(0), to_hour=to_hour).exists()
    _assert_view_get(rf, happy_hour, shop, staff_user)  # Viewing the edit should also still work
Beispiel #3
0
def test_manufacturer_admin_multishop_shop(rf, staff_user, admin_user, superuser):
    with override_settings(E-Commerce_ENABLE_MULTIPLE_SHOPS=True):
        shop1 = factories.get_shop(identifier="shop1", enabled=True)
        shop2 = factories.get_shop(identifier="shop2", enabled=True)
        shop1.staff_members.add(staff_user)
        shop2.staff_members.add(staff_user)

        assert Manufacturer.objects.count() == 0
        user = admin_user if superuser else staff_user

        request = apply_request_middleware(rf.post("/", data=dict(name="Manuf shop2")), user=user, shop=shop2)
        set_shop(request, shop2)
        view_func = ManufacturerEditView.as_view()
        response = view_func(request)
        assert response.status_code == 302

        if superuser:
            assert Manufacturer.objects.first().shops.count() == 0
        else:
            assert Manufacturer.objects.first().shops.first() == shop2

        for view_class in (ManufacturerEditView, ManufacturerListView):
            view_instance = view_class()
            view_instance.request= request

            assert view_instance.get_queryset().count() == 1
            if superuser:
                assert view_instance.get_queryset().first().shops.count() == 0
            else:
                assert view_instance.get_queryset().first().shops.count() == 1
                assert view_instance.get_queryset().first().shops.first() == shop2

        request = apply_request_middleware(rf.post("/", data=dict(name="Manuf shop1")), user=user, shop=shop1)
        set_shop(request, shop1)
        view_func = ManufacturerEditView.as_view()
        response = view_func(request)
        assert response.status_code == 302

        if superuser:
            assert Manufacturer.objects.last().shops.count() == 0
        else:
            assert Manufacturer.objects.last().shops.first() == shop1

        for view_class in (ManufacturerEditView, ManufacturerListView):
            view_instance = view_class()
            view_instance.request= request

            assert view_instance.get_queryset().count() == (2 if superuser else 1)

            if superuser:
                assert view_instance.get_queryset().first().shops.count() == 0
                assert view_instance.get_queryset().last().shops.count() == 0
            else:
                assert view_instance.get_queryset().first().shops.count() == 1
                assert view_instance.get_queryset().first().shops.first() == shop1
Beispiel #4
0
def test_edit_shared_file(admin_user):
    with override_settings(E-Commerce_ENABLE_MULTIPLE_SHOPS=True):
        shop1 = factories.get_shop(identifier="shop1", enabled=True)
        shop2 = factories.get_shop(identifier="shop2", enabled=True)

        folder1 = Folder.objects.create(name="folder1")
        folder2 = Folder.objects.create(name="folder2")
        file = File.objects.create(original_filename="test.jpg", folder=folder1)  # Shared file
        file_count = File.objects.count()
        assert force_text(file) == "test.jpg"

        response = _mbv_command(shop1, admin_user, {"action": "rename_file", "id": file.pk, "name": "test.tiff"})
        assert not response["success"]
        response = _mbv_command(shop1, admin_user, {"action": "move_file", "file_id": file.pk, "folder_id": folder2.pk})
        assert not response["success"]
        assert File.objects.get(pk=file.pk).folder == folder1
        response = _mbv_command(shop1, admin_user, {"action": "delete_file", "id": file.pk})
        assert not response["success"]

        # Let's make sure rename works when only one shop owns the file
        media_file = MediaFile.objects.create(file=file)
        media_file.shops.add(shop1)
        response = _mbv_command(shop1, admin_user, {"action": "rename_file", "id": file.pk, "name": "test.tiff"})
        assert response["success"]
        file = File.objects.get(pk=file.pk)
        assert force_text(file) == "test.tiff"

        # Let's move the file to different folder
        response = _mbv_command(shop1, admin_user, {"action": "move_file", "file_id": file.pk, "folder_id": folder2.pk})
        assert response["success"]
        assert File.objects.get(pk=file.pk).folder == folder2

        # Then add second shop for the file and let's check and
        # renaming should be disabled again.
        media_file.shops.add(shop2)
        response = _mbv_command(shop1, admin_user, {"action": "rename_file", "id": file.pk, "name": "test.tiff"})
        assert not response["success"]
        response = _mbv_command(shop1, admin_user, {"action": "delete_file", "id": file.pk})
        assert not response["success"]
        response = _mbv_command(shop2, admin_user, {"action": "rename_file", "id": file.pk, "name": "test.tiff"})
        assert not response["success"]
        response = _mbv_command(shop2, admin_user, {"action": "delete_file", "id": file.pk})
        assert not response["success"]

        # Finally remove the file as shop2
        media_file.shops.remove(shop1)
        response = _mbv_command(shop1, admin_user, {"action": "delete_file", "id": file.pk})
        assert response["error"] == "File matching query does not exist."
        response = _mbv_command(shop2, admin_user, {"action": "delete_file", "id": file.pk})
        assert response["success"]
        assert File.objects.count() == file_count - 1
def test_happy_hours_admin_edit_view(rf, staff_user, admin_user):
    with override_settings(E-Commerce_ENABLE_MULTIPLE_SHOPS=True):
        shop = factories.get_default_shop()
        shop.staff_members.add(staff_user)
        factories.get_shop(identifier="shop2", enabled=True)
        assert Shop.objects.count() == 2

        # Staff user gets shop automatically
        data = {
            "name": "Happiest Hour 2pm",
            "weekdays": [6], # Sun
            "from_hour": datetime.time(hour=14, minute=0),
            "to_hour": datetime.time(hour=14, minute=0)
        }
        request = apply_request_middleware(rf.post("/", data=data), user=staff_user, shop=shop)
        set_shop(request, shop)
        assert request.shop == shop
        view_func = HappyHourEditView.as_view()
        response = view_func(request)
        if hasattr(response, "render"):
            response.render()

        assert response.status_code == 302
        happy_hour1 = HappyHour.objects.first()
        assert happy_hour1 is not None
        assert happy_hour1.shops.first() == shop
        assert happy_hour1.time_ranges.count() == 1  # Since happy hour starts and ends on same day

        # Test with superuser and with different shop
        shop2 = factories.get_shop(enabled=True)
        request = apply_request_middleware(rf.post("/", data=data), user=admin_user, shop=shop2)
        set_shop(request, shop2)
        view_func = HappyHourEditView.as_view()
        response = view_func(request)
        assert response.status_code == 302
        assert HappyHour.objects.count() == 2

        happy_hour2 = HappyHour.objects.exclude(id=happy_hour1.pk).first()
        assert happy_hour1 != happy_hour2
        assert happy_hour2.shops.count() == 1
        assert happy_hour2.shops.filter(id=shop2.pk).first()

        # Staff user can only view coupon codes since that has the right shop
        _assert_view_get(rf, happy_hour1, shop, staff_user)
        _assert_view_get(rf, happy_hour2, shop, staff_user, True)

        # Superuser can see both if needed, but only when right shop is active
        _assert_view_get(rf, happy_hour1, shop, admin_user)
        _assert_view_get(rf, happy_hour2, shop, admin_user, True)
        _assert_view_get(rf, happy_hour2, shop2, admin_user)
def test_exceptions_admin_edit_view(rf, staff_user, admin_user):
    with override_settings(E-Commerce_ENABLE_MULTIPLE_SHOPS=True):
        shop = factories.get_default_shop()
        shop.staff_members.add(staff_user)
        factories.get_shop(identifier="shop2", enabled=True)
        assert Shop.objects.count() == 2

        # Staff user gets shop automatically
        data = {
            "name": "No deals in next 2 days!",
            "start_datetime": datetime.datetime(year=2018, month=11, day=9),
            "end_datetime": datetime.datetime(year=2018, month=11, day=11),
        }
        request = apply_request_middleware(rf.post("/", data=data), user=staff_user, shop=shop)
        set_shop(request, shop)
        assert request.shop == shop
        view_func = AvailabilityExceptionEditView.as_view()
        response = view_func(request)
        if hasattr(response, "render"):
            response.render()

        assert response.status_code == 302
        exception1 = AvailabilityException.objects.first()
        assert exception1 is not None
        assert exception1.shops.first() == shop

        # Test with superuser and with different shop
        shop2 = factories.get_shop(enabled=True)
        request = apply_request_middleware(rf.post("/", data=data), user=admin_user, shop=shop2)
        set_shop(request, shop2)
        view_func = AvailabilityExceptionEditView.as_view()
        response = view_func(request)
        assert response.status_code == 302
        assert AvailabilityException.objects.count() == 2

        exception2 = AvailabilityException.objects.exclude(id=exception1.pk).first()
        assert exception1 != exception2
        assert exception2.shops.count() == 1
        assert exception2.shops.filter(id=shop2.pk).exists()

        # Staff user can only view coupon codes since that has the right shop
        _assert_view_get(rf, exception1, shop, staff_user)
        _assert_view_get(rf, exception2, shop, staff_user, True)

        # Superuser can see both if needed, but only when right shop is active
        _assert_view_get(rf, exception1, shop, admin_user)
        _assert_view_get(rf, exception2, shop, admin_user, True)
        _assert_view_get(rf, exception2, shop2, admin_user)
def _test_happy_hours_delete_view(rf, index):
    shop = factories.get_shop(identifier="shop%s" % index, enabled=True)
    staff_user = factories.create_random_user(is_staff=True)
    shop.staff_members.add(staff_user)
    happy_hour_name = "The Hour %s" % index
    happy_hour = HappyHour.objects.create(name=happy_hour_name)
    happy_hour.shops = [shop]
    extra_happy_hour= HappyHour.objects.create(name="Extra Hour %s" % index)
    extra_happy_hour.shops = [shop]

    assert HappyHour.objects.filter(name=happy_hour_name).exists()
    view_func = HappyHourDeleteView.as_view()
    request = apply_request_middleware(rf.post("/"), user=staff_user, shop=shop)
    set_shop(request, shop)
    response = view_func(request, pk=happy_hour.pk)
    if hasattr(response, "render"):
        response.render()
    assert response.status_code == 302
    assert not HappyHour.objects.filter(name=happy_hour_name).exists()

    # Make sure that this staff can't remove other people discounts
    other_exceptions = HappyHour.objects.exclude(shops=shop)
    exception_count = other_exceptions.count()
    for coupon in other_exceptions:
        view_func = HappyHourDeleteView.as_view()
        request = apply_request_middleware(rf.post("/"), user=staff_user, shop=shop)
        set_shop(request, shop)
        with pytest.raises(Http404):
            response = view_func(request, pk=coupon.pk)
            if hasattr(response, "render"):
                response.render()

    assert exception_count == HappyHour.objects.exclude(shops=shop).count()
def _test_happy_hours_list_view(rf, index):
    shop = factories.get_shop(identifier="shop%s" % index, enabled=True)
    staff_user = factories.create_random_user(is_staff=True)
    shop.staff_members.add(staff_user)

    happy_hour = HappyHour.objects.create(name="After Work %s" % index)
    happy_hour.shops = [shop]

    view_func = HappyHourListView.as_view()
    request = apply_request_middleware(
        rf.get("/", {
            "jq": json.dumps({"perPage": 100, "page": 1})
        }),
        user=staff_user,
        shop=shop)
    set_shop(request, shop)
    response = view_func(request)
    if hasattr(response, "render"):
        response.render()
    assert response.status_code == 200

    view_instance = HappyHourListView()
    view_instance.request = request
    assert request.shop == shop
    assert view_instance.get_queryset().count() == 1

    data = json.loads(view_instance.get(request).content.decode("UTF-8"))
    assert len(data["items"]) == 1
Beispiel #9
0
def test_category_tour(browser, admin_user, live_server, settings):
    shop = factories.get_default_shop()
    shop2 = factories.get_shop(identifier="shop2")
    admin_user_2 = factories.create_random_user(is_staff=True, is_superuser=True)
    admin_user_2.set_password("password")
    admin_user_2.save()

    shop.staff_members.add(admin_user)
    shop.staff_members.add(admin_user_2)

    for user in [admin_user, admin_user_2]:
        initialize_admin_browser_test(browser, live_server, settings, username=user.username, tour_complete=False)
        wait_until_condition(browser, lambda x: x.is_text_present("Welcome!"))
        browser.visit(live_server + "/sa/categories/new")

        wait_until_condition(browser, lambda x: x.is_text_present("Add a new product category"), timeout=30)
        wait_until_condition(browser, lambda x: x.is_element_present_by_css(".shepherd-button.btn-primary"))
        click_element(browser, ".shepherd-button.btn-primary")
        wait_until_condition(browser, lambda x: not x.is_element_present_by_css(".shepherd-button"))
        wait_until_condition(browser, lambda x: is_tour_complete(shop, "category", user))

        # check whether the tour is shown again
        browser.visit(live_server + "/sa/categories/new")
        wait_until_condition(browser, lambda x: not x.is_text_present("Add a new product category"))

        browser.visit(live_server + "/logout")
        browser.visit(live_server + "/sa")

        assert is_tour_complete(shop2, "category", user) is False
Beispiel #10
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_exception_delete_view(rf, index):
    shop = factories.get_shop(identifier="shop%s" % index, enabled=True)
    staff_user = factories.create_random_user(is_staff=True)
    shop.staff_members.add(staff_user)
    exception_name = "Exception %s" % index
    exception = AvailabilityException.objects.create(
        name=exception_name, start_datetime=now(), end_datetime=now())
    exception.shops = [shop]
    extra_exception = AvailabilityException.objects.create(
        name="Extra Exception %s" % index, start_datetime=now(), end_datetime=now())
    extra_exception.shops = [shop]

    assert AvailabilityException.objects.filter(name=exception_name).exists()
    view_func = AvailabilityExceptionDeleteView.as_view()
    request = apply_request_middleware(rf.post("/"), user=staff_user, shop=shop)
    set_shop(request, shop)
    response = view_func(request, pk=exception.pk)
    if hasattr(response, "render"):
        response.render()
    assert response.status_code == 302
    assert not AvailabilityException.objects.filter(name=exception_name).exists()

    # Make sure that this staff can't remove other people discounts
    other_exceptions = AvailabilityException.objects.exclude(shops=shop)
    exception_count = other_exceptions.count()
    for coupon in other_exceptions:
        view_func = AvailabilityExceptionDeleteView.as_view()
        request = apply_request_middleware(rf.post("/"), user=staff_user, shop=shop)
        set_shop(request, shop)
        with pytest.raises(Http404):
            response = view_func(request, pk=coupon.pk)
            if hasattr(response, "render"):
                response.render()

    assert exception_count == AvailabilityException.objects.exclude(shops=shop).count()
def _test_coupon_code_list_view(rf, index):
    shop = factories.get_shop(identifier="shop%s" % index, enabled=True)
    staff_user = factories.create_random_user(is_staff=True)
    shop.staff_members.add(staff_user)

    coupon_code = CouponCode.objects.create(code="%s" % index)
    coupon_code.shops = [shop]

    view_func = CouponCodeListView.as_view()
    request = apply_request_middleware(
        rf.get("/", {
            "jq": json.dumps({"perPage": 100, "page": 1})
        }),
        user=staff_user,
        shop=shop)
    set_shop(request, shop)
    response = view_func(request)
    if hasattr(response, "render"):
        response.render()
    assert response.status_code == 200

    view_instance = CouponCodeListView()
    view_instance.request = request
    assert request.shop == shop
    assert view_instance.get_queryset().count() == 1

    data = json.loads(view_instance.get(request).content.decode("UTF-8"))
    assert len(data["items"]) == 1
    coupon_code_data = [item for item in data["items"] if item["_id"] == coupon_code.pk][0]
    assert coupon_code_data["usages"] == 0
def _test_coupon_code_delete_view(rf, index):
    shop = factories.get_shop(identifier="shop%s" % index, enabled=True)
    staff_user = factories.create_random_user(is_staff=True)
    shop.staff_members.add(staff_user)
    code = "code-%s" % index
    coupon = CouponCode.objects.create(code=code)
    coupon.shops = [shop]
    extra_coupon = CouponCode.objects.create(code="extra-coupon-%s" % index)
    extra_coupon.shops = [shop]

    assert CouponCode.objects.filter(code=code).exists()
    view_func = CouponCodeDeleteView.as_view()
    request = apply_request_middleware(rf.post("/"), user=staff_user, shop=shop)
    set_shop(request, shop)
    response = view_func(request, pk=coupon.pk)
    if hasattr(response, "render"):
        response.render()
    assert response.status_code == 302
    assert not CouponCode.objects.filter(code=code).exists()

    # Make sure that this staff can't remove other people discounts
    other_coupons = CouponCode.objects.exclude(shops=shop)
    coupon_count = other_coupons.count()
    for coupon in other_coupons:
        view_func = CouponCodeDeleteView.as_view()
        request = apply_request_middleware(rf.post("/"), user=staff_user, shop=shop)
        set_shop(request, shop)
        with pytest.raises(Http404):
            response = view_func(request, pk=coupon.pk)
            if hasattr(response, "render"):
                response.render()

    assert coupon_count == CouponCode.objects.exclude(shops=shop).count()
Beispiel #14
0
def test_product_tour(browser, admin_user, live_server, settings):
    shop = factories.get_default_shop()
    shop2 = factories.get_shop(identifier="shop2")
    admin_user_2 = factories.create_random_user(is_staff=True, is_superuser=True)
    admin_user_2.set_password("password")
    admin_user_2.save()
    product = factories.get_default_product()
    shop_product = product.get_shop_instance(shop)

    shop.staff_members.add(admin_user)
    shop.staff_members.add(admin_user_2)

    for user in [admin_user, admin_user_2]:
        initialize_admin_browser_test(browser, live_server, settings, username=user.username, tour_complete=False)
        wait_until_condition(browser, lambda x: x.is_text_present("Welcome!"))
        browser.visit(live_server + "/sa/products/%d/" % shop_product.pk)

        wait_until_condition(browser, lambda x: x.is_text_present(shop_product.product.name))
        # as this is added through javascript, add an extra timeout
        wait_until_condition(browser, lambda x: x.is_text_present("You are adding a product."), timeout=30)
        wait_until_condition(browser, lambda x: x.is_element_present_by_css(".shepherd-button.btn-primary"))
        click_element(browser, ".shepherd-button.btn-primary")

        category_targets = [
            "a.shepherd-enabled[href='#basic-information-section']",
            "a.shepherd-enabled[href='#additional-details-section']",
            "a.shepherd-enabled[href='#manufacturer-section']",
            "a.shepherd-enabled[href*='-additional-section']",
            "a.shepherd-enabled[href='#product-media-section']",
            "a.shepherd-enabled[href='#product-images-section']",
            "a.shepherd-enabled[href='#contact-group-pricing-section']",
            "a.shepherd-enabled[href='#contact-group-discount-section']"
        ]

        # Scroll top before starting to click. For some reason the first
        # item is not found without this. For Firefox or Chrome the browser
        # does not do any extra scroll which could hide the first item.
        # Steps are scrollTo false on purpose since the scrollTo true is the
        # config which does not work in real world.
        browser.execute_script("window.scrollTo(0,0)")
        for target in category_targets:
            try:
                wait_until_condition(browser, lambda x: x.is_element_present_by_css(target))
                browser.find_by_css(".shepherd-button.btn-primary").last.click()
            except ElementNotInteractableException:
                move_to_element(browser, ".shepherd-button.btn-primary")
                wait_until_condition(browser, lambda x: x.is_element_present_by_css(target))
                browser.find_by_css(".shepherd-button.btn-primary").last.click()

        wait_until_condition(browser, lambda x: is_tour_complete(shop, "product", user))

        # check whether the tour is shown again
        browser.visit(live_server + "/sa/products/%d/" % shop_product.pk)
        wait_until_condition(browser, lambda x: not x.is_text_present("You are adding a product."), timeout=20)

        assert is_tour_complete(shop2, "product", user) is False

        browser.visit(live_server + "/logout")
        browser.visit(live_server + "/sa")
Beispiel #15
0
def test_media_view_images(rf):
    with override_settings(E-Commerce_ENABLE_MULTIPLE_SHOPS=True):
        shop1 = factories.get_shop(identifier="shop1", enabled=True)
        shop1_staff1 = _create_random_staff(shop1)
        shop1_staff2 = _create_random_staff(shop1)

        shop2 = factories.get_shop(identifier="shop2", enabled=True)
        shop2_staff = _create_random_staff(shop2)

        # Let's agree this folder is created by for example carousel
        # so it would be shared with all the shops.
        folder = Folder.objects.create(name="Root")
        assert MediaFolder.objects.count() == 0
        path = "/%s" % folder.name

        File.objects.create(name="normalfile", folder=folder)  # Shared between shops

        # Let's create 4 images for shop 1
        _mbv_upload(shop1, shop1_staff1, path=path)
        _mbv_upload(shop1, shop1_staff1, path=path)
        _mbv_upload(shop1, shop1_staff2, path=path)
        _mbv_upload(shop1, shop1_staff2, path=path)
        assert MediaFile.objects.count() == 4

        # Let's create 3 images for shop 2
        _mbv_upload(shop2, shop2_staff, path=path)
        _mbv_upload(shop2, shop2_staff, path=path)
        _mbv_upload(shop2, shop2_staff, path=path)
        assert MediaFile.objects.count() == 7

        # All files were created to same folder and while uploading
        # the each shop declared that they own the folder.
        assert Folder.objects.count() == 1
        assert MediaFolder.objects.count() == 1
        assert MediaFolder.objects.filter(shops=shop1).exists()
        assert shop1.media_folders.count() == 1
        assert shop1.media_files.count() == 4
        assert MediaFolder.objects.filter(shops=shop2).exists()
        assert shop2.media_folders.count() == 1
        assert shop2.media_files.count() == 3

        # Now let's make sure that each staff can view the folder
        # and all the files she should see.
        _check_that_staff_can_see_folder(rf, shop1, shop1_staff1, folder, 5)
        _check_that_staff_can_see_folder(rf, shop1, shop1_staff2, folder, 5)
        _check_that_staff_can_see_folder(rf, shop2, shop2_staff, folder, 4)
Beispiel #16
0
def test_discount_admin_edit_view(rf, staff_user, admin_user):
    with override_settings(E-Commerce_ENABLE_MULTIPLE_SHOPS=True):
        shop = factories.get_default_shop()
        shop.staff_members.add(staff_user)
        factories.get_shop(identifier="shop2")
        assert Shop.objects.count() == 2

        # Staff user gets shop automatically
        product = factories.create_product("test", shop=shop)
        discount_percentage = 20
        data = {"product": product.pk, "discount_percentage": discount_percentage}
        request = apply_request_middleware(rf.post("/", data=data), user=staff_user, shop=shop)
        set_shop(request, shop)
        assert request.shop == shop
        view_func = DiscountEditView.as_view()
        response = view_func(request)
        if hasattr(response, "render"):
            response.render()

        assert response.status_code == 302
        discount1 = Discount.objects.first()
        assert discount1.shops.first() == shop

        # Test with superuser and with different shop
        shop2 = factories.get_shop(enabled=True)
        request = apply_request_middleware(rf.post("/", data=data), user=admin_user, shop=shop2)
        set_shop(request, shop2)
        view_func = DiscountEditView.as_view()
        response = view_func(request)
        assert response.status_code == 302
        assert Discount.objects.count() == 2

        discount2 = Discount.objects.exclude(id=discount1.pk).first()
        assert discount1 != discount2
        assert discount2.shops.count() == 1
        assert discount2.shops.filter(id=shop2.pk).exists()

        # Staff user can only view discount1 since that has the right shop
        _assert_view_get(rf, discount1, shop, staff_user)
        _assert_view_get(rf, discount2, shop, staff_user, True)

        # Superuser can see both if needed, but only when right shop is active
        _assert_view_get(rf, discount1, shop, admin_user)
        _assert_view_get(rf, discount2, shop, admin_user, True)
        _assert_view_get(rf, discount2, shop2, admin_user)
def test_coupon_codes_admin_edit_view(rf, staff_user, admin_user):
    with override_settings(E-Commerce_ENABLE_MULTIPLE_SHOPS=True):
        shop = factories.get_default_shop()
        shop.staff_members.add(staff_user)
        factories.get_shop(identifier="shop2", enabled=True)
        assert Shop.objects.count() == 2

        # Staff user gets shop automatically
        data = {"code": "potus"}
        request = apply_request_middleware(rf.post("/", data=data), user=staff_user, shop=shop)
        set_shop(request, shop)
        assert request.shop == shop
        view_func = CouponCodeEditView.as_view()
        response = view_func(request)
        if hasattr(response, "render"):
            response.render()

        assert response.status_code == 302
        coupon1 = CouponCode.objects.first()
        assert coupon1.shops.first() == shop

        # Test with superuser and with different shop
        shop2 = factories.get_shop(enabled=True)
        request = apply_request_middleware(rf.post("/", data=data), user=admin_user, shop=shop2)
        set_shop(request, shop2)
        assert request.shop == shop2
        view_func = CouponCodeEditView.as_view()
        response = view_func(request)
        assert response.status_code == 302
        assert CouponCode.objects.count() == 2

        coupon2 = CouponCode.objects.exclude(id=coupon1.pk).first()
        assert coupon1 != coupon2
        assert coupon2.shops.count() == 1
        assert coupon2.shops.filter(id=shop2.pk).exists()

        # Staff user can only view coupon codes for his shop
        _assert_view_get(rf, coupon1, shop, staff_user)
        _assert_view_get(rf, coupon2, shop, staff_user, True)

        # Superuser can see both if needed, but only when right shop is active
        _assert_view_get(rf, coupon1, shop, admin_user)
        _assert_view_get(rf, coupon2, shop, admin_user, True)
        _assert_view_get(rf, coupon2, shop2, admin_user)
Beispiel #18
0
def test_resource_injection(client):
    """
    Test that the GDPR warning is injected into the front template when enabled
    """
    activate("en")
    shop = factories.get_default_shop()
    client = SmartClient()
    index_url = reverse("E-Commerce:index")
    response = client.get(index_url)
    assert "gdpr-consent-warn-bar" not in response.content.decode("utf-8")

    # create a GDPR setting for the shop
    shop_gdpr = GDPRSettings.get_for_shop(shop)
    shop_gdpr.cookie_banner_content = "my cookie banner content"
    shop_gdpr.cookie_privacy_excerpt = " my cookie privacyexcerpt"
    shop_gdpr.enabled = True
    shop_gdpr.save()

    # the contents should be injected in the html
    response = client.get(index_url)
    response_content = response.content.decode("utf-8")
    assert "gdpr-consent-warn-bar" in response_content
    assert shop_gdpr.cookie_banner_content in response_content
    assert shop_gdpr.cookie_privacy_excerpt in response_content

    # create cookie categories
    cookie_category = GDPRCookieCategory.objects.create(
        shop=shop,
        always_active=True,
        cookies="cookie1,cookie2,_cookie3",
        name="RequiredCookies",
        how_is_used="to make the site work"
    )
    default_active_cookie_category = GDPRCookieCategory.objects.create(
        shop=shop,
        always_active=False,
        default_active=True,
        cookies="analyticsCookie",
        name="Analytics",
        how_is_used="to track users"
    )
    response, soup = client.response_and_soup(index_url)
    response_content = response.content.decode("utf-8")
    assert "gdpr-consent-warn-bar" in response_content
    assert cookie_category.cookies in response_content
    assert cookie_category.name in response_content
    assert cookie_category.how_is_used in response_content
    default_active_input = soup.find("input", {"name": "cookie_category_%d" % default_active_cookie_category.pk})
    assert default_active_input.has_attr("checked")

    # make sure no other shop has this
    with override_settings(E-Commerce_ENABLE_MULTIPLE_SHOPS=True):
        shop2 = factories.get_shop(identifier="shop2", status=ShopStatus.DISABLED, domain="shop2")
        response = client.get(index_url, HTTP_HOST=shop2.domain)
        response_content = response.content.decode("utf-8")
        assert "gdpr-consent-warn-bar" not in response_content
Beispiel #19
0
def test_admin_script_list(rf, admin_user):
    with override_settings(E-Commerce_ENABLE_MULTIPLE_SHOPS=True):
        shop1 = factories.get_shop(identifier="shop-1", enabled=True)
        shop2 = factories.get_shop(identifier="shop-2", enabled=True)

        shop1.staff_members.add(admin_user)
        shop2.staff_members.add(admin_user)

        script_shop1 = Script.objects.create(shop=shop1, event_identifier="order_received", name="SHOP 1", enabled=True)
        script_shop2 = Script.objects.create(shop=shop2, event_identifier="order_received", name="SHOP 2", enabled=True)

        view = ScriptEditView.as_view()
        request = apply_request_middleware(rf.get("/"), user=admin_user)
        set_shop(request, shop2)

        with pytest.raises(Http404):
            response = view(request, pk=script_shop1.id)

        response = view(request, pk=script_shop2.id)
        assert response.status_code == 200
Beispiel #20
0
def test_home_tour(browser, admin_user, live_server, settings):
    shop = factories.get_default_shop()
    shop2 = factories.get_shop(identifier="shop2")
    admin_user_2 = factories.create_random_user(is_staff=True, is_superuser=True)
    admin_user_2.set_password("password")
    admin_user_2.save()

    shop.staff_members.add(admin_user)
    shop.staff_members.add(admin_user_2)

    for user in [admin_user, admin_user_2]:
        initialize_admin_browser_test(browser, live_server, settings, username=user.username, tour_complete=False)
        wait_until_condition(browser, lambda x: x.is_text_present("Welcome!"))
        browser.visit(live_server + "/sa/home")

        wait_until_condition(browser, lambda x: x.is_text_present("Hi, new shop owner!"), timeout=30)
        wait_until_condition(browser, lambda x: x.is_element_present_by_css(".shepherd-button.btn-primary"))
        click_element(browser, ".shepherd-button.btn-primary")

        category_targets = [
            ".shepherd-enabled[data-target-id='category-1'",
            ".shepherd-enabled[data-target-id='category-2'",
            ".shepherd-enabled[data-target-id='category-3'",
            ".shepherd-enabled[data-target-id='category-5'",
            ".shepherd-enabled[data-target-id='category-9'",
            ".shepherd-enabled[data-target-id='category-4'",
            ".shepherd-enabled[data-target-id='category-6'",
            ".shepherd-enabled[data-target-id='category-7'",
            ".shepherd-enabled[data-target-id='category-8'",
            ".shepherd-enabled#site-search",
            ".shepherd-enabled.shop-btn.visit-store",
        ]
        for target in category_targets:
            wait_until_condition(browser, lambda x: x.is_element_present_by_css(target))
            move_to_element(browser, ".shepherd-button.btn-primary")
            browser.find_by_css(".shepherd-button.btn-primary").last.click()

        wait_until_condition(browser, lambda x: x.is_text_present("We're done!"), timeout=30)
        move_to_element(browser, ".shepherd-button.btn-primary")
        browser.find_by_css(".shepherd-button.btn-primary").last.click()
        wait_until_condition(browser, lambda x: is_tour_complete(shop, "home", user))

        # check whether the tour is shown again
        browser.visit(live_server + "/sa/home")
        wait_until_condition(browser, lambda x: not x.is_text_present("Hi, new shop owner!"))

        browser.visit(live_server + "/logout")
        browser.visit(live_server + "/sa")

        wait_until_condition(browser, lambda x: not x.is_text_present("Hi, new shop owner!"))

        assert is_tour_complete(shop2, "home", user) is False
Beispiel #21
0
def test_manufacturer_admin_simple_shop(rf, staff_user, admin_user):
    with override_settings(E-Commerce_ENABLE_MULTIPLE_SHOPS=False):
        shop1 = factories.get_default_shop()
        shop1.staff_members.add(staff_user)

        factories.get_shop(identifier="shop2")

        assert Manufacturer.objects.count() == 0

        # staff user
        request = apply_request_middleware(rf.post("/", data=dict(name="Manuf 1")), user=staff_user)
        view_func = ManufacturerEditView.as_view()
        response = view_func(request)
        assert response.status_code == 302
        assert Manufacturer.objects.first().shops.first() == shop1

        # superuser
        request = apply_request_middleware(rf.post("/", data=dict(name="Manuf 2")), user=admin_user)
        view_func = ManufacturerEditView.as_view()
        response = view_func(request)
        assert response.status_code == 302
        assert Manufacturer.objects.count() == 2
        assert Manufacturer.objects.last().shops.first() == shop1
Beispiel #22
0
def test_edit_shared_folder(admin_user):
    with override_settings(E-Commerce_ENABLE_MULTIPLE_SHOPS=True):
        shop1 = factories.get_shop(identifier="shop1", enabled=True)
        shop2 = factories.get_shop(identifier="shop2", enabled=True)

        folder = Folder.objects.create(name="Test folder")  # Shared folder
        folder_count = Folder.objects.count()

        response = _mbv_command(shop1, admin_user, {"action": "rename_folder", "id": folder.pk, "name": "Space"})
        assert not response["success"]
        response = _mbv_command(shop1, admin_user, {"action": "delete_folder", "id": folder.pk})
        assert not response["success"]

        # Let's make sure rename works when only one shop owns the folder
        media_folder = MediaFolder.objects.create(folder=folder)
        media_folder.shops.add(shop1)
        response = _mbv_command(shop1, admin_user, {"action": "rename_folder", "id": folder.pk, "name": "Space"})
        assert response["success"]
        assert Folder.objects.get(pk=folder.pk).name == "Space"

        # Then add second shop for the folder and let's check and
        # renaming should be disabled again.
        media_folder.shops.add(shop2)
        response = _mbv_command(shop1, admin_user, {"action": "rename_folder", "id": folder.pk, "name": "Space"})
        assert not response["success"]
        response = _mbv_command(shop1, admin_user, {"action": "delete_folder", "id": folder.pk})
        assert not response["success"]
        response = _mbv_command(shop2, admin_user, {"action": "delete_folder", "id": folder.pk})
        assert not response["success"]

        # Finally remove the folder as shop2
        media_folder.shops.remove(shop1)
        response = _mbv_command(shop1, admin_user, {"action": "delete_folder", "id": folder.pk})
        assert response["error"] == "Folder matching query does not exist."
        response = _mbv_command(shop2, admin_user, {"action": "delete_folder", "id": folder.pk})
        assert response["success"]
        assert Folder.objects.count() == folder_count - 1
Beispiel #23
0
def test_basket_with_custom_shop(rf):
    """
    Set a different shop for basket
    """
    with override_settings(**CORE_BASKET_SETTINGS):
        shop1 = factories.get_default_shop()
        shop2 = factories.get_shop(identifier="shop2")
        user = factories.create_random_user()
        request = apply_request_middleware(rf.get("/"), user=user, shop=shop1)
        basket_class = cached_load("E-Commerce_BASKET_CLASS_SPEC")
        basket = basket_class(request, "basket", shop=shop2)
        assert basket.shop == shop2

        product_shop2 = factories.create_product("product_shop2", shop2, factories.get_default_supplier(), 10)
        line = basket.add_product(factories.get_default_supplier(), shop2, product_shop2, 1)
        assert line.shop == shop2
Beispiel #24
0
def test_run_multishop():
    shop1 = factories.get_default_shop()
    shop2 = factories.get_shop(identifier="shop2")
    event = get_initialized_test_event()
    step = Step(actions=[AddOrderLogEntry({
        "order": {"variable": "order"},
        "message": {"constant": "It Works."},
        "message_identifier": {"constant": "test_run"},
    })], next=StepNext.STOP)
    script = Script(event_identifier=event.identifier, name="Test Script", shop=shop2, enabled=True)
    script.set_steps([step])
    script.save()

    # runs for shop1 - no script exists
    event.run(shop1)
    assert not event.variable_values["order"].log_entries.filter(identifier="test_run").exists()

    # run for shop2 - ok
    event.run(shop2)
    assert event.variable_values["order"].log_entries.filter(identifier="test_run").exists()
    script.delete()
Beispiel #25
0
def test_dashbord_tour(browser, admin_user, live_server, settings):
    shop = factories.get_default_shop()
    shop2 = factories.get_shop(identifier="shop2")
    admin_user_2 = factories.create_random_user(is_staff=True, is_superuser=True)
    admin_user_2.set_password("password")
    admin_user_2.save()

    shop.staff_members.add(admin_user)
    shop.staff_members.add(admin_user_2)

    # test with admin_user 1
    initialize_admin_browser_test(browser, live_server, settings, shop=shop, tour_complete=False)
    wait_until_condition(browser, lambda x: x.is_text_present("Welcome!"))
    wait_until_condition(browser, lambda x: x.is_text_present("Quicklinks"))
    wait_until_condition(browser, lambda x: x.is_element_present_by_css("#menu-button"))
    wait_until_condition(browser, lambda x: x.is_text_present("This is the dashboard for your store."), timeout=30)
    wait_until_condition(browser, lambda x: x.is_element_present_by_css(".shepherd-button.btn-primary"))
    click_element(browser, ".shepherd-button.btn-primary")
    wait_until_condition(browser, lambda x: not x.is_element_present_by_css(".shepherd-button"))
    wait_until_condition(browser, lambda x: is_tour_complete(shop, "dashboard", admin_user))

    browser.visit(live_server + "/logout")
    browser.visit(live_server + "/sa")

    # test with admin_user 2
    initialize_admin_browser_test(browser, live_server, settings, shop=shop, tour_complete=False, username=admin_user_2.username)
    wait_until_condition(browser, lambda x: x.is_text_present("Welcome!"))
    wait_until_condition(browser, lambda x: x.is_element_present_by_css("#menu-button"))
    wait_until_condition(browser, lambda x: x.is_text_present("This is the dashboard for your store."), timeout=30)
    wait_until_condition(browser, lambda x: x.is_element_present_by_css(".shepherd-button.btn-primary"))
    click_element(browser, ".shepherd-button.btn-primary")
    wait_until_condition(browser, lambda x: not x.is_element_present_by_css(".shepherd-button"))
    wait_until_condition(browser, lambda x: is_tour_complete(shop, "dashboard", admin_user_2))

    # check whether the tour is shown again
    browser.visit(live_server + "/sa")
    wait_until_condition(browser, lambda x: not x.is_text_present("This is the dashboard for your store."))

    assert is_tour_complete(shop2, "dashboard", admin_user) is False
    assert is_tour_complete(shop2, "dashboard", admin_user_2) is False
def test_supplier_price_without_selected_supplier(rf):
    shop = factories.get_shop()

    supplier1 = Supplier.objects.create(name="Test 1")
    supplier1.shops = [shop]
    supplier2 = Supplier.objects.create(name="Test 2")
    supplier2.shops = [shop]

    strategy = "E-Commerce.testing.supplier_pricing.supplier_strategy:CheapestSupplierPriceSupplierStrategy"
    with override_settings(E-Commerce_PRICING_MODULE="supplier_pricing", E-Commerce_SHOP_PRODUCT_SUPPLIERS_STRATEGY=strategy):
        customer = AnonymousContact()
        pricing_mod = get_pricing_module()
        supplier1_ctx = pricing_mod.get_context_from_data(shop, customer, supplier=supplier1)
        supplier2_ctx = pricing_mod.get_context_from_data(shop, customer, supplier=supplier2)

        # Supplied by both suppliers
        product1_default_price = 10
        product1 = factories.create_product("sku1", shop=shop, supplier=supplier1, default_price=product1_default_price)
        shop_product1 = product1.get_shop_instance(shop)
        shop_product1.suppliers.add(supplier2)

        # Both suppliers should get price from shop
        # product default price
        assert product1.get_price(supplier1_ctx).amount.value == product1_default_price
        assert product1.get_price(supplier2_ctx).amount.value == product1_default_price

        # Now let's add per supplier prices
        supplier1_price = 7
        supplier2_price = 8
        SupplierPrice.objects.create(shop=shop, supplier=supplier1, product=product1, amount_value=supplier1_price)
        SupplierPrice.objects.create(shop=shop, supplier=supplier2, product=product1, amount_value=supplier2_price)

        assert product1.get_price(supplier1_ctx).amount.value == supplier1_price
        assert product1.get_price(supplier2_ctx).amount.value == supplier2_price

        # Now pricing context without defined supplier
        # should return cheapest price
        context = pricing_mod.get_context_from_data(shop, customer)
        assert shop_product1.get_supplier().pk == supplier1.pk
        assert product1.get_price(context).amount.value == supplier1_price
def test_staff_authentication():
    shop = factories.get_shop(True, "USD", enabled=True)
    staff_user = factories.create_random_user(is_staff=True)
    staff_user.set_password("randpw")
    staff_user.save()
    staff_user.groups = [factories.get_default_permission_group()]
    shop.staff_members.add(staff_user)

    assert staff_user in [staff for staff in shop.staff_members.all()]
    assert shop.status == ShopStatus.ENABLED
    client = SmartClient()
    url = reverse("E-Commerce_admin:dashboard")
    client.login(username=staff_user.username, password="******")
    response, soup = client.response_and_soup(url)
    assert response.status_code == 200

    shop.status = ShopStatus.DISABLED
    shop.save()

    response, soup = client.response_and_soup(url)
    assert response.status_code == 400
    assert "There is no active shop available" in soup.text
def test_suppliers_list(rf, admin_user):
    shop = factories.get_default_shop()
    shop2 = factories.get_shop(identifier="shop2")

    supplier1 = Supplier.objects.create(name="supplier1")
    supplier2 = Supplier.objects.create(name="supplier1")
    supplier3 = Supplier.objects.create(name="supplier1")
    # only supplier 1 has shop
    supplier1.shops.add(shop)
    supplier3.shops.add(shop2)

    list_view = SupplierListView.as_view()

    staff_user = factories.create_random_user("en", is_staff=True)
    shop.staff_members.add(staff_user)

    for user in [admin_user, staff_user]:
        request = apply_request_middleware(rf.get("/", {"jq": json.dumps({"perPage": 100, "page": 1})}), user=user)
        response = list_view(request)
        data = json.loads(response.content.decode("utf-8"))
        ids = [sup["_id"] for sup in data["items"]]
        assert supplier1.id in ids
        assert supplier2.id in ids
Beispiel #29
0
def test_usage_limit(rf):
    default_price = 10
    request, product, basket = _init_test_for_product_with_basket(rf, default_price)

    discounted_price = 4
    coupon_code = "TEST!2"
    shop = request.shop
    coupon = CouponCode.objects.create(code=coupon_code, active=True)
    coupon.shops = [shop]
    discount = Discount.objects.create(
        active=True, product=product, coupon_code=coupon, discounted_price_value=discounted_price)
    discount.shops.add(request.shop)

    # Can not use coupon code that does not exist
    assert not CouponCode.is_usable(shop, "SIMO", basket.customer)

    # The coupon code should be usable
    assert CouponCode.is_usable(shop, coupon_code, basket.customer)
    assert coupon.can_use_code(shop, basket.customer)

    # Can not add coupon code that is not active
    coupon.active = False
    coupon.save()
    assert not CouponCode.is_usable(shop, coupon_code, basket.customer)
    assert not coupon.can_use_code(shop, basket.customer)

    # Re-activate coupon code
    coupon.active = True
    coupon.save()
    assert CouponCode.is_usable(shop, coupon_code, basket.customer)
    assert coupon.can_use_code(shop, basket.customer)

    # Can not use coupon code that is not attached
    discount.coupon_code = None
    discount.save()
    assert not CouponCode.is_usable(shop, coupon_code, basket.customer)

    # Re-attach discount
    discount.coupon_code = coupon
    discount.save()
    assert CouponCode.is_usable(shop, coupon_code, basket.customer)

    # Coupon code needs to be attached to current shop
    shop2 = factories.get_shop(prices_include_tax=True)
    assert not CouponCode.is_usable(shop2, coupon_code, basket.customer)
    assert CouponCode.is_usable(shop, coupon_code, basket.customer)

    coupon.shops.clear()
    assert not CouponCode.is_usable(shop, coupon_code, basket.customer)
    assert not coupon.can_use_code(shop, basket.customer)
    coupon.shops = [shop]
    assert CouponCode.is_usable(shop, coupon_code, basket.customer)
    assert coupon.can_use_code(shop, basket.customer)

    # Coupon code not yet added to basket even if it is usable
    assert product.get_price_info(request).price == request.shop.create_price(default_price)

    basket.add_code(coupon)
    assert product.get_price_info(request).price == request.shop.create_price(discounted_price)

    order = factories.create_random_order()

    for x in range(50):
        coupon.use(order)

    assert coupon.usage_limit is None
    assert coupon.usages.count() == 50
    assert product.get_price_info(request).price == request.shop.create_price(discounted_price)

    # Set coupon usage limit 50
    coupon.usage_limit = 50
    coupon.save()

    assert not CouponCode.is_usable(shop, coupon.code, order.customer)
    assert product.get_price_info(request).price == request.shop.create_price(default_price)

    # Increase limit by 5
    coupon.usage_limit = 55
    coupon.save()

    for x in range(5):
        assert product.get_price_info(request).price == request.shop.create_price(discounted_price)
        coupon.use(order)

    assert coupon.usages.count() == 55
    assert not CouponCode.is_usable(shop, coupon.code, order.customer)
    assert product.get_price_info(request).price == request.shop.create_price(default_price)
Beispiel #30
0
def _test_discount_list_view(rf, index):
    shop = factories.get_shop(identifier="shop%s" % index, enabled=True)
    staff_user = factories.create_random_user(is_staff=True)
    shop.staff_members.add(staff_user)

    discount1 = Discount.objects.create(identifier="discount_without_effects_%s" % index)
    discount1.shops = [shop]
    discount2 = Discount.objects.create(
        identifier="discount_with_amount_value_only_%s" % index,
        discount_amount_value=20,
        start_datetime=now(),
        end_datetime=now() + datetime.timedelta(days=2))
    discount2.shops = [shop]
    discount3 = Discount.objects.create(
        identifier="discount_with_amount_and_discounted_price_%s" % index,
        discount_amount_value=20,
        discounted_price_value=4,
        start_datetime=now(),
        end_datetime=now() + datetime.timedelta(days=2))
    discount3.shops = [shop]
    discount4 = Discount.objects.create(
        identifier="test_with_discounted_price_and_percentage_%s" % index,
        discounted_price_value=4,
        discount_percentage=0.20,
        start_datetime=now(),
        end_datetime=now() + datetime.timedelta(days=2))
    discount4.shops = [shop]

    view_func = DiscountListView.as_view()
    request = apply_request_middleware(
        rf.get("/", {
            "jq": json.dumps({"perPage": 100, "page": 1})
        }),
        user=staff_user,
        shop=shop)
    set_shop(request, shop)
    response = view_func(request)
    if hasattr(response, "render"):
        response.render()
    assert response.status_code == 200

    view_instance = DiscountListView()
    view_instance.request = request
    assert request.shop == shop
    assert view_instance.get_queryset().count() == 4

    data = json.loads(view_instance.get(request).content.decode("UTF-8"))
    assert len(data["items"]) == 4
    discount1_data = [item for item in data["items"] if item["_id"] == discount1.pk][0]
    assert discount1_data["discount_effect"] == "-"

    discount2_data = [item for item in data["items"] if item["_id"] == discount2.pk][0]
    assert len(discount2_data["discount_effect"].split(",")) == 1
    assert "20" in discount2_data["discount_effect"]

    discount3_data = [item for item in data["items"] if item["_id"] == discount3.pk][0]
    assert len(discount3_data["discount_effect"].split(",")) == 2
    assert "20" in discount3_data["discount_effect"]
    assert "4" in discount3_data["discount_effect"]

    discount4_data = [item for item in data["items"] if item["_id"] == discount4.pk][0]
    assert len(discount4_data["discount_effect"].split(",")) == 2
    assert "20" in discount4_data["discount_effect"]
    assert "4" in discount4_data["discount_effect"]