@creator.co/wapi 1.2.4 → 1.2.6
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/.github/workflows/npmpublish.yml +1 -1
- package/README.md +216 -5
- package/dist/index.d.ts +15 -0
- package/dist/index.js.map +1 -1
- package/dist/jest.config.js +1 -1
- package/dist/jest.config.js.map +1 -1
- package/dist/package.json +13 -2
- package/dist/src/API/Request.d.ts +45 -82
- package/dist/src/API/Request.js +49 -77
- package/dist/src/API/Request.js.map +1 -1
- package/dist/src/API/Response.d.ts +94 -163
- package/dist/src/API/Response.js +101 -161
- package/dist/src/API/Response.js.map +1 -1
- package/dist/src/API/Utils.d.ts +21 -42
- package/dist/src/API/Utils.js +22 -43
- package/dist/src/API/Utils.js.map +1 -1
- package/dist/src/BaseEvent/EventProcessor.d.ts +32 -55
- package/dist/src/BaseEvent/EventProcessor.js +30 -38
- package/dist/src/BaseEvent/EventProcessor.js.map +1 -1
- package/dist/src/BaseEvent/Process.d.ts +20 -43
- package/dist/src/BaseEvent/Process.js +16 -27
- package/dist/src/BaseEvent/Process.js.map +1 -1
- package/dist/src/BaseEvent/Transaction.d.ts +104 -2
- package/dist/src/BaseEvent/Transaction.js +196 -41
- package/dist/src/BaseEvent/Transaction.js.map +1 -1
- package/dist/src/Config/Configuration.d.ts +48 -66
- package/dist/src/Config/Configuration.js +25 -42
- package/dist/src/Config/Configuration.js.map +1 -1
- package/dist/src/Config/EnvironmentVar.d.ts +30 -57
- package/dist/src/Config/EnvironmentVar.js +28 -41
- package/dist/src/Config/EnvironmentVar.js.map +1 -1
- package/dist/src/Crypto/Crypto.d.ts +17 -35
- package/dist/src/Crypto/Crypto.js +12 -21
- package/dist/src/Crypto/Crypto.js.map +1 -1
- package/dist/src/Crypto/JWT.d.ts +21 -32
- package/dist/src/Crypto/JWT.js +14 -22
- package/dist/src/Crypto/JWT.js.map +1 -1
- package/dist/src/Database/Database.d.ts +18 -0
- package/dist/src/Database/Database.js +18 -0
- package/dist/src/Database/Database.js.map +1 -0
- package/dist/src/Database/DatabaseManager.d.ts +32 -0
- package/dist/src/Database/DatabaseManager.js +50 -0
- package/dist/src/Database/DatabaseManager.js.map +1 -0
- package/dist/src/Database/DatabaseTransaction.d.ts +65 -0
- package/dist/src/Database/DatabaseTransaction.js +183 -0
- package/dist/src/Database/DatabaseTransaction.js.map +1 -0
- package/dist/src/Database/integrations/knex/KnexDatabase.d.ts +22 -0
- package/dist/src/Database/integrations/knex/KnexDatabase.js +108 -0
- package/dist/src/Database/integrations/knex/KnexDatabase.js.map +1 -0
- package/dist/src/Database/integrations/knex/KnexTransaction.d.ts +37 -0
- package/dist/src/Database/integrations/knex/KnexTransaction.js +60 -0
- package/dist/src/Database/integrations/knex/KnexTransaction.js.map +1 -0
- package/dist/src/Database/integrations/pgsql/PostgresDatabase.d.ts +30 -0
- package/dist/src/Database/integrations/pgsql/PostgresDatabase.js +108 -0
- package/dist/src/Database/integrations/pgsql/PostgresDatabase.js.map +1 -0
- package/dist/src/Database/integrations/pgsql/PostgresTransaction.d.ts +37 -0
- package/dist/src/Database/integrations/pgsql/PostgresTransaction.js +60 -0
- package/dist/src/Database/integrations/pgsql/PostgresTransaction.js.map +1 -0
- package/dist/src/Globals.d.ts +26 -94
- package/dist/src/Globals.js +26 -95
- package/dist/src/Globals.js.map +1 -1
- package/dist/src/Logger/Logger.d.ts +82 -105
- package/dist/src/Logger/Logger.js +111 -136
- package/dist/src/Logger/Logger.js.map +1 -1
- package/dist/src/Mailer/Mailer.d.ts +39 -75
- package/dist/src/Mailer/Mailer.js +36 -65
- package/dist/src/Mailer/Mailer.js.map +1 -1
- package/dist/src/Publisher/Publisher.d.ts +17 -25
- package/dist/src/Publisher/Publisher.js +21 -32
- package/dist/src/Publisher/Publisher.js.map +1 -1
- package/dist/src/Server/RouteResolver.d.ts +14 -22
- package/dist/src/Server/RouteResolver.js +21 -34
- package/dist/src/Server/RouteResolver.js.map +1 -1
- package/dist/src/Server/Router.d.ts +72 -51
- package/dist/src/Server/Router.js +8 -17
- package/dist/src/Server/Router.js.map +1 -1
- package/dist/src/Server/lib/ContainerServer.d.ts +15 -31
- package/dist/src/Server/lib/ContainerServer.js +13 -28
- package/dist/src/Server/lib/ContainerServer.js.map +1 -1
- package/dist/src/Server/lib/Server.d.ts +17 -32
- package/dist/src/Server/lib/Server.js +18 -28
- package/dist/src/Server/lib/Server.js.map +1 -1
- package/dist/src/Server/lib/container/GenericHandler.d.ts +5 -0
- package/dist/src/Server/lib/container/GenericHandler.js +16 -3
- package/dist/src/Server/lib/container/GenericHandler.js.map +1 -1
- package/dist/src/Server/lib/container/GenericHandlerEvent.d.ts +22 -37
- package/dist/src/Server/lib/container/GenericHandlerEvent.js +29 -41
- package/dist/src/Server/lib/container/GenericHandlerEvent.js.map +1 -1
- package/dist/src/Server/lib/container/HealthHandler.d.ts +6 -0
- package/dist/src/Server/lib/container/HealthHandler.js +6 -0
- package/dist/src/Server/lib/container/HealthHandler.js.map +1 -1
- package/dist/src/Server/lib/container/Proxy.d.ts +24 -52
- package/dist/src/Server/lib/container/Proxy.js +52 -52
- package/dist/src/Server/lib/container/Proxy.js.map +1 -1
- package/dist/src/Server/lib/container/Utils.d.ts +6 -10
- package/dist/src/Server/lib/container/Utils.js +6 -10
- package/dist/src/Server/lib/container/Utils.js.map +1 -1
- package/dist/src/Validation/Validator.d.ts +9 -13
- package/dist/src/Validation/Validator.js +8 -12
- package/dist/src/Validation/Validator.js.map +1 -1
- package/index.ts +15 -0
- package/jest.config.ts +1 -1
- package/package.json +13 -2
- package/src/API/Request.ts +66 -84
- package/src/API/Response.ts +144 -203
- package/src/API/Utils.ts +28 -44
- package/src/BaseEvent/EventProcessor.ts +52 -77
- package/src/BaseEvent/Process.ts +27 -52
- package/src/BaseEvent/Transaction.ts +147 -27
- package/src/Config/Configuration.ts +59 -76
- package/src/Config/EnvironmentVar.ts +39 -62
- package/src/Crypto/Crypto.ts +20 -36
- package/src/Crypto/JWT.ts +31 -35
- package/src/Database/Database.ts +19 -0
- package/src/Database/DatabaseManager.ts +51 -0
- package/src/Database/DatabaseTransaction.ts +118 -0
- package/src/Database/integrations/knex/KnexDatabase.ts +47 -0
- package/src/Database/integrations/knex/KnexTransaction.ts +51 -0
- package/src/Database/integrations/pgsql/PostgresDatabase.ts +49 -0
- package/src/Database/integrations/pgsql/PostgresTransaction.ts +54 -0
- package/src/Database/types.d.ts +49 -0
- package/src/Globals.ts +28 -96
- package/src/Logger/Logger.ts +141 -160
- package/src/Mailer/Mailer.ts +43 -76
- package/src/Publisher/Publisher.ts +31 -40
- package/src/Server/RouteResolver.ts +31 -52
- package/src/Server/Router.ts +75 -54
- package/src/Server/lib/ContainerServer.ts +20 -32
- package/src/Server/lib/Server.ts +19 -34
- package/src/Server/lib/container/GenericHandler.ts +17 -3
- package/src/Server/lib/container/GenericHandlerEvent.ts +44 -54
- package/src/Server/lib/container/HealthHandler.ts +6 -0
- package/src/Server/lib/container/Proxy.ts +39 -58
- package/src/Server/lib/container/Utils.ts +7 -10
- package/src/Validation/Validator.ts +11 -13
- package/tests/API/Response.test.ts +55 -56
- package/tests/BaseEvent/EventProcessor.test.ts +49 -50
- package/tests/BaseEvent/Process.test.ts +2 -2
- package/tests/BaseEvent/Transaction.test.ts +102 -44
- package/tests/Config/Config.test.ts +27 -27
- package/tests/Config/EnvironmentVar.test.ts +54 -18
- package/tests/Database/DatabaseManager.test.ts +55 -0
- package/tests/Database/integrations/knex/KnexDatabase.test.ts +53 -0
- package/tests/Database/integrations/knex/KnexTransaction.test.ts +133 -0
- package/tests/Database/integrations/pg/PostgresDatabase.test.ts +50 -0
- package/tests/Database/integrations/pg/PostgresTransaction.test.ts +51 -0
- package/tests/Publisher/Publisher.test.ts +3 -3
- package/tests/Server/lib/ContainerServer.test.ts +21 -22
- package/tests/Server/lib/container/GenericHandler.test.ts +31 -32
- package/tests/Server/lib/container/GenericHandlerEvent.test.ts +2 -2
- package/tests/Server/lib/container/HealthHandler.test.ts +6 -7
- package/tests/Server/lib/container/Proxy.test.ts +37 -35
- package/tsconfig.json +6 -1
|
@@ -17,9 +17,15 @@ function testRemoteEnv(mock, type, command) {
|
|
|
17
17
|
|
|
18
18
|
test('Does not accept sync resolve', async () => {
|
|
19
19
|
mock.on(command).resolves({
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
...(type == EnvironmentType.PlainRemote
|
|
21
|
+
? {
|
|
22
|
+
Parameter: {
|
|
23
|
+
Value: undefined,
|
|
24
|
+
},
|
|
25
|
+
}
|
|
26
|
+
: {
|
|
27
|
+
SecretString: undefined,
|
|
28
|
+
}),
|
|
23
29
|
})
|
|
24
30
|
let err = null
|
|
25
31
|
try {
|
|
@@ -34,9 +40,15 @@ function testRemoteEnv(mock, type, command) {
|
|
|
34
40
|
|
|
35
41
|
test('Optional value with null value', async () => {
|
|
36
42
|
mock.on(command).resolves({
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
43
|
+
...(type == EnvironmentType.PlainRemote
|
|
44
|
+
? {
|
|
45
|
+
Parameter: {
|
|
46
|
+
Value: undefined,
|
|
47
|
+
},
|
|
48
|
+
}
|
|
49
|
+
: {
|
|
50
|
+
SecretString: undefined,
|
|
51
|
+
}),
|
|
40
52
|
})
|
|
41
53
|
const env = new EnvironmentVar('abc', type, true)
|
|
42
54
|
const token = await env.resolve()
|
|
@@ -53,9 +65,15 @@ function testRemoteEnv(mock, type, command) {
|
|
|
53
65
|
test('Optional value with valid response', async () => {
|
|
54
66
|
const value = 'abc'
|
|
55
67
|
mock.on(command).resolves({
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
68
|
+
...(type == EnvironmentType.PlainRemote
|
|
69
|
+
? {
|
|
70
|
+
Parameter: {
|
|
71
|
+
Value: value,
|
|
72
|
+
},
|
|
73
|
+
}
|
|
74
|
+
: {
|
|
75
|
+
SecretString: value,
|
|
76
|
+
}),
|
|
59
77
|
})
|
|
60
78
|
const env = new EnvironmentVar(value, type, true)
|
|
61
79
|
const token = await env.resolve()
|
|
@@ -80,9 +98,15 @@ function testRemoteEnv(mock, type, command) {
|
|
|
80
98
|
|
|
81
99
|
test('Does not accept sync resolve', async () => {
|
|
82
100
|
mock.on(command).resolves({
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
101
|
+
...(type == EnvironmentType.PlainRemote
|
|
102
|
+
? {
|
|
103
|
+
Parameter: {
|
|
104
|
+
Value: undefined,
|
|
105
|
+
},
|
|
106
|
+
}
|
|
107
|
+
: {
|
|
108
|
+
SecretString: undefined,
|
|
109
|
+
}),
|
|
86
110
|
})
|
|
87
111
|
let err = null
|
|
88
112
|
try {
|
|
@@ -97,9 +121,15 @@ function testRemoteEnv(mock, type, command) {
|
|
|
97
121
|
|
|
98
122
|
test('Required fails when null', async () => {
|
|
99
123
|
mock.on(command).resolves({
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
124
|
+
...(type == EnvironmentType.PlainRemote
|
|
125
|
+
? {
|
|
126
|
+
Parameter: {
|
|
127
|
+
Value: undefined,
|
|
128
|
+
},
|
|
129
|
+
}
|
|
130
|
+
: {
|
|
131
|
+
SecretString: undefined,
|
|
132
|
+
}),
|
|
103
133
|
})
|
|
104
134
|
let err = null
|
|
105
135
|
try {
|
|
@@ -129,9 +159,15 @@ function testRemoteEnv(mock, type, command) {
|
|
|
129
159
|
test('Required value with valid response', async () => {
|
|
130
160
|
const value = 'abc'
|
|
131
161
|
mock.on(command).resolves({
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
162
|
+
...(type == EnvironmentType.PlainRemote
|
|
163
|
+
? {
|
|
164
|
+
Parameter: {
|
|
165
|
+
Value: value,
|
|
166
|
+
},
|
|
167
|
+
}
|
|
168
|
+
: {
|
|
169
|
+
SecretString: value,
|
|
170
|
+
}),
|
|
135
171
|
})
|
|
136
172
|
const env = new EnvironmentVar(value, type)
|
|
137
173
|
const token = await env.resolve()
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { expect } from 'chai'
|
|
2
|
+
|
|
3
|
+
import { DatabaseManager } from '../../src/Database/DatabaseManager'
|
|
4
|
+
import type { DatabaseType, DbConfig } from '../../src/Database/types'
|
|
5
|
+
|
|
6
|
+
type FakeDatabase = { host: string; type: 'knex' | 'pg' }
|
|
7
|
+
|
|
8
|
+
const fakeConfig = (host: string, type: DatabaseType) => {
|
|
9
|
+
return {
|
|
10
|
+
type,
|
|
11
|
+
host,
|
|
12
|
+
} as DbConfig<typeof type>
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
describe('Database Manager', () => {
|
|
16
|
+
test('should correctly create and cache database instances', () => {
|
|
17
|
+
const underTest = new DatabaseManager()
|
|
18
|
+
|
|
19
|
+
underTest['databases'] = {
|
|
20
|
+
knex: jest.fn(config => {
|
|
21
|
+
return { host: config.host, type: 'knex' } as any
|
|
22
|
+
}) as any,
|
|
23
|
+
pg: jest.fn(config => {
|
|
24
|
+
return { host: config.host, type: 'pg' } as any
|
|
25
|
+
}) as any,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const create = config => underTest.create({ ...config }) as unknown as FakeDatabase
|
|
29
|
+
|
|
30
|
+
const knexConfig1 = fakeConfig('localhost', 'knex')
|
|
31
|
+
const knexConfig2 = fakeConfig('other', 'knex')
|
|
32
|
+
const pgConfig1 = fakeConfig('localhost', 'pg')
|
|
33
|
+
const pgConfig2 = fakeConfig('other', 'pg')
|
|
34
|
+
|
|
35
|
+
const knex1 = create(knexConfig1)
|
|
36
|
+
const knex2 = create(knexConfig1)
|
|
37
|
+
const knex3 = create(knexConfig2)
|
|
38
|
+
|
|
39
|
+
const pg1 = create(pgConfig1)
|
|
40
|
+
const pg2 = create(pgConfig1)
|
|
41
|
+
const pg3 = create(pgConfig2)
|
|
42
|
+
|
|
43
|
+
expect(knex1).to.equal(knex2).to.not.equal(knex3).to.not.equal(pg1)
|
|
44
|
+
|
|
45
|
+
expect(knexConfig1).to.be.deep.equal(knex1).to.be.deep.equal(knex2)
|
|
46
|
+
|
|
47
|
+
expect(knex3).to.be.deep.equal(knexConfig2)
|
|
48
|
+
|
|
49
|
+
expect(pg1).to.equal(pg2).to.not.equal(pg3)
|
|
50
|
+
|
|
51
|
+
expect(pgConfig1).to.be.deep.equal(pg1).to.be.deep.equal(pg2)
|
|
52
|
+
|
|
53
|
+
expect(pg3).to.be.deep.equal(pgConfig2)
|
|
54
|
+
})
|
|
55
|
+
})
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Knex } from 'knex'
|
|
2
|
+
|
|
3
|
+
import { KnexDatabase } from '../../../../src/Database/integrations/knex/KnexDatabase'
|
|
4
|
+
import { KnexTransactionImpl } from '../../../../src/Database/integrations/knex/KnexTransaction'
|
|
5
|
+
import type { DbConfig } from '../../../../src/Database/types'
|
|
6
|
+
|
|
7
|
+
const config: DbConfig<'knex'> = {
|
|
8
|
+
type: 'knex',
|
|
9
|
+
username: 'username',
|
|
10
|
+
password: 'password',
|
|
11
|
+
host: 'host',
|
|
12
|
+
port: 1234,
|
|
13
|
+
database: 'database',
|
|
14
|
+
driver: 'driver',
|
|
15
|
+
maxConnections: 1,
|
|
16
|
+
autoCommit: true,
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const expectedImplConfig = {
|
|
20
|
+
client: config.driver,
|
|
21
|
+
connection: {
|
|
22
|
+
host: config.host,
|
|
23
|
+
port: config.port,
|
|
24
|
+
user: config.username,
|
|
25
|
+
password: config.password,
|
|
26
|
+
database: config.database,
|
|
27
|
+
},
|
|
28
|
+
pool: {
|
|
29
|
+
min: 1,
|
|
30
|
+
max: config.maxConnections,
|
|
31
|
+
},
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
describe('KnexDatabase', () => {
|
|
35
|
+
test('KnexDatabase', async () => {
|
|
36
|
+
const mockTrans = { a: 'b' } as any
|
|
37
|
+
const mockClient = jest.fn(
|
|
38
|
+
() =>
|
|
39
|
+
({
|
|
40
|
+
transaction: async () => mockTrans,
|
|
41
|
+
}) as Knex
|
|
42
|
+
)
|
|
43
|
+
KnexDatabase['knexProvider'] = mockClient
|
|
44
|
+
|
|
45
|
+
const underTest = new KnexDatabase(config)
|
|
46
|
+
expect(mockClient).toBeCalledWith(expectedImplConfig)
|
|
47
|
+
|
|
48
|
+
const trans = await underTest.transaction()
|
|
49
|
+
|
|
50
|
+
expect(trans).toBeInstanceOf(KnexTransactionImpl)
|
|
51
|
+
expect(trans['delegate']).toBe(mockTrans)
|
|
52
|
+
})
|
|
53
|
+
})
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { Knex } from 'knex'
|
|
2
|
+
|
|
3
|
+
import { KnexDatabase } from '../../../../src/Database/integrations/knex/KnexDatabase'
|
|
4
|
+
import { KnexTransactionImpl } from '../../../../src/Database/integrations/knex/KnexTransaction'
|
|
5
|
+
import type { DbConfig } from '../../../../src/Database/types'
|
|
6
|
+
|
|
7
|
+
const testResources = (config: Partial<DbConfig<'knex'>>) => {
|
|
8
|
+
const database = {
|
|
9
|
+
config: {
|
|
10
|
+
autoCommit: true,
|
|
11
|
+
...config,
|
|
12
|
+
} as DbConfig<'knex'>,
|
|
13
|
+
} as KnexDatabase
|
|
14
|
+
|
|
15
|
+
const delegate = jest.fn().mockImplementation(() => {
|
|
16
|
+
return {
|
|
17
|
+
commit: jest.fn(),
|
|
18
|
+
rollback: jest.fn(),
|
|
19
|
+
select: jest.fn(),
|
|
20
|
+
}
|
|
21
|
+
})() as any as Knex.Transaction
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
delegate,
|
|
25
|
+
underTest: KnexTransactionImpl.wrapDelegate(delegate, database),
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
describe('KnexTransaction', () => {
|
|
30
|
+
test('Can only commit once', async () => {
|
|
31
|
+
const { delegate, underTest } = testResources({})
|
|
32
|
+
await underTest.commit()
|
|
33
|
+
expect(underTest.isOpen).toBe(false)
|
|
34
|
+
expect(delegate.commit).toBeCalled()
|
|
35
|
+
|
|
36
|
+
await expect(underTest.commit).rejects.toThrowError(
|
|
37
|
+
'Cannot commit, transaction is already closed!'
|
|
38
|
+
)
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
test("Can't commit after rollback", async () => {
|
|
42
|
+
const { delegate, underTest } = testResources({})
|
|
43
|
+
await underTest.rollback()
|
|
44
|
+
expect(underTest.isOpen).toBe(false)
|
|
45
|
+
expect(delegate.rollback).toBeCalled()
|
|
46
|
+
|
|
47
|
+
await expect(underTest.commit).rejects.toThrowError(
|
|
48
|
+
'Cannot commit, transaction is already closed!'
|
|
49
|
+
)
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
test('Forwards calls to delegate', async () => {
|
|
53
|
+
const { delegate, underTest } = testResources({})
|
|
54
|
+
await underTest.select('name')
|
|
55
|
+
expect(delegate.select).toBeCalledWith('name')
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
test('Blocks delegate calls after commit', async () => {
|
|
59
|
+
const { delegate, underTest } = testResources({})
|
|
60
|
+
expect(underTest.select).toBeDefined()
|
|
61
|
+
|
|
62
|
+
await underTest.commit()
|
|
63
|
+
expect(delegate.commit).toBeCalled()
|
|
64
|
+
expect(underTest.isOpen).toBe(false)
|
|
65
|
+
|
|
66
|
+
expect(underTest.select).toBeUndefined()
|
|
67
|
+
})
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
describe('KnexTransaction - closeSuccess', () => {
|
|
71
|
+
test('Close success commits', async () => {
|
|
72
|
+
const { delegate, underTest } = testResources({})
|
|
73
|
+
await underTest.closeSuccess()
|
|
74
|
+
expect(delegate.commit).toBeCalled()
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
test("Close success, doesn't commit again if already committed", async () => {
|
|
78
|
+
const { delegate, underTest } = testResources({})
|
|
79
|
+
await underTest.commit()
|
|
80
|
+
expect(delegate.commit).toBeCalledTimes(1)
|
|
81
|
+
await underTest.closeSuccess()
|
|
82
|
+
expect(delegate.commit).toBeCalledTimes(1)
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
test('Close success, rolls back if not autocommit', async () => {
|
|
86
|
+
const { delegate, underTest } = testResources({ autoCommit: false })
|
|
87
|
+
await underTest.closeSuccess()
|
|
88
|
+
expect(delegate.rollback).toBeCalled()
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
test("Close success, doesn't rollback if already committed", async () => {
|
|
92
|
+
const { delegate, underTest } = testResources({ autoCommit: false })
|
|
93
|
+
await underTest.commit()
|
|
94
|
+
expect(delegate.commit).toBeCalledTimes(1)
|
|
95
|
+
await underTest.closeSuccess()
|
|
96
|
+
expect(delegate.rollback).not.toBeCalled()
|
|
97
|
+
expect(delegate.commit).toBeCalledTimes(1)
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
test("Close success, doesn't rollback if already rolled back", async () => {
|
|
101
|
+
const { delegate, underTest } = testResources({ autoCommit: false })
|
|
102
|
+
await underTest.rollback()
|
|
103
|
+
expect(delegate.rollback).toBeCalledTimes(1)
|
|
104
|
+
await underTest.closeSuccess()
|
|
105
|
+
expect(delegate.rollback).toBeCalledTimes(1)
|
|
106
|
+
expect(delegate.commit).not.toBeCalled()
|
|
107
|
+
})
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
describe('KnexTransaction - closeFailure', () => {
|
|
111
|
+
test('Close failure rolls back', async () => {
|
|
112
|
+
const { delegate, underTest } = testResources({})
|
|
113
|
+
await underTest.closeFailure()
|
|
114
|
+
expect(delegate.rollback).toBeCalled()
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
test("Close failure, doesn't rollback again if already rolled back", async () => {
|
|
118
|
+
const { delegate, underTest } = testResources({})
|
|
119
|
+
await underTest.rollback()
|
|
120
|
+
expect(delegate.rollback).toBeCalledTimes(1)
|
|
121
|
+
await underTest.closeFailure()
|
|
122
|
+
expect(delegate.rollback).toBeCalledTimes(1)
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
test("Close failure, doesn't rollback if already committed", async () => {
|
|
126
|
+
const { delegate, underTest } = testResources({ autoCommit: false })
|
|
127
|
+
await underTest.commit()
|
|
128
|
+
expect(delegate.commit).toBeCalledTimes(1)
|
|
129
|
+
await underTest.closeFailure()
|
|
130
|
+
expect(delegate.rollback).not.toBeCalled()
|
|
131
|
+
expect(delegate.commit).toBeCalledTimes(1)
|
|
132
|
+
})
|
|
133
|
+
})
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { PoolClient } from 'pg'
|
|
2
|
+
|
|
3
|
+
import { PostgresDatabase } from '../../../../src/Database/integrations/pgsql/PostgresDatabase'
|
|
4
|
+
import { PostgresTransactionImpl } from '../../../../src/Database/integrations/pgsql/PostgresTransaction'
|
|
5
|
+
import type { DbConfig } from '../../../../src/Database/types'
|
|
6
|
+
|
|
7
|
+
const config: DbConfig<'pg'> = {
|
|
8
|
+
type: 'pg',
|
|
9
|
+
username: 'username',
|
|
10
|
+
password: 'password',
|
|
11
|
+
host: 'host',
|
|
12
|
+
port: 1234,
|
|
13
|
+
database: 'database',
|
|
14
|
+
driver: 'driver',
|
|
15
|
+
maxConnections: 1,
|
|
16
|
+
autoCommit: true,
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const expectedImplConfig = {
|
|
20
|
+
host: config.host,
|
|
21
|
+
port: config.port,
|
|
22
|
+
user: config.username,
|
|
23
|
+
password: config.password,
|
|
24
|
+
database: config.database,
|
|
25
|
+
max: config.maxConnections,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
describe('PostgresDatabase', () => {
|
|
29
|
+
test('PostgresDatabase', async () => {
|
|
30
|
+
const mockTrans = {
|
|
31
|
+
query: jest.fn(() => {}),
|
|
32
|
+
} as any
|
|
33
|
+
const mockClient = jest.fn(
|
|
34
|
+
() =>
|
|
35
|
+
({
|
|
36
|
+
connect: async () => mockTrans,
|
|
37
|
+
}) as PoolClient
|
|
38
|
+
)
|
|
39
|
+
PostgresDatabase['pgProvider'] = mockClient as any
|
|
40
|
+
|
|
41
|
+
const underTest = new PostgresDatabase(config)
|
|
42
|
+
expect(mockClient).toBeCalledWith(expectedImplConfig)
|
|
43
|
+
|
|
44
|
+
const trans = await underTest.transaction()
|
|
45
|
+
|
|
46
|
+
expect(mockTrans.query).toBeCalledWith('BEGIN')
|
|
47
|
+
expect(trans).toBeInstanceOf(PostgresTransactionImpl)
|
|
48
|
+
expect(trans['delegate']).toBe(mockTrans)
|
|
49
|
+
})
|
|
50
|
+
})
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { PoolClient } from 'pg'
|
|
2
|
+
|
|
3
|
+
import { PostgresDatabase } from '../../../../src/Database/integrations/pgsql/PostgresDatabase'
|
|
4
|
+
import { PostgresTransactionImpl } from '../../../../src/Database/integrations/pgsql/PostgresTransaction'
|
|
5
|
+
import type { DbConfig } from '../../../../src/Database/types'
|
|
6
|
+
|
|
7
|
+
const testResources = (config: Partial<DbConfig<'pg'>>) => {
|
|
8
|
+
const database = {
|
|
9
|
+
config: {
|
|
10
|
+
autoCommit: true,
|
|
11
|
+
...config,
|
|
12
|
+
} as DbConfig<'pg'>,
|
|
13
|
+
} as PostgresDatabase
|
|
14
|
+
|
|
15
|
+
const delegate = jest.fn().mockImplementation(() => {
|
|
16
|
+
return {
|
|
17
|
+
commit: jest.fn(),
|
|
18
|
+
rollback: jest.fn(),
|
|
19
|
+
query: jest.fn(),
|
|
20
|
+
}
|
|
21
|
+
})() as any as PoolClient
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
delegate,
|
|
25
|
+
underTest: PostgresTransactionImpl.wrapDelegate(delegate, database),
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
describe('PostgresTransaction', () => {
|
|
30
|
+
test('Can only commit once', async () => {
|
|
31
|
+
const { delegate, underTest } = testResources({})
|
|
32
|
+
await underTest.commit()
|
|
33
|
+
expect(underTest.isOpen).toBe(false)
|
|
34
|
+
expect(delegate.query).toBeCalledWith('COMMIT')
|
|
35
|
+
|
|
36
|
+
await expect(underTest.commit).rejects.toThrowError(
|
|
37
|
+
'Cannot commit, transaction is already closed!'
|
|
38
|
+
)
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
test('Can only rollback once', async () => {
|
|
42
|
+
const { delegate, underTest } = testResources({})
|
|
43
|
+
await underTest.rollback()
|
|
44
|
+
expect(underTest.isOpen).toBe(false)
|
|
45
|
+
expect(delegate.query).toBeCalledWith('ROLLBACK')
|
|
46
|
+
|
|
47
|
+
await expect(underTest.rollback).rejects.toThrowError(
|
|
48
|
+
'Cannot rollback, transaction is already closed!'
|
|
49
|
+
)
|
|
50
|
+
})
|
|
51
|
+
})
|
|
@@ -28,7 +28,7 @@ describe('Encryption', () => {
|
|
|
28
28
|
})
|
|
29
29
|
const res = await provider.publishOnTopic(msg, topic)
|
|
30
30
|
expect(res).is.not.null
|
|
31
|
-
expect(res
|
|
31
|
+
expect(res?.MessageId).to.be.equals(messageId)
|
|
32
32
|
})
|
|
33
33
|
|
|
34
34
|
test('Publishes with success (additional props)', async () => {
|
|
@@ -45,7 +45,7 @@ describe('Encryption', () => {
|
|
|
45
45
|
FifoGroup: 123,
|
|
46
46
|
})
|
|
47
47
|
expect(res).is.not.null
|
|
48
|
-
expect(res
|
|
48
|
+
expect(res?.MessageId).to.be.equals(messageId)
|
|
49
49
|
})
|
|
50
50
|
|
|
51
51
|
test('Publish failure', async () => {
|
|
@@ -53,7 +53,7 @@ describe('Encryption', () => {
|
|
|
53
53
|
const topic = '123'
|
|
54
54
|
SNSMock.on(PublishCommand).rejects(new Error('failed!'))
|
|
55
55
|
const res = await provider.publishOnTopic(msg, topic)
|
|
56
|
-
expect(res).is.
|
|
56
|
+
expect(res).is.undefined
|
|
57
57
|
})
|
|
58
58
|
})
|
|
59
59
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { expect as
|
|
2
|
-
import { expect } from 'chai'
|
|
1
|
+
import { expect as c_expect } from 'chai'
|
|
3
2
|
import * as request from 'supertest'
|
|
4
3
|
import { z } from 'zod'
|
|
5
4
|
|
|
@@ -37,7 +36,7 @@ describe('Container server routing', () => {
|
|
|
37
36
|
.get(Globals.Listener_HTTP_DefaultHealthCheckRoute)
|
|
38
37
|
.expect('Content-Type', 'text/html; charset=utf-8')
|
|
39
38
|
.expect(200)
|
|
40
|
-
|
|
39
|
+
c_expect(res.text).to.be.equals('Healthy!')
|
|
41
40
|
// Not handled
|
|
42
41
|
await request(defaultUrl)
|
|
43
42
|
.get(`/abc`)
|
|
@@ -46,8 +45,8 @@ describe('Container server routing', () => {
|
|
|
46
45
|
|
|
47
46
|
// Unload
|
|
48
47
|
await server.stop('Error')
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
expect(mockExit).toHaveBeenCalledTimes(1)
|
|
49
|
+
expect(mockExit).toBeCalledWith(1)
|
|
51
50
|
})
|
|
52
51
|
|
|
53
52
|
test('Simple route', async () => {
|
|
@@ -68,14 +67,14 @@ describe('Container server routing', () => {
|
|
|
68
67
|
.get(Globals.Listener_HTTP_DefaultHealthCheckRoute)
|
|
69
68
|
.expect('Content-Type', 'text/html; charset=utf-8')
|
|
70
69
|
.expect(200)
|
|
71
|
-
|
|
70
|
+
c_expect(res.text).to.be.equals('Healthy!')
|
|
72
71
|
// Found route
|
|
73
72
|
const resG = await request(defaultUrl)
|
|
74
73
|
.get(`/abc`)
|
|
75
74
|
.expect('Content-Type', 'application/json; charset=utf-8')
|
|
76
75
|
.expect(200)
|
|
77
|
-
|
|
78
|
-
|
|
76
|
+
c_expect(resG.body['name']).to.be.deep.equals('abc')
|
|
77
|
+
c_expect(resG.body['transactionID']).to.not.be.null
|
|
79
78
|
// Found route, but not method
|
|
80
79
|
await request(defaultUrl)
|
|
81
80
|
.post(`/abc`)
|
|
@@ -88,8 +87,8 @@ describe('Container server routing', () => {
|
|
|
88
87
|
.expect(404)
|
|
89
88
|
// Unload
|
|
90
89
|
await server.stop('Error')
|
|
91
|
-
|
|
92
|
-
|
|
90
|
+
expect(mockExit).toHaveBeenCalledTimes(1)
|
|
91
|
+
expect(mockExit).toBeCalledWith(1)
|
|
93
92
|
})
|
|
94
93
|
})
|
|
95
94
|
|
|
@@ -117,11 +116,11 @@ describe('Container server basics', () => {
|
|
|
117
116
|
.get(Globals.Listener_HTTP_DefaultHealthCheckRoute)
|
|
118
117
|
.expect('Content-Type', 'text/html; charset=utf-8')
|
|
119
118
|
.expect(200)
|
|
120
|
-
|
|
119
|
+
c_expect(res.text).to.be.equals('Healthy!')
|
|
121
120
|
// Unload
|
|
122
121
|
await server.stop()
|
|
123
|
-
|
|
124
|
-
|
|
122
|
+
expect(mockExit).toHaveBeenCalledTimes(1)
|
|
123
|
+
expect(mockExit).toBeCalledWith(0)
|
|
125
124
|
resolve(null)
|
|
126
125
|
}, 2000)
|
|
127
126
|
})
|
|
@@ -133,8 +132,8 @@ describe('Container server basics', () => {
|
|
|
133
132
|
process.emit('SIGINT')
|
|
134
133
|
return new Promise(resolve => {
|
|
135
134
|
setTimeout(async () => {
|
|
136
|
-
|
|
137
|
-
|
|
135
|
+
expect(mockExit).toHaveBeenCalledTimes(1)
|
|
136
|
+
expect(mockExit).toBeCalledWith(0)
|
|
138
137
|
resolve(null)
|
|
139
138
|
}, 2000)
|
|
140
139
|
})
|
|
@@ -147,8 +146,8 @@ describe('Container server basics', () => {
|
|
|
147
146
|
process.emit('unhandledRejection')
|
|
148
147
|
return new Promise(resolve => {
|
|
149
148
|
setTimeout(async () => {
|
|
150
|
-
|
|
151
|
-
|
|
149
|
+
expect(mockExit).toHaveBeenCalledTimes(1)
|
|
150
|
+
expect(mockExit).toBeCalledWith(0)
|
|
152
151
|
resolve(null)
|
|
153
152
|
}, 2000)
|
|
154
153
|
})
|
|
@@ -170,11 +169,11 @@ describe('Container server validation', () => {
|
|
|
170
169
|
})
|
|
171
170
|
|
|
172
171
|
function validateValidationFailure(res: any, failureCount?: number) {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
172
|
+
c_expect(res.body['err']).to.be.equals(Globals.ErrorResponseValidationFail)
|
|
173
|
+
c_expect(res.body['errCode']).to.be.equals(Globals.ErrorCode_InvalidInput)
|
|
174
|
+
c_expect(res.body['transactionID']).to.not.be.null
|
|
175
|
+
c_expect(res.body['transactionID']).to.be.an('string')
|
|
176
|
+
c_expect(res.body['validationFailure']?.length).to.be.equals(failureCount || 4)
|
|
178
177
|
}
|
|
179
178
|
|
|
180
179
|
test('Validates empty body', async () => {
|