예제 #1
0
def test_extender_renders_main_menu(rf):
    get_default_shop()

    with override_provides("front_menu_extender", ["wshop_tests.xtheme.test_extenders:TestExtender"]):
        c = SmartClient()
        soup = c.soup(reverse("wshop:index"))
        link_texts = [a.text for a in soup.findAll("a")]
        assert "Test Link to Front" in link_texts
예제 #2
0
def test_theme_without_default_template_dir():
    with override_current_theme_class(WshopTestingTheme, get_default_shop()):
        c = SmartClient()
        soup = c.soup(reverse("wshop:index"))
        assert "Simple base for themes to use" not in soup
        assert "Welcome to test Wshop!" in soup.find("div", {
            "class": "page-content"
        }).text
예제 #3
0
def test_theme_with_default_template_dir():
    get_default_shop()
    with override_current_theme_class(WshopTestingThemeWithCustomBase,
                                      get_default_shop()):
        c = SmartClient()
        soup = c.soup(reverse("wshop:index"))
        assert "Simple base for themes to use" in soup.find("h1").text
        assert "Welcome to test Wshop!" in soup.find("h1").text
예제 #4
0
def test_basic_order_flow(with_company):
    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("wshop: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("wshop: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("wshop: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"
예제 #5
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
예제 #6
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("wshop: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 response.status_code == 404
        response = client.post(company_edit_url, data)
        assert response.status_code == 404
예제 #7
0
def test_customer_edit_redirects_to_login_if_not_logged_in():
    get_default_shop()  # Front middleware needs a Shop to exists
    urls = ["wshop:customer_edit", "wshop: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
예제 #8
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("wshop:checkout", kwargs={"phase": "addresses"})
    methods_path = reverse("wshop:checkout", kwargs={"phase": "methods"})
    confirm_path = reverse("wshop: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['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"
예제 #9
0
def test_checkout_empty_basket(rf):
    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("wshop: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()
예제 #10
0
def test_order_configuration(rf, admin_user):
    shop = get_default_shop()
    # clear shop configurations
    ConfigurationItem.objects.filter(shop=shop).delete()
    client = SmartClient()
    client.login(username="******", password="******")

    url = reverse("wshop_admin:shop.edit", kwargs={"pk": shop.pk})
    response, soup = client.response_and_soup(url)
    assert response.status_code == 200

    length_form_field = "order_configuration-%s" % consts.ORDER_REFERENCE_NUMBER_LENGTH_FIELD
    prefix_form_field = "order_configuration-%s" % consts.ORDER_REFERENCE_NUMBER_PREFIX_FIELD

    length_field = soup.find("input",
                             attrs={"id": "id_%s" % length_form_field})
    prefix_field = soup.find("input",
                             attrs={"id": "id_%s" % prefix_form_field})

    assert length_field
    assert prefix_field

    assert length_field["value"] == str(
        settings.WSHOP_REFERENCE_NUMBER_LENGTH
    )  # default value because nothing set yet
    assert "value" not in prefix_field  # field empty

    data = get_base_form_data(shop)
    data[length_form_field] = "18"
    data[prefix_form_field] = "123"
    response, soup = client.response_and_soup(url, data=data, method="post")
    assert "is required" not in soup.prettify()
    assert response.status_code == 302  # redirect after success

    assert configuration.get(shop,
                             consts.ORDER_REFERENCE_NUMBER_LENGTH_FIELD) == 18

    # set global system settings
    # TODO: Enable this before 1.3
    # set_reference_method(rf, admin_user, OrderReferenceNumberMethod.RUNNING)
    data[length_form_field] = "19"
    data[prefix_form_field] = "0"
    client.post(url, data=data)

    assert configuration.get(shop,
                             consts.ORDER_REFERENCE_NUMBER_LENGTH_FIELD) == 19
    assert not configuration.get(shop,
                                 consts.ORDER_REFERENCE_NUMBER_PREFIX_FIELD
                                 )  # None because disabled line 104, else 0
예제 #11
0
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("wshop: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
예제 #12
0
def test_get_telemetry_data_after_login(rf, admin_user):
    get_default_shop()
    # create users to ensure correct admin is found
    UserFactory()
    UserFactory()

    data = json.loads(get_telemetry_data(rf.get("/")))
    assert data.get("admin_user") == admin_user.email
    assert not data.get("last_login")

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

    data = json.loads(get_telemetry_data(rf.get("/")))
    assert data.get("admin_user") == admin_user.email
    last_login = data.get("last_login", None)
    assert last_login

    last_login_datetime = datetime.datetime.strptime(last_login,
                                                     "%Y-%m-%dT%H:%M:%S.%fZ")
    today = datetime.datetime.now()
    assert last_login_datetime.year == today.year
    assert last_login_datetime.month == today.month
    assert last_login_datetime.day == today.day
예제 #13
0
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("wshop: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
예제 #14
0
def test_company_still_linked_if_customer_contact_edited(regular_user):
    get_default_shop()
    person = get_person_contact(regular_user)
    assert not get_company_contact(regular_user)

    company = CompanyContact()
    company.save()
    company.members.add(person)
    assert get_company_contact(regular_user)

    client = SmartClient()
    client.login(username=REGULAR_USER_USERNAME,
                 password=REGULAR_USER_PASSWORD)
    customer_edit_url = reverse("wshop:customer_edit")
    soup = client.soup(customer_edit_url)

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

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

    assert response.status_code == 302
    assert get_company_contact(regular_user)
def test_notify_on_company_created(regular_user, allow_company_registration):
    if "wshop.front.apps.customer_information" not in settings.INSTALLED_APPS:
        pytest.skip(
            "wshop.front.apps.customer_information required in installed apps")
    if "wshop.notify" not in settings.INSTALLED_APPS:
        pytest.skip("wshop.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("wshop: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 response.status_code == 404
        assert Notification.objects.filter(
            identifier="company_created").count() == 0
예제 #16
0
def test_company_tax_number_limitations(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)

    if allow_company_registration:
        client = SmartClient()
        client.login(username=REGULAR_USER_USERNAME,
                     password=REGULAR_USER_PASSWORD)
        company_edit_url = reverse("wshop: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)

        # re-save should work properly
        response, soup = client.response_and_soup(company_edit_url, data,
                                                  "post")
        assert response.status_code == 302
        client.logout()

        # another company tries to use same tax number
        new_user_password = "******"
        new_user_username = "******"
        user = User.objects.create_user(new_user_username, "*****@*****.**",
                                        new_user_password)
        person = get_person_contact(user=user)
        assert not get_company_contact(user)

        client = SmartClient()
        client.login(username=new_user_username, password=new_user_password)
        company_edit_url = reverse("wshop: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 == 200  # this time around, nothing was saved.
        assert not get_company_contact(user)  # company contact yet

        # change tax number
        data["contact-tax_number"] = "111111"
        response, soup = client.response_and_soup(company_edit_url, data,
                                                  "post")
        assert response.status_code == 302  # this time around, nothing was saved.
        assert get_company_contact(user)  # company contact yet

        # go back to normal and try to get tax number approved
        data["contact-tax_number"] = "111110"
        response, soup = client.response_and_soup(company_edit_url, data,
                                                  "post")
        assert response.status_code == 200  # this time around, nothing was saved.
    else:
        client = SmartClient()
        client.login(username=REGULAR_USER_USERNAME,
                     password=REGULAR_USER_PASSWORD)
        company_edit_url = reverse("wshop:company_edit")
        response = client.get(company_edit_url)
        assert response.status_code == 404
예제 #17
0
def test_order_flow_with_phases(get_shipping_method, shipping_data,
                                get_payment_method, payment_data):
    cache.clear()
    create_default_order_statuses()
    populate_if_required()
    c = SmartClient()
    _populate_client_basket(c)

    # Create methods
    shipping_method = get_shipping_method()
    payment_method = get_payment_method()

    # Resolve paths
    addresses_path = reverse("wshop:checkout", kwargs={"phase": "addresses"})
    methods_path = reverse("wshop:checkout", kwargs={"phase": "methods"})
    shipping_path = reverse("wshop:checkout", kwargs={"phase": "shipping"})
    payment_path = reverse("wshop:checkout", kwargs={"phase": "payment"})
    confirm_path = reverse("wshop:checkout", kwargs={"phase": "confirm"})

    # Phase: Addresses
    addresses_soup = c.soup(addresses_path)
    inputs = fill_address_inputs(addresses_soup, with_company=False)
    response = c.post(addresses_path, data=inputs)
    assert response.status_code == 302, "Address phase should redirect forth to methods"

    # Phase: Methods
    response = c.get(methods_path)
    assert response.status_code == 200
    response = c.post(methods_path,
                      data={
                          "shipping_method": shipping_method.pk,
                          "payment_method": payment_method.pk
                      })
    assert response.status_code == 302, "Methods phase should redirect forth"

    if isinstance(shipping_method.carrier, CarrierWithCheckoutPhase):
        # Phase: Shipping
        response = c.get(shipping_path)
        assert response.status_code == 200
        response = c.post(shipping_path, data=shipping_data)
        assert response.status_code == 302, "Payments phase should redirect forth"

    if isinstance(payment_method.payment_processor, PaymentWithCheckoutPhase):
        # Phase: payment
        response = c.get(payment_path)
        assert response.status_code == 200
        response = c.post(payment_path, data=payment_data)
        assert response.status_code == 302, "Payments phase should redirect forth"

    # Phase: Confirm
    assert Order.objects.count() == 0
    confirm_soup = c.soup(confirm_path)

    response = c.post(confirm_path, data=extract_form_fields(confirm_soup))
    assert response.status_code == 302, "Confirm should redirect forth"

    order = Order.objects.first()

    if isinstance(shipping_method.carrier, CarrierWithCheckoutPhase):
        assert order.shipping_data.get("input_value") == "20540"

    if isinstance(payment_method.payment_processor, PaymentWithCheckoutPhase):
        assert order.payment_data.get("input_value")
        assert order.payment_status == PaymentStatus.NOT_PAID
        # Resolve order specific paths (payment and complete)
        process_payment_path = reverse("wshop:order_process_payment",
                                       kwargs={
                                           "pk": order.pk,
                                           "key": order.key
                                       })
        process_payment_return_path = reverse(
            "wshop:order_process_payment_return",
            kwargs={
                "pk": order.pk,
                "key": order.key
            })
        order_complete_path = reverse("wshop:order_complete",
                                      kwargs={
                                          "pk": order.pk,
                                          "key": order.key
                                      })

        # Check confirm redirection to payment page
        assert response.url.endswith(process_payment_path), (
            "Confirm should have redirected to payment page")

        # Visit payment page
        response = c.get(process_payment_path)
        assert response.status_code == 302, "Payment page should redirect forth"
        assert response.url.endswith(process_payment_return_path)

        # Check payment return
        response = c.get(process_payment_return_path)
        assert response.status_code == 302, "Payment return should redirect forth"
        assert response.url.endswith(order_complete_path)

        # Check payment status has changed to DEFERRED
        order = Order.objects.get(pk=order.pk)  # reload
        assert order.payment_status == PaymentStatus.DEFERRED