@@ -16,6 +16,7 @@ InModuleScope cosmos-db {
16
16
$MOCK_CONTAINER = " MOCK_CONTAINER"
17
17
$MOCK_COLLECTION = " MOCK_COLLECTION"
18
18
$MOCK_RECORD_ID = " MOCK_RECORD_ID"
19
+ $MOCK_ETAG = " MOCK_ETAG"
19
20
20
21
$MOCK_AUTH_HEADER = " MockAuthHeader"
21
22
@@ -29,7 +30,7 @@ InModuleScope cosmos-db {
29
30
$resourceUrl | Should - Be " dbs/$MOCK_CONTAINER /colls/$MOCK_COLLECTION /docs/$expectedId "
30
31
}
31
32
32
- Function VerifyInvokeCosmosDbApiRequest ($verb , $url , $actualBody , $expectedBody , $headers , $expectedId = $MOCK_RECORD_ID , $expectedPartitionKey = $null )
33
+ Function VerifyInvokeCosmosDbApiRequest ($verb , $url , $actualBody , $expectedBody , $headers , $expectedId = $MOCK_RECORD_ID , $expectedPartitionKey = $null , $enforceOptimisticConcurrency = $true )
33
34
{
34
35
$verb | Should - Be " put"
35
36
$url | Should - Be " https://$MOCK_DB .documents.azure.com/dbs/$MOCK_CONTAINER /colls/$MOCK_COLLECTION /docs/$expectedId "
@@ -39,8 +40,12 @@ InModuleScope cosmos-db {
39
40
$global :capturedNow | Should -Not - Be $null
40
41
41
42
$expectedPartitionKey = if ($expectedPartitionKey ) { $expectedPartitionKey } else { $expectedId }
42
- $expectedHeaders = Get-CommonHeaders - now $global :capturedNow - encodedAuthString $MOCK_AUTH_HEADER - PartitionKey $expectedPartitionKey
43
-
43
+
44
+ if ($EnforceOptimisticConcurrency ) {
45
+ $expectedHeaders = $expectedHeaders = Get-CommonHeaders - now $global :capturedNow - encodedAuthString $MOCK_AUTH_HEADER - PartitionKey $expectedPartitionKey - Etag $MOCK_ETAG
46
+ } else {
47
+ $expectedHeaders = Get-CommonHeaders - now $global :capturedNow - encodedAuthString $MOCK_AUTH_HEADER - PartitionKey $expectedPartitionKey
48
+ }
44
49
AssertHashtablesEqual $expectedHeaders $headers
45
50
}
46
51
@@ -65,6 +70,7 @@ InModuleScope cosmos-db {
65
70
id = $MOCK_RECORD_ID ;
66
71
key1 = " value1" ;
67
72
key2 = 2 ;
73
+ " _etag" = $MOCK_ETAG ;
68
74
}
69
75
70
76
Mock Invoke-CosmosDbApiRequest {
@@ -92,6 +98,7 @@ InModuleScope cosmos-db {
92
98
id = $MOCK_RECORD_ID ;
93
99
key1 = " value1" ;
94
100
key2 = 2 ;
101
+ " _etag" = $MOCK_ETAG ;
95
102
}
96
103
97
104
$MOCK_PARTITION_KEY = " MOCK_PARTITION_KEY"
@@ -121,6 +128,7 @@ InModuleScope cosmos-db {
121
128
id = $MOCK_RECORD_ID ;
122
129
key1 = " value1" ;
123
130
key2 = 2 ;
131
+ " _etag" = $MOCK_ETAG ;
124
132
}
125
133
126
134
$MOCK_PARTITION_KEY = " MOCK_PARTITION_KEY"
@@ -147,11 +155,48 @@ InModuleScope cosmos-db {
147
155
Assert-MockCalled Invoke-CosmosDbApiRequest - Times 1
148
156
}
149
157
158
+ It " Optimistic concurrency can be disabled" {
159
+ $response = @ {
160
+ StatusCode = 200 ;
161
+ Content = " {}"
162
+ }
163
+
164
+ $payload = @ {
165
+ id = $MOCK_RECORD_ID ;
166
+ key1 = " value1" ;
167
+ key2 = 2 ;
168
+ " _etag" = $MOCK_ETAG ;
169
+ }
170
+
171
+ $MOCK_PARTITION_KEY = " MOCK_PARTITION_KEY"
172
+ $MOCK_GET_PARTITION_KEY = {
173
+ param ($obj )
174
+
175
+ $obj | Should - BeExactly $payload | Out-Null
176
+
177
+ $MOCK_PARTITION_KEY
178
+ }
179
+
180
+ Mock Invoke-CosmosDbApiRequest {
181
+ param ($verb , $url , $body , $headers )
182
+
183
+ VerifyInvokeCosmosDbApiRequest $verb $url $body $payload $headers - ExpectedPartitionKey $MOCK_PARTITION_KEY - EnforceOptimisticConcurrency $false | Out-Null
184
+
185
+ $response
186
+ }
187
+
188
+ $result = $payload | Update-CosmosDbRecord - ResourceGroup $MOCK_RG - SubscriptionId $MOCK_SUB - Database $MOCK_DB - Container $MOCK_CONTAINER - Collection $MOCK_COLLECTION - GetPartitionKeyBlock $MOCK_GET_PARTITION_KEY - EnforceOptimisticConcurrency $false
189
+
190
+ $result | Should - BeExactly $response
191
+
192
+ Assert-MockCalled Invoke-CosmosDbApiRequest - Times 1
193
+ }
194
+
150
195
It " Sends correct request with custom partition key callback for multiple inputs" {
151
196
$payloads = @ (
152
- @ { id = " 1" };
153
- @ { id = " 2" };
154
- @ { id = " 3" };
197
+ @ { id = " 1" ; " _etag " = $MOCK_ETAG };
198
+ @ { id = " 2" ; " _etag " = $MOCK_ETAG };
199
+ @ { id = " 3" ; " _etag " = $MOCK_ETAG };
155
200
)
156
201
157
202
$global :idx = 0
@@ -199,6 +244,7 @@ InModuleScope cosmos-db {
199
244
$result.Count | Should - Be $payloads.Count
200
245
201
246
Assert-MockCalled Invoke-CosmosDbApiRequest - Times $payloads.Count
247
+ Assert-MockCalled Get-AuthorizationHeader - Times $payloads.Count
202
248
}
203
249
204
250
It " Url encodes the record id in the API url" {
@@ -212,7 +258,8 @@ InModuleScope cosmos-db {
212
258
$expectedAuthHeaderRecordId = $testRecordId # The id in the auth header should not be encoded
213
259
214
260
$payload = @ {
215
- id = $testRecordId
261
+ id = $testRecordId ;
262
+ " _etag" = $MOCK_ETAG ;
216
263
}
217
264
218
265
Mock Invoke-CosmosDbApiRequest {
@@ -236,6 +283,9 @@ InModuleScope cosmos-db {
236
283
$result = $payload | Update-CosmosDbRecord - ResourceGroup $MOCK_RG - SubscriptionId $MOCK_SUB - Database $MOCK_DB - Container $MOCK_CONTAINER - Collection $MOCK_COLLECTION
237
284
238
285
$result | Should - BeExactly $response
286
+
287
+ Assert-MockCalled Invoke-CosmosDbApiRequest - Times 1
288
+ Assert-MockCalled Get-AuthorizationHeader - Times 1
239
289
}
240
290
241
291
It " Should handle exceptions gracefully" {
@@ -247,6 +297,7 @@ InModuleScope cosmos-db {
247
297
id = $MOCK_RECORD_ID ;
248
298
key1 = " value1" ;
249
299
key2 = 2 ;
300
+ " _etag" = $MOCK_ETAG ;
250
301
}
251
302
252
303
Mock Invoke-CosmosDbApiRequest {
@@ -269,6 +320,7 @@ InModuleScope cosmos-db {
269
320
270
321
$result | Should - BeExactly $recordResponse
271
322
Assert-MockCalled Get-ExceptionResponseOrThrow - Times 1
323
+ Assert-MockCalled Invoke-CosmosDbApiRequest - Times 1
272
324
}
273
325
}
274
326
}
0 commit comments