@creator.co/wapi 1.2.1-beta6 → 1.2.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.
Files changed (129) hide show
  1. package/.eslintrc.cjs +29 -22
  2. package/.github/workflows/npmpublish.yml +11 -19
  3. package/.github/workflows/prs.yml +13 -0
  4. package/index.ts +12 -10
  5. package/jest.config.ts +39 -0
  6. package/package.json +15 -4
  7. package/src/API/Request.ts +136 -44
  8. package/src/API/Response.ts +256 -46
  9. package/src/API/Utils.ts +60 -7
  10. package/src/BaseEvent/EventProcessor.ts +93 -28
  11. package/src/BaseEvent/Process.ts +69 -13
  12. package/src/BaseEvent/Transaction.ts +29 -50
  13. package/src/Config/Configuration.ts +119 -19
  14. package/src/Config/EnvironmentVar.ts +100 -21
  15. package/src/Crypto/Crypto.ts +78 -19
  16. package/src/Crypto/JWT.ts +53 -13
  17. package/src/Globals.ts +159 -27
  18. package/src/Logger/Logger.ts +204 -65
  19. package/src/Mailer/Mailer.ts +114 -31
  20. package/src/Publisher/Publisher.ts +57 -16
  21. package/src/Server/RouteResolver.ts +141 -0
  22. package/src/Server/Router.ts +84 -12
  23. package/src/Server/lib/ContainerServer.ts +53 -6
  24. package/src/Server/lib/Server.ts +82 -54
  25. package/src/Server/lib/container/GenericHandler.ts +15 -18
  26. package/src/Server/lib/container/GenericHandlerEvent.ts +78 -50
  27. package/src/Server/lib/container/HealthHandler.ts +2 -2
  28. package/src/Server/lib/container/Proxy.ts +114 -45
  29. package/src/Server/lib/container/Utils.ts +18 -27
  30. package/src/Validation/Validator.ts +23 -7
  31. package/tests/API/Request.test.ts +259 -0
  32. package/tests/API/Response.test.ts +367 -0
  33. package/tests/API/Utils.test.ts +157 -0
  34. package/tests/BaseEvent/EventProcessor.test.ts +262 -0
  35. package/tests/BaseEvent/Process.test.ts +49 -0
  36. package/tests/BaseEvent/Transaction.test.ts +222 -0
  37. package/tests/Config/Config.test.ts +193 -0
  38. package/tests/Config/EnvironmentVar.test.ts +214 -0
  39. package/tests/Crypto/Crypto.test.ts +88 -0
  40. package/tests/Crypto/JWT.test.ts +92 -0
  41. package/tests/Logger/Logger.test.ts +96 -0
  42. package/tests/Mailer/Mailer.test.ts +59 -0
  43. package/tests/Publisher/Publisher.test.ts +60 -0
  44. package/tests/Server/RouteResolver.test.ts +103 -0
  45. package/tests/Server/Router.test.ts +38 -0
  46. package/tests/Server/lib/ContainerServer.test.ts +327 -0
  47. package/tests/Server/lib/Server.test.ts +12 -0
  48. package/tests/Server/lib/container/GenericHandler.test.ts +131 -0
  49. package/tests/Server/lib/container/GenericHandlerEvent.test.ts +102 -0
  50. package/tests/Server/lib/container/HealthHandler.test.ts +30 -0
  51. package/tests/Server/lib/container/Proxy.test.ts +265 -0
  52. package/tests/Server/lib/container/Utils.test.ts +47 -0
  53. package/tests/Test.utils.ts +95 -0
  54. package/tests/Validation/Validator.test.ts +76 -0
  55. package/tests/main.test.ts +15 -0
  56. package/tsconfig.json +1 -0
  57. package/dist/index.d.ts +0 -11
  58. package/dist/index.js +0 -24
  59. package/dist/index.js.map +0 -1
  60. package/dist/package.json +0 -53
  61. package/dist/src/API/Request.d.ts +0 -21
  62. package/dist/src/API/Request.js +0 -86
  63. package/dist/src/API/Request.js.map +0 -1
  64. package/dist/src/API/Response.d.ts +0 -39
  65. package/dist/src/API/Response.js +0 -232
  66. package/dist/src/API/Response.js.map +0 -1
  67. package/dist/src/API/Utils.d.ts +0 -8
  68. package/dist/src/API/Utils.js +0 -49
  69. package/dist/src/API/Utils.js.map +0 -1
  70. package/dist/src/BaseEvent/EventProcessor.d.ts +0 -13
  71. package/dist/src/BaseEvent/EventProcessor.js +0 -151
  72. package/dist/src/BaseEvent/EventProcessor.js.map +0 -1
  73. package/dist/src/BaseEvent/Process.d.ts +0 -12
  74. package/dist/src/BaseEvent/Process.js +0 -114
  75. package/dist/src/BaseEvent/Process.js.map +0 -1
  76. package/dist/src/BaseEvent/Transaction.d.ts +0 -29
  77. package/dist/src/BaseEvent/Transaction.js +0 -248
  78. package/dist/src/BaseEvent/Transaction.js.map +0 -1
  79. package/dist/src/Config/Configuration.d.ts +0 -34
  80. package/dist/src/Config/Configuration.js +0 -93
  81. package/dist/src/Config/Configuration.js.map +0 -1
  82. package/dist/src/Config/EnvironmentVar.d.ts +0 -17
  83. package/dist/src/Config/EnvironmentVar.js +0 -152
  84. package/dist/src/Config/EnvironmentVar.js.map +0 -1
  85. package/dist/src/Crypto/Crypto.d.ts +0 -8
  86. package/dist/src/Crypto/Crypto.js +0 -84
  87. package/dist/src/Crypto/Crypto.js.map +0 -1
  88. package/dist/src/Crypto/JWT.d.ts +0 -16
  89. package/dist/src/Crypto/JWT.js +0 -49
  90. package/dist/src/Crypto/JWT.js.map +0 -1
  91. package/dist/src/Globals.d.ts +0 -21
  92. package/dist/src/Globals.js +0 -35
  93. package/dist/src/Globals.js.map +0 -1
  94. package/dist/src/Logger/Logger.d.ts +0 -34
  95. package/dist/src/Logger/Logger.js +0 -345
  96. package/dist/src/Logger/Logger.js.map +0 -1
  97. package/dist/src/Mailer/Mailer.d.ts +0 -12
  98. package/dist/src/Mailer/Mailer.js +0 -234
  99. package/dist/src/Mailer/Mailer.js.map +0 -1
  100. package/dist/src/Publisher/Publisher.d.ts +0 -10
  101. package/dist/src/Publisher/Publisher.js +0 -109
  102. package/dist/src/Publisher/Publisher.js.map +0 -1
  103. package/dist/src/Server/Router.d.ts +0 -27
  104. package/dist/src/Server/Router.js +0 -22
  105. package/dist/src/Server/Router.js.map +0 -1
  106. package/dist/src/Server/lib/ContainerServer.d.ts +0 -11
  107. package/dist/src/Server/lib/ContainerServer.js +0 -103
  108. package/dist/src/Server/lib/ContainerServer.js.map +0 -1
  109. package/dist/src/Server/lib/Server.d.ts +0 -9
  110. package/dist/src/Server/lib/Server.js +0 -141
  111. package/dist/src/Server/lib/Server.js.map +0 -1
  112. package/dist/src/Server/lib/container/GenericHandler.d.ts +0 -4
  113. package/dist/src/Server/lib/container/GenericHandler.js +0 -136
  114. package/dist/src/Server/lib/container/GenericHandler.js.map +0 -1
  115. package/dist/src/Server/lib/container/GenericHandlerEvent.d.ts +0 -14
  116. package/dist/src/Server/lib/container/GenericHandlerEvent.js +0 -164
  117. package/dist/src/Server/lib/container/GenericHandlerEvent.js.map +0 -1
  118. package/dist/src/Server/lib/container/HealthHandler.d.ts +0 -3
  119. package/dist/src/Server/lib/container/HealthHandler.js +0 -44
  120. package/dist/src/Server/lib/container/HealthHandler.js.map +0 -1
  121. package/dist/src/Server/lib/container/Proxy.d.ts +0 -15
  122. package/dist/src/Server/lib/container/Proxy.js +0 -157
  123. package/dist/src/Server/lib/container/Proxy.js.map +0 -1
  124. package/dist/src/Server/lib/container/Utils.d.ts +0 -6
  125. package/dist/src/Server/lib/container/Utils.js +0 -109
  126. package/dist/src/Server/lib/container/Utils.js.map +0 -1
  127. package/dist/src/Validation/Validator.d.ts +0 -5
  128. package/dist/src/Validation/Validator.js +0 -31
  129. package/dist/src/Validation/Validator.js.map +0 -1
@@ -0,0 +1,59 @@
1
+ import { SESClient, SendRawEmailCommand } from '@aws-sdk/client-ses'
2
+ import { mockClient } from 'aws-sdk-client-mock'
3
+ import { expect } from 'chai'
4
+
5
+ import Mailer from '../../src/Mailer/Mailer'
6
+
7
+ const SESMock = mockClient(SESClient)
8
+
9
+ describe('SendRaw', () => {
10
+ // reset mock
11
+ beforeEach(() => {
12
+ SESMock.reset()
13
+ })
14
+
15
+ const provider = new Mailer('dev+tests@creator.co', 'ca-central-1')
16
+
17
+ test('Send raw with success', async () => {
18
+ const messageId = 'id-123'
19
+ SESMock.on(SendRawEmailCommand).resolves({
20
+ MessageId: messageId,
21
+ })
22
+ const res = await provider.sendRawEmail('test@test.com', 'My message', 'My subject')
23
+ expect(res).is.not.null
24
+ console.log(res)
25
+ })
26
+
27
+ test('Send raw with success', async () => {
28
+ const messageId = 'id-123'
29
+ const from = 'test@test.com'
30
+ const to = 'test@test2.com'
31
+ const msg = 'My message'
32
+ const subject = 'My subject'
33
+ const cc = 'test@test3.com'
34
+ const replyTo = 'test@test4.com'
35
+ SESMock.on(SendRawEmailCommand).resolves({
36
+ MessageId: messageId,
37
+ })
38
+ const res = await provider.sendRawEmail(to, msg, subject, cc, from, replyTo)
39
+ expect(res).is.not.null
40
+ console.log(res)
41
+ })
42
+
43
+ test('Send raw with failure', async () => {
44
+ SESMock.on(SendRawEmailCommand).rejects(new Error('failed!'))
45
+ let res: any = null,
46
+ err: any = null
47
+ try {
48
+ res = await provider.sendRawEmail('test@test.com', 'My message', 'My subject')
49
+ } catch (e) {
50
+ err = e
51
+ }
52
+ expect(res).is.null
53
+ expect(err?.message).to.be.equals('failed!')
54
+ expect(res).is.null
55
+ console.log(res)
56
+ })
57
+ })
58
+
59
+ export {}
@@ -0,0 +1,60 @@
1
+ import { SNSClient, PublishCommand } from '@aws-sdk/client-sns'
2
+ import { mockClient } from 'aws-sdk-client-mock'
3
+ import { expect } from 'chai'
4
+
5
+ import Publisher from '../../src/Publisher/Publisher'
6
+
7
+ const SNSMock = mockClient(SNSClient)
8
+
9
+ describe('Encryption', () => {
10
+ // reset mock
11
+ beforeEach(() => {
12
+ SNSMock.reset()
13
+ })
14
+
15
+ const provider = new Publisher({
16
+ region: 'ca-central-1',
17
+ })
18
+
19
+ test('Publishes with success', async () => {
20
+ const msg = { text: '123' }
21
+ const topic = '123'
22
+ const messageId = 'id-123'
23
+ SNSMock.on(PublishCommand, {
24
+ Message: JSON.stringify(msg),
25
+ TopicArn: topic,
26
+ }).resolves({
27
+ MessageId: messageId,
28
+ })
29
+ const res = await provider.publishOnTopic(msg, topic)
30
+ expect(res).is.not.null
31
+ expect(res.MessageId).to.be.equals(messageId)
32
+ })
33
+
34
+ test('Publishes with success (additional props)', async () => {
35
+ const msg = { text: '123' }
36
+ const topic = '123'
37
+ const messageId = 'id-123'
38
+ SNSMock.on(PublishCommand, {
39
+ Message: JSON.stringify(msg),
40
+ TopicArn: topic,
41
+ }).resolves({
42
+ MessageId: messageId,
43
+ })
44
+ const res = await provider.publishOnTopic(msg, topic, {
45
+ FifoGroup: 123,
46
+ })
47
+ expect(res).is.not.null
48
+ expect(res.MessageId).to.be.equals(messageId)
49
+ })
50
+
51
+ test('Publish failure', async () => {
52
+ const msg = { text: '123' }
53
+ const topic = '123'
54
+ SNSMock.on(PublishCommand).rejects(new Error('failed!'))
55
+ const res = await provider.publishOnTopic(msg, topic)
56
+ expect(res).is.null
57
+ })
58
+ })
59
+
60
+ export {}
@@ -0,0 +1,103 @@
1
+ import { Route } from '../../src/Server/Router'
2
+ import RouteResolver from '../../src/Server/RouteResolver'
3
+
4
+ const mockRoute = (method: Method, path: string) =>
5
+ ({
6
+ method: method,
7
+ path: path,
8
+ }) as any as Route
9
+
10
+ type Method =
11
+ | Lowercase<'GET' | 'POST' | 'PUT' | 'DELETE'>
12
+ | Uppercase<'GET' | 'POST' | 'PUT' | 'DELETE'>
13
+
14
+ describe('RouteResolver', () => {
15
+ test('no routes configured', () => {
16
+ parameterizedTest({}, () => [
17
+ ['GET', '/', undefined],
18
+ ['GET', '', undefined],
19
+ ['GET', 'hjdah', undefined],
20
+ ])
21
+ })
22
+
23
+ test('one route, case insensitive', () => {
24
+ parameterizedTest(
25
+ {
26
+ route: mockRoute('get', '/'),
27
+ },
28
+ routes => [
29
+ ['GET', '/', routes.route],
30
+ ['get', '/', routes.route],
31
+ ['GET', '', routes.route],
32
+ ['GET', 'hjdah', undefined],
33
+ ['POST', '/', undefined],
34
+ ['DELETE', '/', undefined],
35
+ ]
36
+ )
37
+ })
38
+
39
+ test('basic matching', () => {
40
+ parameterizedTest(
41
+ {
42
+ getBase: mockRoute('GET', '/'),
43
+ getA: mockRoute('GET', '/a'),
44
+ getB: mockRoute('GET', '/b'),
45
+ postBase: mockRoute('POST', '/'),
46
+ postA: mockRoute('POST', '/a'),
47
+ variable: mockRoute('GET', '/:a'),
48
+ getAb: mockRoute('GET', '/a/b'),
49
+ },
50
+ routes => [
51
+ ['GET', '/', routes.getBase],
52
+ ['GET', '/a', routes.getA],
53
+ ['GET', '/b', routes.getB],
54
+ ['POST', '/', routes.postBase],
55
+ ['POST', '/a', routes.postA],
56
+ ['GET', '/c', routes.variable],
57
+ ['GET', '/a/b', routes.getAb],
58
+ ]
59
+ )
60
+ })
61
+
62
+ test('path variables', () => {
63
+ parameterizedTest(
64
+ {
65
+ path_vars: mockRoute('get', '/base/:a/:b/:c'),
66
+ abc: mockRoute('get', '/base/a/b/c'),
67
+ abcd: mockRoute('get', '/base/a/b/c/d'),
68
+ abc_path: mockRoute('get', '/base/a/b/c/:d'),
69
+ },
70
+ routes => [
71
+ ['GET', '/base/1/2/3', routes.path_vars],
72
+ ['GET', '/base/a/b/c', routes.abc],
73
+ ['GET', '/base/a/b/c/d', routes.abcd],
74
+ ['GET', '/base/a/b/c/u', routes.abc_path],
75
+ ['GET', '/base/a/b', undefined],
76
+ ['GET', '/base/a/b/c/d/e', undefined],
77
+ ['GET', '/base/a/b/c/d/e/f', undefined],
78
+ ]
79
+ )
80
+ })
81
+
82
+ test('fails to construct with duplicate routes', () => {
83
+ expect(
84
+ () =>
85
+ new RouteResolver({
86
+ routes: [mockRoute('GET', '/a/b/c/:d/:e/b'), mockRoute('GET', '/a/b/c/:jshj/:e/b')],
87
+ })
88
+ ).toThrowError('Duplicate route: GET: /a/b/c/:jshj/:e/b')
89
+ })
90
+ })
91
+
92
+ const parameterizedTest = <T extends { [k: string]: Route }>(
93
+ routes: T,
94
+ tests: (routes: T) => [Method, string, Route?][]
95
+ ) => {
96
+ const underTest = new RouteResolver({
97
+ routes: Object.values(routes),
98
+ })
99
+
100
+ tests(routes).forEach(([method, path, expected]) =>
101
+ expect(underTest.resolveRoute(method, path)).toBe(expected)
102
+ )
103
+ }
@@ -0,0 +1,38 @@
1
+ import { expect } from 'chai'
2
+
3
+ import ContainerServer from '../../src/Server/lib/ContainerServer'
4
+ import Server from '../../src/Server/lib/Server'
5
+ import Router from '../../src/Server/Router'
6
+
7
+ describe('Router basics', () => {
8
+ // @ts-ignore
9
+ let mockExit = jest.spyOn(process, 'exit').mockImplementation(() => {})
10
+ beforeAll(() => {
11
+ // @ts-ignore
12
+ mockExit = jest.spyOn(process, 'exit').mockImplementation(() => {})
13
+ })
14
+ afterAll(() => {
15
+ mockExit.mockRestore()
16
+ })
17
+ beforeEach(() => {
18
+ mockExit.mockReset()
19
+ })
20
+
21
+ test('Serverless server', async () => {
22
+ process.env['HYBRIDLESS_RUNTIME'] = undefined
23
+ const router = new Router({ routes: [] })
24
+ expect(router.getExport()).to.not.be.undefined
25
+ expect(router['server']).to.be.an.instanceof(Server)
26
+ expect(router['server']).to.not.be.an.instanceof(ContainerServer)
27
+ })
28
+ test('Container server', async () => {
29
+ process.env['HYBRIDLESS_RUNTIME'] = 'true'
30
+ const router = new Router({ routes: [] })
31
+ expect(router.getExport()).to.not.be.undefined
32
+ expect(router['server']).to.be.an.instanceof(Server)
33
+ expect(router['server']).to.be.an.instanceof(ContainerServer)
34
+ await router['server']['stop']()
35
+ })
36
+ })
37
+
38
+ export {}
@@ -0,0 +1,327 @@
1
+ import { expect as j_expect } from '@jest/globals'
2
+ import { expect } from 'chai'
3
+ import * as request from 'supertest'
4
+ import { z } from 'zod'
5
+
6
+ import Response from '../../../src/API/Response'
7
+ import Globals from '../../../src/Globals'
8
+ import ContainerServer from '../../../src/Server/lib/ContainerServer'
9
+ import { defaultUrl } from '../../Test.utils'
10
+
11
+ export const ViewSchema = z.object({
12
+ id: z.string(),
13
+ content: z.string(),
14
+ createdAt: z.string(),
15
+ updatedAt: z.string(),
16
+ })
17
+
18
+ describe('Container server routing', () => {
19
+ // @ts-ignore
20
+ let mockExit = jest.spyOn(process, 'exit').mockImplementation(() => {})
21
+ beforeAll(() => {
22
+ // @ts-ignore
23
+ mockExit = jest.spyOn(process, 'exit').mockImplementation(() => {})
24
+ })
25
+ afterAll(() => {
26
+ mockExit.mockRestore()
27
+ })
28
+ beforeEach(() => {
29
+ mockExit.mockReset()
30
+ })
31
+
32
+ test('Health & 404 handler', async () => {
33
+ const server = new ContainerServer({ routes: [] })
34
+ await server.start()
35
+ // Health check
36
+ const res = await request(defaultUrl)
37
+ .get(Globals.Listener_HTTP_DefaultHealthCheckRoute)
38
+ .expect('Content-Type', 'text/html; charset=utf-8')
39
+ .expect(200)
40
+ expect(res.text).to.be.equals('Healthy!')
41
+ // Not handled
42
+ await request(defaultUrl)
43
+ .get(`/abc`)
44
+ .expect('Content-Type', 'application/json; charset=utf-8')
45
+ .expect(404)
46
+
47
+ // Unload
48
+ await server.stop('Error')
49
+ j_expect(mockExit).toHaveBeenCalledTimes(1)
50
+ j_expect(mockExit).toBeCalledWith(1)
51
+ })
52
+
53
+ test('Simple route', async () => {
54
+ const server = new ContainerServer({
55
+ routes: [
56
+ {
57
+ path: '/abc',
58
+ method: 'get',
59
+ handler: async () => {
60
+ return Response.SimpleResponse({ name: 'abc' })
61
+ },
62
+ },
63
+ ],
64
+ })
65
+ await server.start()
66
+ // Health check
67
+ const res = await request(defaultUrl)
68
+ .get(Globals.Listener_HTTP_DefaultHealthCheckRoute)
69
+ .expect('Content-Type', 'text/html; charset=utf-8')
70
+ .expect(200)
71
+ expect(res.text).to.be.equals('Healthy!')
72
+ // Found route
73
+ const resG = await request(defaultUrl)
74
+ .get(`/abc`)
75
+ .expect('Content-Type', 'application/json; charset=utf-8')
76
+ .expect(200)
77
+ expect(resG.body['name']).to.be.deep.equals('abc')
78
+ expect(resG.body['transactionID']).to.not.be.null
79
+ // Found route, but not method
80
+ await request(defaultUrl)
81
+ .post(`/abc`)
82
+ .expect('Content-Type', 'application/json; charset=utf-8')
83
+ .expect(404)
84
+ // Not found route
85
+ await request(defaultUrl)
86
+ .get(`/abc/123`)
87
+ .expect('Content-Type', 'application/json; charset=utf-8')
88
+ .expect(404)
89
+ // Unload
90
+ await server.stop('Error')
91
+ j_expect(mockExit).toHaveBeenCalledTimes(1)
92
+ j_expect(mockExit).toBeCalledWith(1)
93
+ })
94
+ })
95
+
96
+ describe('Container server basics', () => {
97
+ // @ts-ignore
98
+ let mockExit = jest.spyOn(process, 'exit').mockImplementation(() => {})
99
+ beforeAll(() => {
100
+ // @ts-ignore
101
+ mockExit = jest.spyOn(process, 'exit').mockImplementation(() => {})
102
+ })
103
+ afterAll(() => {
104
+ mockExit.mockRestore()
105
+ })
106
+ beforeEach(() => {
107
+ mockExit.mockReset()
108
+ })
109
+
110
+ test('Starts with exports', async () => {
111
+ const server = new ContainerServer({ routes: [] })
112
+ server.getExport()
113
+ return new Promise(resolve => {
114
+ setTimeout(async () => {
115
+ // Health check
116
+ const res = await request(defaultUrl)
117
+ .get(Globals.Listener_HTTP_DefaultHealthCheckRoute)
118
+ .expect('Content-Type', 'text/html; charset=utf-8')
119
+ .expect(200)
120
+ expect(res.text).to.be.equals('Healthy!')
121
+ // Unload
122
+ await server.stop()
123
+ j_expect(mockExit).toHaveBeenCalledTimes(1)
124
+ j_expect(mockExit).toBeCalledWith(0)
125
+ resolve(null)
126
+ }, 2000)
127
+ })
128
+ })
129
+
130
+ test('Stops if process sends message SIGINT', async () => {
131
+ const server = new ContainerServer({ routes: [] })
132
+ await server.start()
133
+ process.emit('SIGINT')
134
+ return new Promise(resolve => {
135
+ setTimeout(async () => {
136
+ j_expect(mockExit).toHaveBeenCalledTimes(1)
137
+ j_expect(mockExit).toBeCalledWith(0)
138
+ resolve(null)
139
+ }, 2000)
140
+ })
141
+ }, 10000)
142
+
143
+ test('Stops if process sends message unhandledRejection', async () => {
144
+ const server = new ContainerServer({ routes: [] })
145
+ await server.start()
146
+ // @ts-ignore
147
+ process.emit('unhandledRejection')
148
+ return new Promise(resolve => {
149
+ setTimeout(async () => {
150
+ j_expect(mockExit).toHaveBeenCalledTimes(1)
151
+ j_expect(mockExit).toBeCalledWith(0)
152
+ resolve(null)
153
+ }, 2000)
154
+ })
155
+ }, 10000)
156
+ })
157
+
158
+ describe('Container server validation', () => {
159
+ // @ts-ignore
160
+ let mockExit = jest.spyOn(process, 'exit').mockImplementation(() => {})
161
+ beforeAll(() => {
162
+ // @ts-ignore
163
+ mockExit = jest.spyOn(process, 'exit').mockImplementation(() => {})
164
+ })
165
+ afterAll(() => {
166
+ mockExit.mockRestore()
167
+ })
168
+ beforeEach(() => {
169
+ mockExit.mockReset()
170
+ })
171
+
172
+ function validateValidationFailure(res: any, failureCount?: number) {
173
+ expect(res.body['err']).to.be.equals(Globals.ErrorResponseValidationFail)
174
+ expect(res.body['errCode']).to.be.equals(Globals.ErrorCode_InvalidInput)
175
+ expect(res.body['transactionID']).to.not.be.null
176
+ expect(res.body['transactionID']).to.be.an('string')
177
+ expect(res.body['validationFailure']?.length).to.be.equals(failureCount || 4)
178
+ }
179
+
180
+ test('Validates empty body', async () => {
181
+ const server = new ContainerServer({
182
+ routes: [
183
+ {
184
+ path: '/abc',
185
+ method: 'post',
186
+ inputSchema: ViewSchema,
187
+ handler: async () => {
188
+ return Response.SimpleResponse({ name: 'abc' })
189
+ },
190
+ },
191
+ ],
192
+ })
193
+ await server.start()
194
+ // Validation fails, empty body
195
+ const resG = await request(defaultUrl)
196
+ .post(`/abc`)
197
+ .expect('Content-Type', 'application/json; charset=utf-8')
198
+ .expect(400)
199
+ validateValidationFailure(resG)
200
+ await server.stop()
201
+ })
202
+
203
+ test('Validates empty string body', async () => {
204
+ const server = new ContainerServer({
205
+ routes: [
206
+ {
207
+ path: '/abc',
208
+ method: 'post',
209
+ inputSchema: ViewSchema,
210
+ handler: async () => {
211
+ return Response.SimpleResponse({ name: 'abc' })
212
+ },
213
+ },
214
+ ],
215
+ })
216
+ await server.start()
217
+ // Validation fails, empty body
218
+ const resG = await request(defaultUrl)
219
+ .post(`/abc`)
220
+ .send('')
221
+ .expect('Content-Type', 'application/json; charset=utf-8')
222
+ .expect(400)
223
+ validateValidationFailure(resG)
224
+ await server.stop()
225
+ })
226
+
227
+ test('Validates empty object body', async () => {
228
+ const server = new ContainerServer({
229
+ routes: [
230
+ {
231
+ path: '/abc',
232
+ method: 'post',
233
+ inputSchema: ViewSchema,
234
+ handler: async () => {
235
+ return Response.SimpleResponse({ name: 'abc' })
236
+ },
237
+ },
238
+ ],
239
+ })
240
+ await server.start()
241
+ // Validation fails, empty body
242
+ const resG = await request(defaultUrl)
243
+ .post(`/abc`)
244
+ .send({})
245
+ .expect('Content-Type', 'application/json; charset=utf-8')
246
+ .expect(400)
247
+ validateValidationFailure(resG)
248
+ await server.stop()
249
+ })
250
+
251
+ test('Validates missing props body', async () => {
252
+ const server = new ContainerServer({
253
+ routes: [
254
+ {
255
+ path: '/abc',
256
+ method: 'post',
257
+ inputSchema: ViewSchema,
258
+ handler: async () => {
259
+ return Response.SimpleResponse({ name: 'abc' })
260
+ },
261
+ },
262
+ ],
263
+ })
264
+ await server.start()
265
+ // Validation fails, empty body
266
+ const resG = await request(defaultUrl)
267
+ .post(`/abc`)
268
+ .send({ id: '123' })
269
+ .expect('Content-Type', 'application/json; charset=utf-8')
270
+ .expect(400)
271
+ validateValidationFailure(resG, 3)
272
+ await server.stop()
273
+ })
274
+
275
+ test('Validates wrong type props body', async () => {
276
+ const server = new ContainerServer({
277
+ routes: [
278
+ {
279
+ path: '/abc',
280
+ method: 'post',
281
+ inputSchema: ViewSchema,
282
+ handler: async () => {
283
+ return Response.SimpleResponse({ name: 'abc' })
284
+ },
285
+ },
286
+ ],
287
+ })
288
+ await server.start()
289
+ // Validation fails, empty body
290
+ const resG = await request(defaultUrl)
291
+ .post(`/abc`)
292
+ .send({ id: 123 })
293
+ .expect('Content-Type', 'application/json; charset=utf-8')
294
+ .expect(400)
295
+ validateValidationFailure(resG)
296
+ await server.stop()
297
+ })
298
+
299
+ test('Validates successfully', async () => {
300
+ const server = new ContainerServer({
301
+ routes: [
302
+ {
303
+ path: '/abc',
304
+ method: 'post',
305
+ inputSchema: ViewSchema,
306
+ handler: async () => {
307
+ return Response.SimpleResponse({ name: 'abc' })
308
+ },
309
+ },
310
+ ],
311
+ })
312
+ await server.start()
313
+ // Validation fails, empty body
314
+ await request(defaultUrl)
315
+ .post(`/abc`)
316
+ .send({
317
+ id: '123',
318
+ content: '123',
319
+ createdAt: new Date(),
320
+ updatedAt: new Date(),
321
+ })
322
+ .expect('Content-Type', 'application/json; charset=utf-8')
323
+ .expect(200)
324
+ await server.stop()
325
+ })
326
+ })
327
+ export {}
@@ -0,0 +1,12 @@
1
+ import { expect } from 'chai'
2
+
3
+ import Server from '../../../src/Server/lib/Server'
4
+
5
+ describe('Server basics', () => {
6
+ test('Works', async () => {
7
+ const server = new Server({ routes: [] })
8
+ expect(server.getExport()).to.not.be.undefined
9
+ })
10
+ })
11
+
12
+ export {}