Example #1
0
def test_summernote_editor_picture(browser, admin_user, live_server, settings):
    activate("en")
    factories.get_default_shop()
    factories.get_default_product_type()
    factories.get_default_sales_unit()
    factories.get_default_tax_class()
    filer_image = factories.get_random_filer_image()

    initialize_admin_browser_test(browser, live_server, settings)
    browser.driver.set_window_size(1920, 1080)

    url = reverse("E-Commerce_admin:shop_product.new")
    browser.visit("%s%s" % (live_server, url))
    wait_until_condition(browser, condition=lambda x: x.is_text_present("New shop product"))

    img_icon_selector = "#id_base-description__en-editor-wrap i[class='note-icon-picture']"
    move_to_element(browser, img_icon_selector)
    click_element(browser, img_icon_selector)
    wait_until_condition(browser, lambda b: len(b.windows) == 2)

    # change to the media browser window
    browser.windows.current = browser.windows[1]

    # click to select the picture
    wait_until_appeared(browser, "a.file-preview")
    click_element(browser, "a.file-preview")

    # back to the main window
    wait_until_condition(browser, lambda b: len(b.windows) == 1)
    browser.windows.current = browser.windows[0]

    # make sure the image was added to the editor
    wait_until_appeared(
        browser,
        "#id_base-description__en-editor-wrap .note-editable img[src='%s']" % filer_image.url, timeout=20)
Example #2
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_custom_view_toolbar_buttons(rf, admin_user):
    factories.get_default_shop()
    request = apply_request_middleware(rf.get("/"), user=admin_user)
    list_view_func = ContactGroupPriceDisplayListView.as_view()
    edit_view_func = ContactGroupPriceDisplayEditView.as_view()

    with override_provides("contact_group_price_list_toolbar_provider", [
        "E-Commerce.testing.modules.mocker.toolbar:ContactGroupPriceDisplayButtonProvider"
    ]):
        list_response = list_view_func(request)
        list_response.render()
        list_content = list_response.content.decode("utf-8")
        assert "btn-contact-group-hello" in list_content

        edit_response = edit_view_func(request)
        edit_response.render()
        edit_response = edit_response.content.decode("utf-8")
        assert "btn-contact-group-hello" not in edit_response

    # use global provider - all views should have that button
    with override_provides("admin_toolbar_button_provider", [
        "E-Commerce.testing.modules.mocker.toolbar:ContactGroupPriceDisplayButtonProvider"
    ]):
        list_response = list_view_func(request)
        list_response.render()
        list_content = list_response.content.decode("utf-8")
        assert "btn-contact-group-hello" in list_content

        edit_response = edit_view_func(request)
        edit_response.render()
        edit_response = edit_response.content.decode("utf-8")
        assert "btn-contact-group-hello" in edit_response
def test_view_custom_mass_actions(rf, admin_user):
    factories.get_default_shop()
    request = apply_request_middleware(rf.get("/", {"jq": json.dumps({"perPage": 100, "page": 1})}), user=admin_user)
    list_view_func = ManufacturerListView.as_view()

    # no mass actions
    response = list_view_func(request)
    data = json.loads(response.content.decode("utf-8"))
    assert not data["massActions"]

    # test with specific key
    with override_provides("manufacturer_list_mass_actions_provider", [
        "E-Commerce.testing.modules.mocker.mass_actions:DummyMassActionProvider"
    ]):
        response = list_view_func(request)
        data = json.loads(response.content.decode("utf-8"))
        identifiers = [action["key"] for action in data["massActions"]]
        assert "dummy_mass_action_1" in identifiers
        assert "dummy_mass_action_2" in identifiers

    list_view_func = SalesUnitListView.as_view()
    # test with global
    with override_provides("admin_mass_actions_provider", [
        "E-Commerce.testing.modules.mocker.mass_actions:DummyMassActionProvider"
    ]):
        response = list_view_func(request)
        data = json.loads(response.content.decode("utf-8"))
        identifiers = [action["key"] for action in data["massActions"]]
        assert "dummy_mass_action_1" in identifiers
        assert "dummy_mass_action_2" in identifiers
Example #5
0
def test_update_injection():
    shop = factories.get_default_shop()
    client = SmartClient()
    index_url = reverse("E-Commerce:index")

    page = ensure_gdpr_privacy_policy(shop)
    shop_gdpr = GDPRSettings.get_for_shop(shop)
    shop_gdpr.enabled = True
    shop_gdpr.privacy_policy = page
    shop_gdpr.save()

    assert_update(client, index_url, False)  # nothing consented in past, should not show

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

    client.login(username=user.username, password=password)
    assert_update(client, index_url, False)  # no consent given, should not be visible

    create_user_consent_for_all_documents(shop, user)
    assert_update(client, index_url, False)

    with reversion.create_revision():
        page.save()

    assert not is_documents_consent_in_sync(shop, user)
    assert_update(client, index_url, True)

    # consent
    client.get(reverse("E-Commerce:gdpr_policy_consent", kwargs=dict(page_id=page.pk)))
    assert is_documents_consent_in_sync(shop, user)
    assert_update(client, index_url, False)
def test_force_views_only_for_staff(rf):
    shop = factories.get_default_shop()
    user = factories.create_random_user(is_staff=True)
    person_contact = get_person_contact(user)

    # Start forcing. There shouldn't be any changes to
    # request customer due calling the force functions since
    # those just do the redirect in case the current is user
    # is not shop staff.
    request = apply_request_middleware(rf.get("/"), user=user)
    assert request.customer == person_contact

    _call_force_view(request, force_anonymous_contact)

    request = apply_request_middleware(rf.get("/"), user=user)
    assert request.customer == person_contact

    _call_force_view(request, force_person_contact)

    request = apply_request_middleware(rf.get("/"), user=user)
    assert request.customer == person_contact

    _call_force_view(request, force_company_contact)

    request = apply_request_middleware(rf.get("/"), user=user)
    assert request.customer == person_contact

    assert get_company_contact(user) is None
Example #7
0
def test_company_contact_for_shop_staff(rf, admin_user):
    company_contact = get_company_contact(admin_user)
    assert company_contact is None

    shop = factories.get_default_shop()
    # Let's create shop for the shop staff
    company_contact = get_company_contact_for_shop_staff(shop, admin_user)

    company_contact = get_company_contact_for_shop_staff(shop, admin_user)
    assert company_contact is not None

    # Let's create second staff member to make sure all good with
    # creating company contact for shop staff.
    new_staff_user = factories.create_random_user()
    with pytest.raises(AssertionError):
        get_company_contact_for_shop_staff(shop, new_staff_user)

    new_staff_user.is_staff = True
    new_staff_user.save()
    
    with pytest.raises(AssertionError):
        # Since the new staff is not in shop members. The admin user
        # passed since he is also superuser.
        get_company_contact_for_shop_staff(shop, new_staff_user)

    shop.staff_members.add(new_staff_user)
    assert company_contact == get_company_contact_for_shop_staff(shop, new_staff_user)

    # Make sure both user has person contact linked to the company contact
    company_members = company_contact.members.all()
    assert get_person_contact(admin_user) in company_members
    assert get_person_contact(new_staff_user) in company_members
def test_manufacturer_filter_get_fields(rf):
    cache.clear()

    shop = factories.get_default_shop()

    request = apply_request_middleware(rf.get("/"))
    assert ManufacturerProductListFilter().get_fields(request, None) is None

    manufacturer = Manufacturer.objects.create(name="Random Brand Inc")
    assert ManufacturerProductListFilter().get_fields(request, None) is None

    category = factories.get_default_category()
    product = factories.create_product("sku", shop=shop)
    shop_product = product.get_shop_instance(shop=shop)
    shop_product.primary_category = category
    shop_product.save()

    assert ManufacturerProductListFilter().get_fields(request, category) is None

    # Now once we link manufacturer to product we should get
    # form field for manufacturer
    product.manufacturer = manufacturer
    product.save()
    form_field = ManufacturerProductListFilter().get_fields(request, category)[0][1]
    assert form_field is not None
    assert form_field.label == "Manufacturers"

    with override_settings(E-Commerce_FRONT_OVERRIDE_SORTS_AND_FILTERS_LABELS_LOGIC={"manufacturers": "Brands"}):
        form_field = ManufacturerProductListFilter().get_fields(request, category)[0][1]
        assert form_field is not None
        assert form_field.label == "Brands"
Example #9
0
def test_email_action_with_template_body():
    with override_settings(LANGUAGES=(("en", "en"))):
        SUPER_TEST_TEMPLATE_DATA = {
            "en": {
                # English
                "subject": "Hello, {{ name }}!",
                "body_template": "<html><style>.dog-color { color: red; }</style><body>%html_body%</body></html>",
                "body": "Hi, {{ name }}. This is a test.",
                "content_type": "plain"
            }
        }

        if settings.EMAIL_BACKEND != 'django.core.mail.backends.locmem.EmailBackend':
            pytest.skip("Need locmem email backend")

        mail.outbox = []  # Clear the Django testing mail outbox

        event = get_initialized_test_event()
        ctx = Context.from_event(event, shop=factories.get_default_shop())
        ctx.set("name", "Luke J. Warm")  # This variable isn't published by the event, but it's used by the template
        se = SendEmail({
            "template_data": SUPER_TEST_TEMPLATE_DATA,
            "from_email": {"constant": "*****@*****.**"},
            "recipient": {"constant": "*****@*****.**"},
            "language": {"constant": "ja"},
        })
        se.execute(ctx)  # Once
        assert len(mail.outbox) == 1  # 'send_identifier' should ensure this is true
        msg = mail.outbox[0]
        assert msg.to == ['*****@*****.**']
        assert msg.from_email == '*****@*****.**'
        assert ".dog-color { color: red; }" in msg.body
        assert "Luke J. Warm" in msg.body
Example #10
0
def test_shop_remove_available_languages(admin_user):
    shop = factories.get_default_shop()
    client = SmartClient()

    with override_settings(
        LANGUAGES=[
            ("en", "English"),
            ("fi", "Finnish"),
        ],
        LANGUAGE_CODE="en",
        PARLER_DEFAULT_LANGUAGE_CODE = "en"
    ):
        # there is no language set for the shop, the first one will be used
        response = client.get(reverse("E-Commerce:index"))
        assert get_language() == "en"

        # request js catalog file
        response = client.get(reverse("E-Commerce:js-catalog"))
        assert get_language() == "en"

        # when requesting admin js catalog, the language should be any of the available
        client.get("E-Commerce_admin:js-catalog")
        assert get_language() == "en"

        set_shop_available_languages(shop, ["fi"])

        response = client.get(reverse("E-Commerce:index"))
        assert get_language() == "fi"

        response = client.get(reverse("E-Commerce:js-catalog"))
        assert get_language() == "fi"

        client.get("E-Commerce_admin:js-catalog")
        assert get_language() == "en"
Example #11
0
def test_product_price(client):
    shop = factories.get_default_shop()
    product = factories.create_product("sku", shop=shop, default_price=30)
    shop_product = product.get_shop_instance(shop)

    supplier_data = [
        ("Johnny Inc", 30),
        ("Mike Inc", 20),
        ("Simon Inc", 10),
    ]
    for name, product_price in supplier_data:
        supplier = Supplier.objects.create(name=name)
        shop_product.suppliers.add(supplier)
        SupplierPrice.objects.create(supplier=supplier, shop=shop, product=product, amount_value=product_price)

    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):
        for name, price in supplier_data:
            supplier = Supplier.objects.get(name=name)
            response = client.get(
                reverse('E-Commerce:xtheme_extra_view', kwargs={
                        'view': 'product_price'
                    }
                ) + "?id=%s&quantity=%s&supplier=%s" % (product.pk, 1, supplier.pk)
            )
            soup = BeautifulSoup(response.content)
            price_span = soup.find("span", {"class": "product-price"})
            assert "%s" % price in price_span.text
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
def test_list_view_with_multiple_suppliers(rf, admin_user):
    shop = factories.get_default_shop()

    product = factories.create_product(sku="test", shop=shop)
    shop_product = product.get_shop_instance(shop)
    shop_product.primary_category = factories.get_default_category()
    shop_product.save()
    shop_product.categories.add(shop_product.primary_category)

    # Also one product with supplier
    supplier = factories.get_default_supplier()
    product2 = factories.create_product(sku="test2", shop=shop, supplier=supplier)
    shop_product2 = product2.get_shop_instance(shop)
    shop_product2.primary_category = factories.get_default_category()
    shop_product2.save()
    shop_product2.categories.add(shop_product.primary_category)

    with override_settings(E-Commerce_ENABLE_MULTIPLE_SUPPLIERS=True):
        view = load("E-Commerce.admin.modules.products.views:ProductListView").as_view()
        request = apply_request_middleware(rf.get("/", {
            "jq": json.dumps({"perPage": 100, "page": 1})
        }), user=admin_user)
        response = view(request)
        assert 200 <= response.status_code < 300

        data = json.loads(response.content.decode("utf-8"))
        product_data = [item for item in data["items"] if item["_id"] == shop_product.pk][0]
        assert product_data["primary_category"] == factories.get_default_category().name
        assert product_data["categories"] == factories.get_default_category().name
        assert product_data["categories"] == factories.get_default_category().name
        assert product_data["suppliers"] == ""

        product_data2 = [item for item in data["items"] if item["_id"] == shop_product2.pk][0]
        assert product_data2["suppliers"] == factories.get_default_supplier().name
Example #14
0
def test_notification(admin_user, specific_user):
    AddNotification(make_bind_data(
        variables={"priority": "priority"},
        constants={
            "message": "Hi {{ name }}!",
            "message_identifier": "hi mom",
            "url": "http://burymewithmymoney.com/",
            "recipient_type": (RecipientType.SPECIFIC_USER if specific_user else RecipientType.ADMINS),
            "recipient": (admin_user if specific_user else None),
            "priority": Priority.CRITICAL
        }
    )).execute(Context.from_variables(name="Justin Case", shop=factories.get_default_shop()))
    notif = Notification.objects.last()
    assert isinstance(notif, Notification)
    if specific_user:
        assert notif.recipient == admin_user
        assert Notification.objects.unread_for_user(admin_user).get(pk=notif.pk)
    assert notif.identifier == "hi mom"
    assert notif.message == "Hi Justin Case!"
    assert notif.priority == Priority.CRITICAL
    assert notif.url == "http://burymewithmymoney.com/"
    with pytest.raises(ValueError):
        notif.url = "http://www.theuselessweb.com/"

    assert not notif.is_read
    notif.mark_read(admin_user)  # Once, for setting
    notif.mark_read(admin_user)  # Twice, for branch checking
    assert notif.marked_read_by == admin_user
    assert very_recently(notif.marked_read_on)
Example #15
0
def test_log_entry_on_unloggable_object(target_obj):
    event = get_initialized_test_event()
    event.variable_values["order"] = target_obj  # invalidate log target _before_ creating context
    ctx = Context.from_event(event, shop=factories.get_default_shop())
    n_log_entries = ctx.log_entry_queryset.count()
    ctx.add_log_entry_on_log_target("blap", "blorr")
    assert ctx.log_entry_queryset.count() == n_log_entries  # couldn't add :(
Example #16
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
Example #17
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
Example #18
0
def get_context(rf, customer=None):
    request = rf.get("/")
    request.shop = factories.get_default_shop()
    apply_request_middleware(request)
    if customer:
        request.customer = customer
    return get_jinja_context(**{"request": request})
Example #19
0
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)
    assert response.status_code == 302

    urls = []

    try:
        urls.append(get_model_url(object_instance, kind="edit", user=admin_user, shop=shop))
    except NoModelUrl:
        pass

    try:
        urls.append(get_model_url(object_instance, kind="detail", user=admin_user, shop=shop))
    except NoModelUrl:
        pass

    assert response.url in urls

    # pass the mode query parameter
    response = _get_edit_object_view(rf, view, model, object_instance.id, admin_user, shop, mode="test")
    assert response.status_code == 302
    assert "mode=test" in response.url
Example #20
0
def test_comment_visibility(admin_user):
    shop = factories.get_default_shop()

    admin_contact = get_person_contact(admin_user)

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

    normal_user = factories.create_random_user("en")
    normal_contact = get_person_contact(normal_user)

    task_type = TaskType.objects.create(name="Request", shop=shop)
    task = create_task(shop, admin_contact, task_type, "my task")

    task.comment(admin_contact, "This is only visibile for super users", TaskCommentVisibility.ADMINS_ONLY)
    task.comment(staff_contact, "This is only visibile for staff only", TaskCommentVisibility.STAFF_ONLY)
    task.comment(normal_contact, "This is visibile for everyone", TaskCommentVisibility.PUBLIC)

    # admin see all comments
    assert task.comments.for_contact(admin_contact).count() == 3
    # staff see all public + staff only
    assert task.comments.for_contact(staff_contact).count() == 2
    # normal contact see all public
    assert task.comments.for_contact(normal_contact).count() == 1
    # anonymous contact see all public
    assert task.comments.for_contact(AnonymousContact()).count() == 1
Example #21
0
def test_edit_object_view_errors(rf, admin_user):
    shop = factories.get_default_shop()
    view = EditObjectView.as_view()

    # missing params
    response = view(apply_request_middleware(rf.get(reverse("E-Commerce_admin:edit")), user=admin_user, shop=shop))
    assert response.status_code == 400
    assert "Invalid object" in response.content.decode("utf-8")

    # invalid model
    response = _get_edit_object_view(rf, view, ".", None, admin_user, shop)
    assert response.status_code == 400
    assert "Invalid model" in response.content.decode("utf-8")

    # invalid object ID
    product = factories.create_product("p1", shop, factories.get_default_supplier())
    model = ".".join(ContentType.objects.get_for_model(product).natural_key())
    with pytest.raises(Http404) as error:
        _get_edit_object_view(rf, view, model, product.id + 10, admin_user, shop)
    assert "Object not found" in str(error)

    # object has no admin url
    from E-Commerce.core.models import ConfigurationItem
    config = ConfigurationItem.objects.create(shop=shop, key="test", value={"value": 123})
    model = ".".join(ContentType.objects.get_for_model(config).natural_key())
    with pytest.raises(Http404) as error:
        _get_edit_object_view(rf, view, model, config.id, admin_user, shop)
    assert "Object not found" in str(error)
Example #22
0
def test_forcing_to_person_and_anonymous_contact(rf, admin_user):
    company_contact = get_company_contact(admin_user)
    assert company_contact is None
    shop = factories.get_default_shop()
    company_contact = get_company_contact_for_shop_staff(shop, admin_user)
    assert isinstance(company_contact, CompanyContact)
    assert company_contact == get_company_contact(admin_user)

    person_contact = get_person_contact(admin_user)
    assert person_contact is not None
    assert not person_contact.is_anonymous

    force_person_contact_for_user(admin_user)
    assert get_company_contact(admin_user) is None

    force_anonymous_contact_for_user(admin_user)
    assert get_person_contact(admin_user).is_anonymous

    force_person_contact_for_user(admin_user, False)
    assert get_company_contact(admin_user) is None  # Since the person contact is still anonymous
    assert get_person_contact(admin_user).is_anonymous

    force_anonymous_contact_for_user(admin_user, False)
    assert company_contact == get_company_contact(admin_user)
    assert not get_person_contact(admin_user).is_anonymous
Example #23
0
def test_add_product_with_extra_parent_line(rf):
    """
    Add product to basket with extra info and parent line
    """
    with override_settings(**CORE_BASKET_SETTINGS):
        shop = factories.get_default_shop()
        user = factories.create_random_user()
        product = factories.create_product("product", shop, factories.get_default_supplier(), 10)
        request = apply_request_middleware(rf.get("/"), user=user)
        basket = get_basket(request, "basket")
        basket.customer = get_person_contact(user)

        cmd_response = basket_commands.handle_add(request, basket, product.id, 1, extra={"more": "stuff"})
        line_id1 = cmd_response["line_id"]
        assert cmd_response["ok"]
        line1 = basket.get_basket_line(line_id1)
        assert line1._data["more"] == "stuff"

        cmd_response = basket_commands.handle_add(
            request, basket, product.id, 1, parent_line=line1, force_new_line=True)
        line_id2 = cmd_response["line_id"]
        assert cmd_response["ok"]
        line2 = basket.get_basket_line(line_id2)
        assert not line2._data

        assert line_id1 != line_id2
        assert line2.parent_line.line_id == line_id1
Example #24
0
def test_authenticate_form_without_consent_checkboxes(client):
    activate("en")
    shop = factories.get_default_shop()
    user = factories.create_random_user("en")
    user.email = "*****@*****.**"
    user.set_password("1234")
    user.save()

    consent_text = printable_gibberish()
    gdpr_settings = GDPRSettings.get_for_shop(shop)
    gdpr_settings.enabled = True
    gdpr_settings.skip_consent_on_auth = True
    gdpr_settings.auth_consent_text = consent_text
    gdpr_settings.save()

    # create privacy policy GDPR document
    privacy_policy = ensure_gdpr_privacy_policy(shop)

    redirect_target = "/redirect-success/"
    client = SmartClient()

    login_url = reverse("E-Commerce:login")
    response = client.get(login_url)
    soup = BeautifulSoup(response.content)
    login_form = soup.find("form", {"action": "/login/"})
    assert len(login_form.findAll("input")) == 4
    assert consent_text in login_form.text

    # user didn't check the privacy policy agreement
    response = client.post(login_url, data={
        "username": user.email,
        "password": "******",
        REDIRECT_FIELD_NAME: redirect_target
    })
    assert response.status_code == 302
Example #25
0
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()
Example #26
0
def test_field_provider(rf, admin_user):
    activate("en")
    shop = factories.get_default_shop()
    gdpr_settings = GDPRSettings.get_for_shop(shop)
    gdpr_settings.enabled = True
    gdpr_settings.save()
    # create privacy policy GDPR document
    privacy_policy = ensure_gdpr_privacy_policy(shop)
    page_consent_key = "accept_%d" % privacy_policy.pk

    request = apply_request_middleware(rf.post("/"), shop=shop, user=admin_user)
    field_provider = GDPRFieldProvider()

    # call twice.. the field should be there while the user hasn't consented to the page
    for test in range(2):
        fields = field_provider.get_fields(request=request)
        assert page_consent_key in [f.name for f in fields]

    # consent to the page, the field shouldn't be there
    create_user_consent_for_all_documents(shop, admin_user)
    fields = field_provider.get_fields(request=request)
    assert page_consent_key not in [f.name for f in fields]

    # change the document version - field must be there again
    privacy_policy.save()
    fields = field_provider.get_fields(request=request)
    assert page_consent_key in [f.name for f in fields]

    # check if the field is shown for anonymous
    request = apply_request_middleware(rf.post("/"), shop=shop, user=AnonymousUser())
    fields = field_provider.get_fields(request=request)
    assert page_consent_key in [f.name for f in fields]
def test_discounted_price(rf):
    shop = factories.get_default_shop()
    supplier = factories.get_default_supplier()
    request = rf.get("/")
    request.shop = shop
    apply_request_middleware(request)
    assert request.shop == shop

    original_price = 10
    product = factories.create_product("test1", shop=shop, supplier=supplier, default_price=original_price)
    shop_product = product.get_shop_instance(shop)

    # Set discount with discount amount for $2
    discount_amount = 2
    discount = Discount.objects.create(
        active=True, product=product, supplier=supplier, discount_amount_value=discount_amount)
    discount.shops = [shop]

    # Even though the supplier is matching with the product there is no discount
    # since the supplier is not in pricing context.
    assert not hasattr(request, "supplier")
    assert supplier in shop_product.suppliers.all()
    assert product.get_price_info(request).price == request.shop.create_price(10)

    setattr(request, "supplier", supplier)
    assert product.get_price_info(request).price == request.shop.create_price(8)

    # No discount once we change the discount supplier
    new_supplier = Supplier.objects.create(identifier="*")
    discount.supplier = new_supplier
    discount.save()
    assert product.get_price_info(request).price == request.shop.create_price(10)
Example #28
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
Example #29
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")
Example #30
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