From 2f140996d5c1f49bfe2f4c679445d99f3c478f46 Mon Sep 17 00:00:00 2001 From: Sugui Date: Sun, 21 Apr 2024 12:26:59 +0200 Subject: [PATCH] Added concurrency test, and added CORS and CORS test --- bun.lockb | Bin 54645 -> 55759 bytes package.json | 2 ++ src/app.ts | 2 ++ src/services/gelbooruApiService.ts | 5 ++-- test/app.test.ts | 10 ++++++++ ...roller.test.ts => imageController.test.ts} | 2 -- ...geService.test.ts => imageService.test.ts} | 16 ++++++++++-- yarn.lock | 24 ++++++++++++++++-- 8 files changed, 53 insertions(+), 8 deletions(-) create mode 100644 test/app.test.ts rename test/{ImageController/ImageController.test.ts => imageController.test.ts} (83%) rename test/{ImageService/ImageService.test.ts => imageService.test.ts} (72%) diff --git a/bun.lockb b/bun.lockb index 347f41e4f365a6f2ab3c1d172580761089bcd6e2..fe1d9777b25be36fe6f35c6e3b146f7f99682557 100755 GIT binary patch delta 8414 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 j6+5!|j)_YMCCx^DZc diff --git a/package.json b/package.json index ef606ba..28ba82e 100644 --- a/package.json +++ b/package.json @@ -14,8 +14,10 @@ "typescript": "^5.0.0" }, "dependencies": { + "@types/cors": "^2.8.17", "async-mutex": "^0.5.0", "compression": "^1.7.4", + "cors": "^2.8.5", "express": "^4.19.2", "express-list-endpoints": "^6.0.0", "winston": "^3.13.0" diff --git a/src/app.ts b/src/app.ts index e34f131..8dda20e 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,4 +1,5 @@ import compression from "compression"; +import cors from "cors"; import express from "express"; import listEndpoints from "express-list-endpoints"; import * as imageController from "src/controllers/imageController"; @@ -7,6 +8,7 @@ const app = express(); app.use(express.json()); app.use(compression()); +app.use(cors()); app.get("/", (_, res) => { const endpoints = listEndpoints(app); diff --git a/src/services/gelbooruApiService.ts b/src/services/gelbooruApiService.ts index f584892..9e5b151 100644 --- a/src/services/gelbooruApiService.ts +++ b/src/services/gelbooruApiService.ts @@ -3,9 +3,10 @@ import logger from "src/logger"; import GelbooruApiResponse from "src/types/GelbooruApiResponse"; import GelbooruServiceResponse from "src/types/GelbooruServiceResponse"; +export const LIMIT = env.GELBOORU_IMAGES_PER_REQUEST || 100; +export const TAGS = encodeURIComponent(env.GELBOORU_TAGS || ""); + export async function get(): Promise { - const LIMIT = env.GELBOORU_IMAGES_PER_REQUEST || 100; - const TAGS = encodeURIComponent(env.GELBOORU_TAGS || ""); const url: string = `https://gelbooru.com/index.php?page=dapi&s=post&q=index&limit=${LIMIT}&json=1&tags=${TAGS}`; const response: GelbooruApiResponse = (await fetch(url).then( diff --git a/test/app.test.ts b/test/app.test.ts new file mode 100644 index 0000000..efa5e79 --- /dev/null +++ b/test/app.test.ts @@ -0,0 +1,10 @@ +import { describe, expect, it } from "bun:test"; +import app from "src/app"; +import request from "supertest"; + +describe("CORS implementation", () => { + it("should implement CORS", async () => { + const { headers } = await request(app).get('/'); + expect(headers['access-control-allow-origin']).toEqual('*'); + }) +}) \ No newline at end of file diff --git a/test/ImageController/ImageController.test.ts b/test/imageController.test.ts similarity index 83% rename from test/ImageController/ImageController.test.ts rename to test/imageController.test.ts index 4c8746b..ea35df1 100644 --- a/test/ImageController/ImageController.test.ts +++ b/test/imageController.test.ts @@ -9,8 +9,6 @@ afterAll(() => { describe("endpoint returns the correct status codes", () => { it("should return 200 if successful", async () => { - // Can't mock ImageService partially because of bun incomplete implementation of testing :( - // It goes to the network directly to test const res = await request(app).get("/image"); expect(res.status).toBe(200); }); diff --git a/test/ImageService/ImageService.test.ts b/test/imageService.test.ts similarity index 72% rename from test/ImageService/ImageService.test.ts rename to test/imageService.test.ts index 67e36c0..5f909c0 100644 --- a/test/ImageService/ImageService.test.ts +++ b/test/imageService.test.ts @@ -1,16 +1,28 @@ import { afterAll, describe, expect, it, jest, mock, spyOn } from "bun:test"; import Image from "src/types/Image"; +import request from "supertest"; import * as gelbooruApiService from "src/services/gelbooruApiService"; import * as botApiService from "src/services/botApiService"; import * as imageService from "src/services/imageService"; +import app from "src/app"; +import { response } from "express"; afterAll(() => { jest.restoreAllMocks(); }) describe("the service is thread-safe", () => { - it("should run normally when 2 processes call the get() method with 1 remaining image in the queue", async () => { - // TODO + it("should not crash when multiple processes call the get() method with 1 remaining image in the queue", async () => { + const NUM_OF_REQUESTS = 110; + + const getFn = spyOn(imageService, "get"); + + const promises = Array(NUM_OF_REQUESTS).fill(null) + .map(_ => request(app).get("/image")); + const responses = await Promise.all(promises); + + expect(getFn).toHaveBeenCalledTimes(NUM_OF_REQUESTS); + responses.forEach(res => expect(res.status).toBe(200)); }) }) diff --git a/yarn.lock b/yarn.lock index ff9aa21..288f4bd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1,6 +1,6 @@ # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. # yarn lockfile v1 -# bun ./bun.lockb --hash: 9A5A612BBFD3E7ED-76a31de2b7c4bbe8-8DB93E498B9CBB30-9cf1116024820c4f +# bun ./bun.lockb --hash: 4B368415A9637562-70781726b75e86ab-6261B8AB82430501-a22712f647bcbfe3 "@colors/colors@1.6.0", "@colors/colors@^1.6.0": @@ -44,6 +44,13 @@ resolved "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.5.tgz" integrity sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q== +"@types/cors@^2.8.17": + version "2.8.17" + resolved "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz" + integrity sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA== + dependencies: + "@types/node" "*" + "@types/express@*", "@types/express@^4.17.21": version "4.17.21" resolved "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz" @@ -336,6 +343,14 @@ cookiejar@^2.1.4: resolved "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz" integrity sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw== +cors@^2.8.5: + version "2.8.5" + resolved "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + debug@2.6.9: version "2.6.9" resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" @@ -689,6 +704,11 @@ negotiator@0.6.3: resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== +object-assign@^4: + version "4.1.1" + resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + object-inspect@^1.13.1: version "1.13.1" resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz" @@ -953,7 +973,7 @@ utils-merge@1.0.1: resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== -vary@~1.1.2: +vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==