Skip to content

Commit 9d6a4b7

Browse files
committed
add tests for transactions
1 parent ae131a6 commit 9d6a4b7

File tree

5 files changed

+215
-13
lines changed

5 files changed

+215
-13
lines changed

src/__tests__/parse.unit.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,21 @@ const TestTable = new Table({
1717
DocumentClient
1818
})
1919

20+
const CompositeEntity = new Entity({
21+
// Specify entity name
22+
name: 'CompositeEntity',
23+
24+
// Define attributes
25+
attributes: {
26+
pk: { type: 'string', partitionKey: true },
27+
sk: { type: 'string', sortKey: true, hidden: true },
28+
test_composite: ['sk',0, { save: true }],
29+
test_composite2: ['sk',1, { save: false }],
30+
test_composite3: ['sk',2, { }]
31+
},
32+
table: TestTable
33+
})
34+
2035

2136
describe('parse',()=>{
2237

@@ -83,5 +98,19 @@ describe('parse',()=>{
8398
})
8499
})
85100

101+
// it('parses composite field without "save"', ()=>{
102+
// let item = CompositeEntity.parse({
103+
// pk: 'test@test.com',
104+
// sk: 'active#email#foo',
105+
// test_composite: 'test'
106+
// })
107+
// expect(item).toEqual({
108+
// pk: 'test@test.com',
109+
// test_composite: 'test',
110+
// test_composite2: 'email',
111+
// test_composite3: 'foo'
112+
// })
113+
// })
114+
86115

87116
}) // end parse

src/__tests__/table.query.unit.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ const TestEntity = new Entity({
2222

2323
describe('query',()=>{
2424

25-
it('queries a table with no options', () => {
26-
let result = TestTable.queryParams('test')
25+
it('queries a table with no options', async () => {
26+
let result = TestTable.query('test',{ execute: false })
2727
expect(result).toEqual({
2828
TableName: 'test-table',
2929
KeyConditionExpression: '#pk = :pk',
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// @xts-nocheck
2+
import { Table, Entity } from '../index'
3+
import { DocumentClient } from './bootstrap-tests'
4+
5+
const TestTable = new Table({
6+
name: 'test-table',
7+
alias: 'testTable',
8+
partitionKey: 'pk',
9+
sortKey: 'sk',
10+
indexes: { GSI1: { partitionKey: 'GSI1pk', sortKey: 'GSIsk1' } },
11+
DocumentClient
12+
})
13+
14+
const TestEntity = new Entity({
15+
name: 'TestEntity',
16+
autoExecute: false,
17+
attributes: {
18+
email: { type: 'string', partitionKey: true },
19+
sort: { type: 'string', sortKey: true },
20+
test: 'string'
21+
},
22+
table: TestTable
23+
})
24+
25+
describe('transactGet',()=>{
26+
27+
it('fails when transactGet is empty', () => {
28+
// @ts-expect-error
29+
expect(() => { TestTable.transactGetParams() })
30+
.toThrow(`No items supplied`)
31+
})
32+
33+
it('fails when transactGet items is an empty array', () => {
34+
expect(() => { TestTable.transactGetParams([]) })
35+
.toThrow(`No items supplied`)
36+
})
37+
38+
it('transactGets data from a single table', () => {
39+
let result = TestTable.transactGetParams([
40+
TestEntity.getTransaction({ pk: 'test', sk: 'testsk'})
41+
])
42+
expect(result).toHaveProperty('TransactItems')
43+
expect(result.TransactItems[0]).toHaveProperty('Get')
44+
expect(result.TransactItems[0].Get.TableName).toBe('test-table')
45+
expect(result.TransactItems[0].Get.Key).toEqual({ pk: 'test', sk: 'testsk'})
46+
})
47+
48+
it('fails when extra options', () => {
49+
expect(() => { TestTable.transactGetParams([
50+
TestEntity.getTransaction({ pk: 'test', sk: 'testsk'})
51+
],
52+
// @ts-expect-error
53+
{ invalid: true }
54+
) })
55+
.toThrow(`Invalid transactGet options: invalid`)
56+
})
57+
58+
it('fails when providing an invalid capacity setting', () => {
59+
expect(() => { TestTable.transactGetParams(
60+
[TestEntity.getTransaction({ pk: 'test', sk: 'testsk'})],
61+
{ capacity: 'test' }
62+
) })
63+
.toThrow(`'capacity' must be one of 'NONE','TOTAL', OR 'INDEXES'`)
64+
})
65+
66+
it('fails when providing an invalid getTransaction item', () => {
67+
expect(() => { TestTable.transactGetParams(
68+
// @ts-expect-error
69+
[{}]
70+
) })
71+
.toThrow(`Invalid transaction item. Use the 'getTransaction' method on an entity.`)
72+
})
73+
74+
75+
})
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { DocumentClient } from 'aws-sdk/clients/dynamodb'
2+
import { Table, Entity } from '../index'
3+
import { DocumentClient as docClient } from './bootstrap-tests'
4+
5+
const TestTable = new Table({
6+
name: 'test-table',
7+
alias: 'testTable',
8+
partitionKey: 'pk',
9+
sortKey: 'sk',
10+
indexes: { GSI1: { partitionKey: 'GSI1pk', sortKey: 'GSIsk1' } },
11+
DocumentClient: docClient
12+
})
13+
14+
const TestEntity = new Entity({
15+
name: 'TestEntity',
16+
autoExecute: false,
17+
attributes: {
18+
email: { type: 'string', partitionKey: true },
19+
sort: { type: 'string', sortKey: true },
20+
test: 'string'
21+
},
22+
table: TestTable
23+
})
24+
25+
describe('transactWrite',()=>{
26+
27+
it('fails when transactWrite is empty', () => {
28+
// @ts-expect-error
29+
expect(() => { TestTable.transactWriteParams() })
30+
.toThrow(`No items supplied`)
31+
})
32+
33+
it('fails when transactWrite items is an empty array', () => {
34+
expect(() => { TestTable.transactWriteParams([]) })
35+
.toThrow(`No items supplied`)
36+
})
37+
38+
it('transactWrite put, update, delete data', () => {
39+
let result = TestTable.transactWriteParams([
40+
TestEntity.putTransaction({ pk: 'test', sk: 'testsk1', test: 'test'}),
41+
TestEntity.updateTransaction({ pk: 'test', sk: 'testsk2', test: 'test'}),
42+
TestEntity.deleteTransaction({ pk: 'test', sk: 'testsk3', test: 'test'})
43+
])
44+
45+
expect(result.TransactItems[0].Put!.Item.sk).toBe('testsk1')
46+
expect(result.TransactItems[1].Update!.UpdateExpression).toBe('SET #_ct = if_not_exists(#_ct,:_ct), #_md = :_md, #_et = if_not_exists(#_et,:_et), #test = :test')
47+
expect(result.TransactItems[2].Delete!.Key.sk).toBe('testsk3')
48+
})
49+
50+
it('fails when extra options', () => {
51+
expect(() => { TestTable.transactWriteParams(
52+
[TestEntity.putTransaction({ pk: 'test', sk: 'testsk'})],
53+
// @ts-expect-error
54+
{ invalid: true }
55+
) })
56+
.toThrow(`Invalid transactWrite options: invalid`)
57+
})
58+
59+
it('fails when providing an invalid capacity setting', () => {
60+
expect(() => { TestTable.transactWriteParams(
61+
[TestEntity.putTransaction({ pk: 'test', sk: 'testsk'})],
62+
{ capacity: 'test' }
63+
) })
64+
.toThrow(`'capacity' must be one of 'NONE','TOTAL', OR 'INDEXES'`)
65+
})
66+
67+
it('fails when providing an invalid metrics setting', () => {
68+
expect(() => { TestTable.transactWriteParams(
69+
[TestEntity.putTransaction({ pk: 'test', sk: 'testsk'})],
70+
{ metrics: 'test' }
71+
) })
72+
.toThrow(`'metrics' must be one of 'NONE' OR 'SIZE'`)
73+
})
74+
75+
})

src/classes/Table.ts

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,7 @@ class Table {
436436

437437
// If auto execute enabled
438438
if (options.execute || (this.autoExecute && options.execute !== false)) {
439+
439440
const result = await this.DocumentClient!.query(payload).promise()
440441

441442
// If auto parse enable
@@ -1134,7 +1135,7 @@ class Table {
11341135

11351136

11361137

1137-
parseBatchWriteResponse(
1138+
private parseBatchWriteResponse(
11381139
result: any,
11391140
options:batchWriteOptions = {}
11401141
): any {
@@ -1277,10 +1278,26 @@ class Table {
12771278
* Creates a TransactGetItems object: https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactGetItems.html
12781279
*/
12791280
transactGetParams(
1280-
items: ({ Entity?: any } & DocumentClient.TransactGetItem)[] = [],
1281+
_items: ({ Entity?: any } & DocumentClient.TransactGetItem)[],
1282+
options?: transactGetParamsOptions,
1283+
meta?: false | undefined
1284+
) : DocumentClient.TransactGetItemsInput
1285+
transactGetParams(
1286+
_items: ({ Entity?: any } & DocumentClient.TransactGetItem)[],
1287+
options: transactGetParamsOptions,
1288+
meta: true
1289+
) : transactGetParamsMeta
1290+
transactGetParams(
1291+
_items: ({ Entity?: any } & DocumentClient.TransactGetItem)[],
12811292
options: transactGetParamsOptions = {},
12821293
meta: boolean = false
1283-
) {
1294+
): DocumentClient.TransactGetItemsInput | transactGetParamsMeta {
1295+
1296+
let items = Array.isArray(_items) ? _items : _items ? [_items] : []
1297+
1298+
// Error on no items
1299+
if (items.length === 0)
1300+
error(`No items supplied`)
12841301

12851302
// Extract valid options
12861303
const {
@@ -1292,8 +1309,8 @@ class Table {
12921309
const args = Object.keys(_args).filter(x => !['execute','parse'].includes(x))
12931310

12941311
// Error on extraneous arguments
1295-
if (Object.keys(args).length > 0)
1296-
error(`Invalid transactGet options: ${Object.keys(args).join(', ')}`)
1312+
if (args.length > 0)
1313+
error(`Invalid transactGet options: ${args.join(', ')}`)
12971314

12981315
// Verify capacity
12991316
if (capacity !== undefined
@@ -1317,9 +1334,9 @@ class Table {
13171334
capacity ? { ReturnConsumedCapacity: capacity.toUpperCase() } : null
13181335
)
13191336

1320-
return meta ?
1321-
{ Entities, payload } as transactGetParamsMeta
1322-
: payload as DocumentClient.TransactGetItemsInput
1337+
// Return transact items
1338+
return (meta) ? { Entities, payload } : payload
1339+
13231340
} // end transactGetParams
13241341

13251342

@@ -1365,10 +1382,16 @@ class Table {
13651382
* Creates a TransactWriteItems object: https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactWriteItems.html
13661383
*/
13671384
transactWriteParams(
1368-
items: DocumentClient.TransactWriteItemList = [],
1385+
_items: DocumentClient.TransactWriteItemList,
13691386
options: transactWriteParamsOptions = {}
13701387
): DocumentClient.TransactWriteItemsInput {
13711388

1389+
let items = Array.isArray(_items) ? _items : _items ? [_items] : []
1390+
1391+
// Error on no items
1392+
if (items.length === 0)
1393+
error(`No items supplied`)
1394+
13721395
// Extract valid options
13731396
const {
13741397
capacity, // ReturnConsumedCapacity (none, total, or indexes)
@@ -1381,8 +1404,8 @@ class Table {
13811404
const args = Object.keys(_args).filter(x => !['execute','parse'].includes(x))
13821405

13831406
// Error on extraneous arguments
1384-
if (Object.keys(args).length > 0)
1385-
error(`Invalid transactWrite options: ${Object.keys(args).join(', ')}`)
1407+
if (args.length > 0)
1408+
error(`Invalid transactWrite options: ${args.join(', ')}`)
13861409

13871410
// Verify capacity
13881411
if (capacity !== undefined

0 commit comments

Comments
 (0)