1
+ // tslint:disable:no-unnecessary-class
2
+
1
3
import * as DynamoDB from 'aws-sdk/clients/dynamodb'
2
4
import { of } from 'rxjs'
3
5
import { Organization } from '../../../../test/models'
@@ -7,38 +9,53 @@ import { BatchWriteSingleTableRequest } from './batch-write-single-table.request
7
9
8
10
describe ( 'batch write single table request' , ( ) => {
9
11
const tableName = getTableName ( Organization )
12
+ const item : Organization = < Organization > {
13
+ id : 'myId' ,
14
+ createdAtDate : new Date ( ) ,
15
+ name : 'myOrg' ,
16
+ }
10
17
11
- let item : Organization
12
18
let dynamoRx : DynamoRx
13
19
let request : BatchWriteSingleTableRequest < Organization >
14
20
15
- let nextSpyFn : ( ) => { value : number }
16
- const generatorMock = ( ) => < any > { next : nextSpyFn }
21
+ describe ( 'constructor' , ( ) => {
22
+ it ( 'should throw when no class was given' , ( ) => {
23
+ expect ( ( ) => new BatchWriteSingleTableRequest ( < any > null , < any > null ) ) . toThrow ( )
24
+ } )
25
+ it ( 'should throw when class given is not @Model decorated' , ( ) => {
26
+ class NoModel { }
27
+ expect ( ( ) => new BatchWriteSingleTableRequest ( < any > null , NoModel ) ) . toThrow ( )
28
+ } )
17
29
18
- beforeEach ( ( ) => {
19
- item = < any > {
20
- id : 'myId' ,
21
- createdAtDate : new Date ( ) ,
22
- name : 'myOrg' ,
23
- }
24
- nextSpyFn = jest . fn ( ) . mockImplementation ( ( ) => ( { value : 0 } ) )
30
+ it ( 'should initialize params' , ( ) => {
31
+ request = new BatchWriteSingleTableRequest ( < any > null , Organization )
32
+ expect ( request . params ) . toEqual ( {
33
+ RequestItems : {
34
+ [ tableName ] : [ ] ,
35
+ } ,
36
+ } )
37
+ } )
25
38
} )
26
39
27
40
describe ( 'correct params' , ( ) => {
28
41
beforeEach ( ( ) => {
29
- dynamoRx = new DynamoRx ( )
30
42
request = new BatchWriteSingleTableRequest ( dynamoRx , Organization )
43
+ } )
44
+
45
+ it ( 'returnConsumedCapacity' , ( ) => {
46
+ request . returnConsumedCapacity ( 'TOTAL' )
47
+ expect ( request . params . ReturnConsumedCapacity ) . toBe ( 'TOTAL' )
48
+ } )
31
49
32
- const output : DynamoDB . BatchWriteItemOutput = { }
33
- spyOn ( dynamoRx , 'batchWriteItem' ) . and . returnValue ( of ( output ) )
50
+ it ( 'returnItemCollectionMetrics' , ( ) => {
51
+ request . returnItemCollectionMetrics ( 'SIZE' )
52
+ expect ( request . params . ReturnItemCollectionMetrics ) . toBe ( 'SIZE' )
34
53
} )
35
54
36
- it ( 'delete with complex primary key' , async ( ) => {
55
+ it ( 'delete with composite key' , ( ) => {
37
56
request . delete ( [ item ] )
38
- await request . exec ( generatorMock ) . toPromise ( )
39
57
40
- expect ( dynamoRx . batchWriteItem ) . toHaveBeenCalledTimes ( 1 )
41
- expect ( dynamoRx . batchWriteItem ) . toHaveBeenCalledWith ( {
58
+ expect ( request . params ) . toEqual ( {
42
59
RequestItems : {
43
60
[ tableName ] : [
44
61
{
@@ -52,15 +69,12 @@ describe('batch write single table request', () => {
52
69
] ,
53
70
} ,
54
71
} )
55
- expect ( nextSpyFn ) . toHaveBeenCalledTimes ( 0 )
56
72
} )
57
73
58
74
it ( 'put object' , async ( ) => {
59
75
request . put ( [ item ] )
60
- await request . exec ( generatorMock ) . toPromise ( )
61
76
62
- expect ( dynamoRx . batchWriteItem ) . toHaveBeenCalledTimes ( 1 )
63
- expect ( dynamoRx . batchWriteItem ) . toHaveBeenCalledWith ( {
77
+ expect ( request . params ) . toEqual ( {
64
78
RequestItems : {
65
79
[ tableName ] : [
66
80
{
@@ -75,50 +89,103 @@ describe('batch write single table request', () => {
75
89
] ,
76
90
} ,
77
91
} )
78
- expect ( nextSpyFn ) . toHaveBeenCalledTimes ( 0 )
79
92
} )
80
93
81
- it ( 'delete >25 items in two requests' , async ( ) => {
82
- const twentyFiveItems = [ ]
83
- for ( let i = 0 ; i < 25 ; i ++ ) {
84
- twentyFiveItems . push ( item )
85
- }
86
- request . delete ( twentyFiveItems )
94
+ it ( 'adding >25 items in first delete call throws' , ( ) => {
95
+ const twentyFiveItems = new Array ( 30 ) . map ( ( ) => item )
96
+ expect ( ( ) => request . delete ( twentyFiveItems ) ) . toThrow ( )
97
+ } )
98
+
99
+ it ( 'adding >25 items in second delete call throws' , ( ) => {
100
+ const twentyFiveItems = new Array ( 25 ) . map ( ( ) => item )
87
101
request . delete ( twentyFiveItems )
88
- await request . exec ( generatorMock ) . toPromise ( )
89
- expect ( dynamoRx . batchWriteItem ) . toHaveBeenCalledTimes ( 2 )
90
- expect ( nextSpyFn ) . toHaveBeenCalledTimes ( 0 )
102
+ expect ( ( ) => request . delete ( twentyFiveItems ) ) . toThrow ( )
103
+ } )
104
+
105
+ it ( 'adding >25 items in first put call throws' , ( ) => {
106
+ const twentyFiveItems = new Array ( 30 ) . map ( ( ) => item )
107
+ expect ( ( ) => request . put ( twentyFiveItems ) ) . toThrow ( )
108
+ } )
109
+
110
+ it ( 'adding >25 items in second put call throws' , ( ) => {
111
+ const twentyFiveItems = new Array ( 25 ) . map ( ( ) => item )
112
+ request . put ( twentyFiveItems )
113
+ expect ( ( ) => request . put ( twentyFiveItems ) ) . toThrow ( )
91
114
} )
92
115
} )
93
116
94
- describe ( 'correct backoff' , ( ) => {
117
+ describe ( 'Unprocessed items' , ( ) => {
118
+ const output : DynamoDB . BatchWriteItemOutput = {
119
+ UnprocessedItems : {
120
+ [ tableName ] : [
121
+ {
122
+ PutRequest : {
123
+ Item : {
124
+ id : { S : 'myId' } ,
125
+ createdAtDate : { S : item . createdAtDate . toISOString ( ) } ,
126
+ name : { S : 'myOrg' } ,
127
+ } ,
128
+ } ,
129
+ } ,
130
+ ] ,
131
+ } ,
132
+ }
133
+
134
+ let generatorSpy : jasmine . Spy
135
+ let nextFnSpy : jasmine . Spy
136
+ let batchWriteItemSpy : jasmine . Spy
137
+
95
138
beforeEach ( ( ) => {
96
- dynamoRx = new DynamoRx ( )
139
+ batchWriteItemSpy = jasmine . createSpy ( ) . and . returnValues ( of ( output ) , of ( output ) , of ( { MyResult : true } ) )
140
+ nextFnSpy = jasmine . createSpy ( ) . and . returnValue ( { value : 0 } )
141
+ dynamoRx = < DynamoRx > ( < any > { batchWriteItem : batchWriteItemSpy } )
142
+ generatorSpy = jasmine . createSpy ( ) . and . returnValue ( { next : nextFnSpy } )
143
+
97
144
request = new BatchWriteSingleTableRequest ( dynamoRx , Organization )
145
+ } )
98
146
99
- const output : DynamoDB . BatchWriteItemOutput = {
100
- UnprocessedItems : {
101
- [ tableName ] : [
102
- {
103
- PutRequest : {
104
- Item : {
105
- id : { S : 'myId' } ,
106
- createdAtDate : { S : item . createdAtDate . toISOString ( ) } ,
107
- name : { S : 'myOrg' } ,
108
- } ,
109
- } ,
110
- } ,
111
- ] ,
112
- } ,
113
- }
114
- spyOn ( dynamoRx , 'batchWriteItem' ) . and . returnValues ( of ( output ) , of ( { } ) )
147
+ it ( 'should retry when unprocessed items are returned' , async ( ) => {
148
+ request . put ( [ item ] )
149
+ await request . exec ( < any > generatorSpy ) . toPromise ( )
150
+
151
+ // only one instance of the generator should be created
152
+ expect ( generatorSpy ) . toHaveBeenCalledTimes ( 1 )
153
+
154
+ expect ( nextFnSpy ) . toHaveBeenCalledTimes ( 2 )
155
+
156
+ expect ( batchWriteItemSpy ) . toHaveBeenCalledTimes ( 3 )
115
157
} )
116
158
117
- it ( 'should retry when capacity is exceeded ' , async ( ) => {
159
+ it ( 'should keep other params in additional calls ' , async ( ) => {
118
160
request . put ( [ item ] )
119
- await request . exec ( generatorMock ) . toPromise ( )
120
- expect ( dynamoRx . batchWriteItem ) . toHaveBeenCalledTimes ( 2 )
121
- expect ( nextSpyFn ) . toHaveBeenCalledTimes ( 1 )
161
+ request . returnConsumedCapacity ( 'TOTAL' )
162
+ request . returnItemCollectionMetrics ( 'SIZE' )
163
+ await request . exec ( < any > generatorSpy ) . toPromise ( )
164
+
165
+ expect ( batchWriteItemSpy ) . toHaveBeenCalledTimes ( 3 )
166
+ const paramsThirdCall = < DynamoDB . BatchWriteItemInput > batchWriteItemSpy . calls . all ( ) [ 2 ] . args [ 0 ]
167
+
168
+ expect ( paramsThirdCall ) . toBeDefined ( )
169
+ expect ( paramsThirdCall . ReturnConsumedCapacity ) . toBe ( 'TOTAL' )
170
+ expect ( paramsThirdCall . ReturnItemCollectionMetrics ) . toBe ( 'SIZE' )
171
+ } )
172
+ } )
173
+
174
+ describe ( 'exec / execFullResponse' , ( ) => {
175
+ beforeEach ( ( ) => {
176
+ dynamoRx = < DynamoRx > ( < any > { batchWriteItem : ( ) => of ( { myResponse : true } ) } )
177
+ request = new BatchWriteSingleTableRequest ( dynamoRx , Organization )
178
+ request . delete ( [ item ] )
179
+ } )
180
+
181
+ it ( 'exec should return nothing' , async ( ) => {
182
+ const response = await request . exec ( ) . toPromise ( )
183
+ expect ( response ) . toBeUndefined ( )
184
+ } )
185
+
186
+ it ( 'execFullResponse should return BatchWriteItemOutput' , async ( ) => {
187
+ const response = await request . execFullResponse ( ) . toPromise ( )
188
+ expect ( response ) . toEqual ( { myResponse : true } )
122
189
} )
123
190
} )
124
191
} )
0 commit comments