feat: associate device id with username when logging in
This commit is contained in:
@@ -5,6 +5,7 @@ import { streamSSE } from "hono/streaming";
|
||||
import { fetchEpisodes } from "~/controllers/episodes/getByAniListId";
|
||||
import { maybeScheduleNextAiringEpisode } from "~/libs/maybeScheduleNextAiringEpisode";
|
||||
import { readEnvVariable } from "~/libs/readEnvVariable";
|
||||
import { associateDeviceIdWithUsername } from "~/models/token";
|
||||
import { setWatchStatus } from "~/models/watchStatus";
|
||||
import type { Env } from "~/types/env";
|
||||
import { EpisodesResponseSchema } from "~/types/episode";
|
||||
@@ -60,9 +61,8 @@ const route = createRoute({
|
||||
const app = new OpenAPIHono<Env>();
|
||||
|
||||
app.openapi(route, async (c) => {
|
||||
// const deviceId = await c.req.header("X-Aniplay-Device-Id");
|
||||
// const aniListToken = await c.req.header("X-AniList-Token");
|
||||
const { deviceId, token: aniListToken } = await c.req.query();
|
||||
const deviceId = await c.req.header("X-Aniplay-Device-Id");
|
||||
const aniListToken = await c.req.header("X-AniList-Token");
|
||||
|
||||
if (!aniListToken) {
|
||||
return c.json(ErrorResponse, { status: 401 });
|
||||
@@ -74,6 +74,8 @@ app.openapi(route, async (c) => {
|
||||
return c.json(ErrorResponse, { status: 401 });
|
||||
}
|
||||
|
||||
await associateDeviceIdWithUsername(env(c, "workerd"), deviceId, username);
|
||||
|
||||
return streamSSE(
|
||||
c,
|
||||
async (stream) => {
|
||||
|
||||
@@ -118,3 +118,241 @@ exports[`requests the "/episodes" route with list of episodes from Anify 1`] = `
|
||||
"success": true,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`requests the "/episodes" route with list of episodes from Anify 1`] = `
|
||||
{
|
||||
"result": {
|
||||
"episodes": [
|
||||
{
|
||||
"description": null,
|
||||
"id": "/watch/spy-classroom-season-2-18468?ep=103233",
|
||||
"img": null,
|
||||
"number": 1,
|
||||
"rating": null,
|
||||
"title": "Mission: Forgetter I",
|
||||
"updatedAt": 0,
|
||||
},
|
||||
{
|
||||
"description": null,
|
||||
"id": "/watch/spy-classroom-season-2-18468?ep=103632",
|
||||
"img": null,
|
||||
"number": 2,
|
||||
"rating": null,
|
||||
"title": "Mission: Forgetter II",
|
||||
"updatedAt": 0,
|
||||
},
|
||||
{
|
||||
"description": null,
|
||||
"id": "/watch/spy-classroom-season-2-18468?ep=104244",
|
||||
"img": null,
|
||||
"number": 3,
|
||||
"rating": null,
|
||||
"title": "Mission: Forgetter III",
|
||||
"updatedAt": 0,
|
||||
},
|
||||
{
|
||||
"description": null,
|
||||
"id": "/watch/spy-classroom-season-2-18468?ep=104620",
|
||||
"img": null,
|
||||
"number": 4,
|
||||
"rating": null,
|
||||
"title": "Mission: Forgetter IV",
|
||||
"updatedAt": 0,
|
||||
},
|
||||
{
|
||||
"description": null,
|
||||
"id": "/watch/spy-classroom-season-2-18468?ep=104844",
|
||||
"img": null,
|
||||
"number": 5,
|
||||
"rating": null,
|
||||
"title": "File: Glint",
|
||||
"updatedAt": 0,
|
||||
},
|
||||
{
|
||||
"description": null,
|
||||
"id": "/watch/spy-classroom-season-2-18468?ep=105761",
|
||||
"img": null,
|
||||
"number": 6,
|
||||
"rating": null,
|
||||
"title": "File: Dreamspeaker Thea",
|
||||
"updatedAt": 0,
|
||||
},
|
||||
{
|
||||
"description": null,
|
||||
"id": "/watch/spy-classroom-season-2-18468?ep=106135",
|
||||
"img": null,
|
||||
"number": 7,
|
||||
"rating": null,
|
||||
"title": "File: Forgetter Annette",
|
||||
"updatedAt": 0,
|
||||
},
|
||||
{
|
||||
"description": null,
|
||||
"id": "/watch/spy-classroom-season-2-18468?ep=106518",
|
||||
"img": null,
|
||||
"number": 8,
|
||||
"rating": null,
|
||||
"title": "Mission: Dreamspeaker I",
|
||||
"updatedAt": 0,
|
||||
},
|
||||
{
|
||||
"description": null,
|
||||
"id": "/watch/spy-classroom-season-2-18468?ep=106606",
|
||||
"img": null,
|
||||
"number": 9,
|
||||
"rating": null,
|
||||
"title": "Mission: Dreamspeaker II",
|
||||
"updatedAt": 0,
|
||||
},
|
||||
{
|
||||
"description": null,
|
||||
"id": "/watch/spy-classroom-season-2-18468?ep=106981",
|
||||
"img": null,
|
||||
"number": 10,
|
||||
"rating": null,
|
||||
"title": "Mission: Dreamspeaker III",
|
||||
"updatedAt": 0,
|
||||
},
|
||||
{
|
||||
"description": null,
|
||||
"id": "/watch/spy-classroom-season-2-18468?ep=107176",
|
||||
"img": null,
|
||||
"number": 11,
|
||||
"rating": null,
|
||||
"title": "Mission: Dreamspeaker IV",
|
||||
"updatedAt": 0,
|
||||
},
|
||||
{
|
||||
"description": null,
|
||||
"id": "/watch/spy-classroom-season-2-18468?ep=107247",
|
||||
"img": null,
|
||||
"number": 12,
|
||||
"rating": null,
|
||||
"title": "File: Flower Garden Lily",
|
||||
"updatedAt": 0,
|
||||
},
|
||||
],
|
||||
"providerId": "zoro",
|
||||
},
|
||||
"success": true,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`requests the "/episodes" route with list of episodes from Anify 1`] = `
|
||||
{
|
||||
"result": {
|
||||
"episodes": [
|
||||
{
|
||||
"description": null,
|
||||
"id": "/watch/spy-classroom-season-2-18468?ep=103233",
|
||||
"img": null,
|
||||
"number": 1,
|
||||
"rating": null,
|
||||
"title": "Mission: Forgetter I",
|
||||
"updatedAt": 0,
|
||||
},
|
||||
{
|
||||
"description": null,
|
||||
"id": "/watch/spy-classroom-season-2-18468?ep=103632",
|
||||
"img": null,
|
||||
"number": 2,
|
||||
"rating": null,
|
||||
"title": "Mission: Forgetter II",
|
||||
"updatedAt": 0,
|
||||
},
|
||||
{
|
||||
"description": null,
|
||||
"id": "/watch/spy-classroom-season-2-18468?ep=104244",
|
||||
"img": null,
|
||||
"number": 3,
|
||||
"rating": null,
|
||||
"title": "Mission: Forgetter III",
|
||||
"updatedAt": 0,
|
||||
},
|
||||
{
|
||||
"description": null,
|
||||
"id": "/watch/spy-classroom-season-2-18468?ep=104620",
|
||||
"img": null,
|
||||
"number": 4,
|
||||
"rating": null,
|
||||
"title": "Mission: Forgetter IV",
|
||||
"updatedAt": 0,
|
||||
},
|
||||
{
|
||||
"description": null,
|
||||
"id": "/watch/spy-classroom-season-2-18468?ep=104844",
|
||||
"img": null,
|
||||
"number": 5,
|
||||
"rating": null,
|
||||
"title": "File: Glint",
|
||||
"updatedAt": 0,
|
||||
},
|
||||
{
|
||||
"description": null,
|
||||
"id": "/watch/spy-classroom-season-2-18468?ep=105761",
|
||||
"img": null,
|
||||
"number": 6,
|
||||
"rating": null,
|
||||
"title": "File: Dreamspeaker Thea",
|
||||
"updatedAt": 0,
|
||||
},
|
||||
{
|
||||
"description": null,
|
||||
"id": "/watch/spy-classroom-season-2-18468?ep=106135",
|
||||
"img": null,
|
||||
"number": 7,
|
||||
"rating": null,
|
||||
"title": "File: Forgetter Annette",
|
||||
"updatedAt": 0,
|
||||
},
|
||||
{
|
||||
"description": null,
|
||||
"id": "/watch/spy-classroom-season-2-18468?ep=106518",
|
||||
"img": null,
|
||||
"number": 8,
|
||||
"rating": null,
|
||||
"title": "Mission: Dreamspeaker I",
|
||||
"updatedAt": 0,
|
||||
},
|
||||
{
|
||||
"description": null,
|
||||
"id": "/watch/spy-classroom-season-2-18468?ep=106606",
|
||||
"img": null,
|
||||
"number": 9,
|
||||
"rating": null,
|
||||
"title": "Mission: Dreamspeaker II",
|
||||
"updatedAt": 0,
|
||||
},
|
||||
{
|
||||
"description": null,
|
||||
"id": "/watch/spy-classroom-season-2-18468?ep=106981",
|
||||
"img": null,
|
||||
"number": 10,
|
||||
"rating": null,
|
||||
"title": "Mission: Dreamspeaker III",
|
||||
"updatedAt": 0,
|
||||
},
|
||||
{
|
||||
"description": null,
|
||||
"id": "/watch/spy-classroom-season-2-18468?ep=107176",
|
||||
"img": null,
|
||||
"number": 11,
|
||||
"rating": null,
|
||||
"title": "Mission: Dreamspeaker IV",
|
||||
"updatedAt": 0,
|
||||
},
|
||||
{
|
||||
"description": null,
|
||||
"id": "/watch/spy-classroom-season-2-18468?ep=107247",
|
||||
"img": null,
|
||||
"number": 12,
|
||||
"rating": null,
|
||||
"title": "File: Flower Garden Lily",
|
||||
"updatedAt": 0,
|
||||
},
|
||||
],
|
||||
"providerId": "zoro",
|
||||
},
|
||||
"success": true,
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -440,3 +440,885 @@ exports[`requests the "/search" route valid query that returns anilist results 1
|
||||
"success": true,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`requests the "/search" route valid query that returns anilist results 1`] = `
|
||||
{
|
||||
"hasNextPage": false,
|
||||
"results": [
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx151807-yxY3olrjZH4k.png",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx151807-yxY3olrjZH4k.png",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx151807-yxY3olrjZH4k.png",
|
||||
},
|
||||
"id": 151807,
|
||||
"title": {
|
||||
"english": "Solo Leveling",
|
||||
"userPreferred": "Ore dake Level Up na Ken",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx2759-z07kq8Pnw5B1.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx2759-z07kq8Pnw5B1.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx2759-z07kq8Pnw5B1.jpg",
|
||||
},
|
||||
"id": 2759,
|
||||
"title": {
|
||||
"english": "Evangelion: 1.0 You Are (Not) Alone",
|
||||
"userPreferred": "Evangelion Shin Movie: Jo",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx139589-oFz7JwpwRkQV.png",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx139589-oFz7JwpwRkQV.png",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx139589-oFz7JwpwRkQV.png",
|
||||
},
|
||||
"id": 139589,
|
||||
"title": {
|
||||
"english": "Kotaro Lives Alone",
|
||||
"userPreferred": "Kotarou wa Hitorigurashi",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx145815-XsgcXy7WzgtK.png",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx145815-XsgcXy7WzgtK.png",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx145815-XsgcXy7WzgtK.png",
|
||||
},
|
||||
"id": 145815,
|
||||
"title": {
|
||||
"english": "I've Somehow Gotten Stronger When I Improved My Farm-Related Skills",
|
||||
"userPreferred": "Noumin Kanren no Skill Bakka Agetetara Naze ka Tsuyoku Natta.",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx176496-r6oXxEqdZL0n.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx176496-r6oXxEqdZL0n.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx176496-r6oXxEqdZL0n.jpg",
|
||||
},
|
||||
"id": 176496,
|
||||
"title": {
|
||||
"english": "Solo Leveling Season 2 -Arise from the Shadow-",
|
||||
"userPreferred": "Ore dake Level Up na Ken: Season 2 - Arise from the Shadow",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx1965-lWBpcTni9PS9.png",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx1965-lWBpcTni9PS9.png",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx1965-lWBpcTni9PS9.png",
|
||||
},
|
||||
"id": 1965,
|
||||
"title": {
|
||||
"english": null,
|
||||
"userPreferred": "sola",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx118123-xqn5fYsjKXJU.png",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx118123-xqn5fYsjKXJU.png",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx118123-xqn5fYsjKXJU.png",
|
||||
},
|
||||
"id": 118123,
|
||||
"title": {
|
||||
"english": null,
|
||||
"userPreferred": "Holo no Graffiti",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx2582-aB1Vh1jDobQ3.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx2582-aB1Vh1jDobQ3.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx2582-aB1Vh1jDobQ3.jpg",
|
||||
},
|
||||
"id": 2582,
|
||||
"title": {
|
||||
"english": "Armored Trooper Votoms",
|
||||
"userPreferred": "Soukou Kihei Votoms",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx116384-xn0nQAKGFSd7.png",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx116384-xn0nQAKGFSd7.png",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx116384-xn0nQAKGFSd7.png",
|
||||
},
|
||||
"id": 116384,
|
||||
"title": {
|
||||
"english": "Sol Levante",
|
||||
"userPreferred": "Sol Levante",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/nx104073-OQ8YBTy7zmKf.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/nx104073-OQ8YBTy7zmKf.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/nx104073-OQ8YBTy7zmKf.jpg",
|
||||
},
|
||||
"id": 104073,
|
||||
"title": {
|
||||
"english": null,
|
||||
"userPreferred": "Sono Toki, Kanojo wa.",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/15313.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/15313.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/15313.jpg",
|
||||
},
|
||||
"id": 15313,
|
||||
"title": {
|
||||
"english": "Wooser's Hand-to-Mouth Life",
|
||||
"userPreferred": "Wooser no Sono Higurashi",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/8068.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/8068.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/8068.jpg",
|
||||
},
|
||||
"id": 8068,
|
||||
"title": {
|
||||
"english": null,
|
||||
"userPreferred": "Kuroshitsuji Picture Drama",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/3174.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/3174.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/3174.jpg",
|
||||
},
|
||||
"id": 3174,
|
||||
"title": {
|
||||
"english": null,
|
||||
"userPreferred": "sola Specials",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/1443.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/1443.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/1443.jpg",
|
||||
},
|
||||
"id": 1443,
|
||||
"title": {
|
||||
"english": null,
|
||||
"userPreferred": "SOL BIANCA",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx153431-DMBYQxagH3Uu.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx153431-DMBYQxagH3Uu.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx153431-DMBYQxagH3Uu.jpg",
|
||||
},
|
||||
"id": 153431,
|
||||
"title": {
|
||||
"english": null,
|
||||
"userPreferred": "Onna no Sono no Hoshi",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx1444-7Yn6hmQ2bk9D.png",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx1444-7Yn6hmQ2bk9D.png",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx1444-7Yn6hmQ2bk9D.png",
|
||||
},
|
||||
"id": 1444,
|
||||
"title": {
|
||||
"english": "Sol Bianca: The Legacy",
|
||||
"userPreferred": "Sol Bianca: Taiyou no Fune",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/4138.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/4138.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/4138.jpg",
|
||||
},
|
||||
"id": 4138,
|
||||
"title": {
|
||||
"english": "The Adventures of Scamper the Penguin",
|
||||
"userPreferred": "Chiisana Pengin: Lolo no Bouken",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx164192-KQ8sYXbaAl6i.png",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx164192-KQ8sYXbaAl6i.png",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx164192-KQ8sYXbaAl6i.png",
|
||||
},
|
||||
"id": 164192,
|
||||
"title": {
|
||||
"english": "Planetarium",
|
||||
"userPreferred": "Planetarium",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/b5838-QTe07RRZylUm.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/b5838-QTe07RRZylUm.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/b5838-QTe07RRZylUm.jpg",
|
||||
},
|
||||
"id": 5838,
|
||||
"title": {
|
||||
"english": null,
|
||||
"userPreferred": "Furudera no Obake-soudou",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx162882-OQENM5pXn7QQ.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx162882-OQENM5pXn7QQ.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx162882-OQENM5pXn7QQ.jpg",
|
||||
},
|
||||
"id": 162882,
|
||||
"title": {
|
||||
"english": "P.E.T.",
|
||||
"userPreferred": "P.E.T.",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/102710-dVayaOkzATwa.png",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/102710-dVayaOkzATwa.png",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/102710-dVayaOkzATwa.png",
|
||||
},
|
||||
"id": 102710,
|
||||
"title": {
|
||||
"english": "The Garden of Pleasure",
|
||||
"userPreferred": "Kairaku no Sono",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx162881-c7xmNA6DlHFZ.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx162881-c7xmNA6DlHFZ.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx162881-c7xmNA6DlHFZ.jpg",
|
||||
},
|
||||
"id": 162881,
|
||||
"title": {
|
||||
"english": "Mosh Race",
|
||||
"userPreferred": "Mosh Race",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/5935.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/5935.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/5935.jpg",
|
||||
},
|
||||
"id": 5935,
|
||||
"title": {
|
||||
"english": "Marco Polo's Adventures",
|
||||
"userPreferred": "Marco Polo no Boken",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/103449-FxDK8eJuMAKg.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/103449-FxDK8eJuMAKg.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/103449-FxDK8eJuMAKg.jpg",
|
||||
},
|
||||
"id": 103449,
|
||||
"title": {
|
||||
"english": null,
|
||||
"userPreferred": "SOL",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/12993.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/12993.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/12993.jpg",
|
||||
},
|
||||
"id": 12993,
|
||||
"title": {
|
||||
"english": null,
|
||||
"userPreferred": "Sono Mukou no Mukougawa",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/20459.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/20459.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/20459.jpg",
|
||||
},
|
||||
"id": 20459,
|
||||
"title": {
|
||||
"english": null,
|
||||
"userPreferred": "Ganbare! Lulu Lolo",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/b137760-CleNdfmuKRy7.png",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/b137760-CleNdfmuKRy7.png",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/b137760-CleNdfmuKRy7.png",
|
||||
},
|
||||
"id": 137760,
|
||||
"title": {
|
||||
"english": null,
|
||||
"userPreferred": "Soko ni wa Mata Meikyuu",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/7473.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/7473.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/7473.jpg",
|
||||
},
|
||||
"id": 7473,
|
||||
"title": {
|
||||
"english": "Rennyo and His Mother",
|
||||
"userPreferred": "Rennyo to Sono Haha",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/21418-TZYwdItidowx.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/21418-TZYwdItidowx.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/21418-TZYwdItidowx.jpg",
|
||||
},
|
||||
"id": 21418,
|
||||
"title": {
|
||||
"english": null,
|
||||
"userPreferred": "Ganbare! Lulu Lolo 3rd Season",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/103517-XgOUryeFaPDW.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/103517-XgOUryeFaPDW.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/103517-XgOUryeFaPDW.jpg",
|
||||
},
|
||||
"id": 103517,
|
||||
"title": {
|
||||
"english": null,
|
||||
"userPreferred": "Toute wa Sono Kotae",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/b113572-hP9x1SkRJXvA.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/b113572-hP9x1SkRJXvA.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/b113572-hP9x1SkRJXvA.jpg",
|
||||
},
|
||||
"id": 113572,
|
||||
"title": {
|
||||
"english": "Journey to the beyond",
|
||||
"userPreferred": "Sono Saki no Taniji",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/20864.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/20864.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/20864.jpg",
|
||||
},
|
||||
"id": 20864,
|
||||
"title": {
|
||||
"english": null,
|
||||
"userPreferred": "Ganbare! Lulu Lolo 2nd Season",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/15129.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/15129.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/15129.jpg",
|
||||
},
|
||||
"id": 15129,
|
||||
"title": {
|
||||
"english": "Short Animations of Junpei Fujita",
|
||||
"userPreferred": "Tanpen Animation Junpei Fujita",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/nx106557-TPLmwa2EccB9.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/nx106557-TPLmwa2EccB9.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/nx106557-TPLmwa2EccB9.jpg",
|
||||
},
|
||||
"id": 106557,
|
||||
"title": {
|
||||
"english": "A Place to Name",
|
||||
"userPreferred": "Sono Ie no Namae",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/b118133-y7RvDFmr30hZ.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/b118133-y7RvDFmr30hZ.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/b118133-y7RvDFmr30hZ.jpg",
|
||||
},
|
||||
"id": 118133,
|
||||
"title": {
|
||||
"english": "In Inertia",
|
||||
"userPreferred": "Guzu no Soko",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx169686-exScHzB5UX2D.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx169686-exScHzB5UX2D.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx169686-exScHzB5UX2D.jpg",
|
||||
},
|
||||
"id": 169686,
|
||||
"title": {
|
||||
"english": "Indoor Days",
|
||||
"userPreferred": "Soto ni Denai hi",
|
||||
},
|
||||
},
|
||||
],
|
||||
"success": true,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`requests the "/search" route valid query that returns anilist results 1`] = `
|
||||
{
|
||||
"hasNextPage": false,
|
||||
"results": [
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx151807-yxY3olrjZH4k.png",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx151807-yxY3olrjZH4k.png",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx151807-yxY3olrjZH4k.png",
|
||||
},
|
||||
"id": 151807,
|
||||
"title": {
|
||||
"english": "Solo Leveling",
|
||||
"userPreferred": "Ore dake Level Up na Ken",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx2759-z07kq8Pnw5B1.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx2759-z07kq8Pnw5B1.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx2759-z07kq8Pnw5B1.jpg",
|
||||
},
|
||||
"id": 2759,
|
||||
"title": {
|
||||
"english": "Evangelion: 1.0 You Are (Not) Alone",
|
||||
"userPreferred": "Evangelion Shin Movie: Jo",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx139589-oFz7JwpwRkQV.png",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx139589-oFz7JwpwRkQV.png",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx139589-oFz7JwpwRkQV.png",
|
||||
},
|
||||
"id": 139589,
|
||||
"title": {
|
||||
"english": "Kotaro Lives Alone",
|
||||
"userPreferred": "Kotarou wa Hitorigurashi",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx145815-XsgcXy7WzgtK.png",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx145815-XsgcXy7WzgtK.png",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx145815-XsgcXy7WzgtK.png",
|
||||
},
|
||||
"id": 145815,
|
||||
"title": {
|
||||
"english": "I've Somehow Gotten Stronger When I Improved My Farm-Related Skills",
|
||||
"userPreferred": "Noumin Kanren no Skill Bakka Agetetara Naze ka Tsuyoku Natta.",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx176496-r6oXxEqdZL0n.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx176496-r6oXxEqdZL0n.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx176496-r6oXxEqdZL0n.jpg",
|
||||
},
|
||||
"id": 176496,
|
||||
"title": {
|
||||
"english": "Solo Leveling Season 2 -Arise from the Shadow-",
|
||||
"userPreferred": "Ore dake Level Up na Ken: Season 2 - Arise from the Shadow",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx1965-lWBpcTni9PS9.png",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx1965-lWBpcTni9PS9.png",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx1965-lWBpcTni9PS9.png",
|
||||
},
|
||||
"id": 1965,
|
||||
"title": {
|
||||
"english": null,
|
||||
"userPreferred": "sola",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx118123-xqn5fYsjKXJU.png",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx118123-xqn5fYsjKXJU.png",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx118123-xqn5fYsjKXJU.png",
|
||||
},
|
||||
"id": 118123,
|
||||
"title": {
|
||||
"english": null,
|
||||
"userPreferred": "Holo no Graffiti",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx2582-aB1Vh1jDobQ3.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx2582-aB1Vh1jDobQ3.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx2582-aB1Vh1jDobQ3.jpg",
|
||||
},
|
||||
"id": 2582,
|
||||
"title": {
|
||||
"english": "Armored Trooper Votoms",
|
||||
"userPreferred": "Soukou Kihei Votoms",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx116384-xn0nQAKGFSd7.png",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx116384-xn0nQAKGFSd7.png",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx116384-xn0nQAKGFSd7.png",
|
||||
},
|
||||
"id": 116384,
|
||||
"title": {
|
||||
"english": "Sol Levante",
|
||||
"userPreferred": "Sol Levante",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/nx104073-OQ8YBTy7zmKf.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/nx104073-OQ8YBTy7zmKf.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/nx104073-OQ8YBTy7zmKf.jpg",
|
||||
},
|
||||
"id": 104073,
|
||||
"title": {
|
||||
"english": null,
|
||||
"userPreferred": "Sono Toki, Kanojo wa.",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/15313.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/15313.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/15313.jpg",
|
||||
},
|
||||
"id": 15313,
|
||||
"title": {
|
||||
"english": "Wooser's Hand-to-Mouth Life",
|
||||
"userPreferred": "Wooser no Sono Higurashi",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/8068.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/8068.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/8068.jpg",
|
||||
},
|
||||
"id": 8068,
|
||||
"title": {
|
||||
"english": null,
|
||||
"userPreferred": "Kuroshitsuji Picture Drama",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/3174.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/3174.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/3174.jpg",
|
||||
},
|
||||
"id": 3174,
|
||||
"title": {
|
||||
"english": null,
|
||||
"userPreferred": "sola Specials",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/1443.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/1443.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/1443.jpg",
|
||||
},
|
||||
"id": 1443,
|
||||
"title": {
|
||||
"english": null,
|
||||
"userPreferred": "SOL BIANCA",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx153431-DMBYQxagH3Uu.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx153431-DMBYQxagH3Uu.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx153431-DMBYQxagH3Uu.jpg",
|
||||
},
|
||||
"id": 153431,
|
||||
"title": {
|
||||
"english": null,
|
||||
"userPreferred": "Onna no Sono no Hoshi",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx1444-7Yn6hmQ2bk9D.png",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx1444-7Yn6hmQ2bk9D.png",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx1444-7Yn6hmQ2bk9D.png",
|
||||
},
|
||||
"id": 1444,
|
||||
"title": {
|
||||
"english": "Sol Bianca: The Legacy",
|
||||
"userPreferred": "Sol Bianca: Taiyou no Fune",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/4138.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/4138.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/4138.jpg",
|
||||
},
|
||||
"id": 4138,
|
||||
"title": {
|
||||
"english": "The Adventures of Scamper the Penguin",
|
||||
"userPreferred": "Chiisana Pengin: Lolo no Bouken",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx164192-KQ8sYXbaAl6i.png",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx164192-KQ8sYXbaAl6i.png",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx164192-KQ8sYXbaAl6i.png",
|
||||
},
|
||||
"id": 164192,
|
||||
"title": {
|
||||
"english": "Planetarium",
|
||||
"userPreferred": "Planetarium",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/b5838-QTe07RRZylUm.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/b5838-QTe07RRZylUm.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/b5838-QTe07RRZylUm.jpg",
|
||||
},
|
||||
"id": 5838,
|
||||
"title": {
|
||||
"english": null,
|
||||
"userPreferred": "Furudera no Obake-soudou",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx162882-OQENM5pXn7QQ.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx162882-OQENM5pXn7QQ.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx162882-OQENM5pXn7QQ.jpg",
|
||||
},
|
||||
"id": 162882,
|
||||
"title": {
|
||||
"english": "P.E.T.",
|
||||
"userPreferred": "P.E.T.",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/102710-dVayaOkzATwa.png",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/102710-dVayaOkzATwa.png",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/102710-dVayaOkzATwa.png",
|
||||
},
|
||||
"id": 102710,
|
||||
"title": {
|
||||
"english": "The Garden of Pleasure",
|
||||
"userPreferred": "Kairaku no Sono",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx162881-c7xmNA6DlHFZ.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx162881-c7xmNA6DlHFZ.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx162881-c7xmNA6DlHFZ.jpg",
|
||||
},
|
||||
"id": 162881,
|
||||
"title": {
|
||||
"english": "Mosh Race",
|
||||
"userPreferred": "Mosh Race",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/5935.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/5935.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/5935.jpg",
|
||||
},
|
||||
"id": 5935,
|
||||
"title": {
|
||||
"english": "Marco Polo's Adventures",
|
||||
"userPreferred": "Marco Polo no Boken",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/103449-FxDK8eJuMAKg.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/103449-FxDK8eJuMAKg.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/103449-FxDK8eJuMAKg.jpg",
|
||||
},
|
||||
"id": 103449,
|
||||
"title": {
|
||||
"english": null,
|
||||
"userPreferred": "SOL",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/12993.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/12993.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/12993.jpg",
|
||||
},
|
||||
"id": 12993,
|
||||
"title": {
|
||||
"english": null,
|
||||
"userPreferred": "Sono Mukou no Mukougawa",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/20459.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/20459.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/20459.jpg",
|
||||
},
|
||||
"id": 20459,
|
||||
"title": {
|
||||
"english": null,
|
||||
"userPreferred": "Ganbare! Lulu Lolo",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/b137760-CleNdfmuKRy7.png",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/b137760-CleNdfmuKRy7.png",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/b137760-CleNdfmuKRy7.png",
|
||||
},
|
||||
"id": 137760,
|
||||
"title": {
|
||||
"english": null,
|
||||
"userPreferred": "Soko ni wa Mata Meikyuu",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/7473.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/7473.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/7473.jpg",
|
||||
},
|
||||
"id": 7473,
|
||||
"title": {
|
||||
"english": "Rennyo and His Mother",
|
||||
"userPreferred": "Rennyo to Sono Haha",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/21418-TZYwdItidowx.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/21418-TZYwdItidowx.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/21418-TZYwdItidowx.jpg",
|
||||
},
|
||||
"id": 21418,
|
||||
"title": {
|
||||
"english": null,
|
||||
"userPreferred": "Ganbare! Lulu Lolo 3rd Season",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/103517-XgOUryeFaPDW.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/103517-XgOUryeFaPDW.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/103517-XgOUryeFaPDW.jpg",
|
||||
},
|
||||
"id": 103517,
|
||||
"title": {
|
||||
"english": null,
|
||||
"userPreferred": "Toute wa Sono Kotae",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/b113572-hP9x1SkRJXvA.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/b113572-hP9x1SkRJXvA.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/b113572-hP9x1SkRJXvA.jpg",
|
||||
},
|
||||
"id": 113572,
|
||||
"title": {
|
||||
"english": "Journey to the beyond",
|
||||
"userPreferred": "Sono Saki no Taniji",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/20864.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/20864.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/20864.jpg",
|
||||
},
|
||||
"id": 20864,
|
||||
"title": {
|
||||
"english": null,
|
||||
"userPreferred": "Ganbare! Lulu Lolo 2nd Season",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/15129.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/15129.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/15129.jpg",
|
||||
},
|
||||
"id": 15129,
|
||||
"title": {
|
||||
"english": "Short Animations of Junpei Fujita",
|
||||
"userPreferred": "Tanpen Animation Junpei Fujita",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/nx106557-TPLmwa2EccB9.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/nx106557-TPLmwa2EccB9.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/nx106557-TPLmwa2EccB9.jpg",
|
||||
},
|
||||
"id": 106557,
|
||||
"title": {
|
||||
"english": "A Place to Name",
|
||||
"userPreferred": "Sono Ie no Namae",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/b118133-y7RvDFmr30hZ.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/b118133-y7RvDFmr30hZ.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/b118133-y7RvDFmr30hZ.jpg",
|
||||
},
|
||||
"id": 118133,
|
||||
"title": {
|
||||
"english": "In Inertia",
|
||||
"userPreferred": "Guzu no Soko",
|
||||
},
|
||||
},
|
||||
{
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx169686-exScHzB5UX2D.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx169686-exScHzB5UX2D.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx169686-exScHzB5UX2D.jpg",
|
||||
},
|
||||
"id": 169686,
|
||||
"title": {
|
||||
"english": "Indoor Days",
|
||||
"userPreferred": "Soto ni Denai hi",
|
||||
},
|
||||
},
|
||||
],
|
||||
"success": true,
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -77,3 +77,159 @@ The pages of Grimms' Fairy Tales, written by Jacob and Wilhelm, are now presente
|
||||
"success": true,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`requests the "/title" route with a valid id & token 1`] = `
|
||||
{
|
||||
"result": {
|
||||
"averageScore": 66,
|
||||
"bannerImage": "https://s4.anilist.co/file/anilistcdn/media/anime/banner/135643-cmQZCR3z9dB5.jpg",
|
||||
"countryOfOrigin": "JP",
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx135643-2kJt86K9Db9P.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx135643-2kJt86K9Db9P.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx135643-2kJt86K9Db9P.jpg",
|
||||
},
|
||||
"description":
|
||||
"Once upon a time, brothers Jacob and Wilhelm collected fairy tales from across the land and made them into a book. They also had a much younger sister, the innocent and curious Charlotte, who they loved very much. One day, while the brothers were telling Charlotte a fairy tale like usual, they saw that she had a somewhat melancholy look on her face. She asked them, "Do you suppose they really lived happily ever after?"
|
||||
<br><br>
|
||||
The pages of Grimms' Fairy Tales, written by Jacob and Wilhelm, are now presented from the unique perspective of Charlotte, who sees the stories quite differently from her brothers.
|
||||
<br><br>
|
||||
(Source: Netflix Anime)"
|
||||
,
|
||||
"episodes": 6,
|
||||
"genres": [
|
||||
"Fantasy",
|
||||
"Thriller",
|
||||
],
|
||||
"id": 135643,
|
||||
"idMal": 49210,
|
||||
"mediaListEntry": {
|
||||
"id": 402665918,
|
||||
"progress": 1,
|
||||
"status": "CURRENT",
|
||||
},
|
||||
"nextAiringEpisode": null,
|
||||
"status": "FINISHED",
|
||||
"title": {
|
||||
"english": "The Grimm Variations",
|
||||
"userPreferred": "The Grimm Variations",
|
||||
},
|
||||
},
|
||||
"success": true,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`requests the "/title" route with a valid id but no token 1`] = `
|
||||
{
|
||||
"result": {
|
||||
"averageScore": 66,
|
||||
"bannerImage": "https://s4.anilist.co/file/anilistcdn/media/anime/banner/135643-cmQZCR3z9dB5.jpg",
|
||||
"countryOfOrigin": "JP",
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx135643-2kJt86K9Db9P.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx135643-2kJt86K9Db9P.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx135643-2kJt86K9Db9P.jpg",
|
||||
},
|
||||
"description":
|
||||
"Once upon a time, brothers Jacob and Wilhelm collected fairy tales from across the land and made them into a book. They also had a much younger sister, the innocent and curious Charlotte, who they loved very much. One day, while the brothers were telling Charlotte a fairy tale like usual, they saw that she had a somewhat melancholy look on her face. She asked them, "Do you suppose they really lived happily ever after?"
|
||||
<br><br>
|
||||
The pages of Grimms' Fairy Tales, written by Jacob and Wilhelm, are now presented from the unique perspective of Charlotte, who sees the stories quite differently from her brothers.
|
||||
<br><br>
|
||||
(Source: Netflix Anime)"
|
||||
,
|
||||
"episodes": 6,
|
||||
"genres": [
|
||||
"Fantasy",
|
||||
"Thriller",
|
||||
],
|
||||
"id": 135643,
|
||||
"idMal": 49210,
|
||||
"mediaListEntry": null,
|
||||
"nextAiringEpisode": null,
|
||||
"status": "FINISHED",
|
||||
"title": {
|
||||
"english": "The Grimm Variations",
|
||||
"userPreferred": "The Grimm Variations",
|
||||
},
|
||||
},
|
||||
"success": true,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`requests the "/title" route with a valid id & token 1`] = `
|
||||
{
|
||||
"result": {
|
||||
"averageScore": 66,
|
||||
"bannerImage": "https://s4.anilist.co/file/anilistcdn/media/anime/banner/135643-cmQZCR3z9dB5.jpg",
|
||||
"countryOfOrigin": "JP",
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx135643-2kJt86K9Db9P.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx135643-2kJt86K9Db9P.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx135643-2kJt86K9Db9P.jpg",
|
||||
},
|
||||
"description":
|
||||
"Once upon a time, brothers Jacob and Wilhelm collected fairy tales from across the land and made them into a book. They also had a much younger sister, the innocent and curious Charlotte, who they loved very much. One day, while the brothers were telling Charlotte a fairy tale like usual, they saw that she had a somewhat melancholy look on her face. She asked them, "Do you suppose they really lived happily ever after?"
|
||||
<br><br>
|
||||
The pages of Grimms' Fairy Tales, written by Jacob and Wilhelm, are now presented from the unique perspective of Charlotte, who sees the stories quite differently from her brothers.
|
||||
<br><br>
|
||||
(Source: Netflix Anime)"
|
||||
,
|
||||
"episodes": 6,
|
||||
"genres": [
|
||||
"Fantasy",
|
||||
"Thriller",
|
||||
],
|
||||
"id": 135643,
|
||||
"idMal": 49210,
|
||||
"mediaListEntry": {
|
||||
"id": 402665918,
|
||||
"progress": 1,
|
||||
"status": "CURRENT",
|
||||
},
|
||||
"nextAiringEpisode": null,
|
||||
"status": "FINISHED",
|
||||
"title": {
|
||||
"english": "The Grimm Variations",
|
||||
"userPreferred": "The Grimm Variations",
|
||||
},
|
||||
},
|
||||
"success": true,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`requests the "/title" route with a valid id but no token 1`] = `
|
||||
{
|
||||
"result": {
|
||||
"averageScore": 66,
|
||||
"bannerImage": "https://s4.anilist.co/file/anilistcdn/media/anime/banner/135643-cmQZCR3z9dB5.jpg",
|
||||
"countryOfOrigin": "JP",
|
||||
"coverImage": {
|
||||
"extraLarge": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx135643-2kJt86K9Db9P.jpg",
|
||||
"large": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/medium/bx135643-2kJt86K9Db9P.jpg",
|
||||
"medium": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/small/bx135643-2kJt86K9Db9P.jpg",
|
||||
},
|
||||
"description":
|
||||
"Once upon a time, brothers Jacob and Wilhelm collected fairy tales from across the land and made them into a book. They also had a much younger sister, the innocent and curious Charlotte, who they loved very much. One day, while the brothers were telling Charlotte a fairy tale like usual, they saw that she had a somewhat melancholy look on her face. She asked them, "Do you suppose they really lived happily ever after?"
|
||||
<br><br>
|
||||
The pages of Grimms' Fairy Tales, written by Jacob and Wilhelm, are now presented from the unique perspective of Charlotte, who sees the stories quite differently from her brothers.
|
||||
<br><br>
|
||||
(Source: Netflix Anime)"
|
||||
,
|
||||
"episodes": 6,
|
||||
"genres": [
|
||||
"Fantasy",
|
||||
"Thriller",
|
||||
],
|
||||
"id": 135643,
|
||||
"idMal": 49210,
|
||||
"mediaListEntry": null,
|
||||
"nextAiringEpisode": null,
|
||||
"status": "FINISHED",
|
||||
"title": {
|
||||
"english": "The Grimm Variations",
|
||||
"userPreferred": "The Grimm Variations",
|
||||
},
|
||||
},
|
||||
"success": true,
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -27,7 +27,7 @@ describe("requests the /token route", () => {
|
||||
headers: new Headers({
|
||||
"Content-Type": "application/json",
|
||||
}),
|
||||
body: JSON.stringify({ token: "123", deviceId: "123", username: "test" }),
|
||||
body: JSON.stringify({ token: "123", deviceId: "123" }),
|
||||
});
|
||||
|
||||
expect(res.json()).resolves.toEqual({ success: true });
|
||||
@@ -41,50 +41,7 @@ describe("requests the /token route", () => {
|
||||
headers: new Headers({
|
||||
"Content-Type": "application/json",
|
||||
}),
|
||||
body: JSON.stringify({ token: "123", deviceId: "123", username: "test" }),
|
||||
});
|
||||
|
||||
const row = await db
|
||||
.select()
|
||||
.from(deviceTokensTable)
|
||||
.where(eq(deviceTokensTable.deviceId, "123"))
|
||||
.get();
|
||||
|
||||
expect(row).toEqual({
|
||||
deviceId: "123",
|
||||
token: "123",
|
||||
username: "test",
|
||||
lastConnectedAt: expect.any(String),
|
||||
});
|
||||
// since SQL timestamp doesn't support milliseconds, compare to nearest second
|
||||
expect(
|
||||
+DateTime.fromSQL(row!.lastConnectedAt!, { zone: "utc" }).startOf(
|
||||
"second",
|
||||
),
|
||||
).toBeGreaterThanOrEqual(+minimumTimestamp.startOf("second"));
|
||||
});
|
||||
|
||||
it("with username as null, should succeed", async () => {
|
||||
const res = await app.request("/token", {
|
||||
method: "POST",
|
||||
headers: new Headers({
|
||||
"Content-Type": "application/json",
|
||||
}),
|
||||
body: JSON.stringify({ token: "123", deviceId: "123", username: null }),
|
||||
});
|
||||
|
||||
expect(res.json()).resolves.toEqual({ success: true });
|
||||
expect(res.status).toBe(200);
|
||||
});
|
||||
|
||||
it("with username as null, db should contain entry", async () => {
|
||||
const minimumTimestamp = DateTime.now();
|
||||
await app.request("/token", {
|
||||
method: "POST",
|
||||
headers: new Headers({
|
||||
"Content-Type": "application/json",
|
||||
}),
|
||||
body: JSON.stringify({ token: "123", deviceId: "123", username: null }),
|
||||
body: JSON.stringify({ token: "123", deviceId: "123" }),
|
||||
});
|
||||
|
||||
const row = await db
|
||||
@@ -117,7 +74,7 @@ describe("requests the /token route", () => {
|
||||
headers: new Headers({
|
||||
"Content-Type": "application/json",
|
||||
}),
|
||||
body: JSON.stringify({ token: "124", deviceId: "123", username: null }),
|
||||
body: JSON.stringify({ token: "124", deviceId: "123" }),
|
||||
});
|
||||
|
||||
expect(res.json()).resolves.toEqual({ success: true });
|
||||
@@ -134,7 +91,7 @@ describe("requests the /token route", () => {
|
||||
headers: new Headers({
|
||||
"Content-Type": "application/json",
|
||||
}),
|
||||
body: JSON.stringify({ token: "124", deviceId: "123", username: null }),
|
||||
body: JSON.stringify({ token: "124", deviceId: "123" }),
|
||||
});
|
||||
|
||||
const row = await db
|
||||
@@ -157,23 +114,6 @@ describe("requests the /token route", () => {
|
||||
).toBeGreaterThanOrEqual(+minimumTimestamp.startOf("second"));
|
||||
});
|
||||
|
||||
it("token already exists in db, should fail", async () => {
|
||||
await db
|
||||
.insert(deviceTokensTable)
|
||||
.values({ deviceId: "123", token: "123" });
|
||||
|
||||
const res = await app.request("/token", {
|
||||
method: "POST",
|
||||
headers: new Headers({
|
||||
"Content-Type": "application/json",
|
||||
}),
|
||||
body: JSON.stringify({ token: "123", deviceId: "124", username: null }),
|
||||
});
|
||||
|
||||
expect(res.json()).resolves.toEqual({ success: false });
|
||||
expect(res.status).toBe(412);
|
||||
});
|
||||
|
||||
it("token already exists in db, should not insert new entry", async () => {
|
||||
await db
|
||||
.insert(deviceTokensTable)
|
||||
@@ -183,7 +123,7 @@ describe("requests the /token route", () => {
|
||||
headers: new Headers({
|
||||
"Content-Type": "application/json",
|
||||
}),
|
||||
body: JSON.stringify({ token: "123", deviceId: "124", username: null }),
|
||||
body: JSON.stringify({ token: "123", deviceId: "124" }),
|
||||
});
|
||||
|
||||
const row = await db
|
||||
@@ -195,64 +135,6 @@ describe("requests the /token route", () => {
|
||||
expect(row).toBeUndefined();
|
||||
});
|
||||
|
||||
it("associating a username with a token, should succeed", async () => {
|
||||
await db
|
||||
.insert(deviceTokensTable)
|
||||
.values({ deviceId: "123", token: "123" });
|
||||
|
||||
const res = await app.request("/token", {
|
||||
method: "POST",
|
||||
headers: new Headers({
|
||||
"Content-Type": "application/json",
|
||||
}),
|
||||
body: JSON.stringify({
|
||||
token: "123",
|
||||
deviceId: "123",
|
||||
username: "aniplay",
|
||||
}),
|
||||
});
|
||||
|
||||
expect(res.json()).resolves.toEqual({ success: true });
|
||||
expect(res.status).toBe(200);
|
||||
});
|
||||
|
||||
it("associating a username with a token should update existing entry", async () => {
|
||||
const minimumTimestamp = DateTime.now();
|
||||
await db
|
||||
.insert(deviceTokensTable)
|
||||
.values({ deviceId: "123", token: "123" });
|
||||
await app.request("/token", {
|
||||
method: "POST",
|
||||
headers: new Headers({
|
||||
"Content-Type": "application/json",
|
||||
}),
|
||||
body: JSON.stringify({
|
||||
token: "123",
|
||||
deviceId: "123",
|
||||
username: "aniplay",
|
||||
}),
|
||||
});
|
||||
|
||||
const row = await db
|
||||
.select()
|
||||
.from(deviceTokensTable)
|
||||
.where(eq(deviceTokensTable.deviceId, "123"))
|
||||
.get();
|
||||
|
||||
expect(row).toEqual({
|
||||
deviceId: "123",
|
||||
token: "123",
|
||||
username: "aniplay",
|
||||
lastConnectedAt: expect.any(String),
|
||||
});
|
||||
// since SQL timestamp doesn't support milliseconds, compare to nearest second
|
||||
expect(
|
||||
+DateTime.fromSQL(row!.lastConnectedAt!, { zone: "utc" }).startOf(
|
||||
"second",
|
||||
),
|
||||
).toBeGreaterThanOrEqual(+minimumTimestamp.startOf("second"));
|
||||
});
|
||||
|
||||
it("token is invalid, should fail", async () => {
|
||||
mock.module("src/libs/fcm/verifyFcmToken", () => ({
|
||||
verifyFcmToken: () => false,
|
||||
@@ -263,7 +145,7 @@ describe("requests the /token route", () => {
|
||||
headers: new Headers({
|
||||
"Content-Type": "application/json",
|
||||
}),
|
||||
body: JSON.stringify({ token: "123", deviceId: "124", username: null }),
|
||||
body: JSON.stringify({ token: "123", deviceId: "124" }),
|
||||
});
|
||||
|
||||
expect(res.json()).resolves.toEqual({ success: false });
|
||||
@@ -279,7 +161,7 @@ describe("requests the /token route", () => {
|
||||
headers: new Headers({
|
||||
"Content-Type": "application/json",
|
||||
}),
|
||||
body: JSON.stringify({ token: "123", deviceId: "124", username: null }),
|
||||
body: JSON.stringify({ token: "123", deviceId: "124" }),
|
||||
});
|
||||
|
||||
const row = await db
|
||||
|
||||
@@ -3,7 +3,6 @@ import { env } from "hono/adapter";
|
||||
import mapKeys from "lodash.mapkeys";
|
||||
|
||||
import { Case, changeStringCase } from "~/libs/changeStringCase";
|
||||
import { TokenAlreadyExistsError } from "~/libs/errors/TokenAlreadyExists";
|
||||
import type { AdminSdkCredentials } from "~/libs/fcm/getGoogleAuthToken";
|
||||
import { verifyFcmToken } from "~/libs/fcm/verifyFcmToken";
|
||||
import { readEnvVariable } from "~/libs/readEnvVariable";
|
||||
@@ -21,7 +20,6 @@ const app = new OpenAPIHono<Env>();
|
||||
const SaveTokenRequest = z.object({
|
||||
token: z.string(),
|
||||
deviceId: z.string(),
|
||||
username: z.string().nullable(),
|
||||
});
|
||||
|
||||
const SaveTokenResponse = SuccessResponseSchema();
|
||||
@@ -70,8 +68,7 @@ const route = createRoute({
|
||||
});
|
||||
|
||||
app.openapi(route, async (c) => {
|
||||
const { token, deviceId, username } =
|
||||
await c.req.json<typeof SaveTokenRequest._type>();
|
||||
const { token, deviceId } = await c.req.json<typeof SaveTokenRequest._type>();
|
||||
|
||||
try {
|
||||
const isValidToken = await verifyFcmToken(
|
||||
@@ -85,12 +82,8 @@ app.openapi(route, async (c) => {
|
||||
return c.json(ErrorResponse, 401);
|
||||
}
|
||||
|
||||
await saveToken(env(c, "workerd"), deviceId, token, username);
|
||||
await saveToken(env(c, "workerd"), deviceId, token);
|
||||
} catch (error) {
|
||||
if (error instanceof TokenAlreadyExistsError) {
|
||||
return c.json(ErrorResponse, 412);
|
||||
}
|
||||
|
||||
console.error(new Error("Failed to save token", { cause: error }));
|
||||
return c.json(ErrorResponse, 500);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user