From f99a144bc45d6ee9e19b5d8bdf3b07614a9ccc99 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Sat, 19 Jul 2025 17:40:33 +0200 Subject: [PATCH] Add tests for `/videos/:id` --- api/src/models/examples/made-in-abyss.ts | 75 +++++++++ api/tests/helpers/videos-helper.ts | 19 +++ api/tests/videos/get-id.test.ts | 204 +++++++++++++++++++++++ 3 files changed, 298 insertions(+) create mode 100644 api/tests/videos/get-id.test.ts diff --git a/api/src/models/examples/made-in-abyss.ts b/api/src/models/examples/made-in-abyss.ts index fae77b19..ea3ade33 100644 --- a/api/src/models/examples/made-in-abyss.ts +++ b/api/src/models/examples/made-in-abyss.ts @@ -266,6 +266,81 @@ export const madeInAbyss = { }, }, }, + { + kind: "episode", + order: 15, + seasonNumber: 2, + episodeNumber: 2, + translations: { + en: { + name: " Resurrection Festival ", + description: + "Riko and Reg find out more about their past but the question still remains, who or what exactly is Reg?", + }, + }, + runtime: 23, + airDate: "2022-07-06", + thumbnail: + "https://artworks.thetvdb.com/banners/episodes/326109/6174129.jpg", + externalId: { + themoviedatabase: { + serieId: "72636", + season: 2, + episode: 2, + link: "https://www.themoviedb.org/tv/72636/season/2/episode/2", + }, + }, + }, + { + kind: "episode", + order: 16, + seasonNumber: 2, + episodeNumber: 3, + translations: { + en: { + name: "Departure", + description: + "Reg goes on his first cave raid! Meanwhile, Riko makes preparations to go into the abyss to find her mother.", + }, + }, + runtime: 23, + airDate: "2022-07-06", + thumbnail: + "https://artworks.thetvdb.com/banners/episodes/326109/6180539.jpg", + externalId: { + themoviedatabase: { + serieId: "72636", + season: 2, + episode: 3, + link: "https://www.themoviedb.org/tv/72636/season/2/episode/4", + }, + }, + }, + { + kind: "episode", + order: 17, + seasonNumber: 2, + episodeNumber: 4, + translations: { + en: { + name: "The Edge of the Abyss", + description: + "Riko and Reg start their adventure into the Abyss, while there they run into an unexpected familiar face.", + }, + }, + runtime: 23, + airDate: "2022-07-06", + thumbnail: + "https://artworks.thetvdb.com/banners/episodes/326109/6180540.jpg", + externalId: { + themoviedatabase: { + serieId: "72636", + season: 2, + episode: 4, + link: "https://www.themoviedb.org/tv/72636/season/2/episode/4", + }, + }, + }, ], extras: [ { diff --git a/api/tests/helpers/videos-helper.ts b/api/tests/helpers/videos-helper.ts index d21a94dd..c301d3a4 100644 --- a/api/tests/helpers/videos-helper.ts +++ b/api/tests/helpers/videos-helper.ts @@ -29,6 +29,25 @@ export const getVideos = async () => { return [resp, body] as const; }; +export const getVideo = async ( + id: string, + { langs, ...query }: { langs?: string; with?: string[] }, +) => { + const resp = await handlers.handle( + new Request(buildUrl(`videos/${id}`, query), { + method: "GET", + headers: langs + ? { + "Accept-Language": langs, + ...(await getJwtHeaders()), + } + : await getJwtHeaders(), + }), + ); + const body = await resp.json(); + return [resp, body] as const; +}; + export const deleteVideo = async (paths: string[]) => { const resp = await handlers.handle( new Request(buildUrl("videos"), { diff --git a/api/tests/videos/get-id.test.ts b/api/tests/videos/get-id.test.ts new file mode 100644 index 00000000..33fb147e --- /dev/null +++ b/api/tests/videos/get-id.test.ts @@ -0,0 +1,204 @@ +import { beforeAll, describe, expect, it } from "bun:test"; +import { createSerie, createVideo, getVideo } from "tests/helpers"; +import { expectStatus } from "tests/utils"; +import { db } from "~/db"; +import { shows, videos } from "~/db/schema"; +import { madeInAbyss } from "~/models/examples"; + +beforeAll(async () => { + await db.delete(shows); + const [ret, _] = await createSerie(madeInAbyss); + expect(ret.status).toBe(201); + await db.delete(videos); + + await createVideo([ + { + path: "/video/Made in abyss S01E13.mkv", + rendering: "mia13", + part: null, + version: 1, + guess: { + title: "Made in abyss", + episodes: [{ season: 1, episode: 13 }], + kind: "episode", + from: "guessit", + history: [], + }, + for: [{ serie: madeInAbyss.slug, season: 1, episode: 13 }], + }, + { + path: "/video/Made in abyss movie.mkv", + rendering: "mia-movie", + part: null, + version: 1, + guess: { + title: "Made in abyss", + kind: "movie", + from: "guessit", + history: [], + }, + // TODO: i feel like there's a better way than that. we need to make this api better + for: [{ serie: madeInAbyss.slug, order: 13.5 }], + }, + { + path: "/video/Made in abyss s2e1 p1.mkv", + rendering: "mia-s2e1", + part: 1, + version: 1, + guess: { + title: "Made in abyss", + kind: "episode", + episodes: [{ season: 2, episode: 1 }], + from: "guessit", + history: [], + }, + for: [{ serie: madeInAbyss.slug, season: 2, episode: 1 }], + }, + { + path: "/video/Made in abyss s2e1 p2.mkv", + rendering: "mia-s2e1", + part: 2, + version: 1, + guess: { + title: "Made in abyss", + kind: "episode", + episodes: [{ season: 2, episode: 1 }], + from: "guessit", + history: [], + }, + for: [{ serie: madeInAbyss.slug, season: 2, episode: 1 }], + }, + { + path: "/video/Made in abyss s2e1 p2 v2.mkv", + rendering: "mia-s2e1", + part: 2, + version: 2, + guess: { + title: "Made in abyss", + kind: "episode", + episodes: [{ season: 2, episode: 1 }], + from: "guessit", + history: [], + }, + for: [{ serie: madeInAbyss.slug, season: 2, episode: 1 }], + }, + { + path: "/video/Made in abyss s2e2.mkv", + rendering: "mia-s2e2", + part: null, + version: 2, + guess: { + title: "Made in abyss", + kind: "episode", + episodes: [{ season: 2, episode: 2 }], + from: "guessit", + history: [], + }, + for: [ + { serie: madeInAbyss.slug, season: 2, episode: 2 }, + { serie: madeInAbyss.slug, season: 2, episode: 3 }, + ], + }, + { + path: "/video/Made in abyss s2e4.mkv", + rendering: "mia-s2e4", + part: null, + version: 2, + guess: { + title: "Made in abyss", + kind: "episode", + episodes: [{ season: 2, episode: 4 }], + from: "guessit", + history: [], + }, + for: [{ serie: madeInAbyss.slug, season: 2, episode: 4 }], + }, + ]); +}); + +describe("Get videos", () => { + it("Invalid slug", async () => { + const [resp, body] = await getVideo("sotneuhn", { langs: "en" }); + expectStatus(resp, body).toBe(404); + expect(body).toMatchObject({ + status: 404, + message: expect.any(String), + }); + }); + + it("Get video", async () => { + const [resp, body] = await getVideo("made-in-abyss-s1e13", { langs: "en" }); + expectStatus(resp, body).toBe(200); + expect(body).toMatchObject({ + id: expect.any(String), + path: "/video/Made in abyss S01E13.mkv", + rendering: "mia13", + part: null, + version: 1, + guess: { + title: "Made in abyss", + episodes: [{ season: 1, episode: 13 }], + kind: "episode", + from: "guessit", + history: [], + }, + slugs: ["made-in-abyss-s1e13"], + }); + }); + + it("Get video with null previous", async () => { + const [resp, body] = await getVideo("made-in-abyss-s1e13", { + langs: "en", + with: ["previous"], + }); + expectStatus(resp, body).toBe(200); + expect(body).toMatchObject({ + id: expect.any(String), + path: "/video/Made in abyss S01E13.mkv", + rendering: "mia13", + part: null, + version: 1, + guess: { + title: "Made in abyss", + episodes: [{ season: 1, episode: 13 }], + kind: "episode", + from: "guessit", + history: [], + }, + slugs: ["made-in-abyss-s1e13"], + previous: null, + }); + }); + + it("Get video with movie next", async () => { + const [resp, body] = await getVideo("made-in-abyss-s1e13", { + langs: "en", + with: ["previous", "next"], + }); + expectStatus(resp, body).toBe(200); + expect(body).toMatchObject({ + id: expect.any(String), + path: "/video/Made in abyss S01E13.mkv", + rendering: "mia13", + part: null, + version: 1, + guess: { + title: "Made in abyss", + episodes: [{ season: 1, episode: 13 }], + kind: "episode", + from: "guessit", + history: [], + }, + slugs: ["made-in-abyss-s1e13"], + previous: null, + next: { + video: "made-in-abyss-dawn-of-the-deep-soul", + entry: expect.objectContaining({ + slug: "made-in-abyss-dawn-of-the-deep-soul", + name: "Made in Abyss: Dawn of the Deep Soul", + order: 13.5, + }), + }, + }); + }); +});