import { test, before, after } from "node:test"; import assert from "node:assert/strict"; import { pool } from "../db/pool.ts"; import { createApp } from "../index.ts"; import { resetDb, seedMinimal } from "./helpers.ts"; import type { Server } from "node:http"; let ids: Awaited>; let server: Server; let base: string; before(async () => { await resetDb(); ids = await seedMinimal(); server = createApp().listen(0); const addr = server.address() as { port: number }; base = `http://127.0.0.1:${addr.port}`; }); after(async () => { server.close(); await pool.end(); }); function req(path: string, init: RequestInit = {}, userId = ids.ownerUserId) { return fetch(`${base}${path}`, { ...init, headers: { "content-type": "application/json", authorization: `Bearer ${userId}`, ...(init.headers || {}), }, }); } test("crea una clienta y guarda el teléfono normalizado", async () => { const r = await req("/api/clients", { method: "POST", body: JSON.stringify({ name: "Sofía Ramírez", phone: "(55) 4444-3333" }), }); assert.equal(r.status, 201); const { client } = await r.json(); assert.equal(client.phone, "(55) 4444-3333", "conserva lo que tecleó la persona"); assert.equal(client.phone_e164, "+525544443333"); assert.equal(client.contactable, true); }); test("el segundo alta con el mismo número devuelve 409 con la ficha existente", async () => { const r = await req("/api/clients", { method: "POST", body: JSON.stringify({ name: "Sofia R.", phone: "+52 55 4444 3333" }), }); assert.equal(r.status, 409); const body = await r.json(); assert.match(body.error, /ya existe/i); assert.equal(body.existing.name, "Sofía Ramírez"); assert.equal(body.existing.phone_e164, "+525544443333"); }); test("permite dar de alta sin teléfono, marcada como no contactable", async () => { const r = await req("/api/clients", { method: "POST", body: JSON.stringify({ name: "Clienta de mostrador" }), }); assert.equal(r.status, 201); const { client } = await r.json(); assert.equal(client.phone_e164, null); assert.equal(client.contactable, false); }); test("la búsqueda encuentra por teléfono sin formato", async () => { const r = await req("/api/clients?q=5544443333"); const { clients } = await r.json(); assert.equal(clients.length, 1); assert.equal(clients[0].name, "Sofía Ramírez"); }); test("el alta deja rastro en audit_log", async () => { const { rows } = await pool.query( `SELECT action, actor_user_id FROM audit_log WHERE entity = 'clients' AND action = 'create' ORDER BY id DESC LIMIT 1` ); assert.equal(rows[0].action, "create"); assert.equal(rows[0].actor_user_id, ids.ownerUserId); }); test("no se ven clientas de otro negocio", async () => { const other = await pool.query( `INSERT INTO businesses (name, slug, working_hours) VALUES ('Otro Spa','otro','{}'::jsonb) RETURNING id` ); const otherUser = await pool.query( `INSERT INTO users (business_id, email, password, name, role) VALUES ($1,'otro@otro.mx','x','Otro','owner') RETURNING id`, [other.rows[0].id] ); const r = await req("/api/clients", {}, otherUser.rows[0].id); const { clients } = await r.json(); assert.equal(clients.length, 0); });