const BASE = "http://localhost:5173/api"; let pass = 0, fail = 0; async function req(method, path, body, token) { const headers = { "Content-Type": "application/json" }; if (token) headers.authorization = `Bearer ${token}`; const res = await fetch(`${BASE}${path}`, { method, headers, body: body ? JSON.stringify(body) : undefined }); const text = await res.text(); let json; try { json = JSON.parse(text); } catch { json = text; } return { status: res.status, json }; } function check(name, cond, extra = "") { if (cond) { pass++; console.log(` ✓ ${name}`); } else { fail++; console.log(` ✗ ${name} ${extra}`); } } // Admin login const { json: aLogin } = await req("POST", "/auth/login", { email: "admin@agendamax.demo", password: "demo1234" }); check("admin login", aLogin.user?.role === "admin" && aLogin.token, JSON.stringify(aLogin).slice(0, 100)); const A = aLogin.token; // Existing data preserved (resilient count — other test suites may add appointments) const { json: list } = await req("GET", "/admin/businesses", null, A); check("admin lists businesses", list.businesses?.length >= 1, `got ${list.businesses?.length}`); check("biz1 data intact", list.businesses[0]?.stats?.appointments >= 100, `appts=${list.businesses[0]?.stats?.appointments}`); // Platform overview const { json: ov } = await req("GET", "/admin/overview", null, A); check("platform overview", ov.businesses >= 1 && ov.total_appointments >= 100, JSON.stringify(ov)); // Templates const { json: tpls } = await req("GET", "/admin/templates", null, A); check("templates list", tpls.templates?.length === 4, `got ${tpls.templates?.length}`); // Create a barberia business with template + owner const { json: created, status: cStatus } = await req("POST", "/admin/businesses", { name: "Barbería Test", industry: "Barbería", template: "barberia", ownerName: "Test Owner", ownerEmail: "owner.test@barberia.mx", ownerPassword: "demo1234", }, A); check("create business + template seed", cStatus === 201 && !!created.business?.id, JSON.stringify(created).slice(0, 150)); check("barberia seeded services", created.seeded?.services === 8, `got ${created.seeded?.services}`); const newBizId = created.business?.id; // Owner of new business can log in and see only their data (tenant isolation) const { json: oLogin } = await req("POST", "/auth/login", { email: "owner.test@barberia.mx", password: "demo1234" }); check("new owner login", oLogin.user?.role === "owner" && oLogin.user?.business_id === newBizId); const OT = oLogin.token; const { json: oEmps } = await req("GET", "/employees", null, OT); check("tenant isolation: new owner sees only their employees", oEmps.employees?.length === 4, `got ${oEmps.employees?.length}`); const { json: oBiz } = await req("GET", "/business", null, OT); check("new owner business name", oBiz.business?.name === "Barbería Test"); // Owner1 still sees only Lumière (isolation the other way) const { json: owner1 } = await req("POST", "/auth/login", { email: "owner@agendamax.demo", password: "demo1234" }); const { json: o1Emps } = await req("GET", "/employees", null, owner1.token); check("owner1 isolation: still 6 employees", o1Emps.employees?.length === 6, `got ${o1Emps.employees?.length}`); // Admin cannot be blocked, but owner cannot access admin const { status: forb } = await req("GET", "/admin/businesses", null, owner1.token); check("owner blocked from admin (403)", forb === 403); // Update business (plan/status) const { json: upd } = await req("PATCH", `/admin/businesses/${newBizId}`, { plan: "pro", status: "suspended" }, A); check("update business plan/status", upd.business?.plan === "pro" && upd.business?.status === "suspended"); // Reset demo const { json: reset } = await req("POST", `/admin/businesses/${newBizId}/reset-demo`, { template: "blank" }, A); check("reset to blank template", reset.business?.template === "blank" && reset.stats?.services === 0, JSON.stringify(reset.stats)); // Delete business const { status: del } = await req("DELETE", `/admin/businesses/${newBizId}`, null, A); check("delete business", del === 200); const { json: list2 } = await req("GET", "/admin/businesses", null, A); check("business removed", list2.businesses?.length === 1, `got ${list2.businesses?.length}`); // Cascade: owner.test user should be gone const { status: gone } = await req("POST", "/auth/login", { email: "owner.test@barberia.mx", password: "demo1234" }); check("deleted business users removed", gone === 401); console.log(`\n${pass}/${pass + fail} passed${fail ? `, ${fail} FAILED` : ""}`); process.exit(fail ? 1 : 0);