import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { createDbMock, createDbMockState, dbMockStateFromGlobal, type DbMockRow } from "../helpers/db-mock"; vi.mock("@/db", async () => { const { createDbMock, createDbMockState } = await import("../helpers/db-mock"); const state = createDbMockState(); (globalThis as unknown as { __dbMockState: unknown }).__dbMockState = state; return { db: createDbMock(state) }; }); // import หลัง vi.mock — @/db ถูกแทนก่อน import { POST } from "@/app/api/note/auth/session/route"; import { issueDocverToken } from "@/lib/docver-token"; import { ecourtExternalId } from "@/lib/ecourt-fid"; import { __clearStagedDocsForTest, putStagedDoc } from "@/lib/staged-docs"; // PLAN-STAGED.md D5 — ลิงก์ fid-only (body มีแค่ t=): 4 branch ของการเช็ค staging // ตั้งแต่ตอนแลก token · ใช้ hasStagedDoc จริงของ lib/staged-docs (ไม่ยืด TTL) const URL_ = "http://localhost/docedit/api/note/auth/session"; const FID = "F-STAGED-1"; const FILE_ID = "0d7e6a52-9a71-4d40-bd1c-b2e1a44ab133"; const PDF_BYTES = Buffer.from("%PDF-1.7 เอกสาร staging"); function stagedRow(pdfUrl: string): DbMockRow { return { id: FILE_ID, title: "เอกสารทดสอบ", pdfUrl, externalId: ecourtExternalId(FID), typeId: null }; } async function postSession(): Promise { const token = issueDocverToken( { userid: "u1", username: "ผู้ทดสอบ", fid: FID, template: null }, "test-secret", 300, "login", ); return POST( new Request(URL_, { method: "POST", body: JSON.stringify({ t: token }), }), ); } beforeEach(() => { __clearStagedDocsForTest(); const state = dbMockStateFromGlobal(); state.rows = []; state.rowsBySelect = []; state.selectCalls = 0; state.insertAttempts = []; state.updates = []; state.insertErrCode = null; vi.stubEnv("DOCVER_TOKEN_SECRET", "test-secret"); vi.stubEnv("FID_HASH_PEPPER", "test-pepper"); }); afterEach(() => { vi.unstubAllEnvs(); }); describe("D5 — ลิงก์ fid-only (ไม่มี fileUrl)", () => { it("เจอ row staged + hasStagedDoc = true → ได้ fileId ไม่มี fileError", async () => { dbMockStateFromGlobal().rows = [stagedRow(`staged:${FILE_ID}.pdf`)]; putStagedDoc(FILE_ID, PDF_BYTES, "pdf"); const res = await postSession(); expect(res.status).toBe(200); const body = (await res.json()) as { access_token?: string; fileId?: string; fileError?: string }; expect(body.fileId).toBe(FILE_ID); expect(body.fileError).toBeUndefined(); expect(typeof body.access_token).toBe("string"); }); it("เจอ row staged + hasStagedDoc = false (restart/TTL/evict) → fileError พ้นช่วงจัดเตรียม", async () => { dbMockStateFromGlobal().rows = [stagedRow(`staged:${FILE_ID}.pdf`)]; // ไม่ put — staging ว่าง const res = await postSession(); expect(res.status).toBe(200); const body = (await res.json()) as { access_token?: string; fileId?: string; fileError?: string }; expect(body.fileId).toBeUndefined(); expect(body.fileError).toBe("เอกสารพ้นช่วงจัดเตรียม — กลับ e-Court กดลิงก์ใหม่"); // ผู้ใช้ยังได้ token ตามปกติ expect(typeof body.access_token).toBe("string"); }); it("เจอ row ที่ pdf_url เป็น URL ปกติ (เอกสาร N8 แบบเดิม) → ได้ fileId", async () => { dbMockStateFromGlobal().rows = [stagedRow("https://admincourt.go.th/doc.pdf")]; const res = await postSession(); expect(res.status).toBe(200); const body = (await res.json()) as { fileId?: string; fileError?: string }; expect(body.fileId).toBe(FILE_ID); expect(body.fileError).toBeUndefined(); }); it("ไม่เจอ row → fileError ยังไม่ถูกส่งเข้าระบบ (token ออกตามปกติ)", async () => { dbMockStateFromGlobal().rows = []; const res = await postSession(); expect(res.status).toBe(200); const body = (await res.json()) as { fileId?: string; fileError?: string }; expect(body.fileId).toBeUndefined(); expect(body.fileError).toBe("เอกสารยังไม่ถูกส่งเข้าระบบ — กลับ e-Court กดลิงก์ใหม่"); }); });