| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- // ---------------------------------------------------------------------------
- // Ordner: lib
- // Datei: storage.test.js
- // Relativer Pfad: lib/storage.test.js
- // ---------------------------------------------------------------------------
- // tests/lib/storage.test.js
- import {
- describe,
- it,
- expect,
- beforeAll,
- afterAll,
- beforeEach,
- afterEach,
- vi,
- } from "vitest";
- import fs from "node:fs/promises";
- import os from "node:os";
- import path from "node:path";
- import {
- listBranches,
- listYears,
- listMonths,
- listDays,
- listFiles,
- __clearStorageCacheForTests,
- } from "@/lib/storage";
- let tmpRoot;
- beforeAll(async () => {
- // Create a unique temporary directory for the tests
- tmpRoot = await fs.mkdtemp(path.join(os.tmpdir(), "storage-test-"));
- // Point NAS_ROOT_PATH to our temp directory
- process.env.NAS_ROOT_PATH = tmpRoot;
- // Create a fake directory tree:
- // tmpRoot/NL01/2024/10/23/test.pdf
- await fs.mkdir(path.join(tmpRoot, "NL01", "2024", "10", "23"), {
- recursive: true,
- });
- await fs.writeFile(
- path.join(tmpRoot, "NL01", "2024", "10", "23", "test.pdf"),
- "dummy-pdf-content"
- );
- // Add snapshot folder which should be ignored
- await fs.mkdir(path.join(tmpRoot, "@Recently-Snapshot"));
- });
- afterAll(async () => {
- // Clean up the temporary directory after tests
- await fs.rm(tmpRoot, { recursive: true, force: true });
- });
- beforeEach(() => {
- // RHL-006:
- // Storage functions now use a TTL cache. We clear it between tests to ensure
- // each test sees filesystem changes deterministically.
- __clearStorageCacheForTests();
- });
- afterEach(() => {
- // Safety: if a test enables fake timers, always restore real timers afterwards
- // to avoid affecting unrelated tests.
- vi.useRealTimers();
- });
- describe("storage: listBranches", () => {
- it("returns branch names and filters snapshots", async () => {
- const branches = await listBranches();
- expect(branches).toEqual(["NL01"]);
- });
- });
- describe("storage: year/month/day helpers", () => {
- it("returns years for a branch", async () => {
- const years = await listYears("NL01");
- expect(years).toEqual(["2024"]);
- });
- it("returns months for a branch/year", async () => {
- const months = await listMonths("NL01", "2024");
- expect(months).toEqual(["10"]);
- });
- it("returns days for a branch/year/month", async () => {
- const days = await listDays("NL01", "2024", "10");
- expect(days).toEqual(["23"]);
- });
- });
- describe("storage: listFiles", () => {
- it("returns PDF files with relativePath", async () => {
- const files = await listFiles("NL01", "2024", "10", "23");
- expect(files).toEqual([
- {
- name: "test.pdf",
- relativePath: "NL01/2024/10/23/test.pdf",
- },
- ]);
- });
- });
- describe("storage: micro-cache (RHL-006)", () => {
- it("keeps results stable within TTL and refreshes after TTL expires", async () => {
- // Use a dedicated folder so this test doesn't interfere with other fixtures.
- const dayDir = path.join(tmpRoot, "NL01", "2024", "10", "24");
- await fs.mkdir(dayDir, { recursive: true });
- // Initial file
- await fs.writeFile(path.join(dayDir, "a.pdf"), "a");
- // Fake timers allow us to advance time without real waiting.
- vi.useFakeTimers();
- const t0 = new Date("2025-01-01T00:00:00.000Z");
- vi.setSystemTime(t0);
- // First call populates the cache (TTL for files: 15s)
- const first = await listFiles("NL01", "2024", "10", "24");
- expect(first.map((f) => f.name)).toEqual(["a.pdf"]);
- // Add a new file while the cache is still valid.
- await fs.writeFile(path.join(dayDir, "b.pdf"), "b");
- // Second call should still return the cached result (b.pdf not visible yet).
- const second = await listFiles("NL01", "2024", "10", "24");
- expect(second.map((f) => f.name)).toEqual(["a.pdf"]);
- // Advance time beyond the TTL (15s) so the next call re-reads the directory.
- vi.setSystemTime(t0.getTime() + 16_000);
- const third = await listFiles("NL01", "2024", "10", "24");
- expect(third.map((f) => f.name)).toEqual(["a.pdf", "b.pdf"]);
- });
- });
|