@j3r3mcdev/oast-server 1.1.6 → 1.1.8

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 (97) hide show
  1. package/.github/workflows/ci.yml +29 -29
  2. package/.github/workflows/publish.yml +31 -31
  3. package/README.md +192 -192
  4. package/dist/core/router.d.ts +1 -0
  5. package/dist/core/router.js +3 -3
  6. package/dist/index.d.ts +1 -0
  7. package/dist/index.js +16 -1
  8. package/jest.config.js +14 -14
  9. package/package.json +45 -45
  10. package/sadmin list shadows +9 -9
  11. package/src/api/controllers/__tests__/tasks.controller.test.ts +74 -74
  12. package/src/api/controllers/events.controller.ts +10 -10
  13. package/src/api/controllers/health.controller.ts +7 -7
  14. package/src/api/controllers/tasks.controller.ts +41 -41
  15. package/src/api/dto/__tests__/create-task.dto.test.ts +41 -41
  16. package/src/api/dto/__tests__/filter-tasks.dto.test.ts +35 -35
  17. package/src/api/dto/create-task.dto.ts +33 -33
  18. package/src/api/dto/filter-tasks.dto.ts +33 -33
  19. package/src/api/services/__tests__/events.service.test.ts +41 -41
  20. package/src/api/services/__tests__/tasks.service.test.ts +41 -41
  21. package/src/api/services/events.service.ts +17 -17
  22. package/src/api/services/tasks.service.ts +79 -79
  23. package/src/api/sse/events.stream.ts +90 -90
  24. package/src/bootstrap.ts +89 -89
  25. package/src/core/__tests__/core-router.test.ts +30 -30
  26. package/src/core/__tests__/core-server.test.ts +44 -44
  27. package/src/core/__tests__/event.normalizer.test.ts +56 -56
  28. package/src/core/__tests__/event.router.test.ts +89 -89
  29. package/src/core/__tests__/logger.test.ts +32 -32
  30. package/src/core/__tests__/storage-manager.test.ts +74 -74
  31. package/src/core/event.normalizer.ts +147 -147
  32. package/src/core/event.router.ts +13 -13
  33. package/src/core/http/__tests__/adapter-node.test.ts +52 -52
  34. package/src/core/http/__tests__/body-parser-multipart.test.ts +41 -41
  35. package/src/core/http/__tests__/body-parser-raw.test.ts +28 -28
  36. package/src/core/http/__tests__/body-parser-text.test.ts +28 -28
  37. package/src/core/http/__tests__/compile-path.test.ts +39 -39
  38. package/src/core/http/__tests__/middleware-pipeline.test.ts +51 -51
  39. package/src/core/http/__tests__/request.test.ts +34 -34
  40. package/src/core/http/__tests__/response.test.ts +35 -35
  41. package/src/core/http/__tests__/router-match.test.ts +171 -171
  42. package/src/core/http/adapter-node.ts +51 -51
  43. package/src/core/http/buildRequest.ts +18 -18
  44. package/src/core/http/compile-path.ts +32 -32
  45. package/src/core/http/errors.ts +37 -37
  46. package/src/core/http/http-server.ts +52 -52
  47. package/src/core/http/middleware.ts +160 -160
  48. package/src/core/http/request.ts +55 -55
  49. package/src/core/http/response.ts +93 -93
  50. package/src/core/http/router.ts +138 -138
  51. package/src/core/id-generator.ts +8 -8
  52. package/src/core/logger.ts +113 -113
  53. package/src/core/router.ts +44 -44
  54. package/src/core/server.ts +85 -85
  55. package/src/core/storage.ts +64 -64
  56. package/src/index.ts +14 -14
  57. package/src/listeners/api/__tests__/api.controller.test.ts +116 -116
  58. package/src/listeners/api/__tests__/api.extractor.test.ts +46 -46
  59. package/src/listeners/api/__tests__/api.listener.test.ts +82 -82
  60. package/src/listeners/api/__tests__/api.routes.test.ts +155 -155
  61. package/src/listeners/api/__tests__/api.sse.test.ts +105 -105
  62. package/src/listeners/api/api.controllers.ts +67 -67
  63. package/src/listeners/api/api.extractor.ts +43 -43
  64. package/src/listeners/api/api.listener.ts +50 -50
  65. package/src/listeners/api/api.routes.ts +76 -76
  66. package/src/listeners/api/api.sse.ts +38 -38
  67. package/src/listeners/dns/__tests__/dns.test.ts +118 -118
  68. package/src/listeners/dns/dns.extractor.ts +14 -14
  69. package/src/listeners/dns/dns.listener.ts +61 -61
  70. package/src/listeners/http/__tests__/http.extractor.test.ts +59 -59
  71. package/src/listeners/http/__tests__/http.listener.test.ts +133 -133
  72. package/src/listeners/http/http.extractor.ts +15 -15
  73. package/src/listeners/http/http.listener.ts +110 -110
  74. package/src/listeners/listener.interface.ts +4 -4
  75. package/src/listeners/smtp/__tests__/smtp.extractor.test.ts +69 -69
  76. package/src/listeners/smtp/__tests__/smtp.listener.test.ts +150 -150
  77. package/src/listeners/smtp/smtp.extractor.ts +18 -18
  78. package/src/listeners/smtp/smtp.listener.ts +60 -60
  79. package/src/listeners/ssrf/__tests__/ssrf.extractor.test.ts +41 -41
  80. package/src/listeners/ssrf/__tests__/ssrf.listener.test.ts +87 -87
  81. package/src/listeners/ssrf/ssrf.extractor.ts +14 -14
  82. package/src/listeners/ssrf/ssrf.listener.ts +37 -37
  83. package/src/listeners/tcp/tcp.extractor.ts +16 -16
  84. package/src/listeners/tcp/tcp.listener.ts +61 -61
  85. package/src/listeners/webhook/__tests__/webhook.extractor.test.ts +35 -35
  86. package/src/listeners/webhook/__tests__/webhook.listener.test.ts +122 -122
  87. package/src/listeners/webhook/webhook.extractor.ts +12 -12
  88. package/src/listeners/webhook/webhook.listener.ts +58 -58
  89. package/src/listeners/websocket/__tests__/websocket.extractor.test.ts +33 -33
  90. package/src/listeners/websocket/__tests__/websocket.listener.test.ts +90 -90
  91. package/src/listeners/websocket/websocket.extractor.ts +11 -11
  92. package/src/listeners/websocket/websocket.listener.ts +40 -40
  93. package/src/storage-adapters/adapters/__tests__/memory.storage.test.ts +75 -75
  94. package/src/storage-adapters/adapters/memory.storage.ts +64 -64
  95. package/src/storage-adapters/storage.interface.ts +26 -26
  96. package/src/types/event.types.ts +147 -147
  97. package/tsconfig.json +20 -21
@@ -1,32 +1,32 @@
1
- import { Logger, LogEntry } from "../../core/logger";
2
- import { describe, it, expect, jest } from "@jest/globals";
3
-
4
- describe("Logger", () => {
5
- it("appelle les hooks", () => {
6
- const hook = jest.fn<(entry: LogEntry) => void>();
7
- const logger = new Logger({ hooks: [hook], enabled: true });
8
-
9
- logger.info("hello");
10
-
11
- expect(hook).toHaveBeenCalled();
12
- expect(hook.mock.calls[0][0].message).toBe("hello");
13
- });
14
-
15
- it("respecte le niveau de logs", () => {
16
- const hook = jest.fn<(entry: LogEntry) => void>();
17
- const logger = new Logger({ level: "warn", hooks: [hook] });
18
-
19
- logger.info("should not log");
20
- logger.error("should log");
21
-
22
- expect(hook).toHaveBeenCalledTimes(1);
23
- expect(hook.mock.calls[0][0].level).toBe("error");
24
- });
25
-
26
- it("crée un logger enfant avec contexte", () => {
27
- const logger = new Logger({ context: "root" });
28
- const child = logger.withContext("child");
29
-
30
- expect(child).not.toBe(logger);
31
- });
32
- });
1
+ import { Logger, LogEntry } from "../../core/logger";
2
+ import { describe, it, expect, jest } from "@jest/globals";
3
+
4
+ describe("Logger", () => {
5
+ it("appelle les hooks", () => {
6
+ const hook = jest.fn<(entry: LogEntry) => void>();
7
+ const logger = new Logger({ hooks: [hook], enabled: true });
8
+
9
+ logger.info("hello");
10
+
11
+ expect(hook).toHaveBeenCalled();
12
+ expect(hook.mock.calls[0][0].message).toBe("hello");
13
+ });
14
+
15
+ it("respecte le niveau de logs", () => {
16
+ const hook = jest.fn<(entry: LogEntry) => void>();
17
+ const logger = new Logger({ level: "warn", hooks: [hook] });
18
+
19
+ logger.info("should not log");
20
+ logger.error("should log");
21
+
22
+ expect(hook).toHaveBeenCalledTimes(1);
23
+ expect(hook.mock.calls[0][0].level).toBe("error");
24
+ });
25
+
26
+ it("crée un logger enfant avec contexte", () => {
27
+ const logger = new Logger({ context: "root" });
28
+ const child = logger.withContext("child");
29
+
30
+ expect(child).not.toBe(logger);
31
+ });
32
+ });
@@ -1,74 +1,74 @@
1
- import { describe, test, expect } from "@jest/globals";
2
- import { StorageManager } from "../storage"; // si ton fichier s'appelle storage-manager.ts
3
- import { NormalizedHttpEvent } from "../../types/event.types";
4
-
5
- function makeHttpEvent(id: string): NormalizedHttpEvent {
6
- return {
7
- id,
8
- type: "http",
9
- timestamp: Date.now(),
10
- sourceIp: "127.0.0.1",
11
- request: {
12
- method: "GET",
13
- path: "/",
14
- headers: {},
15
- query: {},
16
- body: "",
17
- },
18
- };
19
- }
20
-
21
- describe("StorageManager", () => {
22
- test("save + getEvent", async () => {
23
- const storage = new StorageManager();
24
-
25
- const event = makeHttpEvent("1");
26
- await storage.save(event);
27
-
28
- const found = await storage.getEvent("1");
29
- expect(found).not.toBeNull();
30
- expect(found?.id).toBe("1");
31
- });
32
-
33
- test("listEvents returns events", async () => {
34
- const storage = new StorageManager();
35
-
36
- await storage.save(makeHttpEvent("1"));
37
-
38
- const list = await storage.listEvents({});
39
- expect(list.length).toBe(1);
40
- });
41
-
42
- test("deleteEvent removes event", async () => {
43
- const storage = new StorageManager();
44
-
45
- await storage.save(makeHttpEvent("1"));
46
-
47
- let list = await storage.listEvents({});
48
- expect(list.length).toBe(1);
49
-
50
- await storage.deleteEvent("1");
51
-
52
- list = await storage.listEvents({});
53
- expect(list.length).toBe(0);
54
- });
55
-
56
- test("clearEvents empties storage", async () => {
57
- const storage = new StorageManager();
58
-
59
- await storage.save(makeHttpEvent("1"));
60
- await storage.clearEvents();
61
-
62
- const list = await storage.listEvents({});
63
- expect(list.length).toBe(0);
64
- });
65
-
66
- test("getStats returns correct structure", async () => {
67
- const storage = new StorageManager();
68
-
69
- const stats = await storage.getStats();
70
-
71
- expect(stats.total).toBe(0);
72
- expect(stats.byType).toEqual({});
73
- });
74
- });
1
+ import { describe, test, expect } from "@jest/globals";
2
+ import { StorageManager } from "../storage"; // si ton fichier s'appelle storage-manager.ts
3
+ import { NormalizedHttpEvent } from "../../types/event.types";
4
+
5
+ function makeHttpEvent(id: string): NormalizedHttpEvent {
6
+ return {
7
+ id,
8
+ type: "http",
9
+ timestamp: Date.now(),
10
+ sourceIp: "127.0.0.1",
11
+ request: {
12
+ method: "GET",
13
+ path: "/",
14
+ headers: {},
15
+ query: {},
16
+ body: "",
17
+ },
18
+ };
19
+ }
20
+
21
+ describe("StorageManager", () => {
22
+ test("save + getEvent", async () => {
23
+ const storage = new StorageManager();
24
+
25
+ const event = makeHttpEvent("1");
26
+ await storage.save(event);
27
+
28
+ const found = await storage.getEvent("1");
29
+ expect(found).not.toBeNull();
30
+ expect(found?.id).toBe("1");
31
+ });
32
+
33
+ test("listEvents returns events", async () => {
34
+ const storage = new StorageManager();
35
+
36
+ await storage.save(makeHttpEvent("1"));
37
+
38
+ const list = await storage.listEvents({});
39
+ expect(list.length).toBe(1);
40
+ });
41
+
42
+ test("deleteEvent removes event", async () => {
43
+ const storage = new StorageManager();
44
+
45
+ await storage.save(makeHttpEvent("1"));
46
+
47
+ let list = await storage.listEvents({});
48
+ expect(list.length).toBe(1);
49
+
50
+ await storage.deleteEvent("1");
51
+
52
+ list = await storage.listEvents({});
53
+ expect(list.length).toBe(0);
54
+ });
55
+
56
+ test("clearEvents empties storage", async () => {
57
+ const storage = new StorageManager();
58
+
59
+ await storage.save(makeHttpEvent("1"));
60
+ await storage.clearEvents();
61
+
62
+ const list = await storage.listEvents({});
63
+ expect(list.length).toBe(0);
64
+ });
65
+
66
+ test("getStats returns correct structure", async () => {
67
+ const storage = new StorageManager();
68
+
69
+ const stats = await storage.getStats();
70
+
71
+ expect(stats.total).toBe(0);
72
+ expect(stats.byType).toEqual({});
73
+ });
74
+ });
@@ -1,147 +1,147 @@
1
- import {
2
- RawEvent,
3
- RawDnsEvent,
4
- RawSmtpEvent,
5
- RawTcpEvent,
6
- RawSsrfEvent,
7
- NormalizedHttpEvent,
8
- NormalizedDnsEvent,
9
- NormalizedSmtpEvent,
10
- NormalizedTcpEvent,
11
- NormalizedSsrfEvent,
12
- NormalizedWebhookEvent,
13
- RawWebhookEvent,
14
- NormalizedWebSocketEvent,
15
- RawWebSocketEvent,
16
- } from "../types/event.types";
17
-
18
- import { IdGenerator } from "./id-generator";
19
-
20
- export class EventNormalizer {
21
- //
22
- // -------------------------
23
- // DNS
24
- // -------------------------
25
- //
26
- static normalizeDns(event: RawDnsEvent): NormalizedDnsEvent {
27
- return {
28
- id: IdGenerator.generate(),
29
- type: "dns",
30
- timestamp: Date.now(),
31
- ip: event.ip ?? "",
32
- query: event.query ?? "",
33
- recordType: event.recordType ?? "",
34
- raw: event.raw,
35
- };
36
- }
37
-
38
- //
39
- // -------------------------
40
- // HTTP
41
- // -------------------------
42
- //
43
- static normalizeHttp(event: RawEvent): NormalizedHttpEvent {
44
- const sourceIp = event.ip && event.ip.trim() !== "" ? event.ip : "unknown";
45
-
46
- return {
47
- id: IdGenerator.generate(),
48
- type: "http",
49
- timestamp: Date.now(),
50
- sourceIp,
51
- request: {
52
- method: event.method,
53
- path: event.path,
54
- headers: event.headers,
55
- query: event.query,
56
- body: event.body,
57
- },
58
- };
59
- }
60
-
61
- //
62
- // -------------------------
63
- // SMTP
64
- // -------------------------
65
- //
66
- static normalizeSmtp(event: RawSmtpEvent): NormalizedSmtpEvent {
67
- return {
68
- id: IdGenerator.generate(),
69
- type: "smtp",
70
- timestamp: Date.now(),
71
- ip: event.ip ?? "",
72
- from: event.from ?? "",
73
- to: event.to ?? [],
74
- subject: event.subject ?? "",
75
- body: event.body ?? "",
76
- raw: event.raw,
77
- };
78
- }
79
-
80
- //
81
- // -------------------------
82
- // TCP
83
- // -------------------------
84
- //
85
- static normalizeTcp(event: RawTcpEvent): NormalizedTcpEvent {
86
- return {
87
- id: IdGenerator.generate(),
88
- type: "tcp",
89
- timestamp: Date.now(),
90
- ip: event.ip ?? "",
91
- port: event.port ?? 0,
92
- data: event.data ?? "",
93
- raw: event.raw,
94
- };
95
- }
96
-
97
- //
98
- // -------------------------
99
- // SSRF
100
- // -------------------------
101
- //
102
- static normalizeSsrf(raw: RawSsrfEvent): NormalizedSsrfEvent {
103
- return {
104
- id: IdGenerator.generate(),
105
- type: "ssrf",
106
- timestamp: Date.now(),
107
- sourceIp: raw.ip,
108
- request: {
109
- method: raw.method,
110
- path: raw.path,
111
- headers: raw.headers,
112
- query: raw.query,
113
- },
114
- };
115
- }
116
-
117
- //
118
- // -------------------------
119
- // webhook
120
- // -------------------------
121
- //
122
- static normalizeWebhook(raw: RawWebhookEvent): NormalizedWebhookEvent {
123
- return {
124
- id: IdGenerator.generate(),
125
- type: "webhook",
126
- timestamp: Date.now(),
127
- sourceIp: raw.ip,
128
- headers: raw.headers,
129
- body: raw.body,
130
- };
131
- }
132
-
133
- //
134
- // -------------------------
135
- // websocket
136
- // -------------------------
137
- //
138
- static normalizeWebSocket(raw: RawWebSocketEvent): NormalizedWebSocketEvent {
139
- return {
140
- id: IdGenerator.generate(),
141
- type: "websocket",
142
- timestamp: Date.now(),
143
- sourceIp: raw.ip,
144
- message: raw.message,
145
- };
146
- }
147
- }
1
+ import {
2
+ RawEvent,
3
+ RawDnsEvent,
4
+ RawSmtpEvent,
5
+ RawTcpEvent,
6
+ RawSsrfEvent,
7
+ NormalizedHttpEvent,
8
+ NormalizedDnsEvent,
9
+ NormalizedSmtpEvent,
10
+ NormalizedTcpEvent,
11
+ NormalizedSsrfEvent,
12
+ NormalizedWebhookEvent,
13
+ RawWebhookEvent,
14
+ NormalizedWebSocketEvent,
15
+ RawWebSocketEvent,
16
+ } from "../types/event.types";
17
+
18
+ import { IdGenerator } from "./id-generator";
19
+
20
+ export class EventNormalizer {
21
+ //
22
+ // -------------------------
23
+ // DNS
24
+ // -------------------------
25
+ //
26
+ static normalizeDns(event: RawDnsEvent): NormalizedDnsEvent {
27
+ return {
28
+ id: IdGenerator.generate(),
29
+ type: "dns",
30
+ timestamp: Date.now(),
31
+ ip: event.ip ?? "",
32
+ query: event.query ?? "",
33
+ recordType: event.recordType ?? "",
34
+ raw: event.raw,
35
+ };
36
+ }
37
+
38
+ //
39
+ // -------------------------
40
+ // HTTP
41
+ // -------------------------
42
+ //
43
+ static normalizeHttp(event: RawEvent): NormalizedHttpEvent {
44
+ const sourceIp = event.ip && event.ip.trim() !== "" ? event.ip : "unknown";
45
+
46
+ return {
47
+ id: IdGenerator.generate(),
48
+ type: "http",
49
+ timestamp: Date.now(),
50
+ sourceIp,
51
+ request: {
52
+ method: event.method,
53
+ path: event.path,
54
+ headers: event.headers,
55
+ query: event.query,
56
+ body: event.body,
57
+ },
58
+ };
59
+ }
60
+
61
+ //
62
+ // -------------------------
63
+ // SMTP
64
+ // -------------------------
65
+ //
66
+ static normalizeSmtp(event: RawSmtpEvent): NormalizedSmtpEvent {
67
+ return {
68
+ id: IdGenerator.generate(),
69
+ type: "smtp",
70
+ timestamp: Date.now(),
71
+ ip: event.ip ?? "",
72
+ from: event.from ?? "",
73
+ to: event.to ?? [],
74
+ subject: event.subject ?? "",
75
+ body: event.body ?? "",
76
+ raw: event.raw,
77
+ };
78
+ }
79
+
80
+ //
81
+ // -------------------------
82
+ // TCP
83
+ // -------------------------
84
+ //
85
+ static normalizeTcp(event: RawTcpEvent): NormalizedTcpEvent {
86
+ return {
87
+ id: IdGenerator.generate(),
88
+ type: "tcp",
89
+ timestamp: Date.now(),
90
+ ip: event.ip ?? "",
91
+ port: event.port ?? 0,
92
+ data: event.data ?? "",
93
+ raw: event.raw,
94
+ };
95
+ }
96
+
97
+ //
98
+ // -------------------------
99
+ // SSRF
100
+ // -------------------------
101
+ //
102
+ static normalizeSsrf(raw: RawSsrfEvent): NormalizedSsrfEvent {
103
+ return {
104
+ id: IdGenerator.generate(),
105
+ type: "ssrf",
106
+ timestamp: Date.now(),
107
+ sourceIp: raw.ip,
108
+ request: {
109
+ method: raw.method,
110
+ path: raw.path,
111
+ headers: raw.headers,
112
+ query: raw.query,
113
+ },
114
+ };
115
+ }
116
+
117
+ //
118
+ // -------------------------
119
+ // webhook
120
+ // -------------------------
121
+ //
122
+ static normalizeWebhook(raw: RawWebhookEvent): NormalizedWebhookEvent {
123
+ return {
124
+ id: IdGenerator.generate(),
125
+ type: "webhook",
126
+ timestamp: Date.now(),
127
+ sourceIp: raw.ip,
128
+ headers: raw.headers,
129
+ body: raw.body,
130
+ };
131
+ }
132
+
133
+ //
134
+ // -------------------------
135
+ // websocket
136
+ // -------------------------
137
+ //
138
+ static normalizeWebSocket(raw: RawWebSocketEvent): NormalizedWebSocketEvent {
139
+ return {
140
+ id: IdGenerator.generate(),
141
+ type: "websocket",
142
+ timestamp: Date.now(),
143
+ sourceIp: raw.ip,
144
+ message: raw.message,
145
+ };
146
+ }
147
+ }
@@ -1,13 +1,13 @@
1
- import { EventNormalizer } from "./event.normalizer";
2
- import { Storage } from "../storage-adapters/storage.interface";
3
- import { RawEvent, NormalizedHttpEvent } from "../types/event.types";
4
-
5
- export class EventRouter {
6
- constructor(private storage: Storage) {}
7
-
8
- async handleHttp(event: RawEvent): Promise<NormalizedHttpEvent> {
9
- const normalized = EventNormalizer.normalizeHttp(event);
10
- await this.storage.save(normalized);
11
- return normalized;
12
- }
13
- }
1
+ import { EventNormalizer } from "./event.normalizer";
2
+ import { Storage } from "../storage-adapters/storage.interface";
3
+ import { RawEvent, NormalizedHttpEvent } from "../types/event.types";
4
+
5
+ export class EventRouter {
6
+ constructor(private storage: Storage) {}
7
+
8
+ async handleHttp(event: RawEvent): Promise<NormalizedHttpEvent> {
9
+ const normalized = EventNormalizer.normalizeHttp(event);
10
+ await this.storage.save(normalized);
11
+ return normalized;
12
+ }
13
+ }
@@ -1,52 +1,52 @@
1
- import { NodeAdapter } from "../adapter-node";
2
- import { MiddlewarePipeline } from "../middleware";
3
- import { Router } from "../router";
4
- import { Request } from "../request";
5
- import { Response } from "../response";
6
- import { describe, it, expect, jest } from "@jest/globals";
7
- import * as Build from "../buildRequest";
8
-
9
- describe("NodeAdapter.handle", () => {
10
- it("appelle le handler quand la route match", async () => {
11
- const router = new Router();
12
- const pipeline = new MiddlewarePipeline();
13
-
14
- // mock buildRequest
15
- const buildRequestMock = jest
16
- .spyOn(Build, "buildRequest")
17
- .mockImplementation(
18
- (raw: any, params?: Record<string, string>) =>
19
- new Request({
20
- method: "GET",
21
- path: "/test",
22
- headers: {},
23
- params: params ?? {},
24
- }),
25
- );
26
-
27
- const handler = jest.fn();
28
-
29
- router.match = jest.fn(() => ({
30
- handler,
31
- params: { id: "42" },
32
- middlewares: [],
33
- })) as any;
34
-
35
- pipeline.run = jest.fn(async () => {}) as any;
36
-
37
- const res = {
38
- writableEnded: false,
39
- setHeader: jest.fn(),
40
- end: jest.fn(),
41
- statusCode: 200,
42
- };
43
-
44
- const adapter = new NodeAdapter(router, pipeline);
45
-
46
- await adapter.handle({ url: "/test", method: "GET", headers: {} }, res);
47
-
48
- expect(handler).toHaveBeenCalled();
49
- expect(pipeline.run).toHaveBeenCalled();
50
- expect(buildRequestMock).toHaveBeenCalledTimes(2);
51
- });
52
- });
1
+ import { NodeAdapter } from "../adapter-node";
2
+ import { MiddlewarePipeline } from "../middleware";
3
+ import { Router } from "../router";
4
+ import { Request } from "../request";
5
+ import { Response } from "../response";
6
+ import { describe, it, expect, jest } from "@jest/globals";
7
+ import * as Build from "../buildRequest";
8
+
9
+ describe("NodeAdapter.handle", () => {
10
+ it("appelle le handler quand la route match", async () => {
11
+ const router = new Router();
12
+ const pipeline = new MiddlewarePipeline();
13
+
14
+ // mock buildRequest
15
+ const buildRequestMock = jest
16
+ .spyOn(Build, "buildRequest")
17
+ .mockImplementation(
18
+ (raw: any, params?: Record<string, string>) =>
19
+ new Request({
20
+ method: "GET",
21
+ path: "/test",
22
+ headers: {},
23
+ params: params ?? {},
24
+ }),
25
+ );
26
+
27
+ const handler = jest.fn();
28
+
29
+ router.match = jest.fn(() => ({
30
+ handler,
31
+ params: { id: "42" },
32
+ middlewares: [],
33
+ })) as any;
34
+
35
+ pipeline.run = jest.fn(async () => {}) as any;
36
+
37
+ const res = {
38
+ writableEnded: false,
39
+ setHeader: jest.fn(),
40
+ end: jest.fn(),
41
+ statusCode: 200,
42
+ };
43
+
44
+ const adapter = new NodeAdapter(router, pipeline);
45
+
46
+ await adapter.handle({ url: "/test", method: "GET", headers: {} }, res);
47
+
48
+ expect(handler).toHaveBeenCalled();
49
+ expect(pipeline.run).toHaveBeenCalled();
50
+ expect(buildRequestMock).toHaveBeenCalledTimes(2);
51
+ });
52
+ });