1+ // tslint:disable:no-unnecessary-class
2+
13import * as DynamoDB from 'aws-sdk/clients/dynamodb'
24import { of } from 'rxjs'
35import { Organization } from '../../../../test/models'
@@ -7,38 +9,53 @@ import { BatchWriteSingleTableRequest } from './batch-write-single-table.request
79
810describe ( 'batch write single table request' , ( ) => {
911 const tableName = getTableName ( Organization )
12+ const item : Organization = < Organization > {
13+ id : 'myId' ,
14+ createdAtDate : new Date ( ) ,
15+ name : 'myOrg' ,
16+ }
1017
11- let item : Organization
1218 let dynamoRx : DynamoRx
1319 let request : BatchWriteSingleTableRequest < Organization >
1420
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+ } )
1729
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+ } )
2538 } )
2639
2740 describe ( 'correct params' , ( ) => {
2841 beforeEach ( ( ) => {
29- dynamoRx = new DynamoRx ( )
3042 request = new BatchWriteSingleTableRequest ( dynamoRx , Organization )
43+ } )
44+
45+ it ( 'returnConsumedCapacity' , ( ) => {
46+ request . returnConsumedCapacity ( 'TOTAL' )
47+ expect ( request . params . ReturnConsumedCapacity ) . toBe ( 'TOTAL' )
48+ } )
3149
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' )
3453 } )
3554
36- it ( 'delete with complex primary key' , async ( ) => {
55+ it ( 'delete with composite key' , ( ) => {
3756 request . delete ( [ item ] )
38- await request . exec ( generatorMock ) . toPromise ( )
3957
40- expect ( dynamoRx . batchWriteItem ) . toHaveBeenCalledTimes ( 1 )
41- expect ( dynamoRx . batchWriteItem ) . toHaveBeenCalledWith ( {
58+ expect ( request . params ) . toEqual ( {
4259 RequestItems : {
4360 [ tableName ] : [
4461 {
@@ -52,15 +69,12 @@ describe('batch write single table request', () => {
5269 ] ,
5370 } ,
5471 } )
55- expect ( nextSpyFn ) . toHaveBeenCalledTimes ( 0 )
5672 } )
5773
5874 it ( 'put object' , async ( ) => {
5975 request . put ( [ item ] )
60- await request . exec ( generatorMock ) . toPromise ( )
6176
62- expect ( dynamoRx . batchWriteItem ) . toHaveBeenCalledTimes ( 1 )
63- expect ( dynamoRx . batchWriteItem ) . toHaveBeenCalledWith ( {
77+ expect ( request . params ) . toEqual ( {
6478 RequestItems : {
6579 [ tableName ] : [
6680 {
@@ -75,50 +89,103 @@ describe('batch write single table request', () => {
7589 ] ,
7690 } ,
7791 } )
78- expect ( nextSpyFn ) . toHaveBeenCalledTimes ( 0 )
7992 } )
8093
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 )
87101 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 ( )
91114 } )
92115 } )
93116
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+
95138 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+
97144 request = new BatchWriteSingleTableRequest ( dynamoRx , Organization )
145+ } )
98146
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 )
115157 } )
116158
117- it ( 'should retry when capacity is exceeded ' , async ( ) => {
159+ it ( 'should keep other params in additional calls ' , async ( ) => {
118160 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 } )
122189 } )
123190 } )
124191} )
0 commit comments