Merge branch 'worktree-visual-test-overhaul' — add J-N tests, fix WAITLIST_MODE

This commit is contained in:
Deeman
2026-02-23 21:08:59 +01:00
4 changed files with 42 additions and 2 deletions

View File

@@ -245,16 +245,45 @@ def sign_payload(payload_bytes: bytes, secret: str = "whsec_test_secret") -> str
_VISUAL_PORT = 5111 _VISUAL_PORT = 5111
async def _seed_visual_data(conn):
"""Seed a supplier + feature flags for E2E billing/dashboard tests."""
await conn.execute(
"INSERT INTO users (id, email, created_at)"
" VALUES (999, 'supplier@test.com', datetime('now'))"
)
await conn.execute(
"INSERT INTO suppliers"
" (id, name, slug, tier, claimed_by, claimed_at,"
" country_code, region, category, credit_balance,"
" monthly_credits, contact_name, contact_email, created_at)"
" VALUES (1, 'Test Supplier GmbH', 'test-supplier', 'pro', 999,"
" datetime('now'), 'DE', 'Europe', 'construction', 50,"
" 10, 'Test User', 'supplier@test.com', datetime('now'))"
)
for flag in ("supplier_signup", "markets", "payments",
"planner_export", "lead_unlock"):
await conn.execute(
"INSERT OR REPLACE INTO feature_flags (name, enabled)"
" VALUES (?, 1)", (flag,)
)
await conn.commit()
def _run_visual_server(ready_event): def _run_visual_server(ready_event):
"""Run a Quart dev server in a subprocess for visual/E2E tests. """Run a Quart dev server in a subprocess for visual/E2E tests.
Forces RESEND_API_KEY="" so no real emails are sent. Forces RESEND_API_KEY="" so no real emails are sent.
Forces WAITLIST_MODE=false so feature pages render (not waitlist templates).
Runs migrations in-process to build the full schema (including FTS tables). Runs migrations in-process to build the full schema (including FTS tables).
""" """
import asyncio import asyncio
import os import os
os.environ["RESEND_API_KEY"] = "" os.environ["RESEND_API_KEY"] = ""
os.environ["WAITLIST_MODE"] = "false"
# Config class attributes are evaluated at import time (before fork),
# so we must also patch the live config object directly.
core.config.WAITLIST_MODE = False
async def _serve(): async def _serve():
# Build schema DDL in-process (FTS5 virtual tables need this) # Build schema DDL in-process (FTS5 virtual tables need this)
@@ -276,7 +305,16 @@ def _run_visual_server(ready_event):
conn.row_factory = aiosqlite.Row conn.row_factory = aiosqlite.Row
await conn.execute("PRAGMA foreign_keys=ON") await conn.execute("PRAGMA foreign_keys=ON")
await conn.executescript(schema_ddl) await conn.executescript(schema_ddl)
await conn.commit() # Ensure feature_flags table exists (may be missed if an FTS5
# CREATE VIRTUAL TABLE causes executescript to stop early)
await conn.execute(
"CREATE TABLE IF NOT EXISTS feature_flags"
" (name TEXT PRIMARY KEY, enabled INTEGER NOT NULL DEFAULT 0,"
" description TEXT,"
" updated_at TEXT DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ','now')))"
)
# Seed data needed by E2E tests (supplier dashboard, billing, etc.)
await _seed_visual_data(conn)
core._db = conn core._db = conn
# Patch init_db/close_db where they're USED (app.py imports them # Patch init_db/close_db where they're USED (app.py imports them
@@ -285,7 +323,9 @@ def _run_visual_server(ready_event):
# Patches must stay active through run_task() because before_serving # Patches must stay active through run_task() because before_serving
# hooks call init_db() which would replace our in-memory DB. # hooks call init_db() which would replace our in-memory DB.
with patch("padelnomics.app.init_db", new_callable=AsyncMock), \ with patch("padelnomics.app.init_db", new_callable=AsyncMock), \
patch("padelnomics.app.close_db", new_callable=AsyncMock): patch("padelnomics.app.close_db", new_callable=AsyncMock), \
patch("padelnomics.app.open_analytics_db"), \
patch("padelnomics.app.close_analytics_db"):
app = create_app() app = create_app()
app.config["TESTING"] = True app.config["TESTING"] = True
ready_event.set() ready_event.set()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 722 KiB

After

Width:  |  Height:  |  Size: 721 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 72 KiB