import { describe, it, expect, beforeEach, afterEach } from "vitest"; import fs from "fs"; import os from "os"; import path from "path"; import { NasDocumentManager } from "../services/nas-financials-manager"; /** * Generic NAS archival manager backing both the invoices NAS (NAS_INVOICES) and * the orders NAS (NAS_ORDERS). Uses an isolated temp dir via the constructor * seam so it is deterministic and passes even where the real NAS (Z:) is not * mounted. Layout: {base}/Vydané/YYYY/MM/.pdf — diacritics preserved. */ describe("NasDocumentManager issued-PDF round-trip", () => { let tmpBase: string; let nas: NasDocumentManager; beforeEach(() => { tmpBase = fs.mkdtempSync(path.join(os.tmpdir(), "nas-doc-")); nas = new NasDocumentManager(tmpBase); }); afterEach(() => { fs.rmSync(tmpBase, { recursive: true, force: true }); }); it("saves an issued PDF under Vydané/YYYY/MM/.pdf and reads it back", () => { const buf = Buffer.from("%PDF-1.4 fake order pdf bytes", "utf8"); const rel = nas.saveIssuedPdf("25P0001", 2026, 6, buf); expect(rel).toBe("Vydané/2026/06/25P0001.pdf"); const onDisk = path.join(tmpBase, "Vydané", "2026", "06", "25P0001.pdf"); expect(fs.existsSync(onDisk)).toBe(true); const read = nas.readIssued(rel!); expect(read).not.toBeNull(); expect(read!.fileName).toBe("25P0001.pdf"); expect(read!.data.equals(buf)).toBe(true); }); it("cleanIssued removes a previously-saved PDF across year/month folders", () => { const buf = Buffer.from("pdf", "utf8"); const rel = nas.saveIssuedPdf("25P0002", 2026, 6, buf); expect(nas.readIssued(rel!)).not.toBeNull(); nas.cleanIssued("25P0002"); expect(nas.readIssued(rel!)).toBeNull(); }); it("an unconfigured (empty basePath) manager is not configured and saves nothing", () => { const blank = new NasDocumentManager(""); expect(blank.isConfigured()).toBe(false); expect( blank.saveIssuedPdf("25P0003", 2026, 6, Buffer.from("x")), ).toBeNull(); }); it("re-saving the same number OVERWRITES in place — never a _1 duplicate", () => { const first = nas.saveIssuedPdf("25P0004", 2026, 6, Buffer.from("v1")); const second = nas.saveIssuedPdf("25P0004", 2026, 6, Buffer.from("v2")); // Same canonical path both times, newest content wins. expect(second).toBe(first); const dir = path.join(tmpBase, "Vydané", "2026", "06"); expect(fs.readdirSync(dir)).toEqual(["25P0004.pdf"]); expect(nas.readIssued(second!)!.data.toString()).toBe("v2"); }); it("cleanIssued also sweeps stale _N duplicates left by the old racy save", () => { nas.saveIssuedPdf("25P0005", 2026, 6, Buffer.from("canonical")); // Simulate duplicates the pre-fix uniquePath save created during races. const dir = path.join(tmpBase, "Vydané", "2026", "06"); fs.writeFileSync(path.join(dir, "25P0005_1.pdf"), "stale"); fs.writeFileSync(path.join(dir, "25P0005_2.pdf"), "stale"); // A DIFFERENT number must not be touched by the suffix match. nas.saveIssuedPdf("25P0006", 2026, 6, Buffer.from("other")); nas.cleanIssued("25P0005"); expect(fs.readdirSync(dir).sort()).toEqual(["25P0006.pdf"]); }); });