@@ -25,20 +25,22 @@ public AtomicCreateResourceWithClientGeneratedIdTests(IntegrationTestContext<Tes
25
25
26
26
testContext . ConfigureServices ( services =>
27
27
{
28
- services . AddResourceDefinition < ImplicitlyChangingTextLanguageDefinition > ( ) ;
28
+ services . AddResourceDefinition < AssignIdToTextLanguageDefinition > ( ) ;
29
29
30
30
services . AddSingleton < ResourceDefinitionHitCounter > ( ) ;
31
31
services . AddSingleton < ISystemClock , FrozenSystemClock > ( ) ;
32
32
} ) ;
33
-
34
- var options = ( JsonApiOptions ) testContext . Factory . Services . GetRequiredService < IJsonApiOptions > ( ) ;
35
- options . ClientIdGeneration = ClientIdGenerationMode . Required ;
36
33
}
37
34
38
- [ Fact ]
39
- public async Task Can_create_resource_with_client_generated_guid_ID_having_side_effects ( )
35
+ [ Theory ]
36
+ [ InlineData ( ClientIdGenerationMode . Allowed ) ]
37
+ [ InlineData ( ClientIdGenerationMode . Required ) ]
38
+ public async Task Can_create_resource_with_client_generated_guid_ID_having_side_effects ( ClientIdGenerationMode mode )
40
39
{
41
40
// Arrange
41
+ var options = ( JsonApiOptions ) _testContext . Factory . Services . GetRequiredService < IJsonApiOptions > ( ) ;
42
+ options . ClientIdGeneration = mode ;
43
+
42
44
TextLanguage newLanguage = _fakers . TextLanguage . Generate ( ) ;
43
45
newLanguage . Id = Guid . NewGuid ( ) ;
44
46
@@ -90,10 +92,15 @@ await _testContext.RunOnDatabaseAsync(async dbContext =>
90
92
} ) ;
91
93
}
92
94
93
- [ Fact ]
94
- public async Task Can_create_resource_with_client_generated_string_ID_having_no_side_effects ( )
95
+ [ Theory ]
96
+ [ InlineData ( ClientIdGenerationMode . Allowed ) ]
97
+ [ InlineData ( ClientIdGenerationMode . Required ) ]
98
+ public async Task Can_create_resource_with_client_generated_guid_ID_having_no_side_effects ( ClientIdGenerationMode mode )
95
99
{
96
100
// Arrange
101
+ var options = ( JsonApiOptions ) _testContext . Factory . Services . GetRequiredService < IJsonApiOptions > ( ) ;
102
+ options . ClientIdGeneration = mode ;
103
+
97
104
MusicTrack newTrack = _fakers . MusicTrack . Generate ( ) ;
98
105
newTrack . Id = Guid . NewGuid ( ) ;
99
106
@@ -138,10 +145,72 @@ await _testContext.RunOnDatabaseAsync(async dbContext =>
138
145
} ) ;
139
146
}
140
147
141
- [ Fact ]
142
- public async Task Cannot_create_resource_for_missing_client_generated_ID ( )
148
+ [ Theory ]
149
+ [ InlineData ( ClientIdGenerationMode . Allowed ) ]
150
+ public async Task Can_create_resource_for_missing_client_generated_ID_having_side_effects ( ClientIdGenerationMode mode )
143
151
{
144
152
// Arrange
153
+ var options = ( JsonApiOptions ) _testContext . Factory . Services . GetRequiredService < IJsonApiOptions > ( ) ;
154
+ options . ClientIdGeneration = mode ;
155
+
156
+ string ? newIsoCode = _fakers . TextLanguage . Generate ( ) . IsoCode ;
157
+
158
+ var requestBody = new
159
+ {
160
+ atomic__operations = new [ ]
161
+ {
162
+ new
163
+ {
164
+ op = "add" ,
165
+ data = new
166
+ {
167
+ type = "textLanguages" ,
168
+ attributes = new
169
+ {
170
+ isoCode = newIsoCode
171
+ }
172
+ }
173
+ }
174
+ }
175
+ } ;
176
+
177
+ const string route = "/operations" ;
178
+
179
+ // Act
180
+ ( HttpResponseMessage httpResponse , Document responseDocument ) = await _testContext . ExecutePostAtomicAsync < Document > ( route , requestBody ) ;
181
+
182
+ // Assert
183
+ httpResponse . ShouldHaveStatusCode ( HttpStatusCode . OK ) ;
184
+
185
+ string isoCode = $ "{ newIsoCode } { ImplicitlyChangingTextLanguageDefinition . Suffix } ";
186
+
187
+ responseDocument . Results . ShouldHaveCount ( 1 ) ;
188
+
189
+ responseDocument . Results [ 0 ] . Data . SingleValue . ShouldNotBeNull ( ) . With ( resource =>
190
+ {
191
+ resource . Type . Should ( ) . Be ( "textLanguages" ) ;
192
+ resource . Attributes . ShouldContainKey ( "isoCode" ) . With ( value => value . Should ( ) . Be ( isoCode ) ) ;
193
+ resource . Relationships . ShouldNotBeEmpty ( ) ;
194
+ } ) ;
195
+
196
+ Guid newLanguageId = Guid . Parse ( responseDocument . Results [ 0 ] . Data . SingleValue ! . Id . ShouldNotBeNull ( ) ) ;
197
+
198
+ await _testContext . RunOnDatabaseAsync ( async dbContext =>
199
+ {
200
+ TextLanguage languageInDatabase = await dbContext . TextLanguages . FirstWithIdAsync ( newLanguageId ) ;
201
+
202
+ languageInDatabase . IsoCode . Should ( ) . Be ( isoCode ) ;
203
+ } ) ;
204
+ }
205
+
206
+ [ Theory ]
207
+ [ InlineData ( ClientIdGenerationMode . Required ) ]
208
+ public async Task Cannot_create_resource_for_missing_client_generated_ID ( ClientIdGenerationMode mode )
209
+ {
210
+ // Arrange
211
+ var options = ( JsonApiOptions ) _testContext . Factory . Services . GetRequiredService < IJsonApiOptions > ( ) ;
212
+ options . ClientIdGeneration = mode ;
213
+
145
214
string ? newIsoCode = _fakers . TextLanguage . Generate ( ) . IsoCode ;
146
215
147
216
var requestBody = new
@@ -182,10 +251,15 @@ public async Task Cannot_create_resource_for_missing_client_generated_ID()
182
251
error . Meta . ShouldContainKey ( "requestBody" ) . With ( value => value . ShouldNotBeNull ( ) . ToString ( ) . ShouldNotBeEmpty ( ) ) ;
183
252
}
184
253
185
- [ Fact ]
186
- public async Task Cannot_create_resource_for_existing_client_generated_ID ( )
254
+ [ Theory ]
255
+ [ InlineData ( ClientIdGenerationMode . Allowed ) ]
256
+ [ InlineData ( ClientIdGenerationMode . Required ) ]
257
+ public async Task Cannot_create_resource_for_existing_client_generated_ID ( ClientIdGenerationMode mode )
187
258
{
188
259
// Arrange
260
+ var options = ( JsonApiOptions ) _testContext . Factory . Services . GetRequiredService < IJsonApiOptions > ( ) ;
261
+ options . ClientIdGeneration = mode ;
262
+
189
263
TextLanguage existingLanguage = _fakers . TextLanguage . Generate ( ) ;
190
264
existingLanguage . Id = Guid . NewGuid ( ) ;
191
265
@@ -237,10 +311,15 @@ await _testContext.RunOnDatabaseAsync(async dbContext =>
237
311
error . Meta . Should ( ) . NotContainKey ( "requestBody" ) ;
238
312
}
239
313
240
- [ Fact ]
241
- public async Task Cannot_create_resource_for_incompatible_ID ( )
314
+ [ Theory ]
315
+ [ InlineData ( ClientIdGenerationMode . Allowed ) ]
316
+ [ InlineData ( ClientIdGenerationMode . Required ) ]
317
+ public async Task Cannot_create_resource_for_incompatible_ID ( ClientIdGenerationMode mode )
242
318
{
243
319
// Arrange
320
+ var options = ( JsonApiOptions ) _testContext . Factory . Services . GetRequiredService < IJsonApiOptions > ( ) ;
321
+ options . ClientIdGeneration = mode ;
322
+
244
323
string guid = Unknown . StringId . Guid ;
245
324
246
325
var requestBody = new
@@ -281,10 +360,71 @@ public async Task Cannot_create_resource_for_incompatible_ID()
281
360
error . Meta . ShouldContainKey ( "requestBody" ) . With ( value => value . ShouldNotBeNull ( ) . ToString ( ) . ShouldNotBeEmpty ( ) ) ;
282
361
}
283
362
284
- [ Fact ]
285
- public async Task Cannot_create_resource_with_local_ID ( )
363
+ [ Theory ]
364
+ [ InlineData ( ClientIdGenerationMode . Allowed ) ]
365
+ public async Task Can_create_resource_with_local_ID ( ClientIdGenerationMode mode )
366
+ {
367
+ // Arrange
368
+ var options = ( JsonApiOptions ) _testContext . Factory . Services . GetRequiredService < IJsonApiOptions > ( ) ;
369
+ options . ClientIdGeneration = mode ;
370
+
371
+ string newTitle = _fakers . MusicTrack . Generate ( ) . Title ;
372
+
373
+ var requestBody = new
374
+ {
375
+ atomic__operations = new [ ]
376
+ {
377
+ new
378
+ {
379
+ op = "add" ,
380
+ data = new
381
+ {
382
+ type = "musicTracks" ,
383
+ lid = "new-server-id" ,
384
+ attributes = new
385
+ {
386
+ title = newTitle
387
+ }
388
+ }
389
+ }
390
+ }
391
+ } ;
392
+
393
+ const string route = "/operations" ;
394
+
395
+ // Act
396
+ ( HttpResponseMessage httpResponse , Document responseDocument ) = await _testContext . ExecutePostAtomicAsync < Document > ( route , requestBody ) ;
397
+
398
+ // Assert
399
+ httpResponse . ShouldHaveStatusCode ( HttpStatusCode . OK ) ;
400
+
401
+ responseDocument . Results . ShouldHaveCount ( 1 ) ;
402
+
403
+ responseDocument . Results [ 0 ] . Data . SingleValue . ShouldNotBeNull ( ) . With ( resource =>
404
+ {
405
+ resource . Type . Should ( ) . Be ( "musicTracks" ) ;
406
+ resource . Attributes . ShouldContainKey ( "title" ) . With ( value => value . Should ( ) . Be ( newTitle ) ) ;
407
+ resource . Relationships . Should ( ) . BeNull ( ) ;
408
+ } ) ;
409
+
410
+ Guid newTrackId = Guid . Parse ( responseDocument . Results [ 0 ] . Data . SingleValue ! . Id . ShouldNotBeNull ( ) ) ;
411
+
412
+ await _testContext . RunOnDatabaseAsync ( async dbContext =>
413
+ {
414
+ MusicTrack languageInDatabase = await dbContext . MusicTracks . FirstWithIdAsync ( newTrackId ) ;
415
+
416
+ languageInDatabase . Title . Should ( ) . Be ( newTitle ) ;
417
+ } ) ;
418
+ }
419
+
420
+ [ Theory ]
421
+ [ InlineData ( ClientIdGenerationMode . Required ) ]
422
+ public async Task Cannot_create_resource_with_local_ID ( ClientIdGenerationMode mode )
286
423
{
287
424
// Arrange
425
+ var options = ( JsonApiOptions ) _testContext . Factory . Services . GetRequiredService < IJsonApiOptions > ( ) ;
426
+ options . ClientIdGeneration = mode ;
427
+
288
428
var requestBody = new
289
429
{
290
430
atomic__operations = new [ ]
@@ -320,10 +460,15 @@ public async Task Cannot_create_resource_with_local_ID()
320
460
error . Meta . ShouldContainKey ( "requestBody" ) . With ( value => value . ShouldNotBeNull ( ) . ToString ( ) . ShouldNotBeEmpty ( ) ) ;
321
461
}
322
462
323
- [ Fact ]
324
- public async Task Cannot_create_resource_for_ID_and_local_ID ( )
463
+ [ Theory ]
464
+ [ InlineData ( ClientIdGenerationMode . Allowed ) ]
465
+ [ InlineData ( ClientIdGenerationMode . Required ) ]
466
+ public async Task Cannot_create_resource_for_ID_and_local_ID ( ClientIdGenerationMode mode )
325
467
{
326
468
// Arrange
469
+ var options = ( JsonApiOptions ) _testContext . Factory . Services . GetRequiredService < IJsonApiOptions > ( ) ;
470
+ options . ClientIdGeneration = mode ;
471
+
327
472
var requestBody = new
328
473
{
329
474
atomic__operations = new [ ]
0 commit comments