@tsed/platform-test-sdk
Version:
Package to test platform adapter integration with Ts.ED
298 lines (297 loc) • 13.3 kB
JavaScript
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();
});
});
});
}