Skip to content

Commit

Permalink
Add test helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
zoriya committed Jan 10, 2025
1 parent 0555fcb commit e78f28e
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 120 deletions.
74 changes: 17 additions & 57 deletions api/tests/movies/get-all-movies.test.ts
Original file line number Diff line number Diff line change
@@ -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 () => {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
});
Original file line number Diff line number Diff line change
@@ -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 () => {
Expand Down Expand Up @@ -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));
});
61 changes: 61 additions & 0 deletions api/tests/movies/movies-helper.ts
Original file line number Diff line number Diff line change
@@ -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;
};
30 changes: 2 additions & 28 deletions api/tests/movies/seed-movies.test.ts
Original file line number Diff line number Diff line change
@@ -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 () => {
Expand Down
23 changes: 23 additions & 0 deletions api/tests/utils.ts
Original file line number Diff line number Diff line change
@@ -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<string, any>) => {
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}`;
};

0 comments on commit e78f28e

Please sign in to comment.