diff --git a/api/src/controllers/seed/movies.ts b/api/src/controllers/seed/movies.ts index e7cd3308..16daf805 100644 --- a/api/src/controllers/seed/movies.ts +++ b/api/src/controllers/seed/movies.ts @@ -4,7 +4,7 @@ import { db } from "~/db"; import { entries, entryTranslations, - entryVideoJointure, + entryVideoJointure as evj, shows, showTranslations, videos, @@ -115,7 +115,7 @@ export const seedMovie = async ( let retVideos: { slug: string }[] = []; if (vids) { retVideos = await db - .insert(entryVideoJointure) + .insert(evj) .select( db .select({ @@ -126,16 +126,16 @@ export const seedMovie = async ( concat( ${ret.slug}::text, case when ${videos.part} <> null then concat('-p', ${videos.part}) else '' end, - case when ${videos.version} <> 1 then concat('-v', ${videos.version}) else '' end, - '-', ${videos.rendering} + case when ${videos.version} <> 1 then concat('-v', ${videos.version}) else '' end ) `.as("slug"), + // case when (select count(1) from ${evj} where ${evj.entry} = ${ret.entry}) <> 0 then concat('-', ${videos.rendering}) else '' end }) .from(videos) .where(inArray(videos.id, vids)), ) .onConflictDoNothing() - .returning({ slug: entryVideoJointure.slug }); + .returning({ slug: evj.slug }); } return { diff --git a/api/tests/seed-movies.test.ts b/api/tests/seed-movies.test.ts index 0b0a7d16..df2d717a 100644 --- a/api/tests/seed-movies.test.ts +++ b/api/tests/seed-movies.test.ts @@ -1,12 +1,114 @@ import { afterAll, beforeAll, describe, expect, it, test } from "bun:test"; -import { inArray } from "drizzle-orm"; +import { eq, inArray } from "drizzle-orm"; import Elysia from "elysia"; import { seed } from "~/controllers/seed"; import { db } from "~/db"; -import { shows, videos } from "~/db/schema"; +import { shows, showTranslations, videos } from "~/db/schema"; import { dune, duneVideo } from "~/models/examples/dune-2021"; +import type { SeedMovie } from "~/models/movie"; const app = new Elysia().use(seed); +const createMovie = async (movie: SeedMovie) => { + const resp = await app.handle( + new Request("http://localhost/movies", { + method: "POST", + body: JSON.stringify(movie), + headers: { + "Content-Type": "application/json", + }, + }), + ); + const body = await resp.json(); + return [resp, body] as const; +}; + +function expectStatus(resp: Response, body: object) { + const matcher = expect({ ...body, status: resp.status }); + return { + toBe: (status: number) => { + matcher.toMatchObject({ status: status }); + }, + }; +} + +describe("Movie seeding", () => { + it("Can create a movie", async () => { + // create video beforehand to test linking + await db.insert(videos).values(duneVideo); + + const [resp, body] = await createMovie(dune); + expectStatus(resp, body).toBe(201); + expect(body.id).toBeString(); + expect(body.slug).toBe("dune"); + expect(body.videos).toContainEqual({ slug: "dune" }); + }); + + it("Update existing movie", async () => { + // confirm that db is in the correct state (from previous tests) + const [existing] = await db + .select() + .from(shows) + .where(eq(shows.slug, dune.slug)) + .limit(1); + expect(existing).toMatchObject({ slug: dune.slug, startAir: dune.airDate }); + + const [resp, body] = await createMovie({ + ...dune, + airDate: "2159-12-09", + translations: { + ...dune.translations, + en: { ...dune.translations.en, description: "edited translation" }, + fr: { + name: "dune-but-in-french", + description: null, + tagline: null, + aliases: [], + tags: [], + poster: null, + thumbnail: null, + banner: null, + logo: null, + trailerUrl: null, + }, + }, + }); + const [edited] = await db + .select() + .from(shows) + .where(eq(shows.slug, dune.slug)) + .limit(1); + const translations = await db + .select() + .from(showTranslations) + .where(eq(showTranslations.pk, edited.pk)); + + expectStatus(resp, body).toBe(200); + expect(body.id).toBeString(); + expect(body.slug).toBe("dune"); + expect(body.videos).toBe([]); + expect(edited.startAir).toBe("2159-12-09"); + expect(edited.status).toBe(dune.status); + expect(translations).toMatchObject({ + language: "en", + name: dune.translations.en.name, + description: "edited translation", + }); + expect(translations).toMatchObject({ + language: "fr", + name: "dune-but-in-french", + description: null, + }); + }); + + 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("Create correct video slug (version)", async () => {}); + test.todo("Create correct video slug (part)", async () => {}); + test.todo("Create correct video slug (rendering)", async () => {}); +}); const cleanup = async () => { await db.delete(shows).where(inArray(shows.slug, [dune.slug])); @@ -15,36 +117,3 @@ const cleanup = async () => { // 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 () => {}); -});