torrentclaw-mcp/tests/formatters/content.test.ts
2026-02-12 15:22:11 +01:00

637 lines
17 KiB
TypeScript

import { describe, it, expect } from "vitest";
import {
formatSearchResults,
formatPopularResults,
formatRecentResults,
} from "../../src/formatters/content.js";
import type {
SearchResponse,
PopularResponse,
RecentResponse,
} from "../../src/types.js";
describe("formatSearchResults", () => {
it("formats empty results", () => {
const response: SearchResponse = {
total: 0,
page: 1,
pageSize: 10,
results: [],
};
const text = formatSearchResults(response);
expect(text).toContain("No results found");
});
it("formats a single movie with torrents", () => {
const response: SearchResponse = {
total: 1,
page: 1,
pageSize: 10,
results: [
{
id: 42,
imdbId: "tt1375666",
tmdbId: "27205",
contentType: "movie",
title: "Inception",
titleOriginal: "Inception",
year: 2010,
overview:
"A thief who steals corporate secrets through dream-sharing technology.",
posterUrl: "https://image.tmdb.org/t/p/w500/poster.jpg",
backdropUrl: null,
genres: ["Action", "Science Fiction"],
ratingImdb: "8.8",
ratingTmdb: "8.4",
hasTorrents: true,
torrents: [
{
infoHash: "aaf1e71c0a0e3b1c0f1a2b3c4d5e6f7a8b9c0d1e",
quality: "1080p",
codec: "x265",
sourceType: "BluRay",
sizeBytes: "2147483648",
seeders: 847,
leechers: 23,
magnetUrl:
"magnet:?xt=urn:btih:aaf1e71c0a0e3b1c0f1a2b3c4d5e6f7a8b9c0d1e",
source: "yts",
qualityScore: 85,
uploadedAt: "2024-03-15T12:00:00Z",
languages: ["en"],
audioCodec: "aac",
hdrType: null,
releaseGroup: "YTS",
isProper: false,
isRepack: false,
isRemastered: false,
},
],
},
],
};
const text = formatSearchResults(response);
expect(text).toContain("Found 1 results");
expect(text).toContain("Inception (2010) [movie]");
expect(text).toContain("IMDb: 8.8");
expect(text).toContain("TMDB: 8.4");
expect(text).toContain("Action, Science Fiction");
expect(text).toContain("1080p BluRay x265");
expect(text).toContain("2.0 GB");
expect(text).toContain("847 seeders");
expect(text).toContain("Score: 85");
expect(text).toContain("magnet:");
expect(text).toContain("Content ID: 42");
expect(text).toContain("tt1375666");
});
it("caps torrents at 5 and sorts by qualityScore", () => {
const torrents = Array.from({ length: 8 }, (_, i) => ({
infoHash: `${"a".repeat(39)}${i}`,
quality: `${720 + i * 10}p`,
codec: "x264",
sourceType: "WEB-DL",
sizeBytes: "1073741824",
seeders: 100 + i,
leechers: 10,
magnetUrl: `magnet:?xt=urn:btih:${"a".repeat(39)}${i}`,
source: "knaben:test",
qualityScore: i * 10,
uploadedAt: null,
languages: ["en"],
audioCodec: null,
hdrType: null,
releaseGroup: null,
isProper: false,
isRepack: false,
isRemastered: false,
}));
const response: SearchResponse = {
total: 1,
page: 1,
pageSize: 10,
results: [
{
id: 1,
imdbId: null,
tmdbId: null,
contentType: "movie",
title: "Test Movie",
titleOriginal: null,
year: 2024,
overview: null,
posterUrl: null,
backdropUrl: null,
genres: null,
ratingImdb: null,
ratingTmdb: null,
hasTorrents: true,
torrents,
},
],
};
const text = formatSearchResults(response);
expect(text).toContain("8 total, top 5");
// Highest score (70) should appear first
expect(text).toContain("Score: 70");
});
it("formats KB-sized torrent", () => {
const response: SearchResponse = {
total: 1,
page: 1,
pageSize: 10,
results: [
{
id: 1,
imdbId: null,
tmdbId: null,
contentType: "movie",
title: "Small File",
titleOriginal: null,
year: 2024,
overview: null,
posterUrl: null,
backdropUrl: null,
genres: null,
ratingImdb: null,
ratingTmdb: null,
hasTorrents: true,
torrents: [
{
infoHash: "a".repeat(40),
quality: null,
codec: null,
sourceType: null,
sizeBytes: "512000",
seeders: 5,
leechers: 0,
magnetUrl: null,
source: "test",
qualityScore: null,
uploadedAt: null,
languages: [],
audioCodec: null,
hdrType: null,
releaseGroup: null,
isProper: null,
isRepack: null,
isRemastered: null,
},
],
},
],
};
const text = formatSearchResults(response);
expect(text).toContain("500 KB");
expect(text).toContain("Unknown quality");
expect(text).not.toContain("Score:");
});
it("formats MB-sized torrent", () => {
const response: SearchResponse = {
total: 1,
page: 1,
pageSize: 10,
results: [
{
id: 1,
imdbId: null,
tmdbId: null,
contentType: "movie",
title: "Medium File",
titleOriginal: null,
year: 2024,
overview: null,
posterUrl: null,
backdropUrl: null,
genres: null,
ratingImdb: null,
ratingTmdb: null,
hasTorrents: true,
torrents: [
{
infoHash: "b".repeat(40),
quality: "720p",
codec: null,
sourceType: null,
sizeBytes: "524288000",
seeders: 10,
leechers: 1,
magnetUrl: null,
source: "test",
qualityScore: 50,
uploadedAt: null,
languages: [],
audioCodec: null,
hdrType: null,
releaseGroup: null,
isProper: null,
isRepack: null,
isRemastered: null,
},
],
},
],
};
const text = formatSearchResults(response);
expect(text).toContain("500 MB");
});
it("handles null and NaN sizeBytes", () => {
const response: SearchResponse = {
total: 1,
page: 1,
pageSize: 10,
results: [
{
id: 1,
imdbId: null,
tmdbId: null,
contentType: "movie",
title: "No Size",
titleOriginal: null,
year: null,
overview: null,
posterUrl: null,
backdropUrl: null,
genres: null,
ratingImdb: null,
ratingTmdb: null,
hasTorrents: true,
torrents: [
{
infoHash: "c".repeat(40),
quality: "1080p",
codec: null,
sourceType: null,
sizeBytes: null,
seeders: 1,
leechers: 0,
magnetUrl: null,
source: "test",
qualityScore: null,
uploadedAt: null,
languages: [],
audioCodec: null,
hdrType: null,
releaseGroup: null,
isProper: null,
isRepack: null,
isRemastered: null,
},
{
infoHash: "d".repeat(40),
quality: "720p",
codec: null,
sourceType: null,
sizeBytes: "not-a-number",
seeders: 1,
leechers: 0,
magnetUrl: null,
source: "test",
qualityScore: null,
uploadedAt: null,
languages: [],
audioCodec: null,
hdrType: null,
releaseGroup: null,
isProper: null,
isRepack: null,
isRemastered: null,
},
],
},
],
};
const text = formatSearchResults(response);
// Both null and NaN should produce "?"
expect(text).toContain("(?)");
// No year in title
expect(text).toContain("No Size [movie]");
// No ratings
expect(text).toContain("No ratings");
});
it("truncates long overviews", () => {
const longOverview = "A".repeat(300);
const response: SearchResponse = {
total: 1,
page: 1,
pageSize: 10,
results: [
{
id: 1,
imdbId: null,
tmdbId: null,
contentType: "show",
title: "Long Overview",
titleOriginal: null,
year: 2024,
overview: longOverview,
posterUrl: null,
backdropUrl: null,
genres: null,
ratingImdb: null,
ratingTmdb: null,
hasTorrents: false,
torrents: [],
},
],
};
const text = formatSearchResults(response);
expect(text).toContain("...");
expect(text).not.toContain("A".repeat(300));
});
it("shows HDR type in torrent label", () => {
const response: SearchResponse = {
total: 1,
page: 1,
pageSize: 10,
results: [
{
id: 1,
imdbId: null,
tmdbId: null,
contentType: "movie",
title: "HDR Movie",
titleOriginal: null,
year: 2024,
overview: null,
posterUrl: null,
backdropUrl: null,
genres: null,
ratingImdb: "7.0",
ratingTmdb: null,
hasTorrents: true,
torrents: [
{
infoHash: "e".repeat(40),
quality: "2160p",
codec: "x265",
sourceType: "WEB-DL",
sizeBytes: "10737418240",
seeders: 50,
leechers: 2,
magnetUrl: "magnet:?xt=urn:btih:" + "e".repeat(40),
source: "yts",
qualityScore: 95,
uploadedAt: null,
languages: ["en"],
audioCodec: null,
hdrType: "hdr10",
releaseGroup: null,
isProper: null,
isRepack: null,
isRemastered: null,
},
],
},
],
};
const text = formatSearchResults(response);
expect(text).toContain("2160p WEB-DL x265 hdr10");
expect(text).toContain("10.0 GB");
});
it("compact mode uses short magnet links", () => {
const hash = "aaf1e71c0a0e3b1c0f1a2b3c4d5e6f7a8b9c0d1e";
const fullMagnet = `magnet:?xt=urn:btih:${hash}&dn=Inception&tr=udp://tracker.example.com:6969&tr=udp://tracker2.example.com:6969`;
const response: SearchResponse = {
total: 1,
page: 1,
pageSize: 10,
results: [
{
id: 42,
imdbId: null,
tmdbId: null,
contentType: "movie",
title: "Inception",
titleOriginal: null,
year: 2010,
overview: null,
posterUrl: null,
backdropUrl: null,
genres: null,
ratingImdb: null,
ratingTmdb: null,
hasTorrents: true,
torrents: [
{
infoHash: hash,
quality: "1080p",
codec: null,
sourceType: null,
sizeBytes: "2147483648",
seeders: 100,
leechers: 5,
magnetUrl: fullMagnet,
source: "yts",
qualityScore: 85,
uploadedAt: null,
languages: [],
audioCodec: null,
hdrType: null,
releaseGroup: null,
isProper: null,
isRepack: null,
isRemastered: null,
},
],
},
],
};
const compact = formatSearchResults(response, { compact: true });
const full = formatSearchResults(response);
// Compact: short magnet with just the hash
expect(compact).toContain(`magnet:?xt=urn:btih:${hash}`);
// Compact: no tracker URLs
expect(compact).not.toContain("tracker.example.com");
// Full: includes the full magnet URL with trackers
expect(full).toContain(fullMagnet);
// Compact output should be shorter
expect(compact.length).toBeLessThan(full.length);
// Both include the info hash
expect(compact).toContain(`Info hash: ${hash}`);
expect(full).toContain(`Info hash: ${hash}`);
});
it("compact mode generates magnet even when magnetUrl is null", () => {
const hash = "b".repeat(40);
const response: SearchResponse = {
total: 1,
page: 1,
pageSize: 10,
results: [
{
id: 1,
imdbId: null,
tmdbId: null,
contentType: "movie",
title: "No Magnet",
titleOriginal: null,
year: 2024,
overview: null,
posterUrl: null,
backdropUrl: null,
genres: null,
ratingImdb: null,
ratingTmdb: null,
hasTorrents: true,
torrents: [
{
infoHash: hash,
quality: "720p",
codec: null,
sourceType: null,
sizeBytes: "1073741824",
seeders: 10,
leechers: 0,
magnetUrl: null,
source: "test",
qualityScore: 50,
uploadedAt: null,
languages: [],
audioCodec: null,
hdrType: null,
releaseGroup: null,
isProper: null,
isRepack: null,
isRemastered: null,
},
],
},
],
};
const compact = formatSearchResults(response, { compact: true });
const full = formatSearchResults(response);
// Compact always generates a magnet from info_hash
expect(compact).toContain(`magnet:?xt=urn:btih:${hash}`);
// Full mode: no magnet when magnetUrl is null
expect(full).not.toContain("Magnet:");
});
it("shows streaming info when available", () => {
const response: SearchResponse = {
total: 1,
page: 1,
pageSize: 10,
results: [
{
id: 1,
imdbId: null,
tmdbId: null,
contentType: "movie",
title: "Streaming Test",
titleOriginal: null,
year: 2024,
overview: null,
posterUrl: null,
backdropUrl: null,
genres: null,
ratingImdb: null,
ratingTmdb: null,
hasTorrents: false,
torrents: [],
streaming: {
flatrate: [
{ providerId: 8, name: "Netflix", logo: null, link: null },
{ providerId: 337, name: "Disney+", logo: null, link: null },
],
rent: [],
buy: [],
free: [{ providerId: 100, name: "Tubi", logo: null, link: null }],
},
},
],
};
const text = formatSearchResults(response);
expect(text).toContain("Stream: Netflix, Disney+");
expect(text).toContain("Free: Tubi");
});
});
describe("formatPopularResults", () => {
it("formats empty results", () => {
const response: PopularResponse = {
items: [],
total: 0,
page: 1,
pageSize: 10,
};
expect(formatPopularResults(response)).toContain("No popular content");
});
it("formats popular items with click counts", () => {
const response: PopularResponse = {
items: [
{
id: 1,
title: "Popular Movie",
year: 2024,
contentType: "movie",
posterUrl: null,
ratingImdb: "7.5",
ratingTmdb: "7.2",
clickCount: 150,
},
],
total: 1,
page: 1,
pageSize: 10,
};
const text = formatPopularResults(response);
expect(text).toContain("Popular Movie (2024) [movie]");
expect(text).toContain("150 clicks");
expect(text).toContain("ID: 1");
});
});
describe("formatRecentResults", () => {
it("formats empty results", () => {
const response: RecentResponse = {
items: [],
total: 0,
page: 1,
pageSize: 10,
};
expect(formatRecentResults(response)).toContain("No recent content");
});
it("formats recent items with dates", () => {
const response: RecentResponse = {
items: [
{
id: 5,
title: "New Show",
year: 2025,
contentType: "show",
posterUrl: null,
ratingImdb: null,
ratingTmdb: "6.8",
createdAt: "2025-12-25T10:00:00Z",
},
],
total: 1,
page: 1,
pageSize: 10,
};
const text = formatRecentResults(response);
expect(text).toContain("New Show (2025) [show]");
expect(text).toContain("TMDB: 6.8");
expect(text).toContain("Dec");
expect(text).toContain("ID: 5");
});
});