import { test } from "node:test"; import assert from "node:assert/strict"; import type { ChannelBrief } from "../controller/channels"; import type { ChannelSnapshot } from "../controller/channelSnapshot"; import type { StorageLocation } from "../lib/storageLocations"; import { buildStorageReport, renderStorageReport, storageReportRow, } from "./storage-report"; // Run with: pnpm --filter yt-dlp-transcript-common exec tsx --test bin/storage-report.test.ts // // `archilyzer storage report` is a pure fold over the channel briefs: where // each channel's media is (corpus, a location, a custom path, legacy), its // three tiers' bytes off the report — unknown when the report has no figure, // never 0 — and the totals per place. const LOCATIONS = [ { id: "platter", label: "Platter", root: "/mnt/platter" }, { id: "archive", label: "Archive", root: "/mnt/platter/archive" }, ] as unknown as StorageLocation[]; function brief( slug: string, config: Record, snap: Partial | null, ): ChannelBrief { return { slug, config: { handling: "youtube", name: slug, ...config }, snapshot: snap ? ({ generatedAt: "2026-10-01T00:00:00.000Z", ...snap } as ChannelSnapshot) : null, } as ChannelBrief; } const briefs = [ brief("in-place", {}, { totalMediaBytes: 500, totalTextBytes: 20, totalClipsBytes: 5 }), brief("moved", { mediaDir: "/mnt/platter/archive/moved/media" }, { totalMediaBytes: 900, totalTextBytes: 10 }), brief("custom", { mediaDir: "/srv/elsewhere/custom/media" }, { totalMediaBytes: 100 }), brief("legacy", { dataDir: "/mnt/platter/legacy/data" }, { totalTextBytes: 1 }), brief("old-report", {}, null), brief("posts", { sourceKind: "social", handling: "transcribe", platform: "twitter", postFetcher: "x-gallery-dl" }, { totalMediaBytes: 0, }), ]; test("a channel's place: corpus, the longest location, a custom path, legacy", () => { const rows = Object.fromEntries(briefs.map((b) => [b.slug, storageReportRow(b, LOCATIONS)])); assert.equal(rows["in-place"].place, "corpus"); assert.equal(rows["in-place"].location, null); assert.equal(rows.moved.place, "location"); assert.equal(rows.moved.location, "archive"); assert.equal(rows.custom.place, "custom"); assert.equal(rows.custom.mediaDir, "/srv/elsewhere/custom/media"); assert.equal(rows.legacy.place, "legacy"); assert.equal(rows.legacy.location, "platter"); }); test("a figure the report does not have is unknown, never 0", () => { const row = storageReportRow(briefs[4], LOCATIONS); assert.deepEqual( [row.mediaBytes, row.textBytes, row.clipsBytes, row.reportedAt], [null, null, null, null], ); assert.equal(storageReportRow(briefs[2], LOCATIONS).textBytes, null); }); test("the report leaves out social channels, sorts by media, and totals per place", () => { const report = buildStorageReport(briefs, LOCATIONS); assert.deepEqual( report.rows.map((r) => r.slug), ["moved", "in-place", "custom", "legacy", "old-report"], ); assert.deepEqual(report.totals, { "location:archive": { channels: 1, mediaBytes: 900, unknown: 0 }, corpus: { channels: 2, mediaBytes: 500, unknown: 1 }, custom: { channels: 1, mediaBytes: 100, unknown: 0 }, legacy: { channels: 1, mediaBytes: 0, unknown: 1 }, }); // Narrowed to named channels. assert.deepEqual( buildStorageReport(briefs, LOCATIONS, ["custom"]).rows.map((r) => r.slug), ["custom"], ); }); test("the table says unknown as a dash and names what a move would free", () => { const text = renderStorageReport(buildStorageReport(briefs, LOCATIONS)); assert.match(text, /^channel\s+media \(tierable\)\s+text\s+clips\s+where$/m); assert.match(text, /^old-report\s+—\s+—\s+—\s+corpus disk$/m); assert.match(text, /^moved\s.*location archive$/m); assert.match(text, /on the corpus disk \(a move would free\): 2 channel\(s\), .* media, 1 unknown/); });