@creator.co/wapi 1.7.1-alpha4 → 1.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintignore +3 -0
- package/.eslintrc.cjs +60 -0
- package/.github/workflows/npmpublish.yml +11 -0
- package/.github/workflows/prs.yml +13 -0
- package/dist/package-lock.json +2 -2
- package/dist/package.json +1 -1
- package/jest.config.ts +33 -0
- package/jest.smoke.config.ts +35 -0
- package/package.json +1 -1
- package/tests/API/Request.test.ts +273 -0
- package/tests/API/Response.test.ts +367 -0
- package/tests/API/Utils.test.ts +167 -0
- package/tests/BaseEvent/EventProcessor.test.ts +261 -0
- package/tests/BaseEvent/Process.test.ts +49 -0
- package/tests/BaseEvent/Transaction.test.ts +408 -0
- package/tests/Cache/Redis-client.test.ts +90 -0
- package/tests/Cache/Redis-cluster.test.ts +100 -0
- package/tests/Config/Config.test.ts +205 -0
- package/tests/Config/EnvironmentVar.test.ts +250 -0
- package/tests/Crypto/Crypto.test.ts +88 -0
- package/tests/Crypto/JWT.test.ts +92 -0
- package/tests/Database/DatabaseManager.test.ts +71 -0
- package/tests/Database/integrations/knex/KnexDatabase.test.ts +76 -0
- package/tests/Database/integrations/knex/KnexTransaction.test.ts +149 -0
- package/tests/Database/integrations/kysely/KyselyDatabase.test.ts +113 -0
- package/tests/Database/integrations/kysely/KyselyTransaction.test.ts +119 -0
- package/tests/Database/integrations/pg/PostgresDatabase.test.ts +76 -0
- package/tests/Database/integrations/pg/PostgresTransaction.test.ts +118 -0
- package/tests/Logger/Logger.test.ts +219 -0
- package/tests/Mailer/Mailer.test.ts +59 -0
- package/tests/Publisher/Publisher.test.ts +94 -0
- package/tests/Server/RouteResolver.test.ts +102 -0
- package/tests/Server/Router.test.ts +39 -0
- package/tests/Server/lib/ContainerServer.test.ts +531 -0
- package/tests/Server/lib/Server.test.ts +12 -0
- package/tests/Server/lib/container/GenericHandler.test.ts +131 -0
- package/tests/Server/lib/container/GenericHandlerEvent.test.ts +103 -0
- package/tests/Server/lib/container/HealthHandler.test.ts +30 -0
- package/tests/Server/lib/container/Proxy.test.ts +268 -0
- package/tests/Server/lib/container/Utils.test.ts +47 -0
- package/tests/Test.utils.ts +74 -0
- package/tests/Validation/Validator.test.ts +76 -0
- package/tsconfig.json +26 -0
- package/tsconfig.smoke.json +26 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { jest } from '@jest/globals'
|
|
2
|
+
|
|
3
|
+
import Redis from '../../src/Cache/Redis'
|
|
4
|
+
|
|
5
|
+
let _connectionId = 1
|
|
6
|
+
|
|
7
|
+
async function simpleRedisTest(config: any, concurrent?: boolean) {
|
|
8
|
+
const RedisMock = jest.fn(() => {
|
|
9
|
+
let opened = false
|
|
10
|
+
const connectionId = _connectionId++
|
|
11
|
+
return {
|
|
12
|
+
connectionId,
|
|
13
|
+
isOpen: () => opened,
|
|
14
|
+
close: () => (opened = false),
|
|
15
|
+
connect: jest.fn(() => {
|
|
16
|
+
opened = true
|
|
17
|
+
return {
|
|
18
|
+
mget: jest.fn(() => {
|
|
19
|
+
return true
|
|
20
|
+
}),
|
|
21
|
+
}
|
|
22
|
+
}),
|
|
23
|
+
} as any
|
|
24
|
+
})
|
|
25
|
+
Redis['ClientFactory'] = RedisMock
|
|
26
|
+
// Double call is intentional
|
|
27
|
+
const [provider, provider2] = concurrent
|
|
28
|
+
? await Promise.all([Redis.connection(config), Redis.connection(config)])
|
|
29
|
+
: [await Redis.connection(config), await Redis.connection(config)]
|
|
30
|
+
|
|
31
|
+
// client checks
|
|
32
|
+
expect(RedisMock).toHaveBeenNthCalledWith(1, {
|
|
33
|
+
username: config.username,
|
|
34
|
+
...(config.password ? { password: config.password } : {}),
|
|
35
|
+
disableOfflineQueue: true,
|
|
36
|
+
socket: {
|
|
37
|
+
host: config.hostname,
|
|
38
|
+
tls: config.enableTLS,
|
|
39
|
+
connectTimeout: 10000,
|
|
40
|
+
},
|
|
41
|
+
})
|
|
42
|
+
// Does not have double connection
|
|
43
|
+
expect(provider['connectionId']).toEqual(provider2['connectionId'])
|
|
44
|
+
expect(provider.connect).toHaveBeenCalledTimes(1)
|
|
45
|
+
expect(provider2.connect).toHaveBeenCalledTimes(1)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
describe('Redis (client)', () => {
|
|
49
|
+
beforeEach(async () => {
|
|
50
|
+
// hack to close singleton connection
|
|
51
|
+
if (Redis['singleton'].getValue()) Redis['singleton'].clear()
|
|
52
|
+
})
|
|
53
|
+
test('Simple redis - do not connect twice', async () => {
|
|
54
|
+
await simpleRedisTest({
|
|
55
|
+
hostname: 'redis://localhost',
|
|
56
|
+
username: 'gabe',
|
|
57
|
+
password: 'mypassword',
|
|
58
|
+
enableTLS: true,
|
|
59
|
+
type: 'redis',
|
|
60
|
+
})
|
|
61
|
+
})
|
|
62
|
+
test('Simple redis (no SSL) - do not connect twice', async () => {
|
|
63
|
+
await simpleRedisTest({
|
|
64
|
+
hostname: 'redis://localhost',
|
|
65
|
+
username: 'gabe',
|
|
66
|
+
password: 'mypassword',
|
|
67
|
+
enableTLS: false,
|
|
68
|
+
type: 'redis',
|
|
69
|
+
})
|
|
70
|
+
})
|
|
71
|
+
test('Simple redis (passwordless) - do not connect twice', async () => {
|
|
72
|
+
await simpleRedisTest({
|
|
73
|
+
hostname: 'redis://localhost',
|
|
74
|
+
username: 'gabe',
|
|
75
|
+
enableTLS: false,
|
|
76
|
+
type: 'redis',
|
|
77
|
+
})
|
|
78
|
+
})
|
|
79
|
+
test('Concurrent redis - do not connect twice', async () => {
|
|
80
|
+
await simpleRedisTest(
|
|
81
|
+
{
|
|
82
|
+
hostname: 'redis://localhost',
|
|
83
|
+
username: 'gabe',
|
|
84
|
+
enableTLS: false,
|
|
85
|
+
type: 'redis',
|
|
86
|
+
},
|
|
87
|
+
true
|
|
88
|
+
)
|
|
89
|
+
})
|
|
90
|
+
})
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { jest } from '@jest/globals'
|
|
2
|
+
|
|
3
|
+
import Redis from '../../src/Cache/Redis'
|
|
4
|
+
|
|
5
|
+
let _connectionId = 1
|
|
6
|
+
|
|
7
|
+
async function simpleRedisTest(config: any, concurrent?: boolean) {
|
|
8
|
+
const RedisMock = jest.fn(() => {
|
|
9
|
+
let opened = false
|
|
10
|
+
const connectionId = _connectionId++
|
|
11
|
+
return {
|
|
12
|
+
connectionId,
|
|
13
|
+
isOpen: () => opened,
|
|
14
|
+
close: () => (opened = false),
|
|
15
|
+
connect: jest.fn(() => {
|
|
16
|
+
opened = true
|
|
17
|
+
return {
|
|
18
|
+
mget: jest.fn(() => {
|
|
19
|
+
return true
|
|
20
|
+
}),
|
|
21
|
+
}
|
|
22
|
+
}),
|
|
23
|
+
} as any
|
|
24
|
+
})
|
|
25
|
+
Redis['ClusterFactory'] = RedisMock
|
|
26
|
+
// Double call is intentional
|
|
27
|
+
const [provider, provider2] = concurrent
|
|
28
|
+
? await Promise.all([Redis.connection(config), Redis.connection(config)])
|
|
29
|
+
: [await Redis.connection(config), await Redis.connection(config)]
|
|
30
|
+
|
|
31
|
+
// client checks
|
|
32
|
+
expect(RedisMock).toHaveBeenNthCalledWith(1, {
|
|
33
|
+
defaults: {
|
|
34
|
+
username: config.username,
|
|
35
|
+
...(config.password ? { password: config.password } : {}),
|
|
36
|
+
socket: {
|
|
37
|
+
tls: config.enableTLS,
|
|
38
|
+
connectTimeout: 10000,
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
rootNodes: [
|
|
42
|
+
{
|
|
43
|
+
url: `redis://${config.username}:${config.username}@${config.hostname}:6379`,
|
|
44
|
+
disableOfflineQueue: true,
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
})
|
|
48
|
+
// Does not have double connection
|
|
49
|
+
expect(provider['connectionId']).toEqual(provider2['connectionId'])
|
|
50
|
+
expect(provider.connect).toHaveBeenCalledTimes(1)
|
|
51
|
+
expect(provider2.connect).toHaveBeenCalledTimes(1)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
describe('Redis (cluster)', () => {
|
|
55
|
+
beforeEach(async () => {
|
|
56
|
+
// hack to close singleton connection
|
|
57
|
+
if (Redis['singleton'].getValue()) Redis['singleton'].clear()
|
|
58
|
+
})
|
|
59
|
+
test('Simple redis - do not connect twice', async () => {
|
|
60
|
+
await simpleRedisTest({
|
|
61
|
+
hostname: 'redis://localhost',
|
|
62
|
+
username: 'gabe',
|
|
63
|
+
password: 'mypassword',
|
|
64
|
+
enableTLS: true,
|
|
65
|
+
clusterMode: true,
|
|
66
|
+
type: 'redis',
|
|
67
|
+
})
|
|
68
|
+
})
|
|
69
|
+
test('Simple redis (no SSL) - do not connect twice', async () => {
|
|
70
|
+
await simpleRedisTest({
|
|
71
|
+
hostname: 'redis://localhost',
|
|
72
|
+
username: 'gabe',
|
|
73
|
+
password: 'mypassword',
|
|
74
|
+
enableTLS: false,
|
|
75
|
+
clusterMode: true,
|
|
76
|
+
type: 'redis',
|
|
77
|
+
})
|
|
78
|
+
})
|
|
79
|
+
test('Simple redis (passwordless) - do not connect twice', async () => {
|
|
80
|
+
await simpleRedisTest({
|
|
81
|
+
hostname: 'redis://localhost',
|
|
82
|
+
username: 'gabe',
|
|
83
|
+
enableTLS: false,
|
|
84
|
+
clusterMode: true,
|
|
85
|
+
type: 'redis',
|
|
86
|
+
})
|
|
87
|
+
})
|
|
88
|
+
test('Concurrent redis - do not connect twice', async () => {
|
|
89
|
+
await simpleRedisTest(
|
|
90
|
+
{
|
|
91
|
+
hostname: 'redis://localhost',
|
|
92
|
+
username: 'gabe',
|
|
93
|
+
enableTLS: false,
|
|
94
|
+
clusterMode: true,
|
|
95
|
+
type: 'redis',
|
|
96
|
+
},
|
|
97
|
+
true
|
|
98
|
+
)
|
|
99
|
+
})
|
|
100
|
+
})
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { SSMClient, GetParameterCommand } from '@aws-sdk/client-ssm'
|
|
2
|
+
import { mockClient } from 'aws-sdk-client-mock'
|
|
3
|
+
import { expect as c_expect } from 'chai'
|
|
4
|
+
|
|
5
|
+
import Configuration from '../../src/Config/Configuration'
|
|
6
|
+
import { SampleConfig } from '../Test.utils'
|
|
7
|
+
|
|
8
|
+
const SSMMock = mockClient(SSMClient)
|
|
9
|
+
const config = new Configuration<typeof SampleConfig>(SampleConfig, 'my-prefix')
|
|
10
|
+
describe(`Optional remote environment`, () => {
|
|
11
|
+
// reset mock
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
SSMMock.reset()
|
|
14
|
+
config['resetCache']()
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
test('Does not accept sync get (+ compiler error)', async () => {
|
|
18
|
+
let err = null
|
|
19
|
+
try {
|
|
20
|
+
// @ts-expect-error
|
|
21
|
+
config.get('TOKEN_SECRET')
|
|
22
|
+
} catch (e) {
|
|
23
|
+
err = e
|
|
24
|
+
}
|
|
25
|
+
c_expect(err).is.not.null
|
|
26
|
+
c_expect(err?.['message']).is.not.null
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
test('Optional value with null value', async () => {
|
|
30
|
+
SSMMock.on(GetParameterCommand).resolves({
|
|
31
|
+
Parameter: {
|
|
32
|
+
Value: undefined,
|
|
33
|
+
},
|
|
34
|
+
})
|
|
35
|
+
const token = await config.asyncGet('TOKEN_SECRET_FALSY')
|
|
36
|
+
c_expect(token).is.undefined
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
test('Optional value with empty response', async () => {
|
|
40
|
+
SSMMock.on(GetParameterCommand).resolves({})
|
|
41
|
+
const token = await config.asyncGet('TOKEN_SECRET_FALSY')
|
|
42
|
+
c_expect(token).is.undefined
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
test('Optional value with valid response', async () => {
|
|
46
|
+
const value = 'abc'
|
|
47
|
+
SSMMock.on(GetParameterCommand).resolves({
|
|
48
|
+
Parameter: {
|
|
49
|
+
Value: value,
|
|
50
|
+
},
|
|
51
|
+
})
|
|
52
|
+
const token = await config.asyncGet('TOKEN_SECRET_FALSY')
|
|
53
|
+
c_expect(token).is.not.undefined
|
|
54
|
+
c_expect(token).to.be.equals(value)
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
test('Optional value rejection', async () => {
|
|
58
|
+
SSMMock.on(GetParameterCommand).rejects(new Error('failed!'))
|
|
59
|
+
const token = await config.asyncGet('TOKEN_SECRET_FALSY')
|
|
60
|
+
c_expect(token).is.undefined
|
|
61
|
+
})
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
describe(`Required remote environment`, () => {
|
|
65
|
+
// reset mock
|
|
66
|
+
beforeEach(() => {
|
|
67
|
+
SSMMock.reset()
|
|
68
|
+
config['resetCache']()
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
test('Does not accept sync get (+ compiler error)', async () => {
|
|
72
|
+
let err = null
|
|
73
|
+
try {
|
|
74
|
+
// @ts-expect-error
|
|
75
|
+
config.get('TOKEN_SECRET')
|
|
76
|
+
} catch (e) {
|
|
77
|
+
err = e
|
|
78
|
+
}
|
|
79
|
+
c_expect(err).is.not.null
|
|
80
|
+
c_expect(err?.['message']).is.not.null
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
test('Required value with null value', async () => {
|
|
84
|
+
SSMMock.on(GetParameterCommand).resolves({
|
|
85
|
+
Parameter: {
|
|
86
|
+
Value: undefined,
|
|
87
|
+
},
|
|
88
|
+
})
|
|
89
|
+
let err = null
|
|
90
|
+
try {
|
|
91
|
+
await config.asyncGet('TOKEN_SECRET')
|
|
92
|
+
} catch (e) {
|
|
93
|
+
err = e
|
|
94
|
+
}
|
|
95
|
+
c_expect(err).is.not.null
|
|
96
|
+
c_expect(err?.['message']).is.not.null
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
test('Required value with empty response', async () => {
|
|
100
|
+
SSMMock.on(GetParameterCommand).resolves({})
|
|
101
|
+
let err = null
|
|
102
|
+
try {
|
|
103
|
+
await config.asyncGet('TOKEN_SECRET')
|
|
104
|
+
} catch (e) {
|
|
105
|
+
err = e
|
|
106
|
+
}
|
|
107
|
+
c_expect(err).is.not.null
|
|
108
|
+
c_expect(err?.['message']).is.not.null
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
test('Required value with valid response', async () => {
|
|
112
|
+
const value = 'abc'
|
|
113
|
+
SSMMock.on(GetParameterCommand).resolves({
|
|
114
|
+
Parameter: {
|
|
115
|
+
Value: value,
|
|
116
|
+
},
|
|
117
|
+
})
|
|
118
|
+
const token = await config.asyncGet('TOKEN_SECRET')
|
|
119
|
+
c_expect(token).is.not.undefined
|
|
120
|
+
c_expect(token).to.be.equals(value)
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
test('Required value rejection', async () => {
|
|
124
|
+
SSMMock.on(GetParameterCommand).rejects(new Error('failed!'))
|
|
125
|
+
let err = null
|
|
126
|
+
try {
|
|
127
|
+
await config.asyncGet('TOKEN_SECRET')
|
|
128
|
+
} catch (e) {
|
|
129
|
+
err = e
|
|
130
|
+
}
|
|
131
|
+
c_expect(err).is.not.null
|
|
132
|
+
c_expect(err?.['message']).is.not.null
|
|
133
|
+
})
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
describe(`Optional local environment`, () => {
|
|
137
|
+
beforeEach(() => {
|
|
138
|
+
config['resetCache']()
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
test('Optional value with null value', async () => {
|
|
142
|
+
const token = config.get('PATH123')
|
|
143
|
+
c_expect(token).is.undefined
|
|
144
|
+
})
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
describe(`Required local environment`, () => {
|
|
148
|
+
beforeEach(() => {
|
|
149
|
+
config['resetCache']()
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
test('Test compiler error', async () => {
|
|
153
|
+
let err = null
|
|
154
|
+
try {
|
|
155
|
+
// @ts-expect-error
|
|
156
|
+
await config.asyncGet('PATH')
|
|
157
|
+
} catch (e) {
|
|
158
|
+
err = e
|
|
159
|
+
}
|
|
160
|
+
c_expect(err).is.not.null
|
|
161
|
+
c_expect(err?.['message']).is.not.null
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
test('Required value with null value', async () => {
|
|
165
|
+
let err = null
|
|
166
|
+
try {
|
|
167
|
+
config.get('PATH_FALSY')
|
|
168
|
+
} catch (e) {
|
|
169
|
+
err = e
|
|
170
|
+
}
|
|
171
|
+
c_expect(err).is.not.null
|
|
172
|
+
c_expect(err?.['message']).is.not.null
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
test('Required value with valid response', async () => {
|
|
176
|
+
const key = 'PATH'
|
|
177
|
+
const v = config.get(key)
|
|
178
|
+
c_expect(v).is.not.null
|
|
179
|
+
c_expect(v).to.be.equals(process.env[key])
|
|
180
|
+
})
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
describe(`Caching test`, () => {
|
|
184
|
+
test('Does cache previous fetched value', async () => {
|
|
185
|
+
const value = '123'
|
|
186
|
+
const key = 'TOKEN_SECRET'
|
|
187
|
+
// initial fetch
|
|
188
|
+
SSMMock.on(GetParameterCommand).resolves({
|
|
189
|
+
Parameter: {
|
|
190
|
+
Value: value,
|
|
191
|
+
},
|
|
192
|
+
})
|
|
193
|
+
const v = await config.asyncGet(key)
|
|
194
|
+
c_expect(v).is.not.null
|
|
195
|
+
c_expect(v).to.be.equals(value)
|
|
196
|
+
// subsequent fetch
|
|
197
|
+
SSMMock.reset()
|
|
198
|
+
SSMMock.on(GetParameterCommand).rejects(new Error('failed!'))
|
|
199
|
+
const v2 = await config.asyncGet(key)
|
|
200
|
+
c_expect(v2).is.not.null
|
|
201
|
+
c_expect(v2).to.be.equals(value)
|
|
202
|
+
})
|
|
203
|
+
})
|
|
204
|
+
|
|
205
|
+
export {}
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import { SecretsManagerClient, GetSecretValueCommand } from '@aws-sdk/client-secrets-manager'
|
|
2
|
+
import { SSMClient, GetParameterCommand } from '@aws-sdk/client-ssm'
|
|
3
|
+
import { mockClient } from 'aws-sdk-client-mock'
|
|
4
|
+
import { expect } from 'chai'
|
|
5
|
+
|
|
6
|
+
import EnvironmentVar, { EnvironmentType } from '../../src/Config/EnvironmentVar'
|
|
7
|
+
|
|
8
|
+
const SSMMock = mockClient(SSMClient)
|
|
9
|
+
const SecretsManagerMock = mockClient(SecretsManagerClient)
|
|
10
|
+
|
|
11
|
+
function testRemoteEnv(mock, type, command) {
|
|
12
|
+
describe(`Optional ${type} environment`, () => {
|
|
13
|
+
// reset mock
|
|
14
|
+
beforeEach(() => {
|
|
15
|
+
mock.reset()
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
test('Does not accept sync resolve', async () => {
|
|
19
|
+
mock.on(command).resolves({
|
|
20
|
+
...(type == EnvironmentType.PlainRemote
|
|
21
|
+
? {
|
|
22
|
+
Parameter: {
|
|
23
|
+
Value: undefined,
|
|
24
|
+
},
|
|
25
|
+
}
|
|
26
|
+
: {
|
|
27
|
+
SecretString: undefined,
|
|
28
|
+
}),
|
|
29
|
+
})
|
|
30
|
+
let err = null
|
|
31
|
+
try {
|
|
32
|
+
const env = new EnvironmentVar('abc', type, true)
|
|
33
|
+
env.syncResolve()
|
|
34
|
+
} catch (e) {
|
|
35
|
+
err = e
|
|
36
|
+
}
|
|
37
|
+
expect(err).is.not.null
|
|
38
|
+
expect(err?.['message']).is.not.null
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
test('Optional value with null value', async () => {
|
|
42
|
+
mock.on(command).resolves({
|
|
43
|
+
...(type == EnvironmentType.PlainRemote
|
|
44
|
+
? {
|
|
45
|
+
Parameter: {
|
|
46
|
+
Value: undefined,
|
|
47
|
+
},
|
|
48
|
+
}
|
|
49
|
+
: {
|
|
50
|
+
SecretString: undefined,
|
|
51
|
+
}),
|
|
52
|
+
})
|
|
53
|
+
const env = new EnvironmentVar('abc', type, true)
|
|
54
|
+
const token = await env.resolve()
|
|
55
|
+
expect(token).is.undefined
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
test('Optional value with empty response', async () => {
|
|
59
|
+
mock.on(command).resolves({})
|
|
60
|
+
const env = new EnvironmentVar('abc', type, true)
|
|
61
|
+
const token = await env.resolve()
|
|
62
|
+
expect(token).is.undefined
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
test('Optional value with valid response', async () => {
|
|
66
|
+
const value = 'abc'
|
|
67
|
+
mock.on(command).resolves({
|
|
68
|
+
...(type == EnvironmentType.PlainRemote
|
|
69
|
+
? {
|
|
70
|
+
Parameter: {
|
|
71
|
+
Value: value,
|
|
72
|
+
},
|
|
73
|
+
}
|
|
74
|
+
: {
|
|
75
|
+
SecretString: value,
|
|
76
|
+
}),
|
|
77
|
+
})
|
|
78
|
+
const env = new EnvironmentVar(value, type, true)
|
|
79
|
+
const token = await env.resolve()
|
|
80
|
+
expect(token).is.not.undefined
|
|
81
|
+
expect(token).to.be.equals(value)
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
test('Optional value rejection', async () => {
|
|
85
|
+
const value = 'abc'
|
|
86
|
+
mock.on(command).rejects(new Error('failed!'))
|
|
87
|
+
const env = new EnvironmentVar(value, type, true)
|
|
88
|
+
const token = await env.resolve()
|
|
89
|
+
expect(token).is.undefined
|
|
90
|
+
})
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
describe(`Required ${type} environment`, () => {
|
|
94
|
+
// reset mock
|
|
95
|
+
beforeEach(() => {
|
|
96
|
+
mock.reset()
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
test('Does not accept sync resolve', async () => {
|
|
100
|
+
mock.on(command).resolves({
|
|
101
|
+
...(type == EnvironmentType.PlainRemote
|
|
102
|
+
? {
|
|
103
|
+
Parameter: {
|
|
104
|
+
Value: undefined,
|
|
105
|
+
},
|
|
106
|
+
}
|
|
107
|
+
: {
|
|
108
|
+
SecretString: undefined,
|
|
109
|
+
}),
|
|
110
|
+
})
|
|
111
|
+
let err = null
|
|
112
|
+
try {
|
|
113
|
+
const env = new EnvironmentVar('abc', type)
|
|
114
|
+
env.syncResolve()
|
|
115
|
+
} catch (e) {
|
|
116
|
+
err = e
|
|
117
|
+
}
|
|
118
|
+
expect(err).is.not.null
|
|
119
|
+
expect(err?.['message']).is.not.null
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
test('Required fails when null', async () => {
|
|
123
|
+
mock.on(command).resolves({
|
|
124
|
+
...(type == EnvironmentType.PlainRemote
|
|
125
|
+
? {
|
|
126
|
+
Parameter: {
|
|
127
|
+
Value: undefined,
|
|
128
|
+
},
|
|
129
|
+
}
|
|
130
|
+
: {
|
|
131
|
+
SecretString: undefined,
|
|
132
|
+
}),
|
|
133
|
+
})
|
|
134
|
+
let err = null
|
|
135
|
+
try {
|
|
136
|
+
const env = new EnvironmentVar('abc', type)
|
|
137
|
+
await env.resolve()
|
|
138
|
+
} catch (e) {
|
|
139
|
+
err = e
|
|
140
|
+
}
|
|
141
|
+
console.log(err)
|
|
142
|
+
expect(err).is.not.null
|
|
143
|
+
expect(err?.['message']).is.not.null
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
test('Required fails when empty response', async () => {
|
|
147
|
+
mock.on(command).resolves({})
|
|
148
|
+
let err = null
|
|
149
|
+
try {
|
|
150
|
+
const env = new EnvironmentVar('abc', type)
|
|
151
|
+
await env.resolve()
|
|
152
|
+
} catch (e) {
|
|
153
|
+
err = e
|
|
154
|
+
}
|
|
155
|
+
expect(err).is.not.null
|
|
156
|
+
expect(err?.['message']).is.not.null
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
test('Required value with valid response', async () => {
|
|
160
|
+
const value = 'abc'
|
|
161
|
+
mock.on(command).resolves({
|
|
162
|
+
...(type == EnvironmentType.PlainRemote
|
|
163
|
+
? {
|
|
164
|
+
Parameter: {
|
|
165
|
+
Value: value,
|
|
166
|
+
},
|
|
167
|
+
}
|
|
168
|
+
: {
|
|
169
|
+
SecretString: value,
|
|
170
|
+
}),
|
|
171
|
+
})
|
|
172
|
+
const env = new EnvironmentVar(value, type)
|
|
173
|
+
const token = await env.resolve()
|
|
174
|
+
expect(token).is.not.undefined
|
|
175
|
+
expect(token).to.be.equals(value)
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
test('Required value rejection', async () => {
|
|
179
|
+
mock.on(command).rejects(new Error('failed!'))
|
|
180
|
+
let err = null
|
|
181
|
+
try {
|
|
182
|
+
const env = new EnvironmentVar('abc', type)
|
|
183
|
+
await env.resolve()
|
|
184
|
+
} catch (e) {
|
|
185
|
+
err = e
|
|
186
|
+
}
|
|
187
|
+
expect(err).is.not.null
|
|
188
|
+
expect(err?.['message']).is.not.null
|
|
189
|
+
})
|
|
190
|
+
})
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/* Remote envs test */
|
|
194
|
+
testRemoteEnv(SSMMock, EnvironmentType.PlainRemote, GetParameterCommand)
|
|
195
|
+
testRemoteEnv(SecretsManagerMock, EnvironmentType.SecureRemote, GetSecretValueCommand)
|
|
196
|
+
|
|
197
|
+
describe('Optional Local environment', () => {
|
|
198
|
+
test('Does accept async resolve', async () => {
|
|
199
|
+
const env = new EnvironmentVar('PATH123', EnvironmentType.Local, true)
|
|
200
|
+
const v = await env.resolve()
|
|
201
|
+
expect(v).is.undefined
|
|
202
|
+
})
|
|
203
|
+
|
|
204
|
+
test('Optional value with null value', async () => {
|
|
205
|
+
const env = new EnvironmentVar('PATH123', EnvironmentType.Local, true)
|
|
206
|
+
const token = env.syncResolve()
|
|
207
|
+
expect(token).is.undefined
|
|
208
|
+
})
|
|
209
|
+
|
|
210
|
+
test('Optional value with valid value', async () => {
|
|
211
|
+
const key = 'PATH'
|
|
212
|
+
const env = new EnvironmentVar(key, EnvironmentType.Local, true)
|
|
213
|
+
const token = env.syncResolve()
|
|
214
|
+
expect(token).is.not.undefined
|
|
215
|
+
expect(token).to.be.equals(process.env[key])
|
|
216
|
+
})
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
describe('Required local environment', () => {
|
|
220
|
+
test('Does accept async resolve', async () => {
|
|
221
|
+
const key = 'PATH'
|
|
222
|
+
const env = new EnvironmentVar(key, EnvironmentType.Local)
|
|
223
|
+
const v = await env.resolve()
|
|
224
|
+
expect(v).is.not.null
|
|
225
|
+
expect(v).to.be.equals(process.env[key])
|
|
226
|
+
})
|
|
227
|
+
|
|
228
|
+
test('Required fails when null', async () => {
|
|
229
|
+
let err = null
|
|
230
|
+
try {
|
|
231
|
+
const env = new EnvironmentVar('PATH123', EnvironmentType.Local)
|
|
232
|
+
env.syncResolve()
|
|
233
|
+
} catch (e) {
|
|
234
|
+
err = e
|
|
235
|
+
}
|
|
236
|
+
console.log(err)
|
|
237
|
+
expect(err).is.not.null
|
|
238
|
+
expect(err?.['message']).is.not.null
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
test('Required value with valid value', async () => {
|
|
242
|
+
const key = 'PATH'
|
|
243
|
+
const env = new EnvironmentVar(key, EnvironmentType.Local)
|
|
244
|
+
const v = env.syncResolve()
|
|
245
|
+
expect(v).is.not.null
|
|
246
|
+
expect(v).to.be.equals(process.env[key])
|
|
247
|
+
})
|
|
248
|
+
})
|
|
249
|
+
|
|
250
|
+
export {}
|