def test_theme_without_default_template_dir():
    get_default_shop()
    with override_current_theme_class(ShuupTestingTheme):
        c = SmartClient()
        soup = c.soup(reverse("shuup:index"))
        assert "Simple base for themes to use" not in soup
        assert "Welcome to test Shuup!" in soup.find("div", {"class": "page-content"}).text
示例#2
0
def test_get_installments_cc_does_not_allow_installments():
    """
        Max 9 installs with SIMPLE intereset
        interest_rate = 4.00%
        Credit card does not allow installments
    """
    patch_cielo_request()

    shop = get_default_shop()
    create_default_order_statuses()
    populate_if_required()
    set_current_theme('shuup.themes.classic_gray')
    c = SmartClient()
    _configure_basket(c)
    CieloConfig.objects.create(shop=shop,
                               max_installments=9,
                               installments_without_interest=3,
                               interest_type=InterestType.Simple,
                               interest_rate=Decimal(4.0))

    order_total = (PRODUCT_QTNTY * PRODUCT_PRICE)
    total_price_str = "{0}".format(format_money(shop.create_price(order_total)))

    response = c.get(INSTALLMENTS_PATH, {"cc_brand": CieloCardBrand.Discover})
    json_content = json.loads(response.content.decode("utf-8"))
    assert len(json_content['installments']) == 1
    assert json_content['installments'][0]['number'] == 1
    assert total_price_str in json_content['installments'][0]['name']
示例#3
0
def test_update_injection():
    shop = factories.get_default_shop()
    client = SmartClient()
    index_url = reverse("shuup: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("shuup:gdpr_policy_consent", kwargs=dict(page_id=page.pk)))
    assert is_documents_consent_in_sync(shop, user)
    assert_update(client, index_url, False)
示例#4
0
def test_get_installments_3x_no_intereset():
    """
        Max 3 installs with no intereset
    """
    patch_cielo_request()
    shop = get_default_shop()
    create_default_order_statuses()
    populate_if_required()
    set_current_theme('shuup.themes.classic_gray')
    c = SmartClient()
    _configure_basket(c)
    CieloConfig.objects.create(shop=shop,
                               max_installments=3,
                               installments_without_interest=3)

    order_total = PRODUCT_QTNTY * PRODUCT_PRICE
    total_price_str = "{0}".format(format_money(shop.create_price(order_total)))

    response = c.get(INSTALLMENTS_PATH, {"cc_brand": CieloCardBrand.Visa})
    json_content = json.loads(response.content.decode("utf-8"))
    assert len(json_content['installments']) == 3

    assert json_content['installments'][0]['number'] == 1
    assert total_price_str in json_content['installments'][0]['name']

    total_2x_no_interest = format_money(shop.create_price(order_total / Decimal(2)))
    assert json_content['installments'][1]['number'] == 2
    assert total_price_str in json_content['installments'][1]['name']
    assert total_2x_no_interest in json_content['installments'][1]['name']

    total_3x_no_interest = format_money(shop.create_price(order_total / Decimal(3)))
    assert json_content['installments'][2]['number'] == 3
    assert total_price_str in json_content['installments'][2]['name']
    assert total_3x_no_interest in json_content['installments'][2]['name']
示例#5
0
def test_get_installments_12x_with_simples_intereset():
    """
        Max 12 installs with PRICE intereset
        interest_rate = 2.30%
        min_installment_amount = 30.00
    """
    patch_cielo_request()
    shop = get_default_shop()
    create_default_order_statuses()
    populate_if_required()
    set_current_theme('shuup.themes.classic_gray')
    c = SmartClient()
    _configure_basket(c)
    cielo_config = CieloConfig.objects.create(shop=shop,
                                              max_installments=12,
                                              installments_without_interest=2,
                                              interest_type=InterestType.Price,
                                              interest_rate=Decimal(2.3),
                                              min_installment_amount=Decimal(30))

    order_total = (PRODUCT_QTNTY * PRODUCT_PRICE)
    installment_choices = InstallmentContext(order_total, cielo_config).get_intallments_choices()

    response = c.get(INSTALLMENTS_PATH, {"cc_brand": CieloCardBrand.Visa})
    json_content = json.loads(response.content.decode("utf-8"))
    assert len(json_content['installments']) == len(installment_choices)

    for installment in range(len(installment_choices)):
        total = format_money(shop.create_price(installment_choices[installment][2]))
        installment_amount = format_money(shop.create_price(installment_choices[installment][1]))

        assert json_content['installments'][installment]['number'] == installment+1
        assert installment_amount in json_content['installments'][installment]['name']
        assert total in json_content['installments'][installment]['name']
示例#6
0
def test_basket_line_descriptor(rf):
    shop = factories.get_default_shop()
    user = factories.create_random_user()
    supplier = factories.get_default_supplier()
    product = factories.create_product("product", shop, supplier, 10)

    client = SmartClient()
    response = client.post(path=reverse("shuup:basket"),
                           data={
                               "command": "add",
                               "product_id": product.pk,
                               "quantity": 1
                           })

    with override_provides("front_line_properties_descriptor", [
            "shuup.testing.line_properties_descriptor.TestLinePropertiesDescriptor"
    ]):
        soup = client.soup(reverse("shuup:basket"))
        basket_line_property = soup.find("p",
                                         {"class": "basket-line-property"})
        assert basket_line_property.find("strong", {
            "class": "property-name"
        }).text.strip() == "Type:"
        assert basket_line_property.find("span", {
            "class": "property-value"
        }).text.strip() == "product"
示例#7
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("shuup: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
示例#8
0
def test_product_price_range_filter():
    shop = factories.get_default_shop()
    product = factories.get_default_product()
    category = factories.get_default_category()
    shop_product = product.get_shop_instance(shop)
    shop_product.default_price_value = 10
    shop_product.categories.add(category)
    shop_product.save()

    client = SmartClient()
    set_configuration(category=category,
                      data={
                          "filter_products_by_price": True,
                          "filter_products_by_price_range_min": 5,
                          "filter_products_by_price_range_max": 15,
                          "filter_products_by_price_range_size": 5
                      })
    url = reverse('shuup:category',
                  kwargs={
                      'pk': category.pk,
                      'slug': category.slug
                  })
    response, soup = client.response_and_soup(url)
    assert response.status_code == 200
    assert soup.find(id="product-%d" % product.id)
    price_range_select = soup.find(id="id_price_range")
    price_ranges = price_range_select.find_all("option")
    assert len(price_ranges) == 4

    # filter products with prices above $15
    filtered_url = "{}?price_range={}".format(url,
                                              price_ranges[-1].attrs["value"])
    response, soup = client.response_and_soup(filtered_url)
    assert response.status_code == 200
    assert not soup.find(id="product-%d" % product.id)
示例#9
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("shuup:index"))
        assert get_language() == "en"

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

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

        set_shop_available_languages(shop, ["fi"])

        response = client.get(reverse("shuup:index"))
        assert get_language() == "fi"

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

        client.get("shuup_admin:js-catalog")
        assert get_language() == "en"
示例#10
0
def test_get_installments_cc_does_not_allow_installments():
    """
        Max 9 installs with SIMPLE intereset
        interest_rate = 4.00%
        Credit card does not allow installments
    """
    patch_cielo_request()

    shop = get_default_shop()
    create_default_order_statuses()
    populate_if_required()
    set_current_theme('shuup.themes.classic_gray')
    c = SmartClient()
    _configure_basket(c)
    CieloConfig.objects.create(shop=shop,
                               max_installments=9,
                               installments_without_interest=3,
                               interest_type=InterestType.Simple,
                               interest_rate=Decimal(4.0))

    order_total = (PRODUCT_QTNTY * PRODUCT_PRICE)
    total_price_str = "{0}".format(format_money(
        shop.create_price(order_total)))

    response = c.get(INSTALLMENTS_PATH, {"cc_brand": CieloCardBrand.Discover})
    json_content = json.loads(response.content.decode("utf-8"))
    assert len(json_content['installments']) == 1
    assert json_content['installments'][0]['number'] == 1
    assert total_price_str in json_content['installments'][0]['name']
示例#11
0
def test_theme_with_default_template_dir():
    get_default_shop()
    with override_current_theme_class(ShuupTestingThemeWithCustomBase):
        c = SmartClient()
        soup = c.soup(reverse("shuup:index"))
        assert "Simple base for themes to use" in soup.find("h1").text
        assert "Welcome to test Shuup!" in soup.find("h1").text
示例#12
0
def test_consent_cookies(client):
    """
    Test that the GDPR consent is generated and saved into a cooki
    """
    shop = factories.get_default_shop()
    client = SmartClient()
    index_url = reverse("shuup:index")
    response = client.get(index_url)

    # 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()

    # create cookie categories
    required_cookie_category = GDPRCookieCategory.objects.create(
        shop=shop,
        always_active=True,
        cookies="cookie1,cookir2,_cookie3",
        name="RequiredCookies",
        how_is_used="to make the site work")
    optional_cookie_category = GDPRCookieCategory.objects.create(
        shop=shop,
        always_active=False,
        cookies="_opt1,_opt2,_opt3",
        name="OptionalCookies",
        how_is_used="to spy users")

    # create privacy policy GDPR document
    privacy_policy = Page.objects.create(
        shop=shop,
        title="Privacy policy",
        url="privacy-policy",
        page_type=PageType.GDPR_CONSENT_DOCUMENT,
        content="you just agree",
        available_from=now())
    response = client.get(index_url)
    assert settings.SHUUP_GDPR_CONSENT_COOKIE_NAME not in response.cookies

    # send consent
    response = client.post(
        reverse("shuup:gdpr_consent"),
        data={
            "cookie_category_{}".format(required_cookie_category.id): "on",
            "cookie_category_{}".format(optional_cookie_category.id): "on"
        })

    assert settings.SHUUP_GDPR_CONSENT_COOKIE_NAME in response.cookies
    cookies_data = json.loads(
        response.cookies[settings.SHUUP_GDPR_CONSENT_COOKIE_NAME].value)
    assert privacy_policy.id == cookies_data["documents"][0]["id"]
    assert privacy_policy.url == cookies_data["documents"][0]["url"]

    for cookie in required_cookie_category.cookies.split(","):
        assert cookie in cookies_data["cookies"]
    for cookie in optional_cookie_category.cookies.split(","):
        assert cookie in cookies_data["cookies"]
示例#13
0
def test_extender_renders_main_menu(rf):
    get_default_shop()

    with override_provides("front_menu_extender", ["shuup_tests.xtheme.test_extenders:TestExtender"]):
        c = SmartClient()
        soup = c.soup(reverse("shuup:index"))
        link_texts = [a.text for a in soup.findAll("a")]
        assert "Test Link to Front" in link_texts
示例#14
0
def test_extender_renders_main_menu(rf):
    get_default_shop()

    with override_provides("front_menu_extender", ["shuup_tests.xtheme.test_extenders:TestExtender"]):
        c = SmartClient()
        soup = c.soup(reverse("shuup:index"))
        link_texts = [a.text for a in soup.findAll("a")]
        assert "Test Link to Front" in link_texts
示例#15
0
def initialize_test(regular_user, person=True):
    client = SmartClient()
    get_default_shop()
    if person:
        contact = get_person_contact(regular_user)
    else:
        contact = get_company_contact(regular_user)

    client.login(username=REGULAR_USER_USERNAME, password=REGULAR_USER_PASSWORD)
    return client, contact
示例#16
0
def initialize_test(regular_user, person=True):
    client = SmartClient()
    get_default_shop()
    if person:
        contact = get_person_contact(regular_user)
    else:
        contact = get_company_contact(regular_user)

    client.login(username=REGULAR_USER_USERNAME, password=REGULAR_USER_PASSWORD)
    return client, contact
示例#17
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("shuup:index"))
        assert get_language() == "en"

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

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

        set_shop_available_languages(shop, ["fi"])

        response = client.get(reverse("shuup:index"))
        assert get_language() == "fi"

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

        client.get("shuup_admin:js-catalog")
        assert get_language() == "en"
示例#18
0
def test_basic_order_flow(with_company):
    create_default_order_statuses()
    n_orders_pre = Order.objects.count()
    populate_if_required()
    c = SmartClient()
    product_ids = _populate_client_basket(c)

    addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"})
    addresses_soup = c.soup(addresses_path)
    inputs = fill_address_inputs(addresses_soup, with_company=with_company)
    response = c.post(addresses_path, data=inputs)
    assert response.status_code == 302  # Should redirect forth

    methods_path = reverse("shuup:checkout", kwargs={"phase": "methods"})
    methods_soup = c.soup(methods_path)
    assert c.post(methods_path, data=extract_form_fields(methods_soup)).status_code == 302  # Should redirect forth

    confirm_path = reverse("shuup:checkout", kwargs={"phase": "confirm"})
    confirm_soup = c.soup(confirm_path)
    Product.objects.get(pk=product_ids[0]).soft_delete()
    assert c.post(confirm_path, data=extract_form_fields(confirm_soup)).status_code == 200  # user needs to reconfirm
    data = extract_form_fields(confirm_soup)
    data['product_ids'] = ','.join(product_ids[1:])
    assert c.post(confirm_path, data=data).status_code == 302  # Should redirect forth

    n_orders_post = Order.objects.count()
    assert n_orders_post > n_orders_pre, "order was created"
示例#19
0
def test_basic_order_flow_registered(regular_user):
    cache.clear()
    create_default_order_statuses()
    n_orders_pre = Order.objects.count()
    populate_if_required()
    get_test_script("test script", "order_received")
    # paths
    addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"})
    methods_path = reverse("shuup:checkout", kwargs={"phase": "methods"})
    confirm_path = reverse("shuup:checkout", kwargs={"phase": "confirm"})

    template_data = STEP_DATA[0]["actions"][0]["template_data"]

    LANG_CODE = {
        "en": "US",
        "fi": "FI"
    }

    for lang in ["en", "fi"]:
        n_outbox_pre = len(mail.outbox)
        contact = get_person_contact(regular_user)
        contact.language = lang
        contact.save()

        c = SmartClient()
        c.login(username=REGULAR_USER_USERNAME, password=REGULAR_USER_PASSWORD)

        product_ids = _populate_client_basket(c)

        addresses_soup = c.soup(addresses_path)
        address = get_address(country=LANG_CODE[lang])

        inputs = fill_address_inputs(addresses_soup, address)
        response = c.post(addresses_path, data=inputs)
        assert response.status_code == 302  # Should redirect forth

        methods_soup = c.soup(methods_path)
        assert c.post(methods_path, data=extract_form_fields(methods_soup)).status_code == 302  # Should redirect forth

        confirm_soup = c.soup(confirm_path)
        Product.objects.get(pk=product_ids[0]).soft_delete()
        assert c.post(confirm_path, data=extract_form_fields(confirm_soup)).status_code == 200  # user needs to reconfirm
        data = extract_form_fields(confirm_soup)
        data['product_ids'] = ','.join(product_ids[1:])
        assert c.post(confirm_path, data=data).status_code == 302  # Should redirect forth

        n_orders_post = Order.objects.count()
        assert n_orders_post > n_orders_pre, "order was created"
        assert (len(mail.outbox) == n_outbox_pre + 1), "Sending email failed"
        latest_mail = mail.outbox[-1]

        # mail is always sent in fallback language since user is not registered
        assert latest_mail.subject == template_data[lang]["subject"], "Subject doesn't match"
        assert latest_mail.body == template_data[lang]["body"], "Body doesn't match"
def test_notify_on_company_created(regular_user, allow_company_registration):
    if "shuup.front.apps.customer_information" not in settings.INSTALLED_APPS:
        pytest.skip("shuup.front.apps.customer_information required in installed apps")
    if "shuup.notify" not in settings.INSTALLED_APPS:
        pytest.skip("shuup.notify required in installed apps")

    configuration.set(None, "allow_company_registration", allow_company_registration)
    step = Step(
        cond_op=StepConditionOperator.NONE,
        actions=[
            AddNotification(
                {
                    "message": {"constant": "It Works. {{ customer_email }}"},
                    "message_identifier": {"constant": "company_created"},
                }
            )
        ],
        next=StepNext.STOP,
    )
    script = Script(
        event_identifier=CompanyAccountCreated.identifier, name="Test Script", enabled=True, shop=get_default_shop()
    )
    script.set_steps([step])
    script.save()

    assert not Notification.objects.filter(identifier="company_created").exists()

    assert get_person_contact(regular_user)
    assert not get_company_contact(regular_user)

    client = SmartClient()
    client.login(username=REGULAR_USER_USERNAME, password=REGULAR_USER_PASSWORD)
    company_edit_url = reverse("shuup:company_edit")

    if allow_company_registration:
        client.soup(company_edit_url)

        data = _default_company_data()
        data.update(_default_address_data("billing"))
        data.update(_default_address_data("shipping"))

        response, soup = client.response_and_soup(company_edit_url, data, "post")

        assert response.status_code == 302
        assert get_company_contact(regular_user)
        assert Notification.objects.filter(identifier="company_created").count() == 1
        notification = Notification.objects.filter(identifier="company_created").first()
        assert notification
        assert data["contact-email"] in notification.message

        # New save should not add new notifications
        response, soup = client.response_and_soup(company_edit_url, data, "post")
        assert response.status_code == 302
        assert Notification.objects.filter(identifier="company_created").count() == 1
        script.delete()
    else:
        response = client.get(company_edit_url)
        assert reverse("shuup:customer_edit") in response.url
        assert Notification.objects.filter(identifier="company_created").count() == 0
示例#21
0
def test_consent_cookies():
    """
    Test that the GDPR consent is generated and saved into a cooki
    """
    for code, lang in settings.LANGUAGES:
        activate(code)
        shop = factories.get_default_shop()
        client = SmartClient()
        index_url = reverse("shuup:index")
        response = client.get(index_url)

        # 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()

        # create cookie categories
        required_cookie_category = GDPRCookieCategory.objects.create(
            shop=shop,
            always_active=True,
            cookies="cookie1,cookir2,_cookie3",
            name="RequiredCookies",
            how_is_used="to make the site work"
        )
        optional_cookie_category = GDPRCookieCategory.objects.create(
            shop=shop,
            always_active=False,
            cookies="_opt1,_opt2,_opt3",
            name="OptionalCookies",
            how_is_used="to spy users"
        )

        # create privacy policy GDPR document
        privacy_policy = ensure_gdpr_privacy_policy(shop)
        response = client.get(index_url)
        assert settings.SHUUP_GDPR_CONSENT_COOKIE_NAME not in response.cookies

        # send consent
        response = client.post(reverse("shuup:gdpr_consent"), data={
            "cookie_category_{}".format(required_cookie_category.id): "on",
            "cookie_category_{}".format(optional_cookie_category.id): "on"
        })

        assert settings.SHUUP_GDPR_CONSENT_COOKIE_NAME in response.cookies
        cookies_data = json.loads(response.cookies[settings.SHUUP_GDPR_CONSENT_COOKIE_NAME].value)
        assert privacy_policy.id == cookies_data["documents"][0]["id"]
        assert privacy_policy.url == cookies_data["documents"][0]["url"]

        for cookie in required_cookie_category.cookies.split(","):
            assert cookie in cookies_data["cookies"]
        for cookie in optional_cookie_category.cookies.split(","):
            assert cookie in cookies_data["cookies"]
示例#22
0
def test_admin_set_shop_language(admin_user):
    original_language = get_language()
    shop = factories.get_default_shop()
    client = SmartClient()
    admin_user.set_password("admin")
    admin_user.save()
    client.login(username=admin_user.username, password="******")

    with override_settings(LANGUAGES=[("it", "Italian"), ("fr", "French"),
                                      ("fi", "Finnish"),
                                      ("pt-br", "Portuguese (Brazil)")],
                           LANGUAGE_CODE="it",
                           PARLER_DEFAULT_LANGUAGE_CODE="it"):
        assert get_shop_available_languages(shop) == []
        edit_url = reverse("shuup_admin:shop.edit", kwargs=dict(pk=shop.id))
        payload = {
            "translation_config-available_languages": ["pt-br", "fi"],
            "base-public_name__it":
            shop.public_name,
            "base-name__it":
            shop.name,
            "base-status":
            "1",
            "base-currency":
            shop.currency,
            "product_list_facets-filter_products_by_category_ordering":
            "1",
            "product_list_facets-filter_products_by_price_ordering":
            "1",
            "product_list_facets-limit_product_list_page_size_ordering":
            "1",
            "product_list_facets-sort_products_by_price_ordering":
            "1",
            "product_list_facets-sort_products_by_name_ordering":
            "1",
            "product_list_facets-sort_products_by_ascending_created_date_ordering":
            "1",
            "product_list_facets-sort_products_by_date_created_ordering":
            "1",
            "product_list_facets-filter_products_by_manufacturer_ordering":
            "1",
            "product_list_facets-filter_products_by_variation_value_ordering":
            "1",
            "order_configuration-order_reference_number_length":
            "20",
            "order_configuration-order_reference_number_prefix":
            "10"
        }
        response = client.post(edit_url, data=payload)
        assert response.status_code == 302
        assert get_shop_available_languages(shop) == ["pt-br", "fi"]

    activate(original_language)
示例#23
0
def test_basic_order_flow_not_registered(with_company):
    cache.clear()
    create_default_order_statuses()
    n_orders_pre = Order.objects.count()
    populate_if_required()
    get_test_script("test script", "order_received")
    # paths
    addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"})
    methods_path = reverse("shuup:checkout", kwargs={"phase": "methods"})
    confirm_path = reverse("shuup:checkout", kwargs={"phase": "confirm"})

    template_data = STEP_DATA[0]["actions"][0]["template_data"]

    LANG_CODE = {"en": "US", "fi": "FI"}

    for lang in ["en", "fi"]:
        n_outbox_pre = len(mail.outbox)
        c = SmartClient()
        product_ids = _populate_client_basket(c)

        addresses_soup = c.soup(addresses_path)
        address = get_address(country=LANG_CODE[lang])

        inputs = fill_address_inputs(addresses_soup,
                                     address,
                                     with_company=with_company)
        response = c.post(addresses_path, data=inputs)
        assert response.status_code == 302  # Should redirect forth

        methods_soup = c.soup(methods_path)
        assert c.post(methods_path, data=extract_form_fields(
            methods_soup)).status_code == 302  # Should redirect forth

        confirm_soup = c.soup(confirm_path)
        Product.objects.get(pk=product_ids[0]).soft_delete()
        assert (
            c.post(confirm_path,
                   data=extract_form_fields(confirm_soup)).status_code == 200
        )  # user needs to reconfirm
        data = extract_form_fields(confirm_soup)
        data["accept_terms"] = True
        data["product_ids"] = ",".join(product_ids[1:])
        assert c.post(confirm_path,
                      data=data).status_code == 302  # Should redirect forth

        n_orders_post = Order.objects.count()
        assert n_orders_post > n_orders_pre, "order was created"
        assert len(mail.outbox) == n_outbox_pre + 1, "Sending email failed"
        latest_mail = mail.outbox[-1]

        # mail is always sent in fallback language since user is not registered
        assert latest_mail.subject == template_data["en"][
            "subject"], "Subject doesn't match"
        assert latest_mail.body == template_data["en"][
            "body"], "Body doesn't match"
示例#24
0
def test_theme_with_default_template_dir():
    with override_settings(CACHES={
        'default': {
            'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
            'LOCATION': 'test_configuration_cache',
        }
    }):
        cache.init_cache()
        get_default_shop()
        with override_current_theme_class(ShuupTestingThemeWithCustomBase, get_default_shop()):
            c = SmartClient()
            soup = c.soup(reverse("shuup:index"))
            assert "Simple base for themes to use" in soup.find("h1").text
            assert "Welcome to test Shuup!" in soup.find("h1").text
示例#25
0
def test_register_form(client):
    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)

    redirect_target = "/index/"
    client = SmartClient()

    # user didn't checked the privacy policy agreement
    response = client.post(
        reverse("shuup:registration_register"),
        data={
            "username": "******",
            "email": "*****@*****.**",
            "password1": "1234",
            "password2": "1234",
            REDIRECT_FIELD_NAME: redirect_target,
        },
    )
    assert response.status_code == 200
    assert "You must accept this in order to register." in response.content.decode(
        "utf-8")

    response = client.post(
        reverse("shuup:registration_register"),
        data={
            "username": "******",
            "email": "*****@*****.**",
            "password1": "1234",
            "password2": "1234",
            "accept_%d" % privacy_policy.id: "on",
            REDIRECT_FIELD_NAME: redirect_target,
        },
    )
    assert response.status_code == 302
    assert response.get("location")
    assert response.get("location").endswith(redirect_target)

    user = User.objects.first()

    assert is_documents_consent_in_sync(shop, user)

    ensure_gdpr_privacy_policy(shop, force_update=True)
    assert not is_documents_consent_in_sync(shop, user)
示例#26
0
def test_company_edit_form_links_company(regular_user,
                                         allow_company_registration):
    get_default_shop()
    configuration.set(None, "allow_company_registration",
                      allow_company_registration)
    person = get_person_contact(regular_user)
    assert not get_company_contact(regular_user)

    client = SmartClient()
    client.login(username=REGULAR_USER_USERNAME,
                 password=REGULAR_USER_PASSWORD)

    data = default_company_data()
    data.update(default_address_data("billing"))
    data.update(default_address_data("shipping"))
    company_edit_url = reverse("shuup:company_edit")

    if allow_company_registration:
        soup = client.soup(company_edit_url)
        response, soup = client.response_and_soup(company_edit_url, data,
                                                  "post")
        assert response.status_code == 302
        assert get_company_contact(regular_user)
    else:
        response = client.get(company_edit_url)
        assert reverse("shuup:customer_edit") in response.url
        response = client.post(company_edit_url, data)
        assert reverse("shuup:customer_edit") in response.url
def test_new_shop_product_suppliers_init(rf, admin_user, multiple_suppliers):
    with override_settings(SHUUP_ENABLE_MULTIPLE_SUPPLIERS=multiple_suppliers):
        shop = get_default_shop()
        supplier = get_default_supplier()
        tax_class = get_default_tax_class()
        product_type = get_default_product_type()
        sales_unit = get_default_sales_unit()

        assert ShopProduct.objects.count() == 0
        client = SmartClient()
        client.login(username="******", password="******")
        soup = client.soup(reverse("shuup_admin:shop_product.new"))
        supplier_select = soup.find("select", attrs={"name": "shop%s-suppliers" % shop.id})
        assert len(supplier_select.find_all("option")) == (0 if multiple_suppliers else 1)
示例#28
0
def test_checkout_empty_basket(rf):
    create_default_order_statuses()
    n_orders_pre = Order.objects.count()
    populate_if_required()
    c = SmartClient()
    product_ids = _populate_client_basket(c)
    addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"})
    addresses_soup = c.soup(addresses_path)
    inputs = fill_address_inputs(addresses_soup)
    for product_id in product_ids:
        Product.objects.get(pk=product_id).soft_delete()
    response, soup = c.response_and_soup(addresses_path, data=inputs, method="post")
    assert response.status_code == 200  # Should redirect forth
    assert b"Your shopping cart is empty." in soup.renderContents()
示例#29
0
def test_shop_available_languages(admin_user):
    original_language = get_language()
    shop = factories.get_default_shop()
    client = SmartClient()

    with override_settings(
        LANGUAGES=[
            ("it", "Italian"),
            ("fr", "French"),
            ("fi", "Finnish"),
            ("pt", "Portuguese")
        ],
        LANGUAGE_CODE="it",
        PARLER_DEFAULT_LANGUAGE_CODE = "it"
    ):
        # there is no language set for the shop, the first one will be used
        response = client.get(reverse("shuup:index"))
        assert get_language() == "it"

        # set an invalid language code
        with pytest.raises(ValueError):
            set_shop_available_languages(shop, ["xpto"])

        # limit the langauges for the shop to "fi" and "pt"
        set_shop_available_languages(shop, ["fi", "pt"])

        # the middleware will automatically set the language to "fi" as that is the first one available for the shop
        response = client.get(reverse("shuup:index"))
        assert get_language() == "fi"

        # the same won't happen for any other url - the middleware will only affect front urls
        client.get("shuup_admin:index")
        assert get_language() == "it"

        # test againt front again
        client.get(reverse("shuup:index"))
        assert get_language() == "fi"

        # again for admin
        client.get("shuup_admin:index")
        assert get_language() == "it"

        # remote all available languages
        set_shop_available_languages(shop, [])
        # this should fallback to settings.LAGUAGE_CODE
        response = client.get(reverse("shuup:index"))
        assert get_language() == "it"

    activate(original_language)
def test_customer_edit_redirects_to_login_if_not_logged_in():
    get_default_shop()  # Front middleware needs a Shop to exists
    urls = ["shuup:customer_edit", "shuup:company_edit"]
    for url in urls:
        response = SmartClient().get(reverse(url), follow=False)
        assert response.status_code == 302  # Redirection ("Found")
        assert resolve_url(settings.LOGIN_URL) in response.url
示例#31
0
def test_authenticate_form(client):
    activate("en")
    shop = factories.get_default_shop()
    user = factories.create_random_user("en")
    user.email = "*****@*****.**"
    user.set_password("1234")
    user.save()

    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)

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

    login_url = reverse("shuup:login")
    response = client.get(login_url)
    soup = BeautifulSoup(response.content)
    login_form = soup.find("form", {"action": "/login/"})
    assert len(login_form.findAll("input")) == 5  # 4 + privacy policy checkbox

    # user didn't check the privacy policy agreement
    response = client.post(reverse("shuup:login"),
                           data={
                               "username": user.email,
                               "password": "******",
                               REDIRECT_FIELD_NAME: redirect_target
                           })
    assert response.status_code == 200
    assert "You must accept this in order to authenticate." in response.content.decode(
        "utf-8")

    response = client.post(
        reverse("shuup:login"),
        data={
            "username": user.email,
            "password": "******",
            "accept_%d" % privacy_policy.id: "on",
            REDIRECT_FIELD_NAME: redirect_target,
        },
    )
    assert response.status_code == 302
    assert response.get("location")
    assert response.get("location").endswith(redirect_target)
def test_user_change_password(regular_user, password_value, new_password_2, expected):
    get_default_shop()
    assert check_password(REGULAR_USER_PASSWORD, regular_user.password)

    client = SmartClient()
    client.login(username=REGULAR_USER_USERNAME, password=REGULAR_USER_PASSWORD)
    change_password_url = reverse("shuup:change_password")

    new_password = "******"
    data = {"old_password": password_value, "new_password1": new_password, "new_password2": new_password_2}

    response, soup = client.response_and_soup(change_password_url, data, "post")
    user = get_user_model().objects.get(pk=regular_user.pk)
    assert regular_user == user

    assert check_password(REGULAR_USER_PASSWORD, user.password) != expected
    assert check_password(new_password, user.password) == expected
def test_notify_on_company_created(regular_user, allow_company_registration):
    if "shuup.front.apps.customer_information" not in settings.INSTALLED_APPS:
        pytest.skip("shuup.front.apps.customer_information required in installed apps")
    if "shuup.notify" not in settings.INSTALLED_APPS:
        pytest.skip("shuup.notify required in installed apps")

    configuration.set(None, "allow_company_registration", allow_company_registration)
    step = Step(
        cond_op=StepConditionOperator.NONE,
        actions=[
            AddNotification({
                "message": {"constant": "It Works. {{ customer_email }}"},
                "message_identifier": {"constant": "company_created"},
            })
        ],
        next=StepNext.STOP
    )
    script = Script(
        event_identifier=CompanyAccountCreated.identifier, name="Test Script", enabled=True, shop=get_default_shop())
    script.set_steps([step])
    script.save()

    assert not Notification.objects.filter(identifier="company_created").exists()

    assert get_person_contact(regular_user)
    assert not get_company_contact(regular_user)

    client = SmartClient()
    client.login(username=REGULAR_USER_USERNAME, password=REGULAR_USER_PASSWORD)
    company_edit_url = reverse("shuup:company_edit")

    if allow_company_registration:
        client.soup(company_edit_url)

        data = _default_company_data()
        data.update(_default_address_data("billing"))
        data.update(_default_address_data("shipping"))

        response, soup = client.response_and_soup(company_edit_url, data, "post")

        assert response.status_code == 302
        assert get_company_contact(regular_user)
        assert Notification.objects.filter(identifier="company_created").count() == 1
        notification = Notification.objects.filter(identifier="company_created").first()
        assert notification
        assert data["contact-email"] in notification.message

        # New save should not add new notifications
        response, soup = client.response_and_soup(company_edit_url, data, "post")
        assert response.status_code == 302
        assert Notification.objects.filter(identifier="company_created").count() == 1
        script.delete()
    else:
        response = client.get(company_edit_url)
        assert reverse("shuup:customer_edit") in response.url
        assert Notification.objects.filter(identifier="company_created").count() == 0
示例#34
0
def test_custom_file_transformer_import(admin_user):
    shop = get_default_shop()
    shop.staff_members.add(admin_user)
    get_default_tax_class()
    get_default_product_type()
    get_default_sales_unit()

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

    import_path = reverse("shuup_admin:importer.import.new")
    process_path = reverse("shuup_admin:importer.import_process")

    client = SmartClient()
    client.login(username="******", password="******")
    csv_content = str.encode("sku;name\n123;Teste")
    data = {
        "importer":
        "product_importer",
        "shop":
        shop.pk,
        "language":
        "en",
        "file":
        SimpleUploadedFile("file.csv", csv_content, content_type="text/csv"),
    }
    response = client.post(import_path, data=data)
    assert response.status_code == 302
    with mock.patch.object(ProductImporter, "custom_file_transformer", True):
        assert ProductImporter.custom_file_transformer is True
        query_string = urlparse(response["location"]).query
        process_submit_path = "%s?%s" % (process_path, query_string)
        query = parse_qs(query_string)
        data = {
            "importer": "product_importer",
            "shop": shop.pk,
            "language": "en",
            "n": query.get("n"),
        }
        response = client.post(process_submit_path, data=data)
        assert response.status_code == 302
        assert "The import was queued!" in list(
            response.wsgi_request._messages)[0].message
        task_execution = BackgroundTaskExecution.objects.last()
        assert task_execution.status == BackgroundTaskExecutionStatus.ERROR
        assert "Error! Not implemented: `DataImporter` -> `transform_file()`." in task_execution.error_log
示例#35
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("shuup: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"
    )
    response = client.get(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

    # make sure no other shop has this
    with override_settings(SHUUP_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
示例#36
0
def test_task_type_admin(admin_user):
    activate("en")
    shop = factories.get_default_shop()

    admin_user.set_password(ADMIN_PWD)
    admin_user.save()
    admin_contact = get_person_contact(admin_user)
    admin_contact.shops.add(shop)

    client = SmartClient()
    client.login(username=admin_user.username, password=ADMIN_PWD)

    # Create new task type
    new_task_type_url = reverse("shuup_admin:task_type.new")
    assert TaskType.objects.count() == 0

    # get the form fields
    soup = client.soup(new_task_type_url)
    payload = extract_form_fields(soup)
    payload.update({
        "name__en": "My Task Type"
    })
    response = client.post(new_task_type_url, payload)
    assert response.status_code == 302
    assert TaskType.objects.count() == 1
    task_type = TaskType.objects.first()

    # List task types
    list_task_type_url = reverse("shuup_admin:task_type.list")
    list_data = {
        "jq": json.dumps({
            "sort": None,
            "perPage": 20,
            "page": 1,
            "filters": {}
        })
    }
    response = client.get(list_task_type_url, data=list_data)
    assert task_type.name in response.content.decode("utf-8")

    # Edit task type
    edit_task_type_url = reverse("shuup_admin:task_type.edit", kwargs=dict(pk=task_type.pk))

    soup = client.soup(edit_task_type_url)
    payload = extract_form_fields(soup)
    payload.update({
        "name__en": "My Task Type Edited"
    })
    response = client.post(edit_task_type_url, payload)
    assert response.status_code == 302
示例#37
0
def test_register_form(client):
    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 = Page.objects.create(
        shop=shop,
        title="Privacy policy",
        url="privacy-policy",
        page_type=PageType.GDPR_CONSENT_DOCUMENT,
        content="you just agree",
        available_from=now())

    redirect_target = "/index/"
    client = SmartClient()

    # user didn't checked the privacy policy agreement
    response = client.post(reverse("shuup:registration_register"),
                           data={
                               "username": "******",
                               "email": "*****@*****.**",
                               "password1": "1234",
                               "password2": "1234",
                               REDIRECT_FIELD_NAME: redirect_target
                           })
    assert response.status_code == 200
    assert "You must accept to this to register" in response.content.decode(
        "utf-8")

    response = client.post(reverse("shuup:registration_register"),
                           data={
                               "username": "******",
                               "email": "*****@*****.**",
                               "password1": "1234",
                               "password2": "1234",
                               "accept_%d" % privacy_policy.id: "on",
                               REDIRECT_FIELD_NAME: redirect_target
                           })
    assert response.status_code == 302
    assert response.get("location")
    assert response.get("location").endswith(redirect_target)
示例#38
0
def test_boleto_not_exists():
    initialize()
    view_boleto_path = reverse("shuup:view_boleto",
                               kwargs={
                                   "order_pk": 123,
                                   "order_key": "32131"
                               })
    response = SmartClient().get(view_boleto_path)
    assert response.status_code == 500
示例#39
0
def test_company_edit_form_links_company(regular_user, rf):
    get_default_shop()
    person = get_person_contact(regular_user)
    assert not get_company_contact(regular_user)

    client = SmartClient()
    client.login(username=REGULAR_USER_USERNAME, password=REGULAR_USER_PASSWORD)
    company_edit_url = reverse("shuup:company_edit")
    soup = client.soup(company_edit_url)

    data = default_company_data()
    data.update(default_address_data("billing"))
    data.update(default_address_data("shipping"))

    response, soup = client.response_and_soup(company_edit_url, data, "post")

    assert response.status_code == 302
    assert get_company_contact(regular_user)
示例#40
0
def test_download_examples(rf, admin_user):
    shop = get_default_shop()
    import_url = reverse("shuup_admin:importer.import")

    shop.staff_members.add(admin_user)
    client = SmartClient()
    client.login(username="******", password="******")

    # test downloading all default importers
    from shuup.importer.utils import get_importer, get_importer_choices

    assert len(get_importer_choices())
    for importer, name in get_importer_choices():
        importer_cls = get_importer(importer)

        if importer_cls.has_example_file():
            import_response = client.get("{}?importer={}".format(import_url, importer_cls.identifier))
            assert import_response.status_code == 200
            assert "This importer provides example files" in import_response.content.decode("utf-8")

            for example_file in importer_cls.example_files:
                assert example_file.file_name in import_response.content.decode("utf-8")

                # download file
                download_url = "{}?importer={}&file_name={}".format(
                    reverse("shuup_admin:importer.download_example"),
                    importer_cls.identifier,
                    example_file.file_name
                )
                response = client.get(download_url)

                if importer_cls.identifier == "dummy_file_importer":
                    assert response.status_code == 404
                else:
                    assert response.status_code == 200
                    assert response._headers["content-type"] == ("Content-Type", str(example_file.content_type))
                    assert response._headers["content-disposition"] == ("Content-Disposition", 'attachment; filename=%s' % example_file.file_name)

                    if example_file.template_name:
                        from django.template.loader import get_template
                        template_file = get_template(example_file.template_name).template.filename
                        assert open(template_file, "r").read().strip() == response.content.decode("utf-8").strip()
                    else:
                        assert response.content
示例#41
0
def test_product_subscription_options():
    shop = factories.get_default_shop()
    user = factories.create_random_user()
    supplier = factories.get_default_supplier()
    product = factories.create_product("product", shop, supplier, 10)

    client = SmartClient()

    with override_provides(
            "product_subscription_option_provider",
        [
            "shuup.testing.subscription_option_provider.TestSubscriptionOptionProvider"
        ],
    ):
        response = client.soup(
            reverse("shuup:product",
                    kwargs=dict(pk=product.pk, slug=product.slug)))
        purchase_options = response.find(
            "ul", {"class": "product-purchase-options-list-group"})

        # there is an option for one-time purchase
        one_time_purchase = purchase_options.find_all(
            "li", {"class": "list-group-item"})[0]
        assert one_time_purchase.find("input", {
            "name": "purchase-option",
            "value": "one-time"
        })

        # there is an option for subscription purchase
        subscription = purchase_options.find_all(
            "li", {"class": "list-group-item"})[1]
        assert subscription.find("input", {
            "name": "purchase-option",
            "value": "subscription"
        })
        # the subscription options should be yr and mo, according to the TestSubscriptionOptionProvider
        assert subscription.find_all("input", {
            "name": "subscription-option",
            "value": "mo"
        })
        assert subscription.find_all("input", {
            "name": "subscription-option",
            "value": "yr"
        })
示例#42
0
def test_register_form(client):
    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)

    redirect_target = "/index/"
    client = SmartClient()

    # user didn't checked the privacy policy agreement
    response = client.post(reverse("shuup:registration_register"), data={
        "username": "******",
        "email": "*****@*****.**",
        "password1": "1234",
        "password2": "1234",
        REDIRECT_FIELD_NAME: redirect_target
    })
    assert response.status_code == 200
    assert "You must accept to this to register." in response.content.decode("utf-8")

    response = client.post(reverse("shuup:registration_register"), data={
        "username": "******",
        "email": "*****@*****.**",
        "password1": "1234",
        "password2": "1234",
        "accept_%d" % privacy_policy.id: "on",
        REDIRECT_FIELD_NAME: redirect_target
    })
    assert response.status_code == 302
    assert response.get("location")
    assert response.get("location").endswith(redirect_target)

    user = User.objects.first()

    assert is_documents_consent_in_sync(shop, user)

    ensure_gdpr_privacy_policy(shop, force_update=True)
    assert not is_documents_consent_in_sync(shop, user)
示例#43
0
def test_admin_set_shop_language(admin_user):
    original_language = get_language()
    shop = factories.get_default_shop()
    client = SmartClient()
    admin_user.set_password("admin")
    admin_user.save()
    client.login(username=admin_user.username, password="******")

    with override_settings(
        LANGUAGES=[
            ("it", "Italian"),
            ("fr", "French"),
            ("fi", "Finnish"),
            ("pt-br", "Portuguese (Brazil)")
        ],
        LANGUAGE_CODE="it",
        PARLER_DEFAULT_LANGUAGE_CODE = "it"
    ):
        assert get_shop_available_languages(shop) == []
        edit_url = reverse("shuup_admin:shop.edit", kwargs=dict(pk=shop.id))
        payload = {
            "translation_config-available_languages": ["pt-br", "fi"],
            "base-public_name__it": shop.public_name,
            "base-name__it": shop.name,
            "base-status": "1",
            "base-currency": shop.currency,
            "product_list_facets-filter_products_by_category_ordering": "1",
            "product_list_facets-filter_products_by_price_ordering": "1",
            "product_list_facets-limit_product_list_page_size_ordering": "1",
            "product_list_facets-sort_products_by_price_ordering": "1",
            "product_list_facets-sort_products_by_name_ordering": "1",
            "product_list_facets-sort_products_by_ascending_created_date_ordering": "1",
            "product_list_facets-sort_products_by_date_created_ordering": "1",
            "product_list_facets-filter_products_by_manufacturer_ordering": "1",
            "product_list_facets-filter_products_by_variation_value_ordering": "1",
            "order_configuration-order_reference_number_length": "20",
            "order_configuration-order_reference_number_prefix": "10"
        }
        response = client.post(edit_url, data=payload)
        assert response.status_code == 302
        assert get_shop_available_languages(shop) == ["pt-br", "fi"]

    activate(original_language)
示例#44
0
def test_theme_without_default_template_dir():
    with override_settings(
            CACHES={
                "default": {
                    "BACKEND": "django.core.cache.backends.locmem.LocMemCache",
                    "LOCATION": "test_configuration_cache",
                }
            }):
        cache.init_cache()

        with override_current_theme_class(ShuupTestingTheme,
                                          get_default_shop()):
            c = SmartClient()
            soup = c.soup(reverse("shuup:index"))
            assert "Simple base for themes to use" not in soup
            assert "Welcome to test Shuup!" in soup.find(
                "div", {
                    "class": "page-content"
                }).text
示例#45
0
def test_import_error(admin_user):
    shop = get_default_shop()
    shop.staff_members.add(admin_user)
    get_default_tax_class()
    get_default_product_type()
    get_default_sales_unit()

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

    import_path = reverse("shuup_admin:importer.import")
    process_path = reverse("shuup_admin:importer.import_process")

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

    csv_content = str.encode("sku;name\n123;Teste")
    data = {
        "importer":
        "product_importer",
        "shop":
        shop.pk,
        "language":
        "en",
        "file":
        SimpleUploadedFile("file.csv", csv_content, content_type="text/csv")
    }
    response = client.post(import_path, data=data)
    assert response.status_code == 302
    query_string = urlparse(response["location"]).query
    query = parse_qs(query_string)
    data = {
        "importer": "product_importer",
        "shop": shop.pk,
        "language": "en",
        "n": query.get("n"),
    }
    data = {}
    process_submit_path = "%s?%s" % (process_path, query_string)
    response = client.post(process_submit_path, data=data)
    assert response.status_code == 302
    assert "Failed to import the file." == list(
        response.wsgi_request._messages)[0].message
示例#46
0
def test_gdpr_admin_download_data(client, admin_user):
    """
    Test that admin user can download customer data
    """
    activate("en")
    shop = factories.get_default_shop()
    customer = factories.create_random_person("en")
    product = factories.create_product("p1", shop, factories.get_default_supplier())
    [factories.create_random_order(customer, [product]) for order in range(3)]

    client = SmartClient()
    admin_user.set_password("admin")
    admin_user.save()
    client.login(username=admin_user.username, password="******")
    admin_download_url = reverse("shuup_admin:gdpr.download_data", kwargs=dict(pk=customer.pk))
    response = client.post(admin_download_url)
    assert response.status_code == 200
    assert response._headers["content-disposition"][0] == "Content-Disposition"
    assert response._headers["content-disposition"][1].startswith("attachment; filename=user_data_")
示例#47
0
def test_gdpr_admin_settings(client, admin_user):
    """
    Test that admin user can enable GDPR and add cookie categories
    """
    activate("en")
    shop = factories.get_default_shop()
    client = SmartClient()
    admin_user.set_password("admin")
    admin_user.save()
    client.login(username=admin_user.username, password="******")
    admin_settings_url = reverse("shuup_admin:gdpr.settings")

    assert not GDPRSettings.objects.exists()
    response = client.soup(admin_settings_url)
    assert GDPRSettings.objects.exists()
    s = GDPRSettings.objects.first()
    assert s.cookie_banner_content == settings.SHUUP_GDPR_DEFAULT_BANNER_STRING
    assert s.cookie_privacy_excerpt == settings.SHUUP_GDPR_DEFAULT_EXCERPT_STRING
    assert GDPRCookieCategory.objects.count() == 0

    page = Page.objects.create(shop=shop, available_from=now())
    page.title = "test"
    page.save()
    # create the settings with only basic options
    payload = extract_form_fields(response)
    payload.pop("base-consent_pages")
    payload.update({
        "base-enabled": True,
        "base-privacy_policy_page": page.pk,
        "base-cookie_banner_content__en": "Banner content",
        "base-cookie_privacy_excerpt__en": "Cookie excerpt",
        "cookie_categories-0-id": "",
        "cookie_categories-0-always_active": 1,
        "cookie_categories-0-name__en": "required",
        "cookie_categories-0-how_is_used__en": "to work",
        "cookie_categories-0-cookies": "sessionid",
    })
    response = client.post(admin_settings_url, data=payload)
    assert response.status_code == 302

    assert GDPRCookieCategory.objects.count() == 1

    # add one more cookie category
    payload.update({
        "cookie_categories-1-id": "",
        "cookie_categories-1-always_active": 1,
        "cookie_categories-1-name__en": "Maybe",
        "cookie_categories-1-how_is_used__en": "to spy",
        "cookie_categories-1-cookies": "_ga",
    })
    client.post(admin_settings_url, data=payload)
    assert GDPRCookieCategory.objects.count() == 2
示例#48
0
def test_get_installments_9x_with_simples_intereset():
    """
        Max 9 installs with SIMPLE intereset
        interest_rate = 4.00%
    """
    patch_cielo_request()
    shop = get_default_shop()
    create_default_order_statuses()
    populate_if_required()
    set_current_theme('shuup.themes.classic_gray')
    c = SmartClient()
    _configure_basket(c)
    cielo_config = CieloConfig.objects.create(
        shop=shop,
        max_installments=9,
        installments_without_interest=3,
        interest_type=InterestType.Simple,
        interest_rate=Decimal(4.0))
    SHIP_AMOUNT = Decimal(19.0)
    shipping_method = get_default_shipping_method()
    shipping_method.behavior_components.add(
        FixedCostBehaviorComponent.objects.create(price_value=SHIP_AMOUNT))

    order_total = (PRODUCT_QTNTY * PRODUCT_PRICE) + SHIP_AMOUNT
    installment_choices = InstallmentContext(
        order_total, cielo_config).get_intallments_choices()

    response = c.get(INSTALLMENTS_PATH, {"cc_brand": CieloCardBrand.Visa})
    json_content = json.loads(response.content.decode("utf-8"))
    assert len(json_content['installments']) == len(installment_choices)

    for installment in range(len(installment_choices)):
        total = format_money(
            shop.create_price(installment_choices[installment][2]))
        installment_amount = format_money(
            shop.create_price(installment_choices[installment][1]))

        assert json_content['installments'][installment][
            'number'] == installment + 1
        assert installment_amount in json_content['installments'][installment][
            'name']
        assert total in json_content['installments'][installment]['name']
示例#49
0
def test_page_layout():
    if "shuup.xtheme" not in settings.INSTALLED_APPS:
        pytest.skip("Need shuup.xtheme in INSTALLED_APPS")

    shop = factories.get_default_shop()
    theme = get_current_theme(shop)
    view_config = ViewConfig(theme=theme, shop=shop, view_name="PageView", draft=True)
    page1_content = printable_gibberish()
    page1 = create_page(available_from=datetime.date(1917, 12, 6), content=page1_content, shop=shop, url="test1")
    page2_content = printable_gibberish()
    page2 = create_page(available_from=datetime.date(1917, 12, 6), content=page2_content, shop=shop, url="test2")

    placeholder_name = "cms_page"
    context = {"page": page1}
    layout = view_config.get_placeholder_layout(PageLayout, placeholder_name, context=context)
    assert isinstance(layout, PageLayout)
    assert layout.get_help_text({}) == ""  # Invalid context for help text
    assert page1.title in layout.get_help_text(context)

    # Make sure layout is empty
    serialized = layout.serialize()
    assert len(serialized["rows"]) == 0
    assert serialized["name"] == placeholder_name

    # Add custom plugin to page
    layout.begin_column({"md": 8})
    plugin_text = printable_gibberish()
    layout.add_plugin("text", {"text": plugin_text})
    view_config.save_placeholder_layout(get_layout_data_key(placeholder_name, layout, context), layout)
    view_config.publish()

    c = SmartClient()
    soup = c.soup(reverse("shuup:cms_page", kwargs={"url": page1.url}))
    page_content = soup.find("div", {"class": "page-content"})
    assert page1_content in page_content.text
    assert plugin_text in page_content.text

    c = SmartClient()
    soup = c.soup(reverse("shuup:cms_page", kwargs={"url": page2.url}))
    page_content = soup.find("div", {"class": "page-content"})
    assert page2_content in page_content.text
    assert plugin_text not in page_content.text
示例#50
0
def test_basic_order_flow(with_company, with_signal):
    cache.clear()
    create_default_order_statuses()
    n_orders_pre = Order.objects.count()
    populate_if_required()
    c = SmartClient()
    product_ids = _populate_client_basket(c)

    addresses_path = reverse("shuup:checkout", kwargs={"phase": "addresses"})
    addresses_soup = c.soup(addresses_path)
    inputs = fill_address_inputs(addresses_soup, with_company=with_company)
    response = c.post(addresses_path, data=inputs)
    assert response.status_code == 302  # Should redirect forth

    # Make sure the address is initialized from storage
    # Go back to addresses right before back to methods
    c.soup(addresses_path)

    methods_path = reverse("shuup:checkout", kwargs={"phase": "methods"})
    methods_soup = c.soup(methods_path)
    assert c.post(methods_path, data=extract_form_fields(methods_soup)).status_code == 302  # Should redirect forth

    if with_signal:
        checkout_complete.connect(checkout_complete_signal, dispatch_uid="checkout_complete_signal")

    confirm_path = reverse("shuup:checkout", kwargs={"phase": "confirm"})
    confirm_soup = c.soup(confirm_path)
    Product.objects.get(pk=product_ids[0]).soft_delete()
    assert c.post(confirm_path, data=extract_form_fields(confirm_soup)).status_code == 200  # user needs to reconfirm
    data = extract_form_fields(confirm_soup)
    data['product_ids'] = ','.join(product_ids[1:])
    assert c.post(confirm_path, data=data).status_code == 302  # Should redirect forth

    n_orders_post = Order.objects.count()
    assert n_orders_post > n_orders_pre, "order was created"

    order = Order.objects.first()
    expected_ip = "127.0.0.2" if with_signal else "127.0.0.1"
    assert order.ip_address == expected_ip

    if with_signal:
        checkout_complete.disconnect(dispatch_uid="checkout_complete_signal")
示例#51
0
def test_product_detail_view():
    vc = _get_basic_view_config(view_name="ProductDetailView")
    product = factories.create_product("test", shop=factories.get_default_shop(), name="Test product name")
    product2 = factories.create_product("test2", shop=factories.get_default_shop(), name="Test product name 2")
    placeholder_name = "product_extra_1"
    context = {"product": product}
    layout = vc.get_placeholder_layout(ProductLayout, placeholder_name, context=context)
    plugin_text = printable_gibberish()
    _add_plugin_and_test_save(vc, layout, placeholder_name, context, plugin_text)

    # Also let's confirm that the plugin visibility works with smart client
    c = SmartClient()
    soup = c.soup(reverse("shuup:product", kwargs={"pk": product.id, "slug": product.slug}))
    product_details = soup.find("div", {"class": "product-basic-details"})
    assert plugin_text in product_details.text

    c = SmartClient()
    soup = c.soup(reverse("shuup:product", kwargs={"pk": product2.id, "slug": product2.slug}))
    product_details = soup.find("div", {"class": "product-basic-details"})
    assert plugin_text not in product_details.text
示例#52
0
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("shuup_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
示例#53
0
def test_invalid_files(rf, admin_user):
    lang = "en"
    import_mode = ImportMode.CREATE_UPDATE
    sku = "123"
    name = "test"

    import_path = reverse("shuup_admin:importer.import")
    process_path = reverse("shuup_admin:importer.import_process")
    tax_class = get_default_tax_class()
    product_type = get_default_product_type()
    get_default_sales_unit()

    activate("en")
    shop = get_default_shop()
    shop.staff_members.add(admin_user)
    client = SmartClient()
    client.login(username="******", password="******")
    csv_content = str.encode("sku;name\n%s;%s" % (sku, name))

    # show import view
    data = {
        "importer": "product_importer",
        "shop": shop.pk,
        "language": lang,
        "file": SimpleUploadedFile("file.csv", csv_content, content_type="text/csv")
    }
    response = client.post(import_path, data=data)
    assert response.status_code == 302
    query_string = urlparse(response["location"]).query
    query = parse_qs(query_string)

    data = { # data with missing `n`
        "importer": "product_importer",
        "shop": shop.pk,
        "language": lang,
    }
    response, soup = client.response_and_soup(process_path, data=data)
    assert response.status_code == 400
    assert "File missing." in str(soup)
def test_new_user_information_edit():
    client = SmartClient()
    get_default_shop()
    # create new user
    user_password = "******"
    user = get_user_model().objects.create_user(
        username="******",
        email="*****@*****.**",
        password=user_password,
        first_name="Niilo",
        last_name="Nyyppä",
    )

    client.login(username=user.username, password=user_password)

    # make sure all information matches in form
    customer_edit_url = reverse("shuup:customer_edit")
    soup = client.soup(customer_edit_url)

    assert soup.find(attrs={"name": "contact-email"})["value"] == user.email
    assert soup.find(attrs={"name": "contact-first_name"})["value"] == user.first_name
    assert soup.find(attrs={"name": "contact-last_name"})["value"] == user.last_name

    # Test POSTing
    form = extract_form_fields(soup)
    new_email = "*****@*****.**"
    form["contact-email"] = new_email
    form["contact-country"] = "FI"

    for prefix in ("billing", "shipping"):
        form["%s-city" % prefix] = "test-city"
        form["%s-email" % prefix] = new_email
        form["%s-street" % prefix] = "test-street"
        form["%s-country" % prefix] = "FI"

    response, soup = client.response_and_soup(customer_edit_url, form, "post")

    assert response.status_code == 302
    assert get_user_model().objects.get(pk=user.pk).email == new_email
示例#55
0
def test_gdpr_admin_anonymize(client, admin_user):
    """
    Test that admin user can anonymize contact
    """
    activate("en")
    factories.get_default_shop()
    person = factories.create_random_person("en")
    person.user = factories.create_random_user("en")
    person.save()

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

    anonymized_person = PersonContact.objects.get(id=person.id)
    assert anonymized_person.name != person.name
    assert anonymized_person.user.username != person.user.username