From cc9d9dda5ff25cc24f6dbe15ab8c96667fac7df1 Mon Sep 17 00:00:00 2001 From: Ben Stull Date: Wed, 10 Jun 2026 22:37:10 -0700 Subject: [PATCH] =?UTF-8?q?test(slice-3):=20INV-1=20whole-flow=20bootstrap?= =?UTF-8?q?=20test=20=E2=80=94=20empty=20DB=20to=20admin=20answer=20(?= =?UTF-8?q?=C2=A76.8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- backend/tests/test_bootstrap.py | 42 +++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 backend/tests/test_bootstrap.py diff --git a/backend/tests/test_bootstrap.py b/backend/tests/test_bootstrap.py new file mode 100644 index 0000000..19ffac6 --- /dev/null +++ b/backend/tests/test_bootstrap.py @@ -0,0 +1,42 @@ +"""INV-1's enforcement (SD-0001 §6.8): from an empty database, one test walks the whole +flow — request-code -> verify -> create-storefront -> /me — asserting no step needed +seeded state. Migration idempotence (the second INV-1 test) lives in test_migrations.py.""" +import re + +from fastapi.testclient import TestClient + +from app.main import create_app + + +def test_inv_1_bootstrap_whole_flow_from_empty(fresh_db_url): + # fresh_db_url is a brand-new empty database; create_app() self-migrates (INV-7). + with TestClient(create_app(database_url=fresh_db_url)) as client: + # a fresh deployment serves healthz green before any row exists + assert client.get("/healthz").json() == {"status": "ok"} + + # PUC-2: first visitor requests a code; it reaches them via the dev channel + assert client.post( + "/api/auth/request-code", json={"email": "first@example.com"} + ).status_code == 204 + code = re.search(r"\b(\d{6})\b", client.app.state.mailer.outbox[-1].body).group(1) + + # verify creates account #1 — the first row, through the product alone + verified = client.post( + "/api/auth/verify", json={"email": "first@example.com", "code": code} + ) + assert verified.status_code == 200 + assert verified.json()["created"] is True + assert verified.json()["storefront"] is None # -> create-storefront (PUC-5) + + # PUC-4: create the storefront (blank name -> generated default) + created = client.post("/api/storefronts", json={}) + assert created.status_code == 201 + assert created.json()["name"] == "first's storefront" + + # PUC-6/PUC-8: the admin answer — storefront + email from /me alone + me = client.get("/api/auth/me") + assert me.status_code == 200 + assert me.json() == { + "account": {"email": "first@example.com"}, + "storefront": created.json(), + }