// Ported from internal/arr/mediafile_test.go and the filter tests. import { deepStrictEqual, strictEqual, ok } from "node:assert"; import { test } from "node:test"; import type { MediaFile, Release } from "../src/api/arr.ts"; import { audioTags, facets, fileAttrs, listedValues, matchFile, noFilter, releaseAttrs, visibleReleases, type FileAttrs } from "../src/media.ts"; const attrs = (f: Partial) => fileAttrs({ size: 0, ...f }); test("attributes from media info", () => { deepStrictEqual(attrs({ quality: { quality: { name: "Bluray-2160p", resolution: 2160 } }, mediaInfo: { videoCodec: "x265", videoDynamicRange: "HDR", videoDynamicRangeType: "DV HDR10" }, languages: [{ name: "English" }, { name: "German" }], }), { resolution: 2160, codec: "x265", dv: true, hdr: true, audio: [], languages: ["English", "German"] }); }); test("attribute variants", () => { const cases: [string, Partial, (a: FileAttrs) => boolean][] = [ ["hevc", { mediaInfo: { videoCodec: "HEVC" } }, (a) => a.codec === "x265"], ["h264", { mediaInfo: { videoCodec: "h264" } }, (a) => a.codec === "x264"], ["avc", { mediaInfo: { videoCodec: "AVC" } }, (a) => a.codec === "x264"], ["av1", { mediaInfo: { videoCodec: "AV1" } }, (a) => a.codec === "AV1"], ["unoffered codec not guessed", { sceneName: "x264.Movie", mediaInfo: { videoCodec: "VC-1" } }, (a) => a.codec === ""], ["codec from scene name", { sceneName: "Movie.2020.1080p.BluRay.x265-GRP" }, (a) => a.codec === "x265" && a.resolution === 1080], ["dv from path", { relativePath: "Movie.2160p.DV.HDR10.mkv" }, (a) => a.dv && a.hdr && a.resolution === 2160], ["dv only", { mediaInfo: { videoDynamicRangeType: "DV" } }, (a) => a.dv && !a.hdr], ["hlg", { mediaInfo: { videoDynamicRangeType: "HLG" } }, (a) => a.hdr && !a.dv], ["sdr", { mediaInfo: { videoCodec: "x264" }, sceneName: "Movie.HDRip.x264" }, (a) => !a.hdr && !a.dv], ["hdr word with media info", { relativePath: "Hdr.Story.mkv", mediaInfo: { videoDynamicRange: "SDR" } }, (a) => !a.hdr], ]; for (const [name, f, check] of cases) ok(check(attrs(f)), `${name}: ${JSON.stringify(attrs(f))}`); }); test("release attributes", () => { const r = { title: "Dune.2021.2160p.UHD.BluRay.DV.HDR10.x265-GRP", quality: { quality: { name: "Bluray-2160p", resolution: 2160 } }, languages: [{ name: "English" }], customFormats: [{ name: "HDR" }], } as Release; deepStrictEqual(releaseAttrs(r), { resolution: 2160, codec: "x265", dv: true, hdr: true, audio: [], languages: ["English"] }); const r2 = releaseAttrs({ title: "Show.S01E01.720p.WEB.H.264-GRP" } as Release); ok(r2.resolution === 720 && r2.codec === "x264" && !r2.hdr && !r2.dv); const r3 = releaseAttrs({ title: "Show.S01E01.HDTV.x264-GRP" } as Release); ok(!r3.hdr && !r3.dv, "HDTV is not HDR"); }); test("audio tags", () => { const cases: [string, string[]][] = [ ["Movie.2160p.UHD.BluRay.TrueHD.7.1.Atmos.x265-G", ["Atmos", "TrueHD"]], ["Movie.1080p.DDP5.1.Atmos.x265", ["Atmos", "DD+"]], ["Movie.1080p.DTS-HD.MA.5.1.x264", ["DTS-HD", "DTS"]], ["Movie.2160p.DTS-X.7.1", ["DTS:X", "DTS"]], ["Movie.1080p.DTS.5.1", ["DTS"]], ["Movie.1080p.EAC3.5.1", ["DD+"]], ["Movie.1080p.E-AC-3.5.1", ["DD+"]], ["Movie.1080p.AC3.5.1", ["DD"]], ["Movie.720p.DD5.1.x264", ["DD"]], ["Show.S01E01.AAC.2.0", ["AAC"]], ["Album.FLAC", ["FLAC"]], ["Show.Opus", ["Opus"]], ["Movie.1080p.BluRay.x264-DTSAG", []], ["Movie.1080p.x264", []], ]; for (const [input, want] of cases) deepStrictEqual(audioTags(input), want, input); deepStrictEqual(attrs({ sceneName: "Movie.x264.AC3", mediaInfo: { audioCodec: "TrueHD Atmos" } }).audio, ["Atmos", "TrueHD"]); deepStrictEqual(attrs({ mediaInfo: { audioCodec: "EAC3", audioAdditionalFeatures: "Atmos" } }).audio, ["Atmos", "DD+"]); }); test("filter matching", () => { const a: FileAttrs = { resolution: 2160, codec: "x265", hdr: true, dv: false, audio: ["Atmos", "TrueHD"], languages: ["English"] }; ok(matchFile({ ...noFilter(), res: "2160p", lang: "english", hdr: "HDR", audio: "Atmos" }, a)); ok(!matchFile({ ...noFilter(), hdr: "SDR" }, a)); ok(!matchFile({ ...noFilter(), hdr: "DV" }, a)); ok(matchFile({ ...noFilter(), res: "SD" }, { ...a, resolution: 480 })); ok(!matchFile({ ...noFilter(), res: "SD" }, { ...a, resolution: 0 })); }); test("the dialog offers only options that leave something", () => { const pool = { files: [[{ resolution: 1080, codec: "x264", hdr: false, dv: false, audio: ["DD"], languages: ["German"] }]], unknown: false }; const quality = facets[0]; strictEqual(quality.label, "Quality"); deepStrictEqual(listedValues(quality, noFilter(), pool), ["", "1080p"]); strictEqual(facets[1].label, "Language"); deepStrictEqual(listedValues(facets[1], noFilter(), pool), ["", "German"]); // Unknown files (series not read yet): everything is offered. deepStrictEqual(listedValues(quality, noFilter(), { ...pool, unknown: true }), ["", "2160p", "1080p", "720p", "SD"]); }); test("release order: approved first, then score, quality and age", () => { const r = (guid: string, o: Partial) => ({ guid, title: guid, rejected: false, customFormatScore: 0, qualityWeight: 0, ageMinutes: 0, size: 0, ...o }) as Release; const all = [ r("rejected", { rejected: true, customFormatScore: 900 }), r("old", { customFormatScore: 100, ageMinutes: 500 }), r("new", { customFormatScore: 100, ageMinutes: 5 }), r("best", { customFormatScore: 200 }), ]; deepStrictEqual(visibleReleases(all, false, "best", noFilter()).map((x) => x.guid), ["best", "new", "old", "rejected"]); deepStrictEqual(visibleReleases(all, true, "best", noFilter()).map((x) => x.guid), ["best", "new", "old"]); deepStrictEqual(visibleReleases([r("s", { size: 1 }), r("l", { size: 9 })], false, "size", noFilter()).map((x) => x.guid), ["l", "s"]); });