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 # . 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": "