mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-31 20:24:27 -04:00
Fix existing get movie & add test
This commit is contained in:
parent
c263dd770e
commit
9e1afca9ec
@ -2,21 +2,24 @@ import { Elysia, t } from "elysia";
|
|||||||
import { Movie, MovieTranslation } from "../models/movie";
|
import { Movie, MovieTranslation } from "../models/movie";
|
||||||
import { db } from "../db";
|
import { db } from "../db";
|
||||||
import { shows, showTranslations } from "../db/schema/shows";
|
import { shows, showTranslations } from "../db/schema/shows";
|
||||||
import { eq, and, sql, or, inArray } from "drizzle-orm";
|
import { eq, and, sql, or } from "drizzle-orm";
|
||||||
import { getColumns } from "../db/schema/utils";
|
import { getColumns } from "../db/schema/utils";
|
||||||
import { bubble } from "../models/examples";
|
import { bubble } from "../models/examples";
|
||||||
|
import { comment } from "~/utils";
|
||||||
|
import { processLanguages } from "~/models/utils";
|
||||||
|
|
||||||
const translations = db
|
const translations = db
|
||||||
.selectDistinctOn([showTranslations.language])
|
.selectDistinctOn([showTranslations.pk])
|
||||||
.from(showTranslations)
|
.from(showTranslations)
|
||||||
.where(
|
// .where(
|
||||||
or(
|
// or(
|
||||||
inArray(showTranslations.language, sql.placeholder("langs")),
|
// eq(showTranslations.language, sql`any(${sql.placeholder("langs")})`),
|
||||||
eq(showTranslations.language, shows.originalLanguage),
|
// eq(showTranslations.language, shows.originalLanguage),
|
||||||
),
|
// ),
|
||||||
)
|
// )
|
||||||
.orderBy(
|
.orderBy(
|
||||||
sql`array_position(${showTranslations.language}, ${sql.placeholder("langs")})`,
|
showTranslations.pk,
|
||||||
|
sql`array_position(${sql.placeholder("langs")}, ${showTranslations.language})`,
|
||||||
)
|
)
|
||||||
.as("t");
|
.as("t");
|
||||||
|
|
||||||
@ -26,21 +29,21 @@ const { pk, language, ...translationsCol } = getColumns(translations);
|
|||||||
const findMovie = db
|
const findMovie = db
|
||||||
.select({
|
.select({
|
||||||
...moviesCol,
|
...moviesCol,
|
||||||
|
...translationsCol,
|
||||||
airDate: startAir,
|
airDate: startAir,
|
||||||
translations: translationsCol,
|
|
||||||
})
|
})
|
||||||
.from(shows)
|
.from(shows)
|
||||||
.innerJoin(translations, eq(shows.pk, translations.pk))
|
.innerJoin(translations, eq(shows.pk, translations.pk))
|
||||||
.where(
|
.where(
|
||||||
and(
|
and(
|
||||||
eq(shows.kind, "movie"),
|
eq(shows.kind, "movie"),
|
||||||
or(
|
// or(
|
||||||
eq(shows.id, sql.placeholder("id")),
|
// eq(shows.id, sql.placeholder("id")),
|
||||||
eq(shows.slug, sql.placeholder("id")),
|
eq(shows.slug, sql.placeholder("id")),
|
||||||
),
|
// ),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.orderBy()
|
// .orderBy()
|
||||||
.limit(1)
|
.limit(1)
|
||||||
.prepare("findMovie");
|
.prepare("findMovie");
|
||||||
|
|
||||||
@ -57,12 +60,31 @@ export const movies = new Elysia({ prefix: "/movies", tags: ["movies"] })
|
|||||||
examples: [bubble.slug],
|
examples: [bubble.slug],
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
|
headers: t.Object({
|
||||||
|
"Accept-Language": t.String({
|
||||||
|
default: "*",
|
||||||
|
examples: "en-us, ja;q=0.5",
|
||||||
|
description: comment`
|
||||||
|
List of languages you want the data in.
|
||||||
|
This follows the Accept-Language offical specification
|
||||||
|
(https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language)
|
||||||
|
`,
|
||||||
|
}),
|
||||||
|
}),
|
||||||
response: { 200: "movie", 404: "error" },
|
response: { 200: "movie", 404: "error" },
|
||||||
})
|
})
|
||||||
.get(
|
.get(
|
||||||
"/:id",
|
"/:id",
|
||||||
async ({ params: { id }, error }) => {
|
async ({
|
||||||
const ret = await findMovie.execute({ id });
|
params: { id },
|
||||||
|
headers: { "Accept-Language": languages },
|
||||||
|
error,
|
||||||
|
}) => {
|
||||||
|
const langs = processLanguages(languages);
|
||||||
|
console.log(langs);
|
||||||
|
console.log(findMovie.getQuery());
|
||||||
|
const ret = await findMovie.execute({ id, langs });
|
||||||
|
console.log(ret);
|
||||||
if (ret.length !== 1) return error(404, {});
|
if (ret.length !== 1) return error(404, {});
|
||||||
return ret[0];
|
return ret[0];
|
||||||
},
|
},
|
||||||
@ -71,4 +93,4 @@ export const movies = new Elysia({ prefix: "/movies", tags: ["movies"] })
|
|||||||
description: "Get a movie by id or slug",
|
description: "Get a movie by id or slug",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
)
|
||||||
|
@ -48,3 +48,18 @@ export const Language = (props?: StringProps) =>
|
|||||||
error: "Expected a valid (and NORMALIZED) bcp-47 language code.",
|
error: "Expected a valid (and NORMALIZED) bcp-47 language code.",
|
||||||
...props,
|
...props,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const processLanguages = (languages: string) => {
|
||||||
|
return languages
|
||||||
|
.split(",")
|
||||||
|
.map((x) => {
|
||||||
|
const [lang, q] = x.trim().split(";q=");
|
||||||
|
return [lang, q ? Number.parseFloat(q) : 1] as const;
|
||||||
|
})
|
||||||
|
.sort(([_, q1], [__, q2]) => q1 - q2)
|
||||||
|
.flatMap(([lang]) => {
|
||||||
|
const [base, spec] = lang.split("-");
|
||||||
|
if (spec) return [lang, base];
|
||||||
|
return [lang];
|
||||||
|
});
|
||||||
|
};
|
||||||
|
52
api/tests/get-movies.test.ts
Normal file
52
api/tests/get-movies.test.ts
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
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: {
|
||||||
|
"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 });
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("Get movie", () => {
|
||||||
|
it("Retrive by slug", async () => {
|
||||||
|
const [resp, body] = await getMovie(bubble.slug, "en");
|
||||||
|
|
||||||
|
expectStatus(resp, body).toBe(200);
|
||||||
|
expect(body).toMatchObject({
|
||||||
|
slug: bubble.slug,
|
||||||
|
name: bubble.translations.en.name,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
const ret = await seedMovie(bubble);
|
||||||
|
console.log("seed bubble", ret);
|
||||||
|
});
|
||||||
|
afterAll(async () => {
|
||||||
|
// await db.delete(shows).where(eq(shows.slug, bubble.slug));
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user