mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
Forge jwt for tests
This commit is contained in:
parent
49f700ca6e
commit
0aab4cd84c
1
.github/workflows/api-test.yml
vendored
1
.github/workflows/api-test.yml
vendored
@ -36,5 +36,4 @@ jobs:
|
||||
working-directory: ./api
|
||||
run: bun test
|
||||
env:
|
||||
JWT_SECRET: "TODO"
|
||||
POSTGRES_SERVER: localhost
|
||||
|
@ -14,13 +14,18 @@ const jwks = createRemoteJWKSet(
|
||||
|
||||
const Jwt = t.Object({
|
||||
sub: t.String({ description: "User id" }),
|
||||
username: t.String(),
|
||||
sid: t.String({ description: "Session id" }),
|
||||
username: t.String(),
|
||||
permissions: t.Array(t.String()),
|
||||
});
|
||||
const validator = TypeCompiler.Compile(Jwt);
|
||||
|
||||
export const auth = new Elysia({ name: "auth" })
|
||||
.guard({
|
||||
headers: t.Object({
|
||||
authorization: t.TemplateLiteral("Bearer ${string}"),
|
||||
}),
|
||||
})
|
||||
.macro({
|
||||
permissions(perms: string[]) {
|
||||
return {
|
||||
|
@ -11,7 +11,7 @@ import { showsH } from "./controllers/shows/shows";
|
||||
import { staffH } from "./controllers/staff";
|
||||
import { studiosH } from "./controllers/studios";
|
||||
import { videosH } from "./controllers/videos";
|
||||
import { KError } from "./models/error";
|
||||
import type { KError } from "./models/error";
|
||||
|
||||
export const base = new Elysia({ name: "base" })
|
||||
.onError(({ code, error }) => {
|
||||
@ -61,11 +61,12 @@ export const app = new Elysia({ prefix })
|
||||
detail: {
|
||||
security: [{ bearer: ["core.read"] }, { api: ["core.read"] }],
|
||||
},
|
||||
response: {
|
||||
401: { ...KError, description: "" },
|
||||
403: { ...KError, description: "" },
|
||||
},
|
||||
perms: ["core.read"],
|
||||
// See https://github.com/elysiajs/elysia/issues/1158
|
||||
// response: {
|
||||
// 401: { ...KError, description: "" },
|
||||
// 403: { ...KError, description: "" },
|
||||
// },
|
||||
permissions: ["core.read"],
|
||||
},
|
||||
(app) =>
|
||||
app
|
||||
@ -84,11 +85,12 @@ export const app = new Elysia({ prefix })
|
||||
detail: {
|
||||
security: [{ bearer: ["core.write"] }, { api: ["core.write"] }],
|
||||
},
|
||||
response: {
|
||||
401: { ...KError, description: "" },
|
||||
403: { ...KError, description: "" },
|
||||
},
|
||||
perms: ["core.read"],
|
||||
// See https://github.com/elysiajs/elysia/issues/1158
|
||||
// response: {
|
||||
// 401: { ...KError, description: "" },
|
||||
// 403: { ...KError, description: "" },
|
||||
// },
|
||||
permissions: ["core.write"],
|
||||
},
|
||||
(app) => app.use(videosH).use(seed),
|
||||
);
|
||||
|
17
api/tests/helpers/jwt.ts
Normal file
17
api/tests/helpers/jwt.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { SignJWT } from "jose";
|
||||
|
||||
export async function getJwtHeaders() {
|
||||
const jwt = await new SignJWT({
|
||||
sub: "39158be0-3f59-4c45-b00d-d25b3bc2b884",
|
||||
sid: "04ac7ecc-255b-481d-b0c8-537c1578e3d5",
|
||||
username: "test-username",
|
||||
permissions: ["core.read", "core.write"],
|
||||
})
|
||||
.setProtectedHeader({ alg: "HS256" })
|
||||
.setIssuedAt()
|
||||
.setIssuer(process.env.JWT_ISSUER!)
|
||||
.setExpirationTime("2h")
|
||||
.sign(new TextEncoder().encode(process.env.JWT_SECRET));
|
||||
|
||||
return { Authorization: `Bearer ${jwt}` };
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
import { buildUrl } from "tests/utils";
|
||||
import { app } from "~/base";
|
||||
import type { SeedMovie } from "~/models/movie";
|
||||
import { getJwtHeaders } from "./jwt";
|
||||
|
||||
export const getMovie = async (
|
||||
id: string,
|
||||
@ -15,8 +16,9 @@ export const getMovie = async (
|
||||
headers: langs
|
||||
? {
|
||||
"Accept-Language": langs,
|
||||
...(await getJwtHeaders()),
|
||||
}
|
||||
: {},
|
||||
: await getJwtHeaders(),
|
||||
}),
|
||||
);
|
||||
const body = await resp.json();
|
||||
@ -41,8 +43,9 @@ export const getMovies = async ({
|
||||
headers: langs
|
||||
? {
|
||||
"Accept-Language": langs,
|
||||
...(await getJwtHeaders()),
|
||||
}
|
||||
: {},
|
||||
: await getJwtHeaders(),
|
||||
}),
|
||||
);
|
||||
const body = await resp.json();
|
||||
@ -56,6 +59,7 @@ export const createMovie = async (movie: SeedMovie) => {
|
||||
body: JSON.stringify(movie),
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...(await getJwtHeaders()),
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { buildUrl } from "tests/utils";
|
||||
import { app } from "~/base";
|
||||
import type { SeedSerie } from "~/models/serie";
|
||||
import { getJwtHeaders } from "./jwt";
|
||||
|
||||
export const createSerie = async (serie: SeedSerie) => {
|
||||
const resp = await app.handle(
|
||||
@ -9,6 +10,7 @@ export const createSerie = async (serie: SeedSerie) => {
|
||||
body: JSON.stringify(serie),
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...(await getJwtHeaders()),
|
||||
},
|
||||
}),
|
||||
);
|
||||
@ -29,8 +31,9 @@ export const getSerie = async (
|
||||
headers: langs
|
||||
? {
|
||||
"Accept-Language": langs,
|
||||
...(await getJwtHeaders()),
|
||||
}
|
||||
: {},
|
||||
: await getJwtHeaders(),
|
||||
}),
|
||||
);
|
||||
const body = await resp.json();
|
||||
@ -58,8 +61,9 @@ export const getSeasons = async (
|
||||
headers: langs
|
||||
? {
|
||||
"Accept-Language": langs,
|
||||
...(await getJwtHeaders()),
|
||||
}
|
||||
: {},
|
||||
: await getJwtHeaders(),
|
||||
}),
|
||||
);
|
||||
const body = await resp.json();
|
||||
@ -87,8 +91,9 @@ export const getEntries = async (
|
||||
headers: langs
|
||||
? {
|
||||
"Accept-Language": langs,
|
||||
...(await getJwtHeaders()),
|
||||
}
|
||||
: {},
|
||||
: await getJwtHeaders(),
|
||||
}),
|
||||
);
|
||||
const body = await resp.json();
|
||||
@ -108,6 +113,7 @@ export const getExtras = async (
|
||||
const resp = await app.handle(
|
||||
new Request(buildUrl(`series/${serie}/extras`, opts), {
|
||||
method: "GET",
|
||||
headers: await getJwtHeaders(),
|
||||
}),
|
||||
);
|
||||
const body = await resp.json();
|
||||
@ -124,6 +130,7 @@ export const getUnknowns = async (opts: {
|
||||
const resp = await app.handle(
|
||||
new Request(buildUrl("unknowns", opts), {
|
||||
method: "GET",
|
||||
headers: await getJwtHeaders(),
|
||||
}),
|
||||
);
|
||||
const body = await resp.json();
|
||||
@ -147,8 +154,9 @@ export const getNews = async ({
|
||||
headers: langs
|
||||
? {
|
||||
"Accept-Language": langs,
|
||||
...(await getJwtHeaders()),
|
||||
}
|
||||
: {},
|
||||
: await getJwtHeaders(),
|
||||
}),
|
||||
);
|
||||
const body = await resp.json();
|
||||
|
@ -1,10 +1,12 @@
|
||||
import { buildUrl } from "tests/utils";
|
||||
import { app } from "~/base";
|
||||
import { getJwtHeaders } from "./jwt";
|
||||
|
||||
export const getStaff = async (id: string, query: {}) => {
|
||||
const resp = await app.handle(
|
||||
new Request(buildUrl(`staff/${id}`, query), {
|
||||
method: "GET",
|
||||
headers: await getJwtHeaders(),
|
||||
}),
|
||||
);
|
||||
const body = await resp.json();
|
||||
@ -32,8 +34,9 @@ export const getStaffRoles = async (
|
||||
headers: langs
|
||||
? {
|
||||
"Accept-Language": langs,
|
||||
...(await getJwtHeaders()),
|
||||
}
|
||||
: {},
|
||||
: await getJwtHeaders(),
|
||||
}),
|
||||
);
|
||||
const body = await resp.json();
|
||||
@ -52,6 +55,7 @@ export const getSerieStaff = async (
|
||||
const resp = await app.handle(
|
||||
new Request(buildUrl(`series/${serie}/staff`, opts), {
|
||||
method: "GET",
|
||||
headers: await getJwtHeaders(),
|
||||
}),
|
||||
);
|
||||
const body = await resp.json();
|
||||
@ -70,6 +74,7 @@ export const getMovieStaff = async (
|
||||
const resp = await app.handle(
|
||||
new Request(buildUrl(`movies/${movie}/staff`, opts), {
|
||||
method: "GET",
|
||||
headers: await getJwtHeaders(),
|
||||
}),
|
||||
);
|
||||
const body = await resp.json();
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { buildUrl } from "tests/utils";
|
||||
import { app } from "~/base";
|
||||
import { getJwtHeaders } from "./jwt";
|
||||
|
||||
export const getStudio = async (
|
||||
id: string,
|
||||
@ -11,8 +12,9 @@ export const getStudio = async (
|
||||
headers: langs
|
||||
? {
|
||||
"Accept-Language": langs,
|
||||
...await getJwtHeaders()
|
||||
}
|
||||
: {},
|
||||
: await getJwtHeaders()
|
||||
}),
|
||||
);
|
||||
const body = await resp.json();
|
||||
@ -40,8 +42,9 @@ export const getShowsByStudio = async (
|
||||
headers: langs
|
||||
? {
|
||||
"Accept-Language": langs,
|
||||
...await getJwtHeaders()
|
||||
}
|
||||
: {},
|
||||
: await getJwtHeaders()
|
||||
}),
|
||||
);
|
||||
const body = await resp.json();
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { buildUrl } from "tests/utils";
|
||||
import { app } from "~/base";
|
||||
import type { SeedVideo } from "~/models/video";
|
||||
import { getJwtHeaders } from "./jwt";
|
||||
|
||||
export const createVideo = async (video: SeedVideo | SeedVideo[]) => {
|
||||
const resp = await app.handle(
|
||||
@ -9,6 +10,7 @@ export const createVideo = async (video: SeedVideo | SeedVideo[]) => {
|
||||
body: JSON.stringify(Array.isArray(video) ? video : [video]),
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...(await getJwtHeaders()),
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { beforeAll, describe, expect, it } from "bun:test";
|
||||
import { getJwtHeaders } from "tests/helpers/jwt";
|
||||
import { expectStatus } from "tests/utils";
|
||||
import { db } from "~/db";
|
||||
import { shows } from "~/db/schema";
|
||||
@ -10,8 +11,8 @@ import { app, createMovie, getMovies } from "../helpers";
|
||||
beforeAll(async () => {
|
||||
await db.delete(shows);
|
||||
for (const movie of [bubble, dune1984, dune]) {
|
||||
const [ret, _] = await createMovie(movie);
|
||||
expect(ret.status).toBe(201);
|
||||
const [ret, body] = await createMovie(movie);
|
||||
expectStatus(ret, body).toBe(201);
|
||||
}
|
||||
});
|
||||
|
||||
@ -73,7 +74,9 @@ describe("with a null value", () => {
|
||||
),
|
||||
});
|
||||
|
||||
resp = await app.handle(new Request(next));
|
||||
resp = await app.handle(
|
||||
new Request(next, { headers: await getJwtHeaders() }),
|
||||
);
|
||||
body = await resp.json();
|
||||
|
||||
expectStatus(resp, body).toBe(200);
|
||||
@ -120,7 +123,9 @@ describe("with a null value", () => {
|
||||
),
|
||||
});
|
||||
|
||||
resp = await app.handle(new Request(next));
|
||||
resp = await app.handle(
|
||||
new Request(next, { headers: await getJwtHeaders() }),
|
||||
);
|
||||
body = await resp.json();
|
||||
|
||||
expectStatus(resp, body).toBe(200);
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { beforeAll, describe, expect, it } from "bun:test";
|
||||
import { getJwtHeaders } from "tests/helpers/jwt";
|
||||
import { expectStatus } from "tests/utils";
|
||||
import { db } from "~/db";
|
||||
import { shows } from "~/db/schema";
|
||||
@ -71,7 +72,9 @@ describe("Get all movies", () => {
|
||||
});
|
||||
expectStatus(resp, body).toBe(200);
|
||||
|
||||
resp = await app.handle(new Request(body.next));
|
||||
resp = await app.handle(
|
||||
new Request(body.next, { headers: await getJwtHeaders() }),
|
||||
);
|
||||
body = await resp.json();
|
||||
|
||||
expectStatus(resp, body).toBe(200);
|
||||
@ -104,7 +107,9 @@ describe("Get all movies", () => {
|
||||
),
|
||||
});
|
||||
|
||||
resp = await app.handle(new Request(next));
|
||||
resp = await app.handle(
|
||||
new Request(next, { headers: await getJwtHeaders() }),
|
||||
);
|
||||
body = await resp.json();
|
||||
|
||||
expectStatus(resp, body).toBe(200);
|
||||
@ -160,7 +165,9 @@ describe("Get all movies", () => {
|
||||
expect(items.length).toBe(1);
|
||||
expect(items[0].id).toBe(expectedIds[0]);
|
||||
// Get Second Page
|
||||
resp = await app.handle(new Request(body.next));
|
||||
resp = await app.handle(
|
||||
new Request(body.next, { headers: await getJwtHeaders() }),
|
||||
);
|
||||
body = await resp.json();
|
||||
|
||||
expectStatus(resp, body).toBe(200);
|
||||
@ -175,7 +182,9 @@ describe("Get all movies", () => {
|
||||
});
|
||||
expectStatus(resp, body).toBe(200);
|
||||
|
||||
const resp2 = await app.handle(new Request(body.next));
|
||||
const resp2 = await app.handle(
|
||||
new Request(body.next, { headers: await getJwtHeaders() }),
|
||||
);
|
||||
const body2 = await resp2.json();
|
||||
expectStatus(resp2, body).toBe(200);
|
||||
|
||||
@ -187,7 +196,9 @@ describe("Get all movies", () => {
|
||||
|
||||
it("Get /random", async () => {
|
||||
const resp = await app.handle(
|
||||
new Request("http://localhost/movies/random"),
|
||||
new Request("http://localhost/movies/random", {
|
||||
headers: await getJwtHeaders(),
|
||||
}),
|
||||
);
|
||||
expect(resp.status).toBe(302);
|
||||
const location = resp.headers.get("location")!;
|
||||
|
@ -1,6 +1,9 @@
|
||||
import { beforeAll } from "bun:test";
|
||||
import { migrate } from "~/db";
|
||||
|
||||
process.env.JWT_SECRET = "this is a secret";
|
||||
process.env.JWT_ISSUER = "https://kyoo.zoriya.dev";
|
||||
|
||||
beforeAll(async () => {
|
||||
await migrate();
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user