@tsed/platform-http 8.0.0 → 8.0.2

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.
Files changed (105) hide show
  1. package/.barrelsby.json +1 -1
  2. package/lib/esm/common/index.js +0 -1
  3. package/lib/esm/common/index.js.map +1 -1
  4. package/lib/types/common/fn/adapter.d.ts +1 -1
  5. package/lib/types/common/index.d.ts +0 -1
  6. package/package.json +19 -17
  7. package/src/common/builder/PlatformBuilder.spec.ts +331 -0
  8. package/src/common/builder/PlatformBuilder.ts +426 -0
  9. package/src/common/builder/__fixtures__/PlatformCustom.ts +39 -0
  10. package/src/common/config/interfaces/PlatformJsonMapperSettings.ts +11 -0
  11. package/src/common/config/interfaces/PlatformMulterSettings.ts +21 -0
  12. package/src/common/config/interfaces/PlatformRouterSettings.ts +11 -0
  13. package/src/common/config/interfaces/PlatformStaticsSettings.ts +23 -0
  14. package/src/common/config/services/PlatformConfiguration.spec.ts +181 -0
  15. package/src/common/config/services/PlatformConfiguration.ts +157 -0
  16. package/src/common/constants/routerOptions.ts +1 -0
  17. package/src/common/decorators/PlatformProvider.ts +14 -0
  18. package/src/common/decorators/multer/multerFileSize.spec.ts +22 -0
  19. package/src/common/decorators/multer/multerFileSize.ts +32 -0
  20. package/src/common/decorators/multer/multerOptions.spec.ts +21 -0
  21. package/src/common/decorators/multer/multerOptions.ts +53 -0
  22. package/src/common/decorators/multer/multipartFile.spec.ts +259 -0
  23. package/src/common/decorators/multer/multipartFile.ts +88 -0
  24. package/src/common/decorators/params/error.spec.ts +15 -0
  25. package/src/common/decorators/params/error.ts +16 -0
  26. package/src/common/decorators/params/next.spec.ts +15 -0
  27. package/src/common/decorators/params/next.ts +31 -0
  28. package/src/common/decorators/params/request.spec.ts +49 -0
  29. package/src/common/decorators/params/request.ts +85 -0
  30. package/src/common/decorators/params/response.spec.ts +36 -0
  31. package/src/common/decorators/params/response.ts +73 -0
  32. package/src/common/domain/AnyToPromiseWithCtx.spec.ts +20 -0
  33. package/src/common/domain/AnyToPromiseWithCtx.ts +30 -0
  34. package/src/common/domain/EndpointMetadata.ts +1 -0
  35. package/src/common/domain/PlatformContext.spec.ts +124 -0
  36. package/src/common/domain/PlatformContext.ts +135 -0
  37. package/src/common/domain/PlatformRouteDetails.ts +7 -0
  38. package/src/common/exports.ts +4 -0
  39. package/src/common/fn/adapter.ts +23 -0
  40. package/src/common/fn/application.ts +11 -0
  41. package/src/common/index.ts +62 -0
  42. package/src/common/interfaces/AfterInit.ts +3 -0
  43. package/src/common/interfaces/AfterListen.ts +3 -0
  44. package/src/common/interfaces/AfterRoutesInit.ts +3 -0
  45. package/src/common/interfaces/BeforeInit.ts +3 -0
  46. package/src/common/interfaces/BeforeListen.ts +3 -0
  47. package/src/common/interfaces/BeforeRoutesInit.ts +3 -0
  48. package/src/common/interfaces/HandlerType.ts +12 -0
  49. package/src/common/interfaces/IncomingEvent.ts +6 -0
  50. package/src/common/interfaces/OnReady.ts +3 -0
  51. package/src/common/interfaces/OnRequest.ts +5 -0
  52. package/src/common/interfaces/OnResponse.ts +5 -0
  53. package/src/common/interfaces/OnRoutesInit.ts +3 -0
  54. package/src/common/interfaces/PlatformRouteOptions.ts +17 -0
  55. package/src/common/interfaces/ResponseErrorObject.ts +8 -0
  56. package/src/common/interfaces/Route.ts +12 -0
  57. package/src/common/middlewares/PlatformAcceptMimesMiddleware.spec.ts +215 -0
  58. package/src/common/middlewares/PlatformAcceptMimesMiddleware.ts +24 -0
  59. package/src/common/middlewares/PlatformMulterMiddleware.spec.ts +97 -0
  60. package/src/common/middlewares/PlatformMulterMiddleware.ts +59 -0
  61. package/src/common/services/Platform.spec.ts +145 -0
  62. package/src/common/services/Platform.ts +79 -0
  63. package/src/common/services/PlatformAdapter.ts +89 -0
  64. package/src/common/services/PlatformApplication.spec.ts +101 -0
  65. package/src/common/services/PlatformApplication.ts +54 -0
  66. package/src/common/services/PlatformHandler.spec.ts +152 -0
  67. package/src/common/services/PlatformHandler.ts +140 -0
  68. package/src/common/services/PlatformMiddlewaresChain.spec.ts +96 -0
  69. package/src/common/services/PlatformMiddlewaresChain.ts +55 -0
  70. package/src/common/services/PlatformRequest.spec.ts +185 -0
  71. package/src/common/services/PlatformRequest.ts +181 -0
  72. package/src/common/services/PlatformResponse.spec.ts +344 -0
  73. package/src/common/services/PlatformResponse.ts +388 -0
  74. package/src/common/utils/closeServer.spec.ts +11 -0
  75. package/src/common/utils/closeServer.ts +7 -0
  76. package/src/common/utils/createContext.spec.ts +111 -0
  77. package/src/common/utils/createContext.ts +52 -0
  78. package/src/common/utils/createHttpServer.spec.ts +74 -0
  79. package/src/common/utils/createHttpServer.ts +15 -0
  80. package/src/common/utils/createHttpsServer.spec.ts +73 -0
  81. package/src/common/utils/createHttpsServer.ts +16 -0
  82. package/src/common/utils/createInjector.spec.ts +42 -0
  83. package/src/common/utils/createInjector.ts +55 -0
  84. package/src/common/utils/createServer.ts +51 -0
  85. package/src/common/utils/ensureContext.spec.ts +41 -0
  86. package/src/common/utils/ensureContext.ts +17 -0
  87. package/src/common/utils/getConfiguration.spec.ts +163 -0
  88. package/src/common/utils/getConfiguration.ts +34 -0
  89. package/src/common/utils/getStaticsOptions.spec.ts +27 -0
  90. package/src/common/utils/getStaticsOptions.ts +24 -0
  91. package/src/common/utils/listenServer.ts +17 -0
  92. package/src/common/utils/mapReturnedResponse.spec.ts +35 -0
  93. package/src/common/utils/mapReturnedResponse.ts +10 -0
  94. package/src/common/utils/printRoutes.spec.ts +19 -0
  95. package/src/common/utils/printRoutes.ts +40 -0
  96. package/src/common/utils/resolveControllers.spec.ts +40 -0
  97. package/src/common/utils/resolveControllers.ts +54 -0
  98. package/src/common/utils/setResponseHeaders.spec.ts +84 -0
  99. package/src/common/utils/setResponseHeaders.ts +31 -0
  100. package/src/index.ts +2 -0
  101. package/src/testing/FakeAdapter.ts +69 -0
  102. package/src/testing/FakeResponse.ts +72 -0
  103. package/src/testing/PlatformTest.spec.ts +53 -0
  104. package/src/testing/PlatformTest.ts +157 -0
  105. package/src/testing/index.ts +5 -0
@@ -0,0 +1,185 @@
1
+ import {PlatformHandlerMetadata} from "@tsed/platform-router";
2
+
3
+ import {FakeAdapter} from "../../testing/index.js";
4
+ import {PlatformTest} from "../../testing/PlatformTest.js";
5
+ import {PlatformAdapter} from "./PlatformAdapter.js";
6
+ import {PlatformRequest} from "./PlatformRequest.js";
7
+
8
+ function createRequest() {
9
+ const $ctx = PlatformTest.createRequestContext();
10
+
11
+ return {req: $ctx.request.request, request: $ctx.request};
12
+ }
13
+
14
+ describe("PlatformRequest", () => {
15
+ beforeEach(() => PlatformTest.create());
16
+ afterEach(() => PlatformTest.reset());
17
+
18
+ it("should create a PlatformRequest instance", () => {
19
+ const request = PlatformTest.createRequest();
20
+ const response = PlatformTest.createResponse();
21
+ const $ctx = PlatformTest.createRequestContext({
22
+ event: {
23
+ request,
24
+ response
25
+ }
26
+ });
27
+
28
+ expect($ctx.request.raw).toEqual(request);
29
+ expect($ctx.request.response).toEqual($ctx.response);
30
+ expect($ctx.request.headers).toEqual({});
31
+ expect($ctx.request.get("host")).toEqual(undefined);
32
+ expect($ctx.request.getHeader("host")).toEqual(undefined);
33
+ expect($ctx.request.method).toEqual("GET");
34
+ });
35
+
36
+ describe("secure()", () => {
37
+ it("should return the secure request state (false)", () => {
38
+ const $ctx = PlatformTest.createRequestContext();
39
+
40
+ $ctx.request.request.secure = false;
41
+
42
+ expect($ctx.request.secure).toEqual(false);
43
+ });
44
+ it("should return the secure request state (true)", () => {
45
+ const $ctx = PlatformTest.createRequestContext();
46
+
47
+ $ctx.request.request.secure = true;
48
+ expect($ctx.request.secure).toEqual(true);
49
+ });
50
+ });
51
+
52
+ describe("route()", () => {
53
+ it("should return route", () => {
54
+ const $ctx = PlatformTest.createRequestContext();
55
+ $ctx.handlerMetadata = new PlatformHandlerMetadata({
56
+ handler: () => {}
57
+ });
58
+ $ctx.handlerMetadata.path = "/id";
59
+
60
+ expect($ctx.request.route).toEqual("/id");
61
+ });
62
+ });
63
+
64
+ describe("protocol()", () => {
65
+ it("should return the protocol request state (http)", () => {
66
+ const $ctx = PlatformTest.createRequestContext();
67
+
68
+ $ctx.request.request.protocol = "http";
69
+
70
+ expect($ctx.request.protocol).toEqual("http");
71
+ });
72
+ it("should return the protocol request state (https)", () => {
73
+ const {req, request} = createRequest();
74
+
75
+ req.protocol = "https";
76
+ expect(request.protocol).toEqual("https");
77
+ });
78
+ });
79
+
80
+ describe("host()", () => {
81
+ it("should return the host", () => {
82
+ const {request} = createRequest();
83
+
84
+ request.raw.headers["host"] = "host";
85
+
86
+ expect(request.host).toEqual("host");
87
+ });
88
+ });
89
+
90
+ describe("accepts()", () => {
91
+ it("should set the accepts header", () => {
92
+ const {req, request} = createRequest();
93
+
94
+ vi.spyOn(req, "accepts");
95
+
96
+ request.accepts("application/json");
97
+
98
+ expect(req.accepts).toHaveBeenCalledWith("application/json");
99
+ });
100
+ });
101
+
102
+ describe("rawBody()", () => {
103
+ it("should return the rawBody", () => {
104
+ const {req, request} = createRequest();
105
+ req.rawBody = "raw";
106
+ const raw = request.rawBody;
107
+
108
+ expect(raw).toEqual("raw");
109
+ });
110
+ it("should return the body", () => {
111
+ const {req, request} = createRequest();
112
+ req.body = "raw";
113
+ const raw = request.rawBody;
114
+
115
+ expect(raw).toEqual("raw");
116
+ });
117
+ });
118
+
119
+ describe("files()", () => {
120
+ it("should return the files", () => {
121
+ const {req, request} = createRequest();
122
+ req.files = "files";
123
+
124
+ expect(request.files).toEqual("files");
125
+ });
126
+ });
127
+
128
+ describe("getReq()", () => {
129
+ it("should return req", () => {
130
+ const {req, request} = createRequest();
131
+
132
+ expect(request.req).toEqual(req);
133
+ });
134
+ });
135
+
136
+ describe("getters", () => {
137
+ it("should return the expected data", () => {
138
+ const {request} = createRequest();
139
+ request.raw.originalUrl = "/";
140
+ request.raw.query =
141
+ request.raw.session =
142
+ request.raw.cookies =
143
+ request.raw.params =
144
+ request.raw.body =
145
+ {
146
+ obj: {
147
+ test: "testValue"
148
+ },
149
+ test: "testValue"
150
+ };
151
+
152
+ expect(request.url).toEqual("/");
153
+ expect(request.body).toEqual({
154
+ obj: {
155
+ test: "testValue"
156
+ },
157
+ test: "testValue"
158
+ });
159
+ expect(request.params).toEqual({
160
+ obj: {
161
+ test: "testValue"
162
+ },
163
+ test: "testValue"
164
+ });
165
+ expect(request.query).toEqual({
166
+ obj: {
167
+ test: "testValue"
168
+ },
169
+ test: "testValue"
170
+ });
171
+ expect(request.cookies).toEqual({
172
+ obj: {
173
+ test: "testValue"
174
+ },
175
+ test: "testValue"
176
+ });
177
+ expect(request.session).toEqual({
178
+ obj: {
179
+ test: "testValue"
180
+ },
181
+ test: "testValue"
182
+ });
183
+ });
184
+ });
185
+ });
@@ -0,0 +1,181 @@
1
+ import {Injectable, injectable, ProviderScope, Scope} from "@tsed/di";
2
+ import {IncomingHttpHeaders, IncomingMessage} from "http";
3
+
4
+ import type {PlatformContext} from "../domain/PlatformContext.js";
5
+ import type {PlatformResponse} from "./PlatformResponse.js";
6
+
7
+ declare global {
8
+ namespace TsED {
9
+ // @ts-ignore
10
+ export interface Request {
11
+ id: string;
12
+ }
13
+ }
14
+ }
15
+
16
+ /**
17
+ * Platform Request abstraction layer.
18
+ * @platform
19
+ */
20
+ export class PlatformRequest<Req extends {[key: string]: any} = any> {
21
+ constructor(readonly $ctx: PlatformContext) {}
22
+ /**
23
+ * The current @@PlatformResponse@@.
24
+ */
25
+ get response(): PlatformResponse {
26
+ return this.$ctx.response;
27
+ }
28
+
29
+ get raw(): Req {
30
+ return this.$ctx.event.request as any;
31
+ }
32
+
33
+ get secure(): boolean {
34
+ return this.raw.secure;
35
+ }
36
+
37
+ get host(): string {
38
+ return this.get("host");
39
+ }
40
+
41
+ get protocol(): string {
42
+ return this.raw.protocol;
43
+ }
44
+
45
+ /**
46
+ * Get the url of the request.
47
+ *
48
+ * Is equivalent of `express.response.originalUrl || express.response.url`.
49
+ */
50
+ get url(): string {
51
+ return this.raw.originalUrl || this.raw.url;
52
+ }
53
+
54
+ get headers(): IncomingHttpHeaders {
55
+ return this.raw.headers;
56
+ }
57
+
58
+ get method(): string {
59
+ return this.raw.method;
60
+ }
61
+
62
+ /**
63
+ * Contains key-value pairs of data submitted in the request body. By default, it is `undefined`, and is populated when you use
64
+ * `body-parsing` middleware such as `express.json()` or `express.urlencoded()`.
65
+ */
66
+ get body(): any {
67
+ return this.raw.body;
68
+ }
69
+
70
+ get rawBody(): any {
71
+ return this.raw.rawBody || this.raw.body;
72
+ }
73
+
74
+ /**
75
+ * When using `cookie-parser` middleware, this property is an object that contains cookies sent by the request.
76
+ * If the request contains no cookies, it defaults to `{}`.
77
+ */
78
+ get cookies(): {[key: string]: any} {
79
+ return this.raw.cookies;
80
+ }
81
+
82
+ /**
83
+ * This property is an object containing properties mapped to the named route `parameters`.
84
+ * For example, if you have the route `/user/:name`, then the `name` property is available as `req.params.name`.
85
+ * This object defaults to `{}`.
86
+ */
87
+ get params(): {[key: string]: any} {
88
+ return this.raw.params;
89
+ }
90
+
91
+ /**
92
+ * This property is an object containing a property for each query string parameter in the route.
93
+ * When query parser is set to disabled, it is an empty object `{}`, otherwise it is the result of the configured query parser.
94
+ */
95
+ get query(): {[key: string]: any} {
96
+ return this.raw.query;
97
+ }
98
+
99
+ /**
100
+ * This property is an object containing a property for each session attributes set by any code.
101
+ * It requires to install a middleware like express-session to work.
102
+ */
103
+ get session(): {[key: string]: any} {
104
+ return this.raw.session as any;
105
+ }
106
+
107
+ get files() {
108
+ return this.raw.files;
109
+ }
110
+
111
+ get route() {
112
+ return this.$ctx.handlerMetadata?.path;
113
+ }
114
+
115
+ /**
116
+ * Return the original request framework instance
117
+ */
118
+ get request() {
119
+ return this.getRequest();
120
+ }
121
+
122
+ /**
123
+ * Return the original request node.js instance
124
+ */
125
+ get req() {
126
+ return this.getReq();
127
+ }
128
+
129
+ /**
130
+ * Returns the HTTP request header specified by field. The match is case-insensitive.
131
+ *
132
+ * ```typescript
133
+ * request.get('Content-Type') // => "text/plain"
134
+ * ```
135
+ *
136
+ * @param name
137
+ */
138
+ get(name: string) {
139
+ return this.raw.get(name);
140
+ }
141
+
142
+ getHeader(name: string) {
143
+ return this.get(name);
144
+ }
145
+
146
+ /**
147
+ * Checks if the specified content types are acceptable, based on the request’s Accept HTTP header field. The method returns the best match, or if none of the specified content types is acceptable, returns false (in which case, the application should respond with 406 "Not Acceptable").
148
+ *
149
+ * The type value may be a single MIME type string (such as “application/json”), an extension name such as “json”, a comma-delimited list, or an array. For a list or array, the method returns the best match (if any).
150
+ *
151
+ * @param mime
152
+ */
153
+ accepts(mime: string): string | false;
154
+
155
+ accepts(mime: string[]): string[] | false;
156
+
157
+ accepts(mime?: string | string[]): string | string[] | false {
158
+ // @ts-ignore
159
+ return this.raw.accepts(mime);
160
+ }
161
+
162
+ isAborted() {
163
+ return this.raw.aborted;
164
+ }
165
+
166
+ /**
167
+ * Return the Framework response object (express, koa, etc...)
168
+ */
169
+ getRequest<R = Req>(): R {
170
+ return this.raw as any;
171
+ }
172
+
173
+ /**
174
+ * Return the Node.js response object
175
+ */
176
+ getReq(): IncomingMessage {
177
+ return this.$ctx.event.request;
178
+ }
179
+ }
180
+
181
+ injectable(PlatformRequest).scope(ProviderScope.INSTANCE);
@@ -0,0 +1,344 @@
1
+ import {PlatformViews} from "@tsed/platform-views";
2
+ import {createReadStream} from "fs";
3
+
4
+ import {PlatformTest} from "../../testing/PlatformTest.js";
5
+ import {PlatformResponse} from "./PlatformResponse.js";
6
+
7
+ const rootDir = import.meta.dirname; // automatically replaced by import.meta.dirname on build
8
+
9
+ vi.mock("on-finished");
10
+
11
+ function createResponse() {
12
+ const ctx = PlatformTest.createRequestContext();
13
+ const platformViews = PlatformTest.get(PlatformViews);
14
+
15
+ return {res: ctx.response.raw, response: ctx.response, platformViews, ctx};
16
+ }
17
+
18
+ describe("PlatformResponse", () => {
19
+ beforeEach(() => PlatformTest.create());
20
+ afterEach(() => PlatformTest.reset());
21
+ it("should create a PlatformResponse instance", () => {
22
+ const {res, response, ctx} = createResponse();
23
+
24
+ expect(response.raw).toEqual(res);
25
+ expect(response.request).toEqual(ctx.request);
26
+ });
27
+ describe("statusCode", () => {
28
+ it("should return status code", () => {
29
+ const {res, response} = createResponse();
30
+
31
+ res.statusCode = 201;
32
+
33
+ expect(response.statusCode).toEqual(201);
34
+ });
35
+ });
36
+ describe("status()", () => {
37
+ it("should set status code", () => {
38
+ const {res, response} = createResponse();
39
+ vi.spyOn(res, "status").mockReturnValue(undefined);
40
+ response.status(204);
41
+
42
+ expect(res.status).toHaveBeenCalledWith(204);
43
+ });
44
+ });
45
+ describe("setHeaders()", () => {
46
+ it("should set headers", () => {
47
+ const {res, response} = createResponse();
48
+
49
+ response.setHeaders({"x-token": "token"});
50
+
51
+ expect(res.headers).toEqual({
52
+ "x-request-id": "id",
53
+ "x-token": "token"
54
+ });
55
+ });
56
+ });
57
+ describe("contentType()", () => {
58
+ it("should set content Type", () => {
59
+ const {res, response} = createResponse();
60
+
61
+ response.contentType("application/json");
62
+
63
+ expect(res.headers).toEqual({
64
+ "content-type": "application/json",
65
+ "x-request-id": "id"
66
+ });
67
+ });
68
+ });
69
+ describe("getContentType()", () => {
70
+ it("should get content Type", () => {
71
+ const {res, response} = createResponse();
72
+
73
+ res.headers["content-type"] = "application/json";
74
+
75
+ expect(response.getContentType()).toEqual("application/json");
76
+ });
77
+ });
78
+ describe("contentLength()", () => {
79
+ it("should set content length", () => {
80
+ const {res, response} = createResponse();
81
+
82
+ response.contentLength(5);
83
+
84
+ expect(res.headers).toEqual({"content-length": 5, "x-request-id": "id"});
85
+ });
86
+ });
87
+ describe("getContentLength()", () => {
88
+ it("should set content Type", () => {
89
+ const {res, response} = createResponse();
90
+
91
+ response.contentLength(5);
92
+
93
+ expect(response.getContentLength()).toEqual(5);
94
+ });
95
+
96
+ it("should set content Type (size 0)", () => {
97
+ const {res, response} = createResponse();
98
+
99
+ response.contentLength(" " as any);
100
+
101
+ expect(response.getContentLength()).toEqual(0);
102
+ });
103
+ });
104
+ describe("redirect()", () => {
105
+ it("should set redirect", () => {
106
+ const {res, response} = createResponse();
107
+
108
+ response.redirect(302, "/path");
109
+
110
+ expect(res.headers).toEqual({location: "/path", "x-request-id": "id", "content-length": 27});
111
+ expect(res.statusCode).toEqual(302);
112
+ });
113
+
114
+ it("should set redirect (default status)", () => {
115
+ const {res, response} = createResponse();
116
+
117
+ response.redirect(0, "/path");
118
+
119
+ expect(res.headers).toEqual({location: "/path", "x-request-id": "id", "content-length": 27});
120
+ expect(res.statusCode).toEqual(302);
121
+ });
122
+
123
+ it("should set redirect (301)", () => {
124
+ const {res, response, ctx} = createResponse();
125
+ res.headers["location"] = "https://location";
126
+ ctx.request.getReq().method = "HEAD";
127
+
128
+ response.redirect(301, "https://location");
129
+
130
+ expect(res.headers).toEqual({
131
+ location: "https://location",
132
+ "x-request-id": "id"
133
+ });
134
+ expect(res.statusCode).toEqual(301);
135
+ });
136
+
137
+ it("should set redirect (302, back url)", () => {
138
+ const {res, response, ctx} = createResponse();
139
+ ctx.request.getReq().method = "HEAD";
140
+ ctx.request.headers["referrer"] = "https://referrer.com";
141
+
142
+ response.redirect(302, "back");
143
+
144
+ expect(res.headers).toEqual({
145
+ location: "https://referrer.com",
146
+ "x-request-id": "id"
147
+ });
148
+ expect(res.statusCode).toEqual(302);
149
+ });
150
+ it("should set redirect (302, back url, default)", () => {
151
+ const {res, response, ctx} = createResponse();
152
+ ctx.request.getReq().method = "HEAD";
153
+
154
+ response.redirect(302, "back");
155
+
156
+ expect(res.headers).toEqual({
157
+ location: "/",
158
+ "x-request-id": "id"
159
+ });
160
+ expect(res.statusCode).toEqual(302);
161
+ });
162
+ });
163
+ describe("render()", () => {
164
+ it("should return a string", async () => {
165
+ const {response, platformViews} = createResponse();
166
+
167
+ response.locals.locale = "fr-FR";
168
+ vi.spyOn(platformViews, "render").mockResolvedValue("HTML");
169
+
170
+ const result = await response.render("view", {
171
+ test: "test"
172
+ });
173
+
174
+ expect(platformViews.render).toHaveBeenCalledWith("view", {
175
+ locale: "fr-FR",
176
+ test: "test"
177
+ });
178
+ expect(result).toEqual("HTML");
179
+ });
180
+ });
181
+ describe("location()", () => {
182
+ it("should set location", () => {
183
+ const {res, response} = createResponse();
184
+
185
+ response.location("/path");
186
+
187
+ expect(res.headers).toEqual({
188
+ location: "/path",
189
+ "x-request-id": "id"
190
+ });
191
+ });
192
+ });
193
+ describe("body()", () => {
194
+ it("should call body with undefined", () => {
195
+ const {res, response} = createResponse();
196
+
197
+ response.body(undefined);
198
+
199
+ expect(res.data).toBeUndefined();
200
+ });
201
+ it("should call body with string", () => {
202
+ const {res, response} = createResponse();
203
+
204
+ response.body("string");
205
+
206
+ expect(res.data).toEqual("string");
207
+ expect(response.getBody()).toEqual("string");
208
+ });
209
+ it("should call body with stream", () => {
210
+ const {res, response} = createResponse();
211
+ const stream = createReadStream(rootDir + "/__mock__/data.txt");
212
+ vi.spyOn(stream, "pipe").mockReturnValue(undefined as any);
213
+
214
+ response.body(stream);
215
+
216
+ expect(stream.pipe).toHaveBeenCalledWith(res);
217
+ });
218
+ it("should call body with buffer", () => {
219
+ const {res, response} = createResponse();
220
+ const buffer = Buffer.from("string");
221
+
222
+ response.body(buffer);
223
+
224
+ expect(res.data).toEqual(buffer);
225
+ expect(res.headers).toEqual({
226
+ "content-length": 6,
227
+ "content-type": "application/octet-stream",
228
+ "x-request-id": "id"
229
+ });
230
+ });
231
+ it("should call body with {}", () => {
232
+ const {res, response} = createResponse();
233
+
234
+ response.body({});
235
+
236
+ expect(res.data).toEqual({});
237
+ });
238
+ });
239
+ describe("finish()", () => {
240
+ it("should finish context", async () => {
241
+ const {response, ctx} = createResponse();
242
+
243
+ expect(response.isDone()).toEqual(false);
244
+
245
+ await ctx.finish();
246
+
247
+ expect(response.isDone()).toEqual(true);
248
+ });
249
+ });
250
+ describe("getHeaders()", () => {
251
+ it("should get headers", () => {
252
+ const {res, response} = createResponse();
253
+
254
+ res.headers["content-type"] = "application/json";
255
+
256
+ expect(response.getHeaders()).toEqual({
257
+ "content-type": "application/json",
258
+ "x-request-id": "id"
259
+ });
260
+ });
261
+ });
262
+ describe("response()", () => {
263
+ it("should return the response framework", () => {
264
+ const {res, response} = createResponse();
265
+
266
+ expect(response.response).toEqual(res);
267
+ });
268
+ });
269
+ describe("getRes()", () => {
270
+ it("should return the response framework", () => {
271
+ const {res, response} = createResponse();
272
+
273
+ expect(response.getRes()).toEqual(res);
274
+ });
275
+ });
276
+ describe("res()", () => {
277
+ it("should return the response framework", () => {
278
+ const {res, response} = createResponse();
279
+
280
+ expect(response.res).toEqual(res);
281
+ });
282
+ });
283
+ describe("attachment()", () => {
284
+ it("should set attachment", () => {
285
+ const {res, response} = createResponse();
286
+
287
+ res.attachment = vi.fn();
288
+
289
+ response.attachment("filename");
290
+
291
+ expect(res.attachment).toHaveBeenCalledWith("filename");
292
+ });
293
+ });
294
+ describe("onEnd()", () => {
295
+ it("should listen onEnd event", () => {
296
+ const {res, response} = createResponse();
297
+ const cb = vi.fn();
298
+
299
+ res.on = vi.fn();
300
+
301
+ response.onEnd(cb);
302
+
303
+ expect(res.on).toHaveBeenCalledWith("finish", cb);
304
+ });
305
+ });
306
+ describe("cookie()", () => {
307
+ it("should manipulate cookies", () => {
308
+ const {res, response} = createResponse();
309
+
310
+ res.cookie = (...args: any[]) => {
311
+ let value = `${args[0]}=${args[1]}`;
312
+
313
+ if (!res.headers["set-cookie"]) {
314
+ res.headers["set-cookie"] = value;
315
+ } else {
316
+ res.headers["set-cookie"] = [].concat(res.headers["set-cookie"], value as any);
317
+ }
318
+ };
319
+
320
+ res.clearCookie = (name: string) => {
321
+ res.headers["set-cookie"] = res.headers["set-cookie"].filter((cookie: string) => cookie.startsWith(name + "="));
322
+ };
323
+
324
+ response.cookie("locale", "fr-FR");
325
+ expect(res.headers).toEqual({
326
+ "set-cookie": ["locale=fr-FR"],
327
+ "x-request-id": "id"
328
+ });
329
+
330
+ response.cookie("filename", "test");
331
+ expect(res.headers).toEqual({
332
+ "set-cookie": ["locale=fr-FR", "filename=test"],
333
+ "x-request-id": "id"
334
+ });
335
+
336
+ response.cookie("filename", null);
337
+
338
+ expect(res.headers).toEqual({
339
+ "set-cookie": ["filename=test"],
340
+ "x-request-id": "id"
341
+ });
342
+ });
343
+ });
344
+ });