@tsed/platform-test-sdk 8.0.1 → 8.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +15 -14
- package/src/components/PlatformTestSdk.ts +30 -0
- package/src/data/file.txt +1 -0
- package/src/data/response.data.json +3 -0
- package/src/data/swagger.json +32 -0
- package/src/errors/CustomBadRequest.ts +16 -0
- package/src/errors/CustomInternalError.ts +16 -0
- package/src/index.ts +40 -0
- package/src/interfaces/PlatformTestingSdkOpts.ts +10 -0
- package/src/interfaces/index.ts +4 -0
- package/src/modules/feature/FeatureModule.ts +10 -0
- package/src/modules/feature/controllers/FeatureController.ts +11 -0
- package/src/tests/exports.ts +71 -0
- package/src/tests/testAcceptMime.ts +99 -0
- package/src/tests/testAuth.ts +345 -0
- package/src/tests/testBodyParams.ts +488 -0
- package/src/tests/testCache.ts +283 -0
- package/src/tests/testChildrenControllers.ts +59 -0
- package/src/tests/testCookies.ts +41 -0
- package/src/tests/testCustom404.ts +35 -0
- package/src/tests/testDeepQueryParams.ts +125 -0
- package/src/tests/testErrors.ts +233 -0
- package/src/tests/testHandlers.ts +94 -0
- package/src/tests/testHeaderParams.ts +158 -0
- package/src/tests/testHeaders.ts +78 -0
- package/src/tests/testInheritanceController.ts +206 -0
- package/src/tests/testLocals.ts +53 -0
- package/src/tests/testLocation.ts +40 -0
- package/src/tests/testMiddlewares.ts +155 -0
- package/src/tests/testModule.ts +50 -0
- package/src/tests/testMulter.ts +158 -0
- package/src/tests/testPathParams.ts +127 -0
- package/src/tests/testQueryParams.ts +238 -0
- package/src/tests/testRedirect.ts +129 -0
- package/src/tests/testResponse.ts +533 -0
- package/src/tests/testResponseFilter.ts +106 -0
- package/src/tests/testRouting.ts +71 -0
- package/src/tests/testScopeRequest.ts +116 -0
- package/src/tests/testSession.ts +108 -0
- package/src/tests/testStatics.ts +63 -0
- package/src/tests/testStream.ts +62 -0
- package/src/tests/testView.ts +74 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import {Controller, ProviderScope, Scope, Service} from "@tsed/di";
|
|
2
|
+
import {PlatformTest} from "@tsed/platform-http/testing";
|
|
3
|
+
import {PathParams} from "@tsed/platform-params";
|
|
4
|
+
import {Get} from "@tsed/schema";
|
|
5
|
+
import SuperTest from "supertest";
|
|
6
|
+
import {afterAll, beforeAll, describe, expect, it} from "vitest";
|
|
7
|
+
|
|
8
|
+
import {PlatformTestingSdkOpts} from "../interfaces/index.js";
|
|
9
|
+
|
|
10
|
+
@Service()
|
|
11
|
+
@Scope(ProviderScope.REQUEST)
|
|
12
|
+
export class ScopeRequestService {
|
|
13
|
+
user: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@Controller("/scopes-request")
|
|
17
|
+
@Scope(ProviderScope.REQUEST)
|
|
18
|
+
export class ScopeRequestCtrl {
|
|
19
|
+
userId: string | null;
|
|
20
|
+
|
|
21
|
+
constructor(public scopeRequestService: ScopeRequestService) {}
|
|
22
|
+
|
|
23
|
+
$onDestroy() {
|
|
24
|
+
this.userId = null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@Get("/:id")
|
|
28
|
+
testPerRequest(@PathParams("id") userId: string): Promise<any> {
|
|
29
|
+
this.scopeRequestService.user = userId;
|
|
30
|
+
this.userId = userId;
|
|
31
|
+
|
|
32
|
+
return new Promise((resolve, reject) => {
|
|
33
|
+
if (userId === "0") {
|
|
34
|
+
setTimeout(() => {
|
|
35
|
+
resolve({userId, idSrv: this.scopeRequestService.user, idCtrl: this.userId});
|
|
36
|
+
}, 500);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (userId === "1") {
|
|
40
|
+
setTimeout(() => {
|
|
41
|
+
resolve({userId, idSrv: this.scopeRequestService.user, idCtrl: this.userId});
|
|
42
|
+
}, 300);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (userId === "2") {
|
|
46
|
+
setTimeout(() => {
|
|
47
|
+
resolve({userId, idSrv: this.scopeRequestService.user, idCtrl: this.userId});
|
|
48
|
+
}, 150);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function testScopeRequest(options: PlatformTestingSdkOpts) {
|
|
55
|
+
let request: SuperTest.Agent;
|
|
56
|
+
|
|
57
|
+
beforeAll(
|
|
58
|
+
PlatformTest.bootstrap(options.server, {
|
|
59
|
+
...options,
|
|
60
|
+
mount: {
|
|
61
|
+
"/rest": [ScopeRequestCtrl]
|
|
62
|
+
}
|
|
63
|
+
})
|
|
64
|
+
);
|
|
65
|
+
beforeAll(() => {
|
|
66
|
+
request = SuperTest(PlatformTest.callback());
|
|
67
|
+
});
|
|
68
|
+
afterAll(PlatformTest.reset);
|
|
69
|
+
|
|
70
|
+
describe("GET /rest/scopes-request/:id", () => {
|
|
71
|
+
const send = (id: string) =>
|
|
72
|
+
new Promise((resolve, reject) => {
|
|
73
|
+
request
|
|
74
|
+
.get(`/rest/scopes-request/${id}`)
|
|
75
|
+
.expect(200)
|
|
76
|
+
.end((err: any, response: any) => {
|
|
77
|
+
if (err) {
|
|
78
|
+
reject(err);
|
|
79
|
+
} else {
|
|
80
|
+
resolve({id, ...JSON.parse(response.text)});
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("should respond with the right userId per request", () => {
|
|
86
|
+
const promises = [];
|
|
87
|
+
|
|
88
|
+
promises.push(send("0"));
|
|
89
|
+
promises.push(send("1"));
|
|
90
|
+
promises.push(send("2"));
|
|
91
|
+
|
|
92
|
+
return Promise.all(promises).then((responses) => {
|
|
93
|
+
expect(responses).toEqual([
|
|
94
|
+
{
|
|
95
|
+
id: "0",
|
|
96
|
+
idCtrl: "0",
|
|
97
|
+
idSrv: "0",
|
|
98
|
+
userId: "0"
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
id: "1",
|
|
102
|
+
idCtrl: "1",
|
|
103
|
+
idSrv: "1",
|
|
104
|
+
userId: "1"
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
id: "2",
|
|
108
|
+
idCtrl: "2",
|
|
109
|
+
idSrv: "2",
|
|
110
|
+
userId: "2"
|
|
111
|
+
}
|
|
112
|
+
]);
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import {Constant, Controller} from "@tsed/di";
|
|
2
|
+
import {NotFound} from "@tsed/exceptions";
|
|
3
|
+
import {Req} from "@tsed/platform-http";
|
|
4
|
+
import {PlatformTest} from "@tsed/platform-http/testing";
|
|
5
|
+
import {BodyParams, Session} from "@tsed/platform-params";
|
|
6
|
+
import {Allow, Email, Get, Ignore, MinLength, Post, Property, Required, Returns} from "@tsed/schema";
|
|
7
|
+
import SuperTest from "supertest";
|
|
8
|
+
import {promisify} from "util";
|
|
9
|
+
import {afterAll, beforeAll, describe, expect, it} from "vitest";
|
|
10
|
+
|
|
11
|
+
import {PlatformTestingSdkOpts} from "../interfaces/index.js";
|
|
12
|
+
|
|
13
|
+
export class UserCreation {
|
|
14
|
+
@Property()
|
|
15
|
+
name: string;
|
|
16
|
+
|
|
17
|
+
@Required()
|
|
18
|
+
@Email()
|
|
19
|
+
@Allow(null)
|
|
20
|
+
email: string;
|
|
21
|
+
|
|
22
|
+
@Required()
|
|
23
|
+
@MinLength(6)
|
|
24
|
+
@Allow(null)
|
|
25
|
+
password: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export class User extends UserCreation {
|
|
29
|
+
@Ignore()
|
|
30
|
+
declare password: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@Controller("/session")
|
|
34
|
+
export class SessionCtrl {
|
|
35
|
+
@Constant("PLATFORM_NAME")
|
|
36
|
+
platformName: string;
|
|
37
|
+
|
|
38
|
+
@Post("/connect")
|
|
39
|
+
connect(@Session() session: any, @BodyParams() user: UserCreation) {
|
|
40
|
+
session.user = user;
|
|
41
|
+
|
|
42
|
+
return Promise.resolve(user);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@Get("/userinfo")
|
|
46
|
+
@Returns(200, User)
|
|
47
|
+
userInfo(@Session("user") user: User): Promise<User> {
|
|
48
|
+
if (!user) {
|
|
49
|
+
return Promise.reject(new NotFound("User not found"));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return Promise.resolve(user);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@Get("/logout")
|
|
56
|
+
@Returns(204)
|
|
57
|
+
logout(@Req() req: any) {
|
|
58
|
+
switch (this.platformName) {
|
|
59
|
+
case "koa":
|
|
60
|
+
return Promise.resolve((req.ctx.session = null));
|
|
61
|
+
case "express":
|
|
62
|
+
delete req.session.user;
|
|
63
|
+
|
|
64
|
+
return promisify(req.session.destroy.bind(req.session))();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return Promise.resolve();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function testSession(options: PlatformTestingSdkOpts) {
|
|
72
|
+
let request: SuperTest.Agent;
|
|
73
|
+
beforeAll(
|
|
74
|
+
PlatformTest.bootstrap(options.server, {
|
|
75
|
+
...options,
|
|
76
|
+
mount: {
|
|
77
|
+
"/rest": [SessionCtrl]
|
|
78
|
+
}
|
|
79
|
+
})
|
|
80
|
+
);
|
|
81
|
+
beforeAll(() => {
|
|
82
|
+
request = SuperTest.agent(PlatformTest.callback());
|
|
83
|
+
});
|
|
84
|
+
afterAll(PlatformTest.reset);
|
|
85
|
+
|
|
86
|
+
describe("Scenario1: POST /rest/session/connected", () => {
|
|
87
|
+
it("should keep connected user in session and destroy session", async () => {
|
|
88
|
+
await request.get("/rest/session/userinfo").expect(404);
|
|
89
|
+
|
|
90
|
+
await request.post("/rest/session/connect").send({
|
|
91
|
+
name: "name",
|
|
92
|
+
email: "test@test.fr",
|
|
93
|
+
password: "password1234"
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// @ts-ignore
|
|
97
|
+
const response = await request.get("/rest/session/userinfo").expect(200);
|
|
98
|
+
|
|
99
|
+
expect(response.body).toEqual({
|
|
100
|
+
email: "test@test.fr",
|
|
101
|
+
name: "name"
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
await request.get("/rest/session/logout").expect(204);
|
|
105
|
+
await request.get("/rest/session/userinfo").expect(404);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import {getValue} from "@tsed/core";
|
|
2
|
+
import {Configuration, Controller} from "@tsed/di";
|
|
3
|
+
import {PlatformTest} from "@tsed/platform-http/testing";
|
|
4
|
+
import {PlatformRouter} from "@tsed/platform-router";
|
|
5
|
+
import {readFileSync} from "fs";
|
|
6
|
+
import SuperTest from "supertest";
|
|
7
|
+
import {afterEach, beforeEach, expect, it} from "vitest";
|
|
8
|
+
|
|
9
|
+
import {PlatformTestingSdkOpts} from "../interfaces/index.js";
|
|
10
|
+
|
|
11
|
+
@Controller("/statics")
|
|
12
|
+
class CustomStaticsCtrl {
|
|
13
|
+
constructor(router: PlatformRouter, @Configuration() config: Configuration) {
|
|
14
|
+
router.statics("/", {
|
|
15
|
+
root: String(getValue(config, "statics./"))
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function testStatics(options: PlatformTestingSdkOpts) {
|
|
21
|
+
let request: SuperTest.Agent;
|
|
22
|
+
beforeEach(
|
|
23
|
+
PlatformTest.bootstrap(options.server, {
|
|
24
|
+
...options,
|
|
25
|
+
mount: {
|
|
26
|
+
"/rest": [CustomStaticsCtrl]
|
|
27
|
+
}
|
|
28
|
+
})
|
|
29
|
+
);
|
|
30
|
+
beforeEach(() => {
|
|
31
|
+
request = SuperTest(PlatformTest.callback());
|
|
32
|
+
});
|
|
33
|
+
afterEach(PlatformTest.reset);
|
|
34
|
+
|
|
35
|
+
it("should return index HTML (1)", async () => {
|
|
36
|
+
const response = await request.get("/").expect(200);
|
|
37
|
+
|
|
38
|
+
expect(response.text).toEqual(readFileSync(`${options.rootDir}/public/index.html`, {encoding: "utf8"}));
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("should return index HTML (2)", async () => {
|
|
42
|
+
const response = await request.get("/index.html").expect(200);
|
|
43
|
+
|
|
44
|
+
expect(response.text).toEqual(readFileSync(`${options.rootDir}/public/index.html`, {encoding: "utf8"}));
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("should return index HTML (3)", async () => {
|
|
48
|
+
const response = await request.get("/rest/statics/index.html").expect(200);
|
|
49
|
+
|
|
50
|
+
expect(response.text).toEqual(readFileSync(`${options.rootDir}/public/index.html`, {encoding: "utf8"}));
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("should return 404", async () => {
|
|
54
|
+
const response = await request.get("/index-te.html").expect(404);
|
|
55
|
+
|
|
56
|
+
expect(response.body).toEqual({
|
|
57
|
+
errors: [],
|
|
58
|
+
message: 'Resource "/index-te.html" not found',
|
|
59
|
+
name: "NOT_FOUND",
|
|
60
|
+
status: 404
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import {Controller} from "@tsed/di";
|
|
2
|
+
import {PlatformTest} from "@tsed/platform-http/testing";
|
|
3
|
+
import {ContentType, Get} from "@tsed/schema";
|
|
4
|
+
import {createReadStream} from "fs";
|
|
5
|
+
import {join} from "path";
|
|
6
|
+
import SuperTest from "supertest";
|
|
7
|
+
import {afterAll, beforeAll, describe, expect, it} from "vitest";
|
|
8
|
+
|
|
9
|
+
import {PlatformTestingSdkOpts} from "../interfaces/index.js";
|
|
10
|
+
|
|
11
|
+
const rootDir = import.meta.dirname; // automatically replaced by import.meta.dirname on build
|
|
12
|
+
|
|
13
|
+
@Controller("/stream")
|
|
14
|
+
class TestStreamCtrl {
|
|
15
|
+
@Get("/scenario1")
|
|
16
|
+
@ContentType("application/json")
|
|
17
|
+
testScenario1() {
|
|
18
|
+
return createReadStream(join(rootDir, "../data/response.data.json"), "utf-8");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@Get("/scenario1b")
|
|
22
|
+
@ContentType("application/json")
|
|
23
|
+
testScenario2() {
|
|
24
|
+
return Promise.resolve(createReadStream(join(rootDir, "../data/response.data.json"), "utf-8"));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function testStream(options: PlatformTestingSdkOpts) {
|
|
29
|
+
let request: SuperTest.Agent;
|
|
30
|
+
|
|
31
|
+
beforeAll(
|
|
32
|
+
PlatformTest.bootstrap(options.server, {
|
|
33
|
+
...options,
|
|
34
|
+
mount: {
|
|
35
|
+
"/rest": [TestStreamCtrl]
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
);
|
|
39
|
+
beforeAll(() => {
|
|
40
|
+
request = SuperTest(PlatformTest.callback());
|
|
41
|
+
});
|
|
42
|
+
afterAll(PlatformTest.reset);
|
|
43
|
+
|
|
44
|
+
describe("Scenario1: when endpoint return a stream", () => {
|
|
45
|
+
describe("GET /rest/stream/scenario1", () => {
|
|
46
|
+
it("should return a body", async () => {
|
|
47
|
+
const response = await request.get("/rest/stream/scenario1");
|
|
48
|
+
|
|
49
|
+
expect(response.headers["content-type"]).toContain("application/json");
|
|
50
|
+
expect(response.body).toEqual({id: "1"});
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
describe("GET /rest/stream/scenario1b", () => {
|
|
55
|
+
it("should return a body", async () => {
|
|
56
|
+
const response = await request.get("/rest/stream/scenario1b");
|
|
57
|
+
|
|
58
|
+
expect(response.body).toEqual({id: "1"});
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import {Controller} from "@tsed/di";
|
|
2
|
+
import {PlatformTest} from "@tsed/platform-http/testing";
|
|
3
|
+
import {Middleware, UseBefore} from "@tsed/platform-middlewares";
|
|
4
|
+
import {Locals} from "@tsed/platform-params";
|
|
5
|
+
import {View} from "@tsed/platform-views";
|
|
6
|
+
import {Get} from "@tsed/schema";
|
|
7
|
+
import {EOL} from "os";
|
|
8
|
+
import SuperTest from "supertest";
|
|
9
|
+
import {afterAll, beforeAll, describe, expect, it} from "vitest";
|
|
10
|
+
|
|
11
|
+
import {PlatformTestingSdkOpts} from "../interfaces/index.js";
|
|
12
|
+
|
|
13
|
+
@Middleware()
|
|
14
|
+
class LocalsMiddleware {
|
|
15
|
+
use(@Locals() locals: any) {
|
|
16
|
+
locals.localID = "local-10909";
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
@Controller("/views")
|
|
21
|
+
class ViewCtrl {
|
|
22
|
+
@Get("/scenario-1")
|
|
23
|
+
@UseBefore(LocalsMiddleware)
|
|
24
|
+
@View("view.ejs", {opts: "opts"})
|
|
25
|
+
testScenario1() {
|
|
26
|
+
return {
|
|
27
|
+
world: "world"
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@Get("/scenario-2")
|
|
32
|
+
@View("view", {opts: "opts"}) // missing extension
|
|
33
|
+
testScenario2() {
|
|
34
|
+
return {
|
|
35
|
+
world: "world"
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function testView(options: PlatformTestingSdkOpts) {
|
|
41
|
+
let request: SuperTest.Agent;
|
|
42
|
+
|
|
43
|
+
beforeAll(
|
|
44
|
+
PlatformTest.bootstrap(options.server, {
|
|
45
|
+
...options,
|
|
46
|
+
mount: {
|
|
47
|
+
"/rest": [ViewCtrl]
|
|
48
|
+
}
|
|
49
|
+
})
|
|
50
|
+
);
|
|
51
|
+
beforeAll(() => {
|
|
52
|
+
request = SuperTest(PlatformTest.callback());
|
|
53
|
+
});
|
|
54
|
+
afterAll(() => PlatformTest.reset());
|
|
55
|
+
|
|
56
|
+
describe("Scenario1: GET /rest/views/scenario-1", () => {
|
|
57
|
+
it("should render a view", async () => {
|
|
58
|
+
const response = await request.get("/rest/views/scenario-1").expect(200);
|
|
59
|
+
|
|
60
|
+
expect(response.headers["content-type"]).toEqual("text/html; charset=utf-8");
|
|
61
|
+
expect(response.text).toEqual(`<p>Hello world with opts and ID local-10909</p>${EOL}`);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
describe("Scenario2: GET /rest/views/scenario-2", () => {
|
|
66
|
+
it("should throw an error when extension is not defined", async () => {
|
|
67
|
+
const response = await request.get("/rest/views/scenario-2").expect(500);
|
|
68
|
+
|
|
69
|
+
expect(response.body.name).toEqual("TEMPLATE_RENDER_ERROR");
|
|
70
|
+
expect(response.body.message).toContain("Template rendering error: ViewCtrl.testScenario2()");
|
|
71
|
+
expect(response.body.status).toEqual(500);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
}
|