| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- import os
- from playwright.sync_api import sync_playwright
- import pytest
- from asgi_csrf import asgi_csrf
- from fastapi.testclient import TestClient
- from lxml import html
- import re
- from playwright.sync_api import Page
- from app.main import app
- from app.parser import read_file
- from app.read_settings import read_settings
- @pytest.fixture
- def app_csrf():
- """Return a CSRF token."""
- return asgi_csrf(app, signing_secret=os.getenv("CSRF_SECRET_KEY"))
- def test_stripe_checkout(app_csrf, capsys):
- """This test simulates a Stripe-based checkout workflow:
- - first it POSTs a product to /checkout
- - then it triggers a checkout via POST to /stripe-checkout-session
- """
- client = TestClient(
- app,
- base_url="http://127.0.0.1:5014",
- )
- settings = read_settings("settings.toml")
- # -- add a product
- product_path = "products/g-axxi-i"
- product_headers = {
- "Accept-Language": "en-US,en;q=0.5",
- "Referer": f"http://localhost:5014/{product_path}",
- }
- product_response = client.get(f"/{product_path}", headers=product_headers)
- product_tree = html.fromstring(product_response.content)
- product_csrf_token = product_tree.xpath("//input[@name='csrftoken']")[0].get(
- "value"
- )
- product = read_file(
- settings.git_repo, product_path, settings.document_match, settings.block_types
- )
- product_data = {
- "page": "checkout",
- "operation": "add",
- "product_id": product.meta.product_id,
- "product_path": product.meta.path,
- "price": product.meta.price,
- "quantity": 1,
- "csrftoken": product_csrf_token,
- }
- client.post("/checkout", data=product_data, headers=product_headers)
- # -- make checkout order
- checkout_response_get = client.get("/checkout")
- checkout_tree = html.fromstring(checkout_response_get.content)
- # NOTE if order_id returns index out of range, it means the checkout page has no product-item in it
- # eg. the test product we use could have its inventory amount set to 0.
- order_id = checkout_tree.xpath("//input[@name='order_id']")[0].get("value")
- csrf_token = checkout_tree.xpath("//input[@name='csrftoken']")[0].get("value")
- checkout_data_good = {
- "csrftoken": csrf_token,
- "order_id": order_id,
- "weight": product.meta.weight,
- "email": "test@dark.fi",
- "first_name": "Dark",
- "last_name": "Fi",
- "address": "Somewhere",
- "address_no": "12b",
- "address_extra": "I belong",
- "postal_code": "1225AK",
- "city": "Amsterdam",
- "country": "Netherlands",
- "phone_number": "+310628551809",
- "note": "",
- }
- # NOTE: add `allow_redirect=False` to avoid FastAPI returning 404
- # instead of actual HTTP response, see
- # <https://github.com/tiangolo/fastapi/issues/790>.
- checkout_response_good = client.post(
- "/stripe-checkout-session", data=checkout_data_good, follow_redirects=False
- )
- assert checkout_response_good.status_code == 303
- # stripe checkout page
- with sync_playwright() as playwright:
- browser = playwright.chromium.launch(headless=True)
- context = browser.new_context()
- page = context.new_page()
- page.goto(checkout_response_good.headers['location'])
- page.locator("#cardNumber").fill("4242 4242 4242 4242")
- page.locator("#cardExpiry").fill("05/29")
- page.locator("#cardCvc").fill("111")
- page.locator("#billingName").fill(checkout_data_good['last_name'])
- page.locator(".SubmitButton--complete").click()
- page.goto("http://localhost:5014/checkout/success")
- page.close()
- browser.close()
- def test_nowpayments_checkout(app_csrf):
- """This test simulates a NOWPayments-based checkout workflow:
- - first it POSTs a product to /checkout
- - then it triggers a checkout via POST to /create-now-payments
- """
- client = TestClient(
- app,
- base_url="http://127.0.0.1:5014",
- )
- settings = read_settings("settings.toml")
- # -- add a product
- product_path = "products/g-axxi-i"
- product_headers = {
- "Accept-Language": "en-US,en;q=0.5",
- "Referer": f"http://localhost:5014/{product_path}",
- }
- product_response = client.get(f"/{product_path}", headers=product_headers)
- product_tree = html.fromstring(product_response.content)
- product_csrf_token = product_tree.xpath("//input[@name='csrftoken']")[0].get(
- "value"
- )
- product = read_file(
- settings.git_repo, product_path, settings.document_match, settings.block_types
- )
- product_data = {
- "page": "checkout",
- "redirect_with_items": True,
- "operation": "add",
- "product_id": product.meta.product_id,
- "product_path": product.meta.path,
- "price": product.meta.price,
- "quantity": 1,
- "csrftoken": product_csrf_token,
- }
- client.post("/checkout", data=product_data, headers=product_headers)
- # -- make checkout order
- checkout_response_get = client.get("/checkout")
- checkout_tree = html.fromstring(checkout_response_get.content)
- order_id = checkout_tree.xpath("//input[@name='order_id']")[0].get("value")
- csrf_token = checkout_tree.xpath("//input[@name='csrftoken']")[0].get("value")
- checkout_data_good = {
- "csrftoken": csrf_token,
- "order_id": order_id,
- "weight": product.meta.weight,
- "email": "test@dark.fi",
- "first_name": "<script onerror='alert(\\'hax\\')'>Dark",
- "last_name": "Fi",
- "address": "Somewhere",
- "address_no": "12b",
- "address_extra": "I belong",
- "postal_code": "1225AK",
- "city": "Amsterdam",
- "country": "Netherlands",
- "phone_number": "",
- "note": "eef+eifenf\n\neineienfeifne+eifenife\neiufenf\n\n...",
- }
- # NOTE: add `allow_redirect=False` to avoid FastAPI returning 404
- # instead of actual HTTP response, see
- # <https://github.com/tiangolo/fastapi/issues/790>.
- checkout_response_good = client.post(
- "/create-now-payments", data=checkout_data_good, follow_redirects=False
- )
- assert checkout_response_good.status_code == 303
|