@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,259 @@
1
+ import { APIGatewayEvent, Context } from 'aws-lambda'
2
+ import { expect } from 'chai'
3
+
4
+ import Request from '../../src/API/Request'
5
+ import Logger from '../../src/Logger/Logger'
6
+
7
+ function newReq(event: any, context?: any) {
8
+ const logger = new Logger(
9
+ {
10
+ logLevel: 'DEBUG',
11
+ },
12
+ '123-456'
13
+ )
14
+ return new Request(<APIGatewayEvent>(<unknown>event), <Context>context ? context : {}, logger)
15
+ }
16
+
17
+ describe('Request querystring', () => {
18
+ test('Null query string', () => {
19
+ const r = newReq({
20
+ queryStringParameters: null,
21
+ })
22
+ expect(r.containsQueryParam('123')).to.be.false
23
+ expect(r.getQueryParam('123')).to.be.null
24
+ })
25
+
26
+ test('Empty query string', () => {
27
+ const r = newReq({
28
+ queryStringParameters: {},
29
+ })
30
+ expect(r.containsQueryParam('123')).to.be.false
31
+ expect(r.getQueryParam('123')).to.be.null
32
+ })
33
+
34
+ test('Valid query string', () => {
35
+ const r = newReq({
36
+ queryStringParameters: { '123': 'abc' },
37
+ })
38
+ expect(r.containsQueryParam('123')).to.be.true
39
+ expect(r.getQueryParam('123')).to.be.equals('abc')
40
+ })
41
+
42
+ test('Valid query string number', () => {
43
+ const r = newReq({
44
+ queryStringParameters: { '123': 456 },
45
+ })
46
+ expect(r.containsQueryParam('123')).to.be.true
47
+ expect(r.getQueryParam('123')).to.be.equals(456)
48
+ })
49
+ })
50
+
51
+ describe('Request headers', () => {
52
+ test('Null headers', () => {
53
+ const r = newReq({ headers: null })
54
+ expect(r.getHeader('123')).to.be.null
55
+ })
56
+
57
+ test('Empty headers', () => {
58
+ const r = newReq({ headers: {} })
59
+ expect(r.getHeader('123')).to.be.null
60
+ })
61
+
62
+ test('Valid headers', () => {
63
+ const r = newReq({ headers: { '123': 'abc' } })
64
+ expect(r.getHeader('123')).to.be.equals('abc')
65
+ })
66
+
67
+ test('Auth headers', () => {
68
+ const r = newReq({ headers: { Authorization: 'abc' } })
69
+ expect(r.getAuthorizationHeader()).to.be.equals('abc')
70
+ })
71
+ })
72
+
73
+ describe('Request context', () => {
74
+ test('Null context', () => {
75
+ const r = newReq({ requestContext: null })
76
+ expect(r.getContextParam('123')).to.be.null
77
+ })
78
+
79
+ test('Empty context', () => {
80
+ const r = newReq({ requestContext: {} })
81
+ expect(r.getContextParam('123')).to.be.null
82
+ })
83
+
84
+ test('Valid context', () => {
85
+ const r = newReq({
86
+ requestContext: { '123': 'abc' },
87
+ })
88
+ expect(r.getContextParam('123')).to.be.equals('abc')
89
+ })
90
+ })
91
+
92
+ describe('Request path params', () => {
93
+ test('Null path params', () => {
94
+ const r = newReq({ pathParameters: null })
95
+ expect(r.containsPathParam('123')).to.be.false
96
+ expect(r.getPathParam('123')).to.be.null
97
+ expect(r.getPathParams()).to.be.null
98
+ })
99
+
100
+ test('Empty path params', () => {
101
+ const r = newReq({ pathParameters: {} })
102
+ expect(r.containsPathParam('123')).to.be.false
103
+ expect(r.getPathParam('123')).to.be.null
104
+ expect(r.getPathParams()).to.be.deep.equal({})
105
+ })
106
+
107
+ test('Valid path params', () => {
108
+ const v = { '123': 'abc' }
109
+ const r = newReq({
110
+ pathParameters: v,
111
+ })
112
+ expect(r.containsPathParam('123')).to.be.true
113
+ expect(r.getPathParam('123')).to.be.equals('abc')
114
+ expect(r.getPathParams()).to.be.deep.equal(v)
115
+ })
116
+
117
+ test('Valid path param number', () => {
118
+ const v = { '123': 456 }
119
+ const r = newReq({
120
+ pathParameters: v,
121
+ })
122
+ expect(r.containsPathParam('123')).to.be.true
123
+ expect(r.getPathParam('123')).to.be.equals(456)
124
+ expect(r.getPathParams()).to.be.deep.equal(v)
125
+ })
126
+
127
+ test('Fix path params', () => {
128
+ const v = { '123': 'abc' }
129
+ const r = newReq({ pathParameters: null })
130
+ r.setFixedPathParams(
131
+ Object.keys(v).map(k => ({ name: k })),
132
+ ['/'].concat(Object.values(v))
133
+ )
134
+ expect(r.containsPathParam('123')).to.be.true
135
+ expect(r.getPathParam('123')).to.be.equals('abc')
136
+ expect(r.getPathParams()).to.be.deep.equal(v)
137
+ })
138
+ })
139
+
140
+ describe('Request body', () => {
141
+ test('Null body', () => {
142
+ const r = newReq({ body: null })
143
+ expect(r.getBody()).to.be.null
144
+ })
145
+
146
+ test('Empty body', () => {
147
+ const r = newReq({ body: {} })
148
+ expect(r.getBody()).to.be.deep.equals({})
149
+ })
150
+
151
+ test('Empty string body', () => {
152
+ const r = newReq({ body: '{}' })
153
+ expect(r.getBody()).to.be.deep.equals({})
154
+ })
155
+
156
+ test('Broken json string body', () => {
157
+ const r = newReq({ body: '{name": "Joe"}' })
158
+ expect(r.getBody()).to.be.equals('{name": "Joe"}')
159
+ })
160
+
161
+ test('Valid string body', () => {
162
+ const r = newReq({ body: '{"name": "Joe"}' })
163
+ expect(r.getBody()).to.be.deep.equals({
164
+ name: 'Joe',
165
+ })
166
+ })
167
+
168
+ test('Valid json body', () => {
169
+ const r = newReq({ body: { name: 'Joe' } })
170
+ expect(r.getBody()).to.be.deep.equals({
171
+ name: 'Joe',
172
+ })
173
+ })
174
+ })
175
+
176
+ describe('Request path/method', () => {
177
+ test('Null path/method', () => {
178
+ const r = newReq({
179
+ path: null,
180
+ httpMethod: null,
181
+ })
182
+ expect(r.getPath()).to.be.null
183
+ expect(r.getMethod()).to.be.null
184
+ })
185
+
186
+ test('Empty path/method', () => {
187
+ const r = newReq({
188
+ path: '',
189
+ httpMethod: '',
190
+ })
191
+ expect(r.getPath()).to.be.a('string')
192
+ expect(r.getPath()).to.be.equals('')
193
+ expect(r.getMethod()).to.be.a('string')
194
+ expect(r.getMethod()).to.be.equals('')
195
+ })
196
+
197
+ test('Valid method/path', () => {
198
+ const r = newReq({
199
+ path: '/root',
200
+ httpMethod: 'GET',
201
+ })
202
+ expect(r.getPath()).to.be.a('string')
203
+ expect(r.getPath()).to.be.equals('/root')
204
+ expect(r.getMethod()).to.be.a('string')
205
+ expect(r.getMethod()).to.be.equals('GET')
206
+ })
207
+ })
208
+
209
+ describe('Request ID', () => {
210
+ test('From context', () => {
211
+ const r = newReq({}, { awsRequestId: '123' })
212
+ expect(r.getRequestID()).to.not.be.null
213
+ expect(r.getRequestID()).to.be.equals('123')
214
+ })
215
+
216
+ test('From event', () => {
217
+ const r = newReq({
218
+ requestContext: { requestId: '123' },
219
+ })
220
+ expect(r.getRequestID()).to.not.be.null
221
+ expect(r.getRequestID()).to.be.equals('123')
222
+ })
223
+
224
+ test('unknown', () => {
225
+ const r = newReq({})
226
+ expect(r.getRequestID()).to.not.be.null
227
+ expect(r.getRequestID()).to.be.equals('unknown')
228
+ })
229
+ })
230
+
231
+ describe('Request origin IP', () => {
232
+ test('From context', () => {
233
+ const r = newReq({
234
+ requestContext: {
235
+ identity: { sourceIp: '127.0.0.1' },
236
+ },
237
+ })
238
+ expect(r.getOriginIP()).to.not.be.null
239
+ expect(r.getOriginIP()).to.be.equals('127.0.0.1')
240
+ })
241
+
242
+ test('From header', () => {
243
+ const r = newReq({
244
+ headers: {
245
+ 'X-Forwarded-For': '127.0.0.1',
246
+ },
247
+ })
248
+ expect(r.getOriginIP()).to.not.be.null
249
+ expect(r.getOriginIP()).to.be.equals('127.0.0.1')
250
+ })
251
+
252
+ test('unknown', () => {
253
+ const r = newReq({})
254
+ expect(r.getOriginIP()).to.not.be.null
255
+ expect(r.getOriginIP()).to.be.equals('unknown')
256
+ })
257
+ })
258
+
259
+ export {}
@@ -0,0 +1,367 @@
1
+ import { expect as j_expect } from '@jest/globals'
2
+ import { APIGatewayEvent, Context } from 'aws-lambda'
3
+ import { expect } from 'chai'
4
+
5
+ import Response from '../../src/API/Response'
6
+ import Transaction from '../../src/BaseEvent/Transaction'
7
+ import Globals from '../../src/Globals'
8
+ import { observableTransaction, defaultHeaders } from '../Test.utils'
9
+
10
+ async function testResponse(r: Response<any>, body: any, optCode?: number, optHeaders?: any) {
11
+ const t = observableTransaction()
12
+ const context = t['context']
13
+ const buildR = await r.build(context, t, false)
14
+ expect(buildR).to.be.undefined
15
+ j_expect(t.responseProxy).toBeCalledTimes(1)
16
+ j_expect(context.fail).not.toBeCalled()
17
+ j_expect(context.done).not.toBeCalled()
18
+ j_expect(context.succeed).toHaveBeenCalledWith({
19
+ statusCode: optCode || 400,
20
+ headers: {
21
+ ...defaultHeaders,
22
+ ...(optHeaders || {}),
23
+ },
24
+ ...(body
25
+ ? {
26
+ body: JSON.stringify({
27
+ ...body,
28
+ transactionID: 'unknown',
29
+ }),
30
+ }
31
+ : {}),
32
+ })
33
+ }
34
+
35
+ describe('Response basics', () => {
36
+ test('Null body', () => {
37
+ const r = new Response<null>(200, null)
38
+ expect(r.getCode()).to.be.equals(200)
39
+ expect(r.getBody()).to.be.null
40
+ })
41
+
42
+ test('String body', () => {
43
+ const r = new Response<string>(200, 'abc')
44
+ expect(r.getCode()).to.be.equals(200)
45
+ expect(r.getBody()).to.be.equals('abc')
46
+ })
47
+
48
+ test('Generic body', () => {
49
+ const r = new Response<any>(200, { name: 'abc' })
50
+ r.appendIntoBody('name2', '123')
51
+ expect(r.getCode()).to.be.equals(200)
52
+ expect(r.getBody().name).to.be.equals('abc')
53
+ expect(r.getBody().name2).to.be.equals('123')
54
+ })
55
+
56
+ test('Append/validate header', () => {
57
+ const r = new Response<any>(200, {})
58
+ r.appendHeader('name2', '123')
59
+ expect(r['_headers']['name2']).to.be.equals('123')
60
+ })
61
+ })
62
+
63
+ describe('Response build', () => {
64
+ test('Succeeds to transaction context', async () => {
65
+ const b = { name: 'abc' }
66
+ const r = new Response<any>(200, b)
67
+ r.appendHeader('abc', '123')
68
+ // do not use default, so we dont use proxy response for once
69
+ const t = new Transaction(
70
+ <APIGatewayEvent>(<unknown>{}),
71
+ <Context>(<unknown>{
72
+ done: jest.fn(),
73
+ fail: jest.fn(),
74
+ succeed: jest.fn(),
75
+ })
76
+ )
77
+ const context = t['context']
78
+ const buildR = await r.build(context, t, false)
79
+ expect(buildR).to.be.undefined
80
+ j_expect(context.fail).not.toBeCalled()
81
+ j_expect(context.done).not.toBeCalled()
82
+ j_expect(context.succeed).toHaveBeenCalledWith({
83
+ statusCode: 200,
84
+ headers: {
85
+ ...defaultHeaders,
86
+ abc: '123',
87
+ },
88
+ body: JSON.stringify({
89
+ ...b,
90
+ transactionID: 'unknown',
91
+ }),
92
+ })
93
+ })
94
+
95
+ test('Succeeds with no context call', async () => {
96
+ const b = { name: 'abc' }
97
+ const r = new Response<any>(200, b)
98
+ const t = observableTransaction()
99
+ const context = t['context']
100
+ const buildR = await r.build(context, t, true)
101
+ expect(buildR).to.be.undefined
102
+ j_expect(context.fail).not.toBeCalled()
103
+ j_expect(context.done).not.toBeCalled()
104
+ j_expect(context.succeed).not.toBeCalled()
105
+ })
106
+
107
+ test('Succeeds to transaction context as RAW', async () => {
108
+ const b = { name: 'abc' }
109
+ const r = new Response<any>(200, b, {
110
+ rawBody: true,
111
+ })
112
+ const t = observableTransaction()
113
+ const context = t['context']
114
+ const buildR = await r.build(context, t, false)
115
+ expect(buildR).to.be.undefined
116
+ j_expect(context.fail).not.toBeCalled()
117
+ j_expect(context.done).not.toBeCalled()
118
+ j_expect(context.succeed).toHaveBeenCalledWith({
119
+ ...b,
120
+ transactionID: 'unknown',
121
+ })
122
+ })
123
+
124
+ test('Succeeds to transaction piping', async () => {
125
+ const b = { name: 'abc' }
126
+ const r = new Response<any>(200, b, {
127
+ shouldStream: true,
128
+ })
129
+ const t = observableTransaction()
130
+ const context = t['context']
131
+ const buildR = await r.build(context, t, false)
132
+ await r.build(context, t, false) //pipe twice, should not affect
133
+ expect(buildR).to.be.undefined
134
+ j_expect(context.fail).not.toBeCalled()
135
+ j_expect(context.done).not.toBeCalled()
136
+ j_expect(context.succeed).toHaveBeenCalledTimes(1)
137
+ j_expect(context.succeed).toHaveBeenCalledWith({
138
+ statusCode: 200,
139
+ headers: {
140
+ ...defaultHeaders,
141
+ },
142
+ body: {
143
+ ...b,
144
+ },
145
+ })
146
+ })
147
+
148
+ test('Failure to transaction context as RAW', async () => {
149
+ const b = { name: 'abc' }
150
+ const r = new Response<any>(400, b, {
151
+ rawBody: true,
152
+ })
153
+ const t = observableTransaction()
154
+ const context = t['context']
155
+ const buildR = await r.build(context, t, false)
156
+ expect(buildR).to.be.undefined
157
+ j_expect(context.done).not.toBeCalled()
158
+ j_expect(context.succeed).not.toBeCalled()
159
+ j_expect(context.fail).toHaveBeenCalledTimes(1)
160
+ })
161
+
162
+ test('Failure exception to transaction context as RAW', async () => {
163
+ const b = { name: 'abc' }
164
+ const r = new Response<any>(400, b, {
165
+ rawBody: true,
166
+ throwOnErrors: true,
167
+ })
168
+ const t = observableTransaction()
169
+ const context = t['context']
170
+ let buildR: any = null,
171
+ exception = null
172
+ try {
173
+ buildR = await r.build(context, t, false)
174
+ } catch (e) {
175
+ exception = e
176
+ }
177
+ expect(buildR).to.be.null
178
+ expect(exception).to.not.be.null
179
+ j_expect(context.done).not.toBeCalled()
180
+ j_expect(context.succeed).not.toBeCalled()
181
+ j_expect(context.fail).not.toBeCalled()
182
+ })
183
+
184
+ test('Failure exception to transaction context as RAW and null body', async () => {
185
+ const b = null
186
+ const r = new Response<any>(400, b, {
187
+ rawBody: true,
188
+ throwOnErrors: true,
189
+ })
190
+ const t = observableTransaction()
191
+ const context = t['context']
192
+ let buildR: any = null,
193
+ exception = null
194
+ try {
195
+ buildR = await r.build(context, t, false)
196
+ } catch (e) {
197
+ exception = e
198
+ }
199
+ expect(buildR).to.be.null
200
+ expect(exception).to.not.be.null
201
+ j_expect(context.done).not.toBeCalled()
202
+ j_expect(context.succeed).not.toBeCalled()
203
+ j_expect(context.fail).not.toBeCalled()
204
+ })
205
+
206
+ test('Failure exception to transaction context as RAW and custom ero', async () => {
207
+ const b = { message: 'abc', error: 'error 123' }
208
+ const r = new Response<any>(400, b, {
209
+ rawBody: true,
210
+ throwOnErrors: true,
211
+ })
212
+ const t = observableTransaction()
213
+ const context = t['context']
214
+ let buildR: any = null,
215
+ exception = null
216
+ try {
217
+ buildR = await r.build(context, t, false)
218
+ } catch (e) {
219
+ exception = e
220
+ }
221
+ expect(buildR).to.be.null
222
+ expect(exception).to.not.be.null
223
+ j_expect(context.done).not.toBeCalled()
224
+ j_expect(context.succeed).not.toBeCalled()
225
+ j_expect(context.fail).not.toBeCalled()
226
+ })
227
+ })
228
+
229
+ describe('Response shortcuts', () => {
230
+ test('MissingParamResponse', async () => {
231
+ const pName = 'abc'
232
+ const r = Response.MissingParamResponse(pName)
233
+ await testResponse(r, {
234
+ err: `Invalid request. Path parameter ${pName} is missing.`,
235
+ errCode: Globals.ErrorCode_MissingParam,
236
+ })
237
+ })
238
+
239
+ test('MissingQueryResponse', async () => {
240
+ const pName = 'abc'
241
+ const r = Response.MissingQueryResponse(pName)
242
+ await testResponse(r, {
243
+ err: `Invalid request. Query parameter ${pName} is missing.`,
244
+ errCode: Globals.ErrorCode_MissingParam,
245
+ })
246
+ })
247
+
248
+ test('BadRequestResponse', async () => {
249
+ const message = 'abc'
250
+ const code = 'CODE'
251
+ const optBody = { additional: 123 }
252
+ const r = Response.BadRequestResponse(message, code, optBody)
253
+ await testResponse(r, {
254
+ err: message,
255
+ errCode: code,
256
+ ...optBody,
257
+ })
258
+ })
259
+
260
+ test('BadRequestResponse no opts', async () => {
261
+ const message = 'abc'
262
+ const r = Response.BadRequestResponse(message)
263
+ await testResponse(r, {
264
+ err: message,
265
+ })
266
+ })
267
+
268
+ test('BadRequestResponseWithRollback', async () => {
269
+ const message = 'abc'
270
+ const code = 'CODE'
271
+ const optBody = { additional: 123 }
272
+ const r = Response.BadRequestResponseWithRollback(message, code, optBody)
273
+ await testResponse(r, {
274
+ err: message,
275
+ rollback: true,
276
+ errCode: code,
277
+ ...optBody,
278
+ })
279
+ })
280
+
281
+ test('BadRequestResponseWithRollback no opts', async () => {
282
+ const message = 'abc'
283
+ const r = Response.BadRequestResponseWithRollback(message)
284
+ await testResponse(r, {
285
+ err: message,
286
+ rollback: true,
287
+ })
288
+ })
289
+
290
+ test('UnauthorizedResponse', async () => {
291
+ const message = 'abc'
292
+ const code = 'CODE'
293
+ const r = Response.UnauthorizedResponse(message, code)
294
+ await testResponse(
295
+ r,
296
+ {
297
+ err: message,
298
+ errCode: code,
299
+ },
300
+ 401
301
+ )
302
+ })
303
+
304
+ test('UnauthorizedResponse no code', async () => {
305
+ const message = 'abc'
306
+ const r = Response.UnauthorizedResponse(message)
307
+ await testResponse(r, { err: message }, 401)
308
+ })
309
+
310
+ test('SuccessResponse', async () => {
311
+ const body = { additional: 123 }
312
+ const r = Response.SuccessResponse(body)
313
+ await testResponse(r, body, 200)
314
+ })
315
+
316
+ test('SuccessResponse null body', async () => {
317
+ const r = Response.SuccessResponse(null)
318
+ await testResponse(r, {}, 200)
319
+ })
320
+
321
+ test('SuccessNoContentResponse', async () => {
322
+ const r = Response.SuccessNoContentResponse()
323
+ await testResponse(r, null, 204)
324
+ })
325
+
326
+ test('SimpleResponse', async () => {
327
+ const r = Response.SimpleResponse(null)
328
+ await testResponse(r, null, 200)
329
+ })
330
+
331
+ test('SimpleResponse override statuscode', async () => {
332
+ const r = Response.SimpleResponse(null, 203)
333
+ await testResponse(r, null, 203)
334
+ })
335
+
336
+ test('RedirectResponse', async () => {
337
+ const url = 'https://google.com'
338
+ const r = Response.RedirectResponse(url)
339
+ await testResponse(r, null, 302, { Location: url })
340
+ })
341
+
342
+ test('SuccessStreamResponse', async () => {
343
+ const b = { name: 'abc' }
344
+ const r = Response.SuccessStreamResponse(b, 'test-stream')
345
+ const t = observableTransaction()
346
+ const context = t['context']
347
+ const buildR = await r.build(context, t, false)
348
+ await r.build(context, t, false) //pipe twice, should not affect
349
+ expect(buildR).to.be.undefined
350
+ j_expect(context.fail).not.toBeCalled()
351
+ j_expect(context.done).not.toBeCalled()
352
+ j_expect(context.succeed).toHaveBeenCalledTimes(1)
353
+ j_expect(context.succeed).toHaveBeenCalledWith({
354
+ statusCode: 200,
355
+ headers: {
356
+ ...defaultHeaders,
357
+ 'Content-Type': 'test-stream',
358
+ Connection: 'keep-alive',
359
+ },
360
+ body: {
361
+ ...b,
362
+ },
363
+ })
364
+ })
365
+ })
366
+
367
+ export {}