UNPKG

@tsed/platform-test-sdk

Version:
298 lines (297 loc) 13.3 kB
import { __decorate, __metadata, __param } from "tslib"; import { Controller, Inject } from "@tsed/di"; import { PlatformCache, UseCache } from "@tsed/platform-cache"; import { PlatformTest } from "@tsed/platform-http/testing"; import { PathParams, QueryParams } from "@tsed/platform-params"; import { Get, Head, Post, Property } from "@tsed/schema"; import SuperTest from "supertest"; import { afterEach, beforeEach, describe, expect, it } from "vitest"; let increment = 0; export function testCache(options) { let request; class MyModel { } __decorate([ Property(), __metadata("design:type", String) ], MyModel.prototype, "name", void 0); class MyService { get(id) { return { id: `one:${id}` }; } get2(id) { return { id: `one:${id}` }; } } __decorate([ UseCache({ key: "key" }), __metadata("design:type", Function), __metadata("design:paramtypes", [String]), __metadata("design:returntype", void 0) ], MyService.prototype, "get", null); __decorate([ UseCache({ key(args) { return `key:${args[0]}`; } }), __metadata("design:type", Function), __metadata("design:paramtypes", [String]), __metadata("design:returntype", void 0) ], MyService.prototype, "get2", null); let TestCacheController = class TestCacheController { scenario1() { increment++; return "hello world " + increment; } scenario2() { return { info: "hello child" }; } scenario3() { return undefined; } scenario4() { return { info: "hello child" }; } scenario5(id, model) { return { info: "hello child", id, ...model }; } scenario6(id) { return this.myService.get(id); } scenario7(id) { return this.myService.get2(id); } }; __decorate([ Inject(), __metadata("design:type", MyService) ], TestCacheController.prototype, "myService", void 0); __decorate([ Get("/scenario-1"), UseCache(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", void 0) ], TestCacheController.prototype, "scenario1", null); __decorate([ Get("/scenario-2"), UseCache({ ttl: 400 }), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", void 0) ], TestCacheController.prototype, "scenario2", null); __decorate([ Head("/scenario-3"), UseCache(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", void 0) ], TestCacheController.prototype, "scenario3", null); __decorate([ Post("/scenario-4"), UseCache(), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", void 0) ], TestCacheController.prototype, "scenario4", null); __decorate([ Get("/scenario-5/:id"), UseCache({ ttl: 400 }), __param(0, PathParams("id")), __param(1, QueryParams()), __metadata("design:type", Function), __metadata("design:paramtypes", [String, MyModel]), __metadata("design:returntype", void 0) ], TestCacheController.prototype, "scenario5", null); __decorate([ Get("/scenario-6/:id"), __param(0, PathParams("id")), __metadata("design:type", Function), __metadata("design:paramtypes", [String]), __metadata("design:returntype", void 0) ], TestCacheController.prototype, "scenario6", null); __decorate([ Get("/scenario-7/:id"), __param(0, PathParams("id")), __metadata("design:type", Function), __metadata("design:paramtypes", [String]), __metadata("design:returntype", void 0) ], TestCacheController.prototype, "scenario7", null); TestCacheController = __decorate([ Controller("/caches") ], TestCacheController); describe("withCache", () => { beforeEach(PlatformTest.bootstrap(options.server, { ...options, logger: {}, mount: { "/rest": [TestCacheController] }, cache: { ttl: 300, store: "memory" } })); beforeEach(() => { request = SuperTest(PlatformTest.callback()); }); afterEach(PlatformTest.reset); describe("scenario 1: GET /rest/caches/scenario-1", () => { it("should return data with cached response", async () => { const response = await request.get("/rest/caches/scenario-1").expect(200); const response2 = await request.get("/rest/caches/scenario-1").expect(200); expect(response.text).toContain("hello world"); expect(response.headers["cache-control"]).toMatch(/max-age=300/); expect(response.headers["x-cached"]).toBeUndefined(); expect(response2.text).toContain("hello world"); expect(response2.headers["cache-control"]).toMatch(/max-age=300/); expect(response2.headers["x-cached"]).toEqual("true"); expect(response2.headers["etag"]).toEqual(response.headers["etag"]); }); it("should return 304 when content isn't modified", async () => { const platformCache = PlatformTest.get(PlatformCache); const response = await request.get("/rest/caches/scenario-1").expect(200); if (response.headers["etag"]) { // platform koa doesn't support Etag await request .get("/rest/caches/scenario-1") .set("if-none-match", response.headers["etag"] || "") .expect(304); await platformCache.reset(); await request .get("/rest/caches/scenario-1") .set("if-none-match", response.headers["etag"] || "") .expect(200); } }); it("should return fresh data if cache-control is set to no-cache", async () => { await request.get("/rest/caches/scenario-1").expect(200); const response2 = await request.get("/rest/caches/scenario-1").set("cache-control", "no-cache").expect(200); expect(response2.text).toContain("hello world"); expect(response2.headers["cache-control"]).toMatch(/max-age=300/); expect(response2.headers["x-cached"]).toBeUndefined(); expect(response2.headers["etag"]).toEqual(response2.headers["etag"]); }); }); describe("scenario 2: GET /rest/caches/scenario-2", () => { it("should return data with cached response", async () => { const response = await request.get("/rest/caches/scenario-2").expect(200); const response2 = await request.get("/rest/caches/scenario-2").expect(200); expect(response.body).toEqual({ info: "hello child" }); expect(response.headers["cache-control"]).toMatch(/max-age=400/); expect(response.headers["x-cached"]).toBeUndefined(); expect(response2.body).toEqual({ info: "hello child" }); expect(response2.headers["cache-control"]).toMatch(/max-age=400/); expect(response2.headers["x-cached"]).toEqual("true"); expect(response2.headers["etag"]).toEqual(response.headers["etag"]); }); }); describe("scenario 4: POST /rest/caches/scenario-4", () => { it("should not cache POST method", async () => { const response = await request.post("/rest/caches/scenario-4").expect(200); const response2 = await request.post("/rest/caches/scenario-4").expect(200); expect(response.body).toEqual({ info: "hello child" }); expect(response.headers["cache-control"]).toBeUndefined(); expect(response.headers["x-cached"]).toBeUndefined(); expect(response2.body).toEqual({ info: "hello child" }); expect(response.headers["cache-control"]).toBeUndefined(); expect(response2.headers["x-cached"]).toBeUndefined(); expect(response2.headers["etag"]).toEqual(response.headers["etag"]); }); }); describe("scenario 5: GET /rest/caches/scenario-5", () => { it("should return data with then cache response", async () => { const response = await request.get("/rest/caches/scenario-5/1?name=1").expect(200); const response2 = await request.get("/rest/caches/scenario-5/1?name=1").expect(200); const response3 = await request.get("/rest/caches/scenario-5/2?name=2").expect(200); const response4 = await request.get("/rest/caches/scenario-5/2?name=2").expect(200); const response5 = await request.get("/rest/caches/scenario-5/2?name=3").expect(200); expect(response.body).toEqual({ id: "1", info: "hello child", name: "1" }); expect(response2.body).toEqual({ id: "1", info: "hello child", name: "1" }); expect(response.headers["x-cached"]).toBeUndefined(); expect(response2.headers["x-cached"]).toEqual("true"); expect(response.body).toEqual(response2.body); expect(response3.body).toEqual({ id: "2", info: "hello child", name: "2" }); expect(response4.body).toEqual({ id: "2", info: "hello child", name: "2" }); expect(response3.headers["x-cached"]).toBeUndefined(); expect(response4.headers["x-cached"]).toEqual("true"); expect(response3.body).toEqual(response4.body); expect(response2.body).not.toEqual(response4); expect(response5.body).not.toEqual(response4); }); }); describe("scenario 6: GET /rest/caches/scenario-6", () => { it("should return data from cached service", async () => { const response = await request.get("/rest/caches/scenario-6/1").expect(200); const response2 = await request.get("/rest/caches/scenario-6/2").expect(200); expect(response.body).toEqual({ id: "one:1" }); expect(response2.body).toEqual({ id: "one:1" }); expect(response.headers["x-cached"]).toBeUndefined(); expect(response2.headers["x-cached"]).toBeUndefined(); expect(response.body).toEqual(response2.body); }); }); describe("scenario 7: GET /rest/caches/scenario-7", () => { it("should return data from cached service", async () => { const response = await request.get("/rest/caches/scenario-7/1").expect(200); const response2 = await request.get("/rest/caches/scenario-7/2").expect(200); const response3 = await request.get("/rest/caches/scenario-7/2").expect(200); expect(response.body).toEqual({ id: "one:1" }); expect(response2.body).toEqual({ id: "one:2" }); expect(response3.body).toEqual({ id: "one:2" }); expect(response.body).not.toEqual(response2.body); }); }); }); describe("withoutCache", () => { beforeEach(PlatformTest.bootstrap(options.server, { ...options, logger: {}, cache: false, mount: { "/rest": [TestCacheController] } })); beforeEach(() => { request = SuperTest(PlatformTest.callback()); }); afterEach(PlatformTest.reset); describe("scenario 1: GET /rest/caches/scenario-1", () => { it("should return data with cached response", async () => { const response = await request.get("/rest/caches/scenario-1").expect(200); const response2 = await request.get("/rest/caches/scenario-1").expect(200); expect(response.text).toContain("hello world"); expect(response.headers["x-cached"]).toBeUndefined(); expect(response2.text).toContain("hello world"); expect(response2.headers["x-cached"]).toBeUndefined(); }); }); }); }