diff --git a/api/tests/movies/get-all-movies.test.ts b/api/tests/movies/get-all-movies.test.ts index 9e3aa5bc..09adc457 100644 --- a/api/tests/movies/get-all-movies.test.ts +++ b/api/tests/movies/get-all-movies.test.ts @@ -1,56 +1,20 @@ import { afterAll, beforeAll, describe, expect, it } from "bun:test"; -import Elysia from "elysia"; -import { base } from "~/base"; -import { movies } from "~/controllers/movies"; +import { expectStatus } from "tests/utils"; import { seedMovie } from "~/controllers/seed/movies"; import { db } from "~/db"; import { shows } from "~/db/schema"; import { bubble } from "~/models/examples"; import { dune1984 } from "~/models/examples/dune-1984"; import { dune } from "~/models/examples/dune-2021"; +import { getMovies, movieApp } from "./movies-helper"; -const app = new Elysia().use(base).use(movies); -const getMovies = async ({ - langs, - ...query -}: { - filter?: string; - limit?: number; - after?: string; - sort?: string | string[]; - langs?: string; -}) => { - const params = new URLSearchParams(); - for (const [key, value] of Object.entries(query)) { - if (!Array.isArray(value)) { - params.append(key, value.toString()); - continue; - } - for (const v of value) params.append(key, v.toString()); - } - - const resp = await app.handle( - new Request(`http://localhost/movies?${params}`, { - method: "GET", - headers: langs - ? { - "Accept-Language": langs, - } - : {}, - }), - ); - 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 }); - }, - }; -} +beforeAll(async () => { + await db.delete(shows); + for (const movie of [bubble, dune1984, dune]) await seedMovie(movie); +}); +afterAll(async () => { + await db.delete(shows); +}); describe("Get all movies", () => { it("Invalid filter params", async () => { @@ -108,7 +72,7 @@ describe("Get all movies", () => { }); expectStatus(resp, body).toBe(200); - resp = await app.handle(new Request(body.next)); + resp = await movieApp.handle(new Request(body.next)); body = await resp.json(); expectStatus(resp, body).toBe(200); @@ -141,23 +105,19 @@ describe("Get all movies", () => { ), }); - resp = await app.handle(new Request(next)); + resp = await movieApp.handle(new Request(next)); body = await resp.json(); expectStatus(resp, body).toBe(200); expect(body).toMatchObject({ - items: [expect.objectContaining({ slug: dune1984.slug })], + items: [ + expect.objectContaining({ + slug: dune1984.slug, + airDate: dune1984.airDate, + }), + ], this: next, next: null, }); }); - // TODO: sort with an item that has null in it. We want it to always be last (in both asc & desc). -}); - -beforeAll(async () => { - await db.delete(shows); - for (const movie of [bubble, dune1984, dune]) await seedMovie(movie); -}); -afterAll(async () => { - await db.delete(shows); }); diff --git a/api/tests/movies/get-movies.test.ts b/api/tests/movies/get-movie.test.ts similarity index 75% rename from api/tests/movies/get-movies.test.ts rename to api/tests/movies/get-movie.test.ts index fca0d08a..d43b39b2 100644 --- a/api/tests/movies/get-movies.test.ts +++ b/api/tests/movies/get-movie.test.ts @@ -1,39 +1,21 @@ import { afterAll, beforeAll, describe, expect, it } from "bun:test"; import { eq } from "drizzle-orm"; -import Elysia from "elysia"; -import { base } from "~/base"; -import { movies } from "~/controllers/movies"; import { seedMovie } from "~/controllers/seed/movies"; import { db } from "~/db"; import { shows } from "~/db/schema"; import { bubble } from "~/models/examples"; - -const app = new Elysia().use(base).use(movies); -const getMovie = async (id: string, langs?: string) => { - const resp = await app.handle( - new Request(`http://localhost/movies/${id}`, { - method: "GET", - headers: langs - ? { - "Accept-Language": langs, - } - : {}, - }), - ); - const body = await resp.json(); - return [resp, body] as const; -}; +import { getMovie } from "./movies-helper"; +import { expectStatus } from "tests/utils"; let bubbleId = ""; -function expectStatus(resp: Response, body: object) { - const matcher = expect({ ...body, status: resp.status }); - return { - toBe: (status: number) => { - matcher.toMatchObject({ status: status }); - }, - }; -} +beforeAll(async () => { + const ret = await seedMovie(bubble); + bubbleId = ret.id; +}); +afterAll(async () => { + await db.delete(shows).where(eq(shows.slug, bubble.slug)); +}); describe("Get movie", () => { it("Retrive by slug", async () => { @@ -94,11 +76,3 @@ describe("Get movie", () => { expect(resp.headers.get("Content-Language")).toBe("en"); }); }); - -beforeAll(async () => { - const ret = await seedMovie(bubble); - bubbleId = ret.id; -}); -afterAll(async () => { - await db.delete(shows).where(eq(shows.slug, bubble.slug)); -}); diff --git a/api/tests/movies/movies-helper.ts b/api/tests/movies/movies-helper.ts new file mode 100644 index 00000000..9d160b15 --- /dev/null +++ b/api/tests/movies/movies-helper.ts @@ -0,0 +1,61 @@ +import Elysia from "elysia"; +import { buildUrl } from "tests/utils"; +import { base } from "~/base"; +import { movies } from "~/controllers/movies"; +import { seed } from "~/controllers/seed"; +import type { SeedMovie } from "~/models/movie"; + +export const movieApp = new Elysia().use(base).use(movies).use(seed); + +export const getMovie = async (id: string, langs?: string) => { + const resp = await movieApp.handle( + new Request(`http://localhost/movies/${id}`, { + method: "GET", + headers: langs + ? { + "Accept-Language": langs, + } + : {}, + }), + ); + const body = await resp.json(); + return [resp, body] as const; +}; + +export const getMovies = async ({ + langs, + ...query +}: { + filter?: string; + limit?: number; + after?: string; + sort?: string | string[]; + langs?: string; +}) => { + const resp = await movieApp.handle( + new Request(buildUrl("movies", query), { + method: "GET", + headers: langs + ? { + "Accept-Language": langs, + } + : {}, + }), + ); + const body = await resp.json(); + return [resp, body] as const; +}; + +export const createMovie = async (movie: SeedMovie) => { + const resp = await movieApp.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; +}; diff --git a/api/tests/movies/seed-movies.test.ts b/api/tests/movies/seed-movies.test.ts index 8e950fe8..cb32428a 100644 --- a/api/tests/movies/seed-movies.test.ts +++ b/api/tests/movies/seed-movies.test.ts @@ -1,37 +1,11 @@ import { afterAll, beforeAll, describe, expect, it, test } from "bun:test"; import { eq, inArray } from "drizzle-orm"; -import Elysia from "elysia"; -import { base } from "~/base"; -import { seed } from "~/controllers/seed"; +import { expectStatus } from "tests/utils"; import { db } from "~/db"; import { shows, showTranslations, videos } from "~/db/schema"; import { bubble } from "~/models/examples"; import { dune, duneVideo } from "~/models/examples/dune-2021"; -import type { SeedMovie } from "~/models/movie"; - -const app = new Elysia().use(base).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 }); - }, - }; -} +import { createMovie } from "./movies-helper"; describe("Movie seeding", () => { it("Can create a movie", async () => { diff --git a/api/tests/utils.ts b/api/tests/utils.ts new file mode 100644 index 00000000..be2480d8 --- /dev/null +++ b/api/tests/utils.ts @@ -0,0 +1,23 @@ +import { expect } from "bun:test"; +import Elysia from "elysia"; + +export function expectStatus(resp: Response, body: object) { + const matcher = expect({ ...body, status: resp.status }); + return { + toBe: (status: number) => { + matcher.toMatchObject({ status: status }); + }, + }; +} + +export const buildUrl = (route: string, query: Record) => { + const params = new URLSearchParams(); + for (const [key, value] of Object.entries(query)) { + if (!Array.isArray(value)) { + params.append(key, value.toString()); + continue; + } + for (const v of value) params.append(key, v.toString()); + } + return `http://localhost/${route}?${params}`; +};