diff --git a/api/bunfig.toml b/api/bunfig.toml new file mode 100644 index 00000000..8370a015 --- /dev/null +++ b/api/bunfig.toml @@ -0,0 +1,2 @@ +[test] +preload = ["./tests/setup.ts"] diff --git a/api/src/models/examples/dune-1984.ts b/api/src/models/examples/dune-1984.ts new file mode 100644 index 00000000..6567d8c9 --- /dev/null +++ b/api/src/models/examples/dune-1984.ts @@ -0,0 +1,72 @@ +import type { SeedMovie } from "../movie"; +import type { Video } from "../video"; + +export const dune1984Video: Video = { + id: "d1a62b87-9cfd-4f9c-9ad7-21f9b7fa6290", + slug: "dune-1984", + path: "/video/Dune_1984/Dune (1984).mkv", + rendering: "ea3a0f8f2f2c5b61a07f61e4e8d9f8e01b2b92bcbb6f5ed1151e1f61619c2c0f", + part: null, + version: 1, + createdAt: "2024-12-02T11:45:12.968Z", +}; + +export const dune1984: SeedMovie = { + slug: "dune-1984", + translations: { + en: { + name: "Dune", + tagline: "A journey to the stars begins with a single step.", + description: + "On the planet Arrakis, the young Paul Atreides and his family are thrust into a world of political intrigue and warfare over control of the spice melange, the most valuable substance in the universe.", + aliases: ["Dune 1984", "Dune: David Lynch's Vision", "Dune: The Movie"], + tags: ["sci-fi", "adventure", "drama", "cult-classic", "epic"], + poster: + "https://image.tmdb.org/t/p/original/eVnVrIWkT8esL3XsTc4BjhDhQKq.jpg", + thumbnail: + "https://image.tmdb.org/t/p/original/pCHV6BntWLO2H6wQOj4LwzAWqpa.jpg", + banner: null, + logo: "https://image.tmdb.org/t/p/original/olbKnk2VvFcM2STl0dJAf6kfydo.png", + trailerUrl: "https://www.youtube.com/watch?v=vczYTLQ6oiE", + }, + }, + genres: ["adventure", "drama", "science-fiction"], + rating: 60, + status: "finished", + runtime: 137, + airDate: "1984-12-14", + originalLanguage: "en", + externalId: { + themoviedatabase: { + dataId: "9495", + link: "https://www.themoviedb.org/movie/9495", + }, + imdb: { + dataId: "tt0087182", + link: "https://www.imdb.com/title/tt0087182", + }, + }, + videos: [dune1984Video.id], +}; + +export const dune1984Images = { + poster: { + id: "a5e1c5e4-4176-42f0-a279-8ab6f1ae2d30", + source: + "https://image.tmdb.org/t/p/original/eVnVrIWkT8esL3XsTc4BjhDhQKq.jpg", + blurhash: "L32^9tc~%8~U%OItfNGq9FoLV@X9", + }, + thumbnail: { + id: "fe44141b-58bc-42b7-a5c5-e10b801e99ae", + source: + "https://image.tmdb.org/t/p/original/pCHV6BntWLO2H6wQOj4LwzAWqpa.jpg", + blurhash: "L56~XM~q9ZZX4wbD9Wa|ECxvS~V@", + }, + banner: null, + logo: { + id: "515d7d72-b4f0-4a7d-a27a-eac3495ea8b3", + source: + "https://image.tmdb.org/t/p/original/olbKnk2VvFcM2STl0dJAf6kfydo.png", + blurhash: "LJ4XXK*]JFMzM]V?~Xz$sV?tMdm+", + }, +}; diff --git a/api/src/models/examples/dune-2021.ts b/api/src/models/examples/dune-2021.ts new file mode 100644 index 00000000..64f5985f --- /dev/null +++ b/api/src/models/examples/dune-2021.ts @@ -0,0 +1,72 @@ +import type { SeedMovie } from "../movie"; +import type { Video } from "../video"; + +export const duneVideo: Video = { + id: "c9a0d02e-6b8e-4ac1-b431-45b022ec0708", + slug: "dune", + path: "/video/Dune/Dune (2021).mkv", + rendering: "f1953a4fb58247efb6c15b76468b6a9d13b4155b02094863b1a4f0c3fbb6db58", + part: null, + version: 1, + createdAt: "2024-12-02T10:10:24.968Z", +}; + +export const dune: SeedMovie = { + slug: "dune", + translations: { + en: { + name: "Dune", + tagline: "A mythic and emotionally charged hero's journey.", + description: + "On the desert planet Arrakis, a young nobleman becomes embroiled in a complex struggle for control of the planet's valuable resource, the spice melange.", + aliases: ["Dune: Part One", "Dune 2021"], + tags: ["sci-fi", "adventure", "drama", "action", "epic"], + poster: + "https://image.tmdb.org/t/p/original/wD57HqZ6fXwwDdfQLo4hXLRwGV1.jpg", + thumbnail: + "https://image.tmdb.org/t/p/original/k2ocXnNkmvE6rJomRkExIStFq3v.jpg", + banner: null, + logo: "https://image.tmdb.org/t/p/original/5nDsd3u1c6kDphbtIqkHseLg7HL.png", + trailerUrl: "https://www.youtube.com/watch?v=n9xhJrPXop4", + }, + }, + genres: ["adventure", "drama", "science-fiction", "action"], + rating: 83, + status: "finished", + runtime: 155, + airDate: "2021-10-22", + originalLanguage: "en", + externalId: { + themoviedatabase: { + dataId: "496243", + link: "https://www.themoviedb.org/movie/496243", + }, + imdb: { + dataId: "tt1160419", + link: "https://www.imdb.com/title/tt1160419", + }, + }, + videos: [duneVideo.id], +}; + +export const duneImages = { + poster: { + id: "ea0426d1-4d16-4be9-9e6f-08e5fdf8f209", + source: + "https://image.tmdb.org/t/p/original/wD57HqZ6fXwwDdfQLo4hXLRwGV1.jpg", + blurhash: "L3D8AK$A5l=j~Bt7_4Mw-;WBt4Gf", + }, + thumbnail: { + id: "1b629b7f-3b44-45b9-9432-cb5505045899", + source: + "https://image.tmdb.org/t/p/original/k2ocXnNkmvE6rJomRkExIStFq3v.jpg", + blurhash: "L6l5}7$S0nt7p~2R.9W9tQ%NflWC", + }, + banner: null, + logo: { + id: "c02ec0d2-d04e-4f51-8d4e-4cdd9ca75a7e", + source: + "https://image.tmdb.org/t/p/original/5nDsd3u1c6kDphbtIqkHseLg7HL.png", + blurhash: "LLOQ0t-7e,X6jY?qBtt6c8A4gYof", + }, +}; diff --git a/api/tests/seed-movies.test.ts b/api/tests/seed-movies.test.ts new file mode 100644 index 00000000..0b0a7d16 --- /dev/null +++ b/api/tests/seed-movies.test.ts @@ -0,0 +1,50 @@ +import { afterAll, beforeAll, describe, expect, it, test } from "bun:test"; +import { inArray } from "drizzle-orm"; +import Elysia from "elysia"; +import { seed } from "~/controllers/seed"; +import { db } from "~/db"; +import { shows, videos } from "~/db/schema"; +import { dune, duneVideo } from "~/models/examples/dune-2021"; + +const app = new Elysia().use(seed); + +const cleanup = async () => { + await db.delete(shows).where(inArray(shows.slug, [dune.slug])); + await db.delete(videos).where(inArray(videos.id, [duneVideo.id])); +}; +// cleanup db beforehand to unsure tests are consistent +beforeAll(cleanup); +afterAll(cleanup); + +describe("Movie seeding", () => { + it("Can create a movie", async () => { + // create video beforehand to test linking + await db.insert(videos).values(duneVideo); + + const resp = await app.handle( + new Request("http://localhost/movies", { + method: "POST", + body: JSON.stringify(dune), + headers: { + "Content-Type": "application/json", + }, + }), + ); + const body = await resp.json(); + + expect(resp.status).toBe(201); + expect(body.id).toBeString(); + expect(body.slug).toBe("dune"); + expect(body.videos).toContain({ slug: "dune" }); + }); + + test.todo("Conflicting slug auto-correct", async () => {}); + test.todo("Conflict in slug+year fails", async () => {}); + test.todo("Missing videos send info", async () => {}); + test.todo("Schema error", async () => {}); + test.todo("Invalid translation name", async () => {}); + test.todo("Update existing movie", async () => {}); + test.todo("Create correct video slug (version)", async () => {}); + test.todo("Create correct video slug (part)", async () => {}); + test.todo("Create correct video slug (rendering)", async () => {}); +}); diff --git a/api/tests/setup.ts b/api/tests/setup.ts new file mode 100644 index 00000000..bd83271a --- /dev/null +++ b/api/tests/setup.ts @@ -0,0 +1,10 @@ +import { beforeAll } from "bun:test"; +import { migrate } from "drizzle-orm/node-postgres/migrator"; +import { db } from "~/db"; + +beforeAll(async () => { + await migrate(db, { + migrationsSchema: "kyoo", + migrationsFolder: "./drizzle", + }); +});