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