Implemented all related to the test

This commit is contained in:
Sugui 2024-03-28 12:43:24 +01:00
parent 953dcfe38b
commit 8b38f7bc1f
11 changed files with 93 additions and 20 deletions

View File

@ -1,8 +0,0 @@
export default interface GelbooruServiceResponse {
posts: GelbooruPostResponse[]
}
interface GelbooruPostResponse {
url: string;
tags: string[];
}

View File

@ -0,0 +1,21 @@
import { BotApiResponse } from "../types/BotApiResponse";
class BotApiService {
readonly BOT_API_URL = "piparadis:30000";
async getAll(): Promise<BotApiResponse> {
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();

View File

@ -1,5 +1,5 @@
import GelbooruServiceResponse from "../models/GelbooruServiceResponse"; import GelbooruApiResponse from "../types/GelbooruApiResponse";
import GelbooruApiResponse from "../models/GelbooruApiResponse"; import GelbooruServiceResponse from "../types/GelbooruServiceResponse";
class GelbooruApiService { class GelbooruApiService {
async get(): Promise<GelbooruServiceResponse> { async get(): Promise<GelbooruServiceResponse> {

View File

@ -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<Image> {
while (this.postsQueue.length === 0) {
const validPosts = await this.getNewValidImages();
this.postsQueue = validPosts;
}
return this.postsQueue.pop() as Image;
}
private async getNewValidImages(): Promise<Image[]> {
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();

View File

@ -0,0 +1,5 @@
import BotImage from "./BotImage";
export interface BotApiResponse {
images: BotImage[]
}

7
src/types/BotImage.ts Normal file
View File

@ -0,0 +1,7 @@
export default interface BotImage {
_id: string
url: string
status: string
tags: string[]
__v: number
}

View File

@ -0,0 +1,4 @@
export default interface GelbooruPost {
url: string;
tags: string[];
}

View File

@ -0,0 +1,5 @@
import GelbooruPost from "./GelbooruPost";
export default interface GelbooruServiceResponse {
posts: GelbooruPost[];
}

View File

@ -1,4 +1,5 @@
export default interface Image { export default interface Image {
url: string; url: string;
tags: string[];
content: string; content: string;
} }

View File

@ -1,32 +1,39 @@
import { afterEach, beforeAll, describe, expect, it, mock } from "bun:test"; 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 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", () => { 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 () => { 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 REPEATED_URL = "image.com/1";
const UNIQUE_URL = "image.com/2"; const UNIQUE_URL = "image.com/2";
mock.module("../services/GelbooruApiService", () => { mock.module("../src/services/GelbooruApiService", () => {
let alreadyCalled = false; let alreadyCalled = false;
return { return {
default: { default: {
get: (): GelbooruResponse[] => { get: (): GelbooruApiResponse => {
if (alreadyCalled) { if (alreadyCalled) {
return [{ url: UNIQUE_URL, tags: [] }]; return { posts: [{ url: UNIQUE_URL, tags: [] }] };
} else { } else {
alreadyCalled = true; alreadyCalled = true;
return [{ url: REPEATED_URL, tags: [] }]; return { posts: [{ url: REPEATED_URL, tags: [] }] };
} }
} }
} }
} }
}); });
const botApiImagesResponse = { images: [ mock.module("../src/services/BotApiService", () => ({
{_id: "0", url: REPEATED_URL, status: "consumed", tags: ["pokemon", "computer"]} default: {
]}; getAll: (): BotApiResponse => ({
images: [
{ _id: "0", url: REPEATED_URL, status: "consumed", tags: ["pokemon", "computer"], "__v": 0 }
]
})
}
}));
const image: Image = await ImageService.get(); const image: Image = await ImageService.get();
expect(image.url).not.toBe(REPEATED_URL); expect(image.url).not.toBe(REPEATED_URL);