From 8b38f7bc1f905044053c2981364189fc6985f83a Mon Sep 17 00:00:00 2001 From: Sugui Date: Thu, 28 Mar 2024 12:43:24 +0100 Subject: [PATCH] Implemented all related to the test --- src/models/GelbooruServiceResponse.ts | 8 ----- src/services/BotApiService.ts | 21 +++++++++++++ src/services/GelbooruApiService.ts | 4 +-- src/services/ImageService.ts | 31 ++++++++++++++++++++ src/types/BotApiResponse.ts | 5 ++++ src/types/BotImage.ts | 7 +++++ src/{models => types}/GelbooruApiResponse.ts | 0 src/types/GelbooruPost.ts | 4 +++ src/types/GelbooruServiceResponse.ts | 5 ++++ src/{models => types}/Image.ts | 1 + test/ImageService.test.ts | 27 ++++++++++------- 11 files changed, 93 insertions(+), 20 deletions(-) delete mode 100644 src/models/GelbooruServiceResponse.ts create mode 100644 src/services/BotApiService.ts create mode 100644 src/types/BotApiResponse.ts create mode 100644 src/types/BotImage.ts rename src/{models => types}/GelbooruApiResponse.ts (100%) create mode 100644 src/types/GelbooruPost.ts create mode 100644 src/types/GelbooruServiceResponse.ts rename src/{models => types}/Image.ts (77%) diff --git a/src/models/GelbooruServiceResponse.ts b/src/models/GelbooruServiceResponse.ts deleted file mode 100644 index d3e5994..0000000 --- a/src/models/GelbooruServiceResponse.ts +++ /dev/null @@ -1,8 +0,0 @@ -export default interface GelbooruServiceResponse { - posts: GelbooruPostResponse[] -} - -interface GelbooruPostResponse { - url: string; - tags: string[]; -} \ No newline at end of file diff --git a/src/services/BotApiService.ts b/src/services/BotApiService.ts new file mode 100644 index 0000000..13363c2 --- /dev/null +++ b/src/services/BotApiService.ts @@ -0,0 +1,21 @@ +import { BotApiResponse } from "../types/BotApiResponse"; + +class BotApiService { + readonly BOT_API_URL = "piparadis:30000"; + + async getAll(): Promise { + const get_url = `${this.BOT_API_URL}/images`; + const response: BotApiResponse = await fetch(get_url) + .then(res => { + if (!res.ok) { + throw new Error("Error fetching images"); + } else { + res.json(); + } + }) as BotApiResponse; + return response; + } + +} + +export default new BotApiService(); \ No newline at end of file diff --git a/src/services/GelbooruApiService.ts b/src/services/GelbooruApiService.ts index 3d8bc03..7856075 100644 --- a/src/services/GelbooruApiService.ts +++ b/src/services/GelbooruApiService.ts @@ -1,5 +1,5 @@ -import GelbooruServiceResponse from "../models/GelbooruServiceResponse"; -import GelbooruApiResponse from "../models/GelbooruApiResponse"; +import GelbooruApiResponse from "../types/GelbooruApiResponse"; +import GelbooruServiceResponse from "../types/GelbooruServiceResponse"; class GelbooruApiService { async get(): Promise { diff --git a/src/services/ImageService.ts b/src/services/ImageService.ts index e69de29..1826b8d 100644 --- a/src/services/ImageService.ts +++ b/src/services/ImageService.ts @@ -0,0 +1,31 @@ +import GelbooruServiceResponse from "../types/GelbooruServiceResponse"; +import Image from "../types/Image"; +import BotApiService from "./BotApiService"; +import GelbooruApiService from "./GelbooruApiService"; + +class ImageService { + postsQueue: Image[] = []; + + async get(): Promise { + while (this.postsQueue.length === 0) { + const validPosts = await this.getNewValidImages(); + this.postsQueue = validPosts; + } + return this.postsQueue.pop() as Image; + } + private async getNewValidImages(): Promise { + const gelbooruResponse: GelbooruServiceResponse = await GelbooruApiService.get(); + const posts = gelbooruResponse.posts; + + const botResponse = await BotApiService.getAll(); + const imagesUrls = botResponse.images.map(image => image.url); + + const validPosts = posts + .filter(post => !imagesUrls.some(url => url === post.url)) + .map(post => ({ url: post.url, tags: post.tags, content: "TODO" })); + + return validPosts; + } +} + +export default new ImageService(); \ No newline at end of file diff --git a/src/types/BotApiResponse.ts b/src/types/BotApiResponse.ts new file mode 100644 index 0000000..fc184ce --- /dev/null +++ b/src/types/BotApiResponse.ts @@ -0,0 +1,5 @@ +import BotImage from "./BotImage"; + +export interface BotApiResponse { + images: BotImage[] +} \ No newline at end of file diff --git a/src/types/BotImage.ts b/src/types/BotImage.ts new file mode 100644 index 0000000..ded068e --- /dev/null +++ b/src/types/BotImage.ts @@ -0,0 +1,7 @@ +export default interface BotImage { + _id: string + url: string + status: string + tags: string[] + __v: number +} diff --git a/src/models/GelbooruApiResponse.ts b/src/types/GelbooruApiResponse.ts similarity index 100% rename from src/models/GelbooruApiResponse.ts rename to src/types/GelbooruApiResponse.ts diff --git a/src/types/GelbooruPost.ts b/src/types/GelbooruPost.ts new file mode 100644 index 0000000..775adbb --- /dev/null +++ b/src/types/GelbooruPost.ts @@ -0,0 +1,4 @@ +export default interface GelbooruPost { + url: string; + tags: string[]; +} \ No newline at end of file diff --git a/src/types/GelbooruServiceResponse.ts b/src/types/GelbooruServiceResponse.ts new file mode 100644 index 0000000..a6cf355 --- /dev/null +++ b/src/types/GelbooruServiceResponse.ts @@ -0,0 +1,5 @@ +import GelbooruPost from "./GelbooruPost"; + +export default interface GelbooruServiceResponse { + posts: GelbooruPost[]; +} \ No newline at end of file diff --git a/src/models/Image.ts b/src/types/Image.ts similarity index 77% rename from src/models/Image.ts rename to src/types/Image.ts index 06fd028..fe6d63f 100644 --- a/src/models/Image.ts +++ b/src/types/Image.ts @@ -1,4 +1,5 @@ export default interface Image { url: string; + tags: string[]; content: string; } \ No newline at end of file diff --git a/test/ImageService.test.ts b/test/ImageService.test.ts index 276cabf..989cff0 100644 --- a/test/ImageService.test.ts +++ b/test/ImageService.test.ts @@ -1,33 +1,40 @@ import { afterEach, beforeAll, describe, expect, it, mock } from "bun:test"; -import Image from "../src/models/Image" +import Image from "../src/types/Image" import ImageService from "../src/services/ImageService"; -import GelbooruResponse from "../src/models/GelbooruServiceResponse"; +import GelbooruApiResponse from "../src/types/GelbooruServiceResponse"; +import { BotApiResponse } from "../src/types/BotApiResponse"; describe("endpoint gets a non repeated image", () => { it("should return an image that is not in the response of the /images endpoint of the bot API", async () => { const REPEATED_URL = "image.com/1"; const UNIQUE_URL = "image.com/2"; - mock.module("../services/GelbooruApiService", () => { + mock.module("../src/services/GelbooruApiService", () => { let alreadyCalled = false; return { default: { - get: (): GelbooruResponse[] => { + get: (): GelbooruApiResponse => { if (alreadyCalled) { - return [{ url: UNIQUE_URL, tags: [] }]; + return { posts: [{ url: UNIQUE_URL, tags: [] }] }; } else { alreadyCalled = true; - return [{ url: REPEATED_URL, tags: [] }]; + return { posts: [{ url: REPEATED_URL, tags: [] }] }; } } } } }); - const botApiImagesResponse = { images: [ - {_id: "0", url: REPEATED_URL, status: "consumed", tags: ["pokemon", "computer"]} - ]}; - + mock.module("../src/services/BotApiService", () => ({ + default: { + getAll: (): BotApiResponse => ({ + images: [ + { _id: "0", url: REPEATED_URL, status: "consumed", tags: ["pokemon", "computer"], "__v": 0 } + ] + }) + } + })); + const image: Image = await ImageService.get(); expect(image.url).not.toBe(REPEATED_URL); })