mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
Add support for externalId in POST /videos
This commit is contained in:
parent
7203155747
commit
71b3ee61af
@ -213,7 +213,7 @@ export async function getEntries({
|
|||||||
})
|
})
|
||||||
.from(entries)
|
.from(entries)
|
||||||
.innerJoin(transQ, eq(entries.pk, transQ.pk))
|
.innerJoin(transQ, eq(entries.pk, transQ.pk))
|
||||||
.leftJoinLateral(entryVideosQ, sql`true`)
|
.crossJoinLateral(entryVideosQ)
|
||||||
.leftJoin(progressQ, eq(entries.pk, progressQ.entryPk))
|
.leftJoin(progressQ, eq(entries.pk, progressQ.entryPk))
|
||||||
.where(
|
.where(
|
||||||
and(
|
and(
|
||||||
|
@ -286,7 +286,7 @@ export const historyH = new Elysia({ tags: ["profiles"] })
|
|||||||
})
|
})
|
||||||
.from(hist)
|
.from(hist)
|
||||||
.leftJoin(entries, valEqEntries)
|
.leftJoin(entries, valEqEntries)
|
||||||
.leftJoinLateral(nextEntryQ, sql`true`),
|
.crossJoinLateral(nextEntryQ),
|
||||||
)
|
)
|
||||||
.onConflictDoUpdate({
|
.onConflictDoUpdate({
|
||||||
target: [watchlist.profilePk, watchlist.showPk],
|
target: [watchlist.profilePk, watchlist.showPk],
|
||||||
|
@ -112,7 +112,7 @@ export const nextup = new Elysia({ tags: ["profiles"] })
|
|||||||
.from(entries)
|
.from(entries)
|
||||||
.innerJoin(watchlist, eq(watchlist.nextEntry, entries.pk))
|
.innerJoin(watchlist, eq(watchlist.nextEntry, entries.pk))
|
||||||
.innerJoin(transQ, eq(entries.pk, transQ.pk))
|
.innerJoin(transQ, eq(entries.pk, transQ.pk))
|
||||||
.leftJoinLateral(entryVideosQ, sql`true`)
|
.crossJoinLateral(entryVideosQ)
|
||||||
.leftJoin(entryProgressQ, eq(entries.pk, entryProgressQ.entryPk))
|
.leftJoin(entryProgressQ, eq(entries.pk, entryProgressQ.entryPk))
|
||||||
.where(
|
.where(
|
||||||
and(
|
and(
|
||||||
|
@ -41,7 +41,7 @@ import { entryProgressQ, entryVideosQ, mapProgress } from "../entries";
|
|||||||
export const watchStatusQ = db
|
export const watchStatusQ = db
|
||||||
.select({
|
.select({
|
||||||
...getColumns(watchlist),
|
...getColumns(watchlist),
|
||||||
percent: sql`${watchlist.seenCount}`.as("percent"),
|
percent: sql<number>`${watchlist.seenCount}`.as("percent"),
|
||||||
})
|
})
|
||||||
.from(watchlist)
|
.from(watchlist)
|
||||||
.leftJoin(profiles, eq(watchlist.profilePk, profiles.pk))
|
.leftJoin(profiles, eq(watchlist.profilePk, profiles.pk))
|
||||||
@ -161,9 +161,9 @@ const showRelations = {
|
|||||||
).as("videos"),
|
).as("videos"),
|
||||||
})
|
})
|
||||||
.from(entryVideoJoin)
|
.from(entryVideoJoin)
|
||||||
|
.innerJoin(entries, eq(entries.showPk, shows.pk))
|
||||||
|
.innerJoin(videos, eq(videos.pk, entryVideoJoin.videoPk))
|
||||||
.where(eq(entryVideoJoin.entryPk, entries.pk))
|
.where(eq(entryVideoJoin.entryPk, entries.pk))
|
||||||
.leftJoin(entries, eq(entries.showPk, shows.pk))
|
|
||||||
.leftJoin(videos, eq(videos.pk, entryVideoJoin.videoPk))
|
|
||||||
.as("videos");
|
.as("videos");
|
||||||
},
|
},
|
||||||
firstEntry: ({ languages }: { languages: string[] }) => {
|
firstEntry: ({ languages }: { languages: string[] }) => {
|
||||||
@ -190,7 +190,7 @@ const showRelations = {
|
|||||||
.from(entries)
|
.from(entries)
|
||||||
.innerJoin(transQ, eq(entries.pk, transQ.pk))
|
.innerJoin(transQ, eq(entries.pk, transQ.pk))
|
||||||
.leftJoin(entryProgressQ, eq(entries.pk, entryProgressQ.entryPk))
|
.leftJoin(entryProgressQ, eq(entries.pk, entryProgressQ.entryPk))
|
||||||
.leftJoinLateral(entryVideosQ, sql`true`)
|
.crossJoinLateral(entryVideosQ)
|
||||||
.where(and(eq(entries.showPk, shows.pk), ne(entries.kind, "extra")))
|
.where(and(eq(entries.showPk, shows.pk), ne(entries.kind, "extra")))
|
||||||
.orderBy(entries.order)
|
.orderBy(entries.order)
|
||||||
.limit(1)
|
.limit(1)
|
||||||
@ -220,7 +220,7 @@ const showRelations = {
|
|||||||
.from(entries)
|
.from(entries)
|
||||||
.innerJoin(transQ, eq(entries.pk, transQ.pk))
|
.innerJoin(transQ, eq(entries.pk, transQ.pk))
|
||||||
.leftJoin(entryProgressQ, eq(entries.pk, entryProgressQ.entryPk))
|
.leftJoin(entryProgressQ, eq(entries.pk, entryProgressQ.entryPk))
|
||||||
.leftJoinLateral(entryVideosQ, sql`true`)
|
.crossJoinLateral(entryVideosQ)
|
||||||
.where(eq(watchStatusQ.nextEntry, entries.pk))
|
.where(eq(watchStatusQ.nextEntry, entries.pk))
|
||||||
.as("nextEntry");
|
.as("nextEntry");
|
||||||
},
|
},
|
||||||
|
@ -53,9 +53,8 @@ export const videosH = new Elysia({ prefix: "/videos", tags: ["videos"] })
|
|||||||
slug: shows.slug,
|
slug: shows.slug,
|
||||||
})
|
})
|
||||||
.from(videos)
|
.from(videos)
|
||||||
.leftJoin(
|
.crossJoin(
|
||||||
sql`jsonb_array_elements_text(${videos.guess}->'year') as year`,
|
sql`jsonb_array_elements_text(${videos.guess}->'year') as year`,
|
||||||
sql`true`,
|
|
||||||
)
|
)
|
||||||
.innerJoin(entryVideoJoin, eq(entryVideoJoin.videoPk, videos.pk))
|
.innerJoin(entryVideoJoin, eq(entryVideoJoin.videoPk, videos.pk))
|
||||||
.innerJoin(entries, eq(entries.pk, entryVideoJoin.entryPk))
|
.innerJoin(entries, eq(entries.pk, entryVideoJoin.entryPk))
|
||||||
@ -179,7 +178,6 @@ export const videosH = new Elysia({ prefix: "/videos", tags: ["videos"] })
|
|||||||
return x.for.map((e) => ({
|
return x.for.map((e) => ({
|
||||||
video: vids.find((v) => v.path === x.path)!.pk,
|
video: vids.find((v) => v.path === x.path)!.pk,
|
||||||
path: x.path,
|
path: x.path,
|
||||||
needRendering: x.for!.length > 1,
|
|
||||||
entry: {
|
entry: {
|
||||||
...e,
|
...e,
|
||||||
movie:
|
movie:
|
||||||
@ -216,6 +214,7 @@ export const videosH = new Elysia({ prefix: "/videos", tags: ["videos"] })
|
|||||||
order: entries.order,
|
order: entries.order,
|
||||||
showId: sql`${shows.id}`.as("showId"),
|
showId: sql`${shows.id}`.as("showId"),
|
||||||
showSlug: sql`${shows.slug}`.as("showSlug"),
|
showSlug: sql`${shows.slug}`.as("showSlug"),
|
||||||
|
externalId: entries.externalId,
|
||||||
})
|
})
|
||||||
.from(entries)
|
.from(entries)
|
||||||
.innerJoin(shows, eq(entries.showPk, shows.pk))
|
.innerJoin(shows, eq(entries.showPk, shows.pk))
|
||||||
@ -235,13 +234,12 @@ export const videosH = new Elysia({ prefix: "/videos", tags: ["videos"] })
|
|||||||
videoPk: videos.pk,
|
videoPk: videos.pk,
|
||||||
slug: computeVideoSlug(
|
slug: computeVideoSlug(
|
||||||
entriesQ.slug,
|
entriesQ.slug,
|
||||||
sql`j.needRendering or exists(${hasRenderingQ})`,
|
sql`exists(${hasRenderingQ})`,
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
.from(
|
.from(
|
||||||
values(vidEntries, {
|
values(vidEntries, {
|
||||||
video: "integer",
|
video: "integer",
|
||||||
needRendering: "boolean",
|
|
||||||
entry: "jsonb",
|
entry: "jsonb",
|
||||||
}).as("j"),
|
}).as("j"),
|
||||||
)
|
)
|
||||||
@ -293,6 +291,10 @@ export const videosH = new Elysia({ prefix: "/videos", tags: ["videos"] })
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
and(
|
||||||
|
sql`j.entry ? 'externalId'`,
|
||||||
|
sql`j.entry->'externalId' <@ ${entriesQ.externalId}`,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -1,9 +1,21 @@
|
|||||||
|
import { PatternString } from "@sinclair/typebox";
|
||||||
import { t } from "elysia";
|
import { t } from "elysia";
|
||||||
import { type Prettify, comment } from "~/utils";
|
import { type Prettify, comment } from "~/utils";
|
||||||
import { ExtraType } from "./entry/extra";
|
import { ExtraType } from "./entry/extra";
|
||||||
import { bubbleVideo, registerExamples } from "./examples";
|
import { bubble, bubbleVideo, registerExamples } from "./examples";
|
||||||
import { DbMetadata, EpisodeId, ExternalId, Resource } from "./utils";
|
import { DbMetadata, EpisodeId, ExternalId, Resource } from "./utils";
|
||||||
|
|
||||||
|
const ExternalIds = t.Record(
|
||||||
|
t.String(),
|
||||||
|
t.Omit(
|
||||||
|
t.Union([
|
||||||
|
EpisodeId.patternProperties[PatternString],
|
||||||
|
ExternalId().patternProperties[PatternString],
|
||||||
|
]),
|
||||||
|
["link"],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
export const Guess = t.Recursive((Self) =>
|
export const Guess = t.Recursive((Self) =>
|
||||||
t.Object(
|
t.Object(
|
||||||
{
|
{
|
||||||
@ -13,6 +25,7 @@ export const Guess = t.Recursive((Self) =>
|
|||||||
episode: t.Optional(t.Array(t.Integer(), { default: [] })),
|
episode: t.Optional(t.Array(t.Integer(), { default: [] })),
|
||||||
kind: t.Optional(t.UnionEnum(["episode", "movie", "extra"])),
|
kind: t.Optional(t.UnionEnum(["episode", "movie", "extra"])),
|
||||||
extraKind: t.Optional(ExtraType),
|
extraKind: t.Optional(ExtraType),
|
||||||
|
externalId: t.Optional(ExternalIds),
|
||||||
|
|
||||||
from: t.String({
|
from: t.String({
|
||||||
description: "Name of the tool that made the guess",
|
description: "Name of the tool that made the guess",
|
||||||
@ -78,7 +91,7 @@ export const SeedVideo = t.Object({
|
|||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
t.Object({
|
t.Object({
|
||||||
externalId: t.Union([EpisodeId, ExternalId()]),
|
externalId: ExternalIds,
|
||||||
}),
|
}),
|
||||||
t.Object({
|
t.Object({
|
||||||
movie: t.Union([
|
movie: t.Union([
|
||||||
@ -86,27 +99,29 @@ export const SeedVideo = t.Object({
|
|||||||
t.String({ format: "slug", examples: ["bubble"] }),
|
t.String({ format: "slug", examples: ["bubble"] }),
|
||||||
]),
|
]),
|
||||||
}),
|
}),
|
||||||
t.Intersect([
|
|
||||||
t.Object({
|
t.Object({
|
||||||
serie: t.Union([
|
serie: t.Union([
|
||||||
t.String({ format: "uuid" }),
|
t.String({ format: "uuid" }),
|
||||||
t.String({ format: "slug", examples: ["made-in-abyss"] }),
|
t.String({ format: "slug", examples: ["made-in-abyss"] }),
|
||||||
]),
|
]),
|
||||||
}),
|
|
||||||
t.Union([
|
|
||||||
t.Object({
|
|
||||||
season: t.Integer({ minimum: 1 }),
|
season: t.Integer({ minimum: 1 }),
|
||||||
episode: t.Integer(),
|
episode: t.Integer(),
|
||||||
}),
|
}),
|
||||||
t.Object({
|
t.Object({
|
||||||
|
serie: t.Union([
|
||||||
|
t.String({ format: "uuid" }),
|
||||||
|
t.String({ format: "slug", examples: ["made-in-abyss"] }),
|
||||||
|
]),
|
||||||
order: t.Number(),
|
order: t.Number(),
|
||||||
}),
|
}),
|
||||||
t.Object({
|
t.Object({
|
||||||
|
serie: t.Union([
|
||||||
|
t.String({ format: "uuid" }),
|
||||||
|
t.String({ format: "slug", examples: ["made-in-abyss"] }),
|
||||||
|
]),
|
||||||
special: t.Integer(),
|
special: t.Integer(),
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
]),
|
|
||||||
]),
|
|
||||||
{ default: [] },
|
{ default: [] },
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -123,13 +138,29 @@ export const Video = t.Composite([
|
|||||||
export type Video = Prettify<typeof Video.static>;
|
export type Video = Prettify<typeof Video.static>;
|
||||||
|
|
||||||
// type used in entry responses (the slug comes from the entryVideoJoin)
|
// type used in entry responses (the slug comes from the entryVideoJoin)
|
||||||
export const EmbeddedVideo = t.Composite([
|
export const EmbeddedVideo = t.Composite(
|
||||||
|
[
|
||||||
t.Object({ slug: t.String({ format: "slug" }) }),
|
t.Object({ slug: t.String({ format: "slug" }) }),
|
||||||
t.Omit(Video, ["guess", "createdAt", "updatedAt"]),
|
t.Omit(Video, ["guess", "createdAt", "updatedAt"]),
|
||||||
]);
|
],
|
||||||
|
{ additionalProperties: true },
|
||||||
|
);
|
||||||
export type EmbeddedVideo = Prettify<typeof EmbeddedVideo.static>;
|
export type EmbeddedVideo = Prettify<typeof EmbeddedVideo.static>;
|
||||||
|
|
||||||
registerExamples(Video, bubbleVideo);
|
registerExamples(Video, bubbleVideo);
|
||||||
|
registerExamples(SeedVideo, {
|
||||||
|
...bubbleVideo,
|
||||||
|
for: [
|
||||||
|
{ movie: "bubble" },
|
||||||
|
{
|
||||||
|
externalId: {
|
||||||
|
themoviedatabase: {
|
||||||
|
dataId: bubble.externalId.themoviedatabase.dataId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
export const Guesses = t.Object({
|
export const Guesses = t.Object({
|
||||||
paths: t.Array(t.String()),
|
paths: t.Array(t.String()),
|
||||||
|
@ -8,7 +8,6 @@ import { createSerie, createVideo } from "./helpers";
|
|||||||
// export JWT_SECRET="this is a secret";
|
// export JWT_SECRET="this is a secret";
|
||||||
// export JWT_ISSUER="https://kyoo.zoriya.dev";
|
// export JWT_ISSUER="https://kyoo.zoriya.dev";
|
||||||
|
|
||||||
|
|
||||||
await migrate();
|
await migrate();
|
||||||
await db.delete(shows);
|
await db.delete(shows);
|
||||||
await db.delete(profiles);
|
await db.delete(profiles);
|
||||||
|
@ -220,4 +220,185 @@ describe("Video seeding", () => {
|
|||||||
expect(vid!.evj[0].slug).toBe("made-in-abyss-dawn-of-the-deep-soul");
|
expect(vid!.evj[0].slug).toBe("made-in-abyss-dawn-of-the-deep-soul");
|
||||||
expect(vid!.evj[0].entry.slug).toBe("made-in-abyss-dawn-of-the-deep-soul");
|
expect(vid!.evj[0].entry.slug).toBe("made-in-abyss-dawn-of-the-deep-soul");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("With external id", async () => {
|
||||||
|
const [resp, body] = await createVideo({
|
||||||
|
guess: {
|
||||||
|
title: "mia",
|
||||||
|
season: [0],
|
||||||
|
episode: [3],
|
||||||
|
from: "test",
|
||||||
|
externalId: {
|
||||||
|
themoviedb: { serieId: "72636", season: 1, episode: 13 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
part: null,
|
||||||
|
path: "/video/mia s1e13 [tmdb=72636].mkv",
|
||||||
|
rendering: "notehu",
|
||||||
|
version: 1,
|
||||||
|
for: [
|
||||||
|
{
|
||||||
|
externalId: {
|
||||||
|
themoviedb: { serieId: "72636", season: 1, episode: 13 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
expectStatus(resp, body).toBe(201);
|
||||||
|
expect(body).toBeArrayOfSize(1);
|
||||||
|
expect(body[0].id).toBeString();
|
||||||
|
|
||||||
|
const vid = await db.query.videos.findFirst({
|
||||||
|
where: eq(videos.id, body[0].id),
|
||||||
|
with: {
|
||||||
|
evj: { with: { entry: true } },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(vid).not.toBeNil();
|
||||||
|
expect(vid!.path).toBe("/video/mia s1e13 [tmdb=72636].mkv");
|
||||||
|
expect(vid!.guess).toMatchObject({ title: "mia", from: "test" });
|
||||||
|
|
||||||
|
expect(body[0].entries).toBeArrayOfSize(1);
|
||||||
|
expect(vid!.evj).toBeArrayOfSize(1);
|
||||||
|
|
||||||
|
expect(vid!.evj[0].slug).toBe("made-in-abyss-s1e13-notehu");
|
||||||
|
expect(vid!.evj[0].entry.slug).toBe("made-in-abyss-s1e13");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("With movie external id", async () => {
|
||||||
|
const [resp, body] = await createVideo({
|
||||||
|
guess: {
|
||||||
|
title: "bubble",
|
||||||
|
from: "test",
|
||||||
|
externalId: {
|
||||||
|
themoviedb: { dataId: "912598", season: 1, episode: 13 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
part: null,
|
||||||
|
path: "/video/bubble [tmdb=912598].mkv",
|
||||||
|
rendering: "onetuh",
|
||||||
|
version: 1,
|
||||||
|
for: [
|
||||||
|
{
|
||||||
|
externalId: {
|
||||||
|
themoviedb: { serieId: "912598", season: 1, episode: 13 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
expectStatus(resp, body).toBe(201);
|
||||||
|
expect(body).toBeArrayOfSize(1);
|
||||||
|
expect(body[0].id).toBeString();
|
||||||
|
|
||||||
|
const vid = await db.query.videos.findFirst({
|
||||||
|
where: eq(videos.id, body[0].id),
|
||||||
|
with: {
|
||||||
|
evj: { with: { entry: true } },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(vid).not.toBeNil();
|
||||||
|
expect(vid!.path).toBe("/video/bubble [tmdb=912598].mkv");
|
||||||
|
expect(vid!.guess).toMatchObject({ title: "bubble", from: "test" });
|
||||||
|
|
||||||
|
expect(body[0].entries).toBeArrayOfSize(1);
|
||||||
|
expect(vid!.evj).toBeArrayOfSize(1);
|
||||||
|
|
||||||
|
expect(vid!.evj[0].slug).toBe("bubble-onetuh");
|
||||||
|
expect(vid!.evj[0].entry.slug).toBe("bubble");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Two for the same entry", async () => {
|
||||||
|
const [resp, body] = await createVideo({
|
||||||
|
guess: {
|
||||||
|
title: "bubble",
|
||||||
|
from: "test",
|
||||||
|
externalId: {
|
||||||
|
themoviedb: { dataId: "912598", season: 1, episode: 13 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
part: null,
|
||||||
|
path: "/video/bubble [tmdb=912598].mkv",
|
||||||
|
rendering: "cwhtn",
|
||||||
|
version: 1,
|
||||||
|
for: [
|
||||||
|
{ movie: "bubble" },
|
||||||
|
{
|
||||||
|
externalId: {
|
||||||
|
themoviedb: { serieId: "912598", season: 1, episode: 13 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
expectStatus(resp, body).toBe(201);
|
||||||
|
expect(body).toBeArrayOfSize(1);
|
||||||
|
expect(body[0].id).toBeString();
|
||||||
|
|
||||||
|
const vid = await db.query.videos.findFirst({
|
||||||
|
where: eq(videos.id, body[0].id),
|
||||||
|
with: {
|
||||||
|
evj: { with: { entry: true } },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(vid).not.toBeNil();
|
||||||
|
expect(vid!.path).toBe("/video/bubble [tmdb=912598].mkv");
|
||||||
|
expect(vid!.guess).toMatchObject({ title: "bubble", from: "test" });
|
||||||
|
|
||||||
|
expect(body[0].entries).toBeArrayOfSize(1);
|
||||||
|
expect(vid!.evj).toBeArrayOfSize(1);
|
||||||
|
|
||||||
|
expect(vid!.evj[0].slug).toBe("bubble-cwhtn");
|
||||||
|
expect(vid!.evj[0].entry.slug).toBe("bubble");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Two for the same entry WITHOUT rendering", async () => {
|
||||||
|
await db.delete(videos);
|
||||||
|
const [resp, body] = await createVideo({
|
||||||
|
guess: {
|
||||||
|
title: "bubble",
|
||||||
|
from: "test",
|
||||||
|
externalId: {
|
||||||
|
themoviedb: { dataId: "912598", season: 1, episode: 13 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
part: null,
|
||||||
|
path: "/video/bubble [tmdb=912598].mkv",
|
||||||
|
rendering: "cwhtn",
|
||||||
|
version: 1,
|
||||||
|
for: [
|
||||||
|
{ movie: "bubble" },
|
||||||
|
{
|
||||||
|
externalId: {
|
||||||
|
themoviedb: { serieId: "912598", season: 1, episode: 13 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
expectStatus(resp, body).toBe(201);
|
||||||
|
expect(body).toBeArrayOfSize(1);
|
||||||
|
expect(body[0].id).toBeString();
|
||||||
|
|
||||||
|
const vid = await db.query.videos.findFirst({
|
||||||
|
where: eq(videos.id, body[0].id),
|
||||||
|
with: {
|
||||||
|
evj: { with: { entry: true } },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(vid).not.toBeNil();
|
||||||
|
expect(vid!.path).toBe("/video/bubble [tmdb=912598].mkv");
|
||||||
|
expect(vid!.guess).toMatchObject({ title: "bubble", from: "test" });
|
||||||
|
|
||||||
|
expect(body[0].entries).toBeArrayOfSize(1);
|
||||||
|
expect(vid!.evj).toBeArrayOfSize(1);
|
||||||
|
|
||||||
|
expect(vid!.evj[0].slug).toBe("bubble");
|
||||||
|
expect(vid!.evj[0].entry.slug).toBe("bubble");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user