import { test } from "node:test"; import assert from "node:assert/strict"; import type { ChannelSnapshot } from "../controller/channelSnapshot"; import type { ChannelConfig } from "../lib/channelConfig"; import type { StorageLocation } from "../lib/storageLocations"; import { normalizeBuckets } from "./pipeline/stageStatus"; import { buildChannelRowView, channelVolumeOf, neutralChannelPriority, reportStateOf, type ChannelRowInput, } from "./channelRow"; import { digestReachableCountOf, undownloadedCountOf, untranscribedCountOf, } from "./actionableCounts"; function snapshotOf(patch: Partial = {}): ChannelSnapshot { return { generatedAt: "2026-08-01T00:00:00.000Z", totals: { videos: 10, transcribed: 4, downloaded: 6 }, buckets: normalizeBuckets(undefined), undownloadedIds: [], ...patch, }; } function input(patch: Partial = {}): ChannelRowInput { const config: ChannelConfig = { handling: "transcribe", url: "https://example.test/alpha", name: "Alpha", lastSyncedAt: "2026-07-01T00:00:00.000Z", cookiesFile: "/secret/cookies.txt", } as ChannelConfig; return { slug: "alpha", config, snapshot: snapshotOf(), playlistCount: 12, bands: [], priority: neutralChannelPriority(), media: null, volume: { id: "internal", label: "Internal" }, ...patch, }; } test("a channel with no report: missing, no size, zero work", () => { const row = buildChannelRowView(input({ snapshot: null })); assert.deepEqual(row.report, { generatedAt: null, state: "missing" }); assert.equal(row.mediaBytes, null); assert.deepEqual(row.work, { videos: 0, undownloaded: 0, untranscribed: 0, digestReachable: 0, }); assert.equal(row.downloadCount, 0); assert.equal(row.transcriptCount, 0); }); test("stale when the last sync is newer than the report, else current", () => { const stale = buildChannelRowView( input({ config: { handling: "transcribe", lastSyncedAt: "2026-09-01T00:00:00Z" }, }), ); assert.equal(stale.report.state, "stale"); const current = buildChannelRowView(input()); assert.equal(current.report.state, "current"); assert.equal(current.report.generatedAt, "2026-08-01T00:00:00.000Z"); // Never synced: nothing to be stale against. assert.equal( reportStateOf({ config: {}, snapshot: { generatedAt: "2026-01-01" } }), "current", ); }); test("work equals the census count helpers over the same snapshot", () => { const snap = snapshotOf({ undownloadedIds: ["a", "b", "c"], buckets: { ...normalizeBuckets(undefined), downloadedNoTranscript: ["x", "a"] }, excludedFromDownload: { membersOnly: ["a"], deleted: [], private: [] }, totalMediaBytes: 1234, }); const row = buildChannelRowView(input({ snapshot: snap })); assert.deepEqual(row.work, { videos: 10, undownloaded: undownloadedCountOf(snap), untranscribed: untranscribedCountOf(snap), digestReachable: digestReachableCountOf(snap), }); assert.equal(row.work.undownloaded, 2); assert.equal(row.mediaBytes, 1234); assert.equal(row.downloadCount, 6); assert.equal(row.transcriptCount, 4); }); test("the view carries no config, only the fields a cell draws", () => { const row = buildChannelRowView(input()); assert.equal("config" in row, false); assert.equal(JSON.stringify(row).includes("cookies"), false); assert.equal(row.name, "Alpha"); assert.equal(row.hasUrl, true); assert.equal(row.excludeFromBuild, false); assert.equal(row.lastSyncedAt, "2026-07-01T00:00:00.000Z"); assert.equal(row.playlistCount, 12); const bare = buildChannelRowView(input({ config: { handling: "youtube" } })); assert.equal(bare.name, ""); assert.equal(bare.hasUrl, false); assert.equal(bare.lastSyncedAt, null); }); test("media: in-place is dropped; the label is the volume's unless overridden", () => { const inPlace = buildChannelRowView( input({ media: { status: "in-place", target: "/x", detail: "" } }), ); assert.equal(inPlace.media, null); const moved = buildChannelRowView( input({ media: { status: "ok", target: "/mnt/big/alpha/data", detail: "d" }, volume: { id: "big", label: "Big disk" }, }), ); assert.equal(moved.media?.locationLabel, "Big disk"); assert.equal(moved.volumeId, "big"); const unnamed = buildChannelRowView( input({ media: { status: "unreachable", target: "/mnt/x", detail: "d" }, volume: { id: "", label: "Elsewhere" }, }), ); assert.equal(unnamed.media?.locationLabel, undefined); const overridden = buildChannelRowView( input({ media: { status: "ok", target: "/mnt/big/alpha/data", detail: "d" }, volume: { id: "big", label: "Big disk" }, mediaLocationLabel: undefined, }), ); assert.equal(overridden.media?.locationLabel, undefined); }); test("channelVolumeOf: no mediaDir is internal, a named root wins, else unnamed", () => { const locations = [ { id: "big", label: "Big disk", root: "/mnt/big" }, { id: "bigger", label: "", root: "/mnt/big/inner" }, ] as StorageLocation[]; assert.deepEqual(channelVolumeOf(undefined, locations), { id: "internal", label: "Internal", }); assert.deepEqual(channelVolumeOf({ mediaDir: " " }, locations), { id: "internal", label: "Internal", }); assert.deepEqual(channelVolumeOf({ mediaDir: "/mnt/big/alpha/media" }, locations), { id: "big", label: "Big disk", }); assert.deepEqual(channelVolumeOf({ mediaDir: "/mnt/big/inner/a/media" }, locations), { id: "bigger", label: "bigger", }); assert.deepEqual(channelVolumeOf({ mediaDir: "/elsewhere/a/media" }, locations), { id: "", label: "Elsewhere", }); // A legacy channel (release 17) is placed by its retired `dataDir`. assert.deepEqual(channelVolumeOf({ dataDir: "/mnt/big/old/data" }, locations), { id: "big", label: "Big disk", }); });