diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs index c4f70fe60d..8b0090fe8e 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceTests.cs @@ -261,7 +261,7 @@ public async Task Cannot_create_resource_with_unknown_attribute() error.Detail.Should().Be("Attribute 'doesNotExist' does not exist on resource type 'playlists'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/attributes/doesNotExist"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -366,7 +366,7 @@ public async Task Cannot_create_resource_with_unknown_relationship() error.Detail.Should().Be("Relationship 'doesNotExist' does not exist on resource type 'lyrics'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/doesNotExist"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -478,7 +478,7 @@ public async Task Cannot_create_resource_with_client_generated_ID() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/id"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -513,7 +513,7 @@ public async Task Cannot_create_resource_for_href_element() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/href"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -551,7 +551,7 @@ public async Task Cannot_create_resource_for_ref_element() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -585,7 +585,7 @@ public async Task Cannot_create_resource_for_missing_data() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -620,7 +620,7 @@ public async Task Cannot_create_resource_for_null_data() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -667,7 +667,7 @@ public async Task Cannot_create_resource_for_array_data() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -707,7 +707,7 @@ public async Task Cannot_create_resource_for_missing_type() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -745,7 +745,7 @@ public async Task Cannot_create_resource_for_unknown_type() error.Detail.Should().Be($"Resource type '{Unknown.ResourceType}' does not exist."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -790,7 +790,7 @@ public async Task Cannot_create_resource_with_readonly_attribute() error.Detail.Should().Be("Attribute 'isArchived' on resource type 'playlists' is read-only."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/attributes/isArchived"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -832,7 +832,7 @@ public async Task Cannot_create_resource_with_incompatible_attribute_value() error.Detail.Should().Be("Failed to convert attribute 'bornAt' with value '12345' of type 'Number' to type 'DateTimeOffset'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/attributes/bornAt"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -985,6 +985,6 @@ public async Task Cannot_assign_attribute_with_blocked_capability() error.Detail.Should().Be("The attribute 'createdAt' on resource type 'lyrics' cannot be assigned to."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/attributes/createdAt"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs index 8675f54c3d..0d8f7b14a7 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithClientGeneratedIdTests.cs @@ -247,7 +247,7 @@ public async Task Cannot_create_resource_for_missing_client_generated_ID(ClientI error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Theory] @@ -356,7 +356,7 @@ public async Task Cannot_create_resource_for_incompatible_ID(ClientIdGenerationM error.Detail.Should().Be($"Failed to convert '{guid}' of type 'String' to type 'Int32'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/id"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Theory] @@ -456,7 +456,7 @@ public async Task Cannot_create_resource_with_local_ID(ClientIdGenerationMode mo error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/lid"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Theory] @@ -501,6 +501,6 @@ public async Task Cannot_create_resource_for_ID_and_local_ID(ClientIdGenerationM error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToManyRelationshipTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToManyRelationshipTests.cs index 775b6d2197..0b86e91ddf 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToManyRelationshipTests.cs @@ -238,7 +238,7 @@ public async Task Cannot_create_for_missing_relationship_type() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/performers/data[0]"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -290,7 +290,7 @@ public async Task Cannot_create_for_unknown_relationship_type() error.Detail.Should().Be($"Resource type '{Unknown.ResourceType}' does not exist."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/performers/data[0]/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -341,7 +341,7 @@ public async Task Cannot_create_for_missing_relationship_ID() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/performers/data[0]"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -467,7 +467,7 @@ public async Task Cannot_create_on_relationship_type_mismatch() error.Detail.Should().Be("Type 'playlists' is not convertible to type 'performers' of relationship 'performers'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/performers/data[0]/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -590,7 +590,7 @@ public async Task Cannot_create_with_missing_data_in_OneToMany_relationship() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/performers"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -635,7 +635,7 @@ public async Task Cannot_create_with_null_data_in_ManyToMany_relationship() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/tracks/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -682,7 +682,7 @@ public async Task Cannot_create_with_object_data_in_ManyToMany_relationship() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/tracks/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -734,6 +734,6 @@ public async Task Cannot_assign_relationship_with_blocked_capability() error.Detail.Should().Be("The relationship 'occursIn' on resource type 'musicTracks' cannot be assigned to."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/occursIn"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToOneRelationshipTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToOneRelationshipTests.cs index ff60ccbf87..a140a52322 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToOneRelationshipTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Creating/AtomicCreateResourceWithToOneRelationshipTests.cs @@ -304,7 +304,7 @@ public async Task Cannot_create_for_null_relationship() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/lyric"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -348,7 +348,7 @@ public async Task Cannot_create_for_missing_data_in_relationship() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/lyric"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -400,7 +400,7 @@ public async Task Cannot_create_for_array_data_in_relationship() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/lyric/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -448,7 +448,7 @@ public async Task Cannot_create_for_missing_relationship_type() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/lyric/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -497,7 +497,7 @@ public async Task Cannot_create_for_unknown_relationship_type() error.Detail.Should().Be($"Resource type '{Unknown.ResourceType}' does not exist."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/lyric/data/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -545,7 +545,7 @@ public async Task Cannot_create_for_missing_relationship_ID() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/lyric/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -651,7 +651,7 @@ public async Task Cannot_create_on_relationship_type_mismatch() error.Detail.Should().Be("Type 'playlists' is not convertible to type 'lyrics' of relationship 'lyric'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/lyric/data/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -781,6 +781,6 @@ public async Task Cannot_assign_relationship_with_blocked_capability() error.Detail.Should().Be("The relationship 'language' on resource type 'lyrics' cannot be assigned to."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/language"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Deleting/AtomicDeleteResourceTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Deleting/AtomicDeleteResourceTests.cs index c8c00b1a54..a330577dbd 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Deleting/AtomicDeleteResourceTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Deleting/AtomicDeleteResourceTests.cs @@ -355,7 +355,7 @@ public async Task Cannot_delete_resource_for_href_element() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/href"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -389,7 +389,7 @@ public async Task Cannot_delete_resource_for_missing_ref_element() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -427,7 +427,7 @@ public async Task Cannot_delete_resource_for_missing_type() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -466,7 +466,7 @@ public async Task Cannot_delete_resource_for_unknown_type() error.Detail.Should().Be($"Resource type '{Unknown.ResourceType}' does not exist."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -504,7 +504,7 @@ public async Task Cannot_delete_resource_for_missing_ID() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -586,7 +586,7 @@ public async Task Cannot_delete_resource_for_incompatible_ID() error.Detail.Should().Be($"Failed to convert '{guid}' of type 'String' to type 'Int64'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref/id"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -626,6 +626,6 @@ public async Task Cannot_delete_resource_for_ID_and_local_ID() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Mixed/AtomicRequestBodyTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Mixed/AtomicRequestBodyTests.cs index e4d67f457f..abc4525b60 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Mixed/AtomicRequestBodyTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Mixed/AtomicRequestBodyTests.cs @@ -64,7 +64,7 @@ public async Task Cannot_process_for_null_request_body() error.Title.Should().Be("Failed to deserialize request body: Expected an object, instead of 'null'."); error.Detail.Should().BeNull(); error.Source.Should().BeNull(); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -117,7 +117,7 @@ public async Task Cannot_process_for_missing_operations_array() error.Title.Should().Be("Failed to deserialize request body: No operations found."); error.Detail.Should().BeNull(); error.Source.Should().BeNull(); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -144,7 +144,7 @@ public async Task Cannot_process_empty_operations_array() error.Title.Should().Be("Failed to deserialize request body: No operations found."); error.Detail.Should().BeNull(); error.Source.Should().BeNull(); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -175,7 +175,7 @@ public async Task Cannot_process_null_operation() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Mixed/MaximumOperationsPerRequestTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Mixed/MaximumOperationsPerRequestTests.cs index 0173e1c6d4..b18c4991db 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Mixed/MaximumOperationsPerRequestTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Mixed/MaximumOperationsPerRequestTests.cs @@ -73,7 +73,7 @@ public async Task Cannot_process_more_operations_than_maximum() error.Detail.Should().Be("The number of operations in this request (3) is higher than the maximum of 2."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicAddToToManyRelationshipTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicAddToToManyRelationshipTests.cs index 5ddc0d55fd..419c8e5b16 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicAddToToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicAddToToManyRelationshipTests.cs @@ -70,7 +70,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("Relationship 'ownedBy' is not a to-many relationship."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref/relationship"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -265,7 +265,7 @@ public async Task Cannot_add_for_href_element() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/href"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -304,7 +304,7 @@ public async Task Cannot_add_for_missing_type_in_ref() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -344,7 +344,7 @@ public async Task Cannot_add_for_unknown_type_in_ref() error.Detail.Should().Be($"Resource type '{Unknown.ResourceType}' does not exist."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -383,7 +383,7 @@ public async Task Cannot_add_for_missing_ID_in_ref() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -482,7 +482,7 @@ public async Task Cannot_add_for_ID_and_local_ID_in_ref() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -521,7 +521,7 @@ public async Task Cannot_add_for_missing_relationship_in_ref() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -561,7 +561,7 @@ public async Task Cannot_add_for_unknown_relationship_in_ref() error.Detail.Should().Be($"Relationship '{Unknown.Relationship}' does not exist on resource type 'performers'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref/relationship"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -609,7 +609,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -658,7 +658,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -709,7 +709,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -756,7 +756,7 @@ public async Task Cannot_add_for_missing_type_in_data() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data[0]"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -804,7 +804,7 @@ public async Task Cannot_add_for_unknown_type_in_data() error.Detail.Should().Be($"Resource type '{Unknown.ResourceType}' does not exist."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data[0]/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -851,7 +851,7 @@ public async Task Cannot_add_for_missing_ID_in_data() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data[0]"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -900,7 +900,7 @@ public async Task Cannot_add_for_ID_and_local_ID_in_data() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data[0]"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1029,7 +1029,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("Type 'playlists' is not convertible to type 'performers' of relationship 'performers'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data[0]/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1132,6 +1132,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("The relationship 'occursIn' on resource type 'musicTracks' cannot be added to."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref/relationship"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicRemoveFromToManyRelationshipTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicRemoveFromToManyRelationshipTests.cs index a914e59ac3..98d954c910 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicRemoveFromToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicRemoveFromToManyRelationshipTests.cs @@ -70,7 +70,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("Relationship 'ownedBy' is not a to-many relationship."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref/relationship"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -264,7 +264,7 @@ public async Task Cannot_remove_for_href_element() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/href"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -303,7 +303,7 @@ public async Task Cannot_remove_for_missing_type_in_ref() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -343,7 +343,7 @@ public async Task Cannot_remove_for_unknown_type_in_ref() error.Detail.Should().Be($"Resource type '{Unknown.ResourceType}' does not exist."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -382,7 +382,7 @@ public async Task Cannot_remove_for_missing_ID_in_ref() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -481,7 +481,7 @@ public async Task Cannot_remove_for_ID_and_local_ID_in_ref() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -521,7 +521,7 @@ public async Task Cannot_remove_for_unknown_relationship_in_ref() error.Detail.Should().Be($"Relationship '{Unknown.Relationship}' does not exist on resource type 'performers'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref/relationship"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -569,7 +569,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -618,7 +618,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -669,7 +669,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -716,7 +716,7 @@ public async Task Cannot_remove_for_missing_type_in_data() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data[0]"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -764,7 +764,7 @@ public async Task Cannot_remove_for_unknown_type_in_data() error.Detail.Should().Be($"Resource type '{Unknown.ResourceType}' does not exist."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data[0]/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -811,7 +811,7 @@ public async Task Cannot_remove_for_missing_ID_in_data() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data[0]"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -860,7 +860,7 @@ public async Task Cannot_remove_for_ID_and_local_ID_in_data() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data[0]"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -989,7 +989,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("Type 'playlists' is not convertible to type 'performers' of relationship 'performers'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data[0]/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1093,6 +1093,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("The relationship 'occursIn' on resource type 'musicTracks' cannot be removed from."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref/relationship"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicReplaceToManyRelationshipTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicReplaceToManyRelationshipTests.cs index 38d2d1aac0..3653763f60 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicReplaceToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicReplaceToManyRelationshipTests.cs @@ -299,7 +299,7 @@ public async Task Cannot_replace_for_href_element() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/href"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -338,7 +338,7 @@ public async Task Cannot_replace_for_missing_type_in_ref() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -378,7 +378,7 @@ public async Task Cannot_replace_for_unknown_type_in_ref() error.Detail.Should().Be($"Resource type '{Unknown.ResourceType}' does not exist."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -417,7 +417,7 @@ public async Task Cannot_replace_for_missing_ID_in_ref() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -533,7 +533,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be($"Failed to convert '{guid}' of type 'String' to type 'Int16'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref/id"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -574,7 +574,7 @@ public async Task Cannot_replace_for_ID_and_local_ID_in_ref() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -614,7 +614,7 @@ public async Task Cannot_replace_for_unknown_relationship_in_ref() error.Detail.Should().Be($"Relationship '{Unknown.Relationship}' does not exist on resource type 'performers'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref/relationship"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -662,7 +662,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -711,7 +711,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -762,7 +762,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -809,7 +809,7 @@ public async Task Cannot_replace_for_missing_type_in_data() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data[0]"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -857,7 +857,7 @@ public async Task Cannot_replace_for_unknown_type_in_data() error.Detail.Should().Be($"Resource type '{Unknown.ResourceType}' does not exist."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data[0]/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -904,7 +904,7 @@ public async Task Cannot_replace_for_missing_ID_in_data() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data[0]"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -953,7 +953,7 @@ public async Task Cannot_replace_for_ID_and_local_ID_in_data() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data[0]"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1082,7 +1082,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("Failed to convert 'invalid-guid' of type 'String' to type 'Guid'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data[0]/id"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1138,7 +1138,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("Type 'playlists' is not convertible to type 'performers' of relationship 'performers'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data[0]/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1191,6 +1191,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("The relationship 'occursIn' on resource type 'musicTracks' cannot be assigned to."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref/relationship"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicUpdateToOneRelationshipTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicUpdateToOneRelationshipTests.cs index 3d543a15f6..a079f9d829 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicUpdateToOneRelationshipTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Relationships/AtomicUpdateToOneRelationshipTests.cs @@ -552,7 +552,7 @@ public async Task Cannot_create_for_href_element() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/href"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -591,7 +591,7 @@ public async Task Cannot_create_for_missing_type_in_ref() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -631,7 +631,7 @@ public async Task Cannot_create_for_unknown_type_in_ref() error.Detail.Should().Be($"Resource type '{Unknown.ResourceType}' does not exist."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -670,7 +670,7 @@ public async Task Cannot_create_for_missing_ID_in_ref() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -778,7 +778,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("Failed to convert 'invalid-guid' of type 'String' to type 'Guid'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref/id"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -819,7 +819,7 @@ public async Task Cannot_create_for_ID_and_local_ID_in_ref() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -859,7 +859,7 @@ public async Task Cannot_create_for_unknown_relationship_in_ref() error.Detail.Should().Be($"Relationship '{Unknown.Relationship}' does not exist on resource type 'performers'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref/relationship"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -907,7 +907,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -963,7 +963,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1007,7 +1007,7 @@ public async Task Cannot_create_for_missing_type_in_data() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1052,7 +1052,7 @@ public async Task Cannot_create_for_unknown_type_in_data() error.Detail.Should().Be($"Resource type '{Unknown.ResourceType}' does not exist."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1096,7 +1096,7 @@ public async Task Cannot_create_for_missing_ID_in_data() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1142,7 +1142,7 @@ public async Task Cannot_create_for_ID_and_local_ID_in_data() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1250,7 +1250,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("Failed to convert 'invalid-guid' of type 'String' to type 'Guid'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/id"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1303,7 +1303,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("Type 'playlists' is not convertible to type 'lyrics' of relationship 'lyric'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1356,6 +1356,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("The relationship 'language' on resource type 'lyrics' cannot be assigned to."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref/relationship"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicReplaceToManyRelationshipTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicReplaceToManyRelationshipTests.cs index 31a2b61512..32db3a5221 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicReplaceToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicReplaceToManyRelationshipTests.cs @@ -337,7 +337,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/performers"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -391,7 +391,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/performers/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -447,7 +447,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/performers/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -499,7 +499,7 @@ public async Task Cannot_replace_for_missing_type_in_relationship_data() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/tracks/data[0]"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -552,7 +552,7 @@ public async Task Cannot_replace_for_unknown_type_in_relationship_data() error.Detail.Should().Be($"Resource type '{Unknown.ResourceType}' does not exist."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/performers/data[0]/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -604,7 +604,7 @@ public async Task Cannot_replace_for_missing_ID_in_relationship_data() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/performers/data[0]"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -658,7 +658,7 @@ public async Task Cannot_replace_for_ID_and_local_ID_relationship_in_data() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/performers/data[0]"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -797,7 +797,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("Type 'playlists' is not convertible to type 'performers' of relationship 'performers'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/performers/data[0]/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -858,6 +858,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("The relationship 'occursIn' on resource type 'musicTracks' cannot be assigned to."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/occursIn"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateResourceTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateResourceTests.cs index 2e97812c19..8bf1ae451b 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateResourceTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateResourceTests.cs @@ -208,7 +208,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("Attribute 'doesNotExist' does not exist on resource type 'musicTracks'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/attributes/doesNotExist"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -321,7 +321,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("Relationship 'doesNotExist' does not exist on resource type 'musicTracks'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/doesNotExist"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -639,7 +639,7 @@ public async Task Cannot_update_resource_for_href_element() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/href"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -745,7 +745,7 @@ public async Task Cannot_update_resource_for_missing_type_in_ref() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -794,7 +794,7 @@ public async Task Cannot_update_resource_for_missing_ID_in_ref() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -845,7 +845,7 @@ public async Task Cannot_update_resource_for_ID_and_local_ID_in_ref() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -879,7 +879,7 @@ public async Task Cannot_update_resource_for_missing_data() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -914,7 +914,7 @@ public async Task Cannot_update_resource_for_null_data() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -968,7 +968,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1012,7 +1012,7 @@ public async Task Cannot_update_resource_for_missing_type_in_data() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1056,7 +1056,7 @@ public async Task Cannot_update_resource_for_missing_ID_in_data() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1102,7 +1102,7 @@ public async Task Cannot_update_resource_for_ID_and_local_ID_in_data() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1152,7 +1152,7 @@ public async Task Cannot_update_on_resource_type_mismatch_between_ref_and_data() error.Detail.Should().Be("Type 'playlists' is not convertible to type 'performers'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1205,7 +1205,7 @@ public async Task Cannot_update_on_resource_ID_mismatch_between_ref_and_data() error.Detail.Should().Be($"Expected '{performerId1}' instead of '{performerId2}'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/id"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1255,7 +1255,7 @@ public async Task Cannot_update_on_resource_local_ID_mismatch_between_ref_and_da error.Detail.Should().Be("Expected 'local-1' instead of 'local-2'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/lid"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1307,7 +1307,7 @@ public async Task Cannot_update_on_mixture_of_ID_and_local_ID_between_ref_and_da error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1359,7 +1359,7 @@ public async Task Cannot_update_on_mixture_of_local_ID_and_ID_between_ref_and_da error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1404,7 +1404,7 @@ public async Task Cannot_update_resource_for_unknown_type() error.Detail.Should().Be($"Resource type '{Unknown.ResourceType}' does not exist."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1500,7 +1500,7 @@ public async Task Cannot_update_resource_for_incompatible_ID() error.Detail.Should().Be($"Failed to convert '{guid}' of type 'String' to type 'Int32'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/ref/id"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1551,7 +1551,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("Attribute 'isArchived' on resource type 'playlists' is read-only."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/attributes/isArchived"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1602,7 +1602,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/attributes/id"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1653,7 +1653,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("Failed to convert attribute 'bornAt' with value '123.45' of type 'Number' to type 'DateTimeOffset'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/attributes/bornAt"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1813,6 +1813,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("The attribute 'createdAt' on resource type 'lyrics' cannot be assigned to."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/attributes/createdAt"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateToOneRelationshipTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateToOneRelationshipTests.cs index 00133e29ea..a8c6881616 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateToOneRelationshipTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Updating/Resources/AtomicUpdateToOneRelationshipTests.cs @@ -613,7 +613,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/lyric"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -666,7 +666,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/lyric"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -727,7 +727,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/lyric/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -776,7 +776,7 @@ public async Task Cannot_create_for_missing_type_in_relationship_data() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/track/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -826,7 +826,7 @@ public async Task Cannot_create_for_unknown_type_in_relationship_data() error.Detail.Should().Be($"Resource type '{Unknown.ResourceType}' does not exist."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/lyric/data/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -875,7 +875,7 @@ public async Task Cannot_create_for_missing_ID_in_relationship_data() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/lyric/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -926,7 +926,7 @@ public async Task Cannot_create_for_ID_and_local_ID_in_relationship_data() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/lyric/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1044,7 +1044,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("Type 'playlists' is not convertible to type 'lyrics' of relationship 'lyric'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/lyric/data/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1102,6 +1102,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("The relationship 'language' on resource type 'lyrics' cannot be assigned to."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/atomic:operations[0]/data/relationships/language"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ExceptionHandling/ExceptionHandlerTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ExceptionHandling/ExceptionHandlerTests.cs index 8a635c734f..35a5364938 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ExceptionHandling/ExceptionHandlerTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ExceptionHandling/ExceptionHandlerTests.cs @@ -109,20 +109,8 @@ public async Task Logs_and_produces_error_response_on_deserialization_failure() error.StatusCode.Should().Be(HttpStatusCode.UnprocessableEntity); error.Title.Should().Be("Failed to deserialize request body: Unknown resource type found."); error.Detail.Should().Be("Resource type '' does not exist."); - - error.Meta.Should().ContainKey("requestBody").WhoseValue.With(value => - { - JsonElement element = value.Should().BeOfType().Subject; - element.GetString().Should().Be(requestBody); - }); - - error.Meta.Should().ContainKey("stackTrace").WhoseValue.With(value => - { - JsonElement element = value.Should().BeOfType().Subject; - IEnumerable stackTraceLines = element.EnumerateArray().Select(token => token.GetString()); - - stackTraceLines.Should().NotBeEmpty(); - }); + error.Meta.Should().ContainRequestBody(requestBody); + error.Meta.Should().HaveStackTrace(); IReadOnlyList logMessages = loggerProvider.GetMessages(); logMessages.Should().BeEmpty(); @@ -157,14 +145,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.StatusCode.Should().Be(HttpStatusCode.InternalServerError); error.Title.Should().Be("An unhandled error occurred while processing this request."); error.Detail.Should().Be("Exception has been thrown by the target of an invocation."); - - error.Meta.Should().ContainKey("stackTrace").WhoseValue.With(value => - { - JsonElement element = value.Should().BeOfType().Subject; - IEnumerable stackTraceLines = element.EnumerateArray().Select(token => token.GetString()); - - stackTraceLines.Should().ContainMatch("*ThrowingArticle*"); - }); + error.Meta.Should().HaveInStackTrace("*ThrowingArticle*"); responseDocument.Meta.Should().BeNull(); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/NamingConventions/PascalCasingTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/NamingConventions/PascalCasingTests.cs index 1b630cdc92..9da9e4e520 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/NamingConventions/PascalCasingTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/NamingConventions/PascalCasingTests.cs @@ -1,5 +1,4 @@ using System.Net; -using System.Text.Json; using FluentAssertions; using JsonApiDotNetCore.Serialization.Objects; using TestBuildingBlocks; @@ -58,11 +57,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => responseDocument.Included[0].Relationships.Should().BeNull(); responseDocument.Included[0].Links.RefShould().NotBeNull().And.Subject.Self.Should().Be(link); - responseDocument.Meta.Should().ContainKey("Total").WhoseValue.With(value => - { - JsonElement element = value.Should().BeOfType().Subject; - element.GetInt32().Should().Be(2); - }); + responseDocument.Meta.Should().ContainTotal(2, "Total"); } [Fact] diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Creating/CreateResourceTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Creating/CreateResourceTests.cs index de1623fb12..004fcb2121 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Creating/CreateResourceTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Creating/CreateResourceTests.cs @@ -288,7 +288,7 @@ public async Task Cannot_create_resource_with_unknown_attribute() error.Detail.Should().Be("Attribute 'doesNotExist' does not exist on resource type 'workItems'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/attributes/doesNotExist"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -375,7 +375,7 @@ public async Task Cannot_create_resource_with_unknown_relationship() error.Detail.Should().Be("Relationship 'doesNotExist' does not exist on resource type 'workItems'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/doesNotExist"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -460,7 +460,7 @@ public async Task Cannot_create_resource_with_client_generated_ID() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/id"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -511,7 +511,7 @@ public async Task Cannot_create_resource_for_null_request_body() error.Title.Should().Be("Failed to deserialize request body: Expected an object, instead of 'null'."); error.Detail.Should().BeNull(); error.Source.Should().BeNull(); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -541,7 +541,7 @@ public async Task Cannot_create_resource_for_missing_data() error.Title.Should().Be("Failed to deserialize request body: The 'data' element is required."); error.Detail.Should().BeNull(); error.Source.Should().BeNull(); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -569,7 +569,7 @@ public async Task Cannot_create_resource_for_null_data() error.Title.Should().Be("Failed to deserialize request body: Expected an object, instead of 'null'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -603,7 +603,7 @@ public async Task Cannot_create_resource_for_array_data() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -636,7 +636,7 @@ public async Task Cannot_create_resource_for_missing_type() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -670,7 +670,7 @@ public async Task Cannot_create_resource_for_unknown_type() error.Detail.Should().Be($"Resource type '{Unknown.ResourceType}' does not exist."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -728,7 +728,7 @@ public async Task Cannot_create_on_resource_type_mismatch_between_url_and_body() error.Detail.Should().Be("Type 'rgbColors' is not convertible to type 'workItems'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -763,7 +763,7 @@ public async Task Cannot_create_resource_with_readonly_attribute() error.Detail.Should().Be("Attribute 'isDeprecated' on resource type 'workItemGroups' is read-only."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/attributes/isDeprecated"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -787,7 +787,7 @@ public async Task Cannot_create_resource_for_broken_JSON_request_body() error.Title.Should().Be("Failed to deserialize request body."); error.Detail.Should().StartWith("'{' is invalid after a property name."); error.Source.Should().BeNull(); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -822,7 +822,7 @@ public async Task Cannot_create_resource_with_incompatible_attribute_value() error.Detail.Should().Be("Failed to convert attribute 'dueAt' with value 'not-a-valid-time' of type 'String' to type 'Nullable'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/attributes/dueAt"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -959,6 +959,6 @@ public async Task Cannot_assign_attribute_with_blocked_capability() error.Detail.Should().Be("The attribute 'isImportant' on resource type 'workItems' cannot be assigned to."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/attributes/isImportant"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithClientGeneratedIdTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithClientGeneratedIdTests.cs index 5d8e5041c9..681dc034c2 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithClientGeneratedIdTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithClientGeneratedIdTests.cs @@ -338,7 +338,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Theory] @@ -381,7 +381,7 @@ public async Task Cannot_create_resource_with_client_generated_zero_guid_ID(Clie error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Theory] @@ -424,7 +424,7 @@ public async Task Cannot_create_resource_with_client_generated_empty_guid_ID(Cli error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Theory] @@ -519,7 +519,7 @@ public async Task Cannot_create_resource_with_client_generated_zero_long_ID(Clie error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Theory] @@ -563,7 +563,7 @@ public async Task Cannot_create_resource_with_client_generated_empty_long_ID(Cli error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Theory] diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToManyRelationshipTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToManyRelationshipTests.cs index ef2c3ee216..9323133ae1 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToManyRelationshipTests.cs @@ -362,7 +362,7 @@ public async Task Cannot_create_for_missing_relationship_type() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/subscribers/data[0]"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -407,7 +407,7 @@ public async Task Cannot_create_for_unknown_relationship_type() error.Detail.Should().Be($"Resource type '{Unknown.ResourceType}' does not exist."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/subscribers/data[0]/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -451,7 +451,7 @@ public async Task Cannot_create_for_missing_relationship_ID() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/subscribers/data[0]"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -560,7 +560,7 @@ public async Task Cannot_create_on_relationship_type_mismatch() error.Detail.Should().Be("Type 'rgbColors' is not convertible to type 'userAccounts' of relationship 'subscribers'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/subscribers/data[0]/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -663,7 +663,7 @@ public async Task Cannot_create_with_missing_data_in_OneToMany_relationship() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/subscribers"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -701,7 +701,7 @@ public async Task Cannot_create_with_null_data_in_ManyToMany_relationship() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/tags/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -741,7 +741,7 @@ public async Task Cannot_create_with_object_data_in_ManyToMany_relationship() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/tags/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -789,7 +789,7 @@ public async Task Cannot_create_resource_with_local_ID() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/lid"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -834,6 +834,6 @@ public async Task Cannot_assign_relationship_with_blocked_capability() error.Detail.Should().Be("The relationship 'items' on resource type 'workItemGroups' cannot be assigned to."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/items"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToOneRelationshipTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToOneRelationshipTests.cs index 362e9ec958..42c63fd357 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToOneRelationshipTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Creating/CreateResourceWithToOneRelationshipTests.cs @@ -337,7 +337,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/assignee"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -382,7 +382,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/assignee"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -435,7 +435,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/assignee/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -476,7 +476,7 @@ public async Task Cannot_create_for_missing_relationship_type() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/assignee/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -518,7 +518,7 @@ public async Task Cannot_create_for_unknown_relationship_type() error.Detail.Should().Be($"Resource type '{Unknown.ResourceType}' does not exist."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/assignee/data/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -559,7 +559,7 @@ public async Task Cannot_create_for_missing_relationship_ID() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/assignee/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -644,7 +644,7 @@ public async Task Cannot_create_on_relationship_type_mismatch() error.Detail.Should().Be("Type 'rgbColors' is not convertible to type 'userAccounts' of relationship 'assignee'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/assignee/data/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -760,7 +760,7 @@ public async Task Cannot_create_resource_with_local_ID() error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/lid"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -802,6 +802,6 @@ public async Task Cannot_assign_relationship_with_blocked_capability() error.Detail.Should().Be("The relationship 'group' on resource type 'workItems' cannot be assigned to."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/group"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Relationships/AddToToManyRelationshipTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Relationships/AddToToManyRelationshipTests.cs index e2f3c8933b..2da2983765 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Relationships/AddToToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Relationships/AddToToManyRelationshipTests.cs @@ -58,7 +58,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Title.Should().Be("Failed to deserialize request body: Only to-many relationships can be targeted through this endpoint."); error.Detail.Should().Be("Relationship 'assignee' is not a to-many relationship."); error.Source.Should().BeNull(); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -239,7 +239,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Title.Should().Be("Failed to deserialize request body: Expected an object, instead of 'null'."); error.Detail.Should().BeNull(); error.Source.Should().BeNull(); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -281,7 +281,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data[0]"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -324,7 +324,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be($"Resource type '{Unknown.ResourceType}' does not exist."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data[0]/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -366,7 +366,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data[0]"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -684,7 +684,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("Type 'userAccounts' is not convertible to type 'workTags' of relationship 'tags'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data[0]/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -802,7 +802,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Title.Should().Be("Failed to deserialize request body: The 'data' element is required."); error.Detail.Should().BeNull(); error.Source.Should().BeNull(); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -838,7 +838,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -876,7 +876,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1020,6 +1020,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Title.Should().Be("Failed to deserialize request body: Relationship cannot be added to."); error.Detail.Should().Be("The relationship 'items' on resource type 'workItemGroups' cannot be added to."); error.Source.Should().BeNull(); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs index c9b948ca34..c8499bb95e 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs @@ -69,7 +69,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Title.Should().Be("Failed to deserialize request body: Only to-many relationships can be targeted through this endpoint."); error.Detail.Should().Be("Relationship 'assignee' is not a to-many relationship."); error.Source.Should().BeNull(); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -351,7 +351,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Title.Should().Be("Failed to deserialize request body: Expected an object, instead of 'null'."); error.Detail.Should().BeNull(); error.Source.Should().BeNull(); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -394,7 +394,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data[0]"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -437,7 +437,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be($"Resource type '{Unknown.ResourceType}' does not exist."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data[0]/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -479,7 +479,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data[0]"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -797,7 +797,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("Type 'userAccounts' is not convertible to type 'workTags' of relationship 'tags'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data[0]/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -917,7 +917,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Title.Should().Be("Failed to deserialize request body: The 'data' element is required."); error.Detail.Should().BeNull(); error.Source.Should().BeNull(); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -953,7 +953,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -991,7 +991,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1138,7 +1138,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Title.Should().Be("Failed to deserialize request body: Relationship cannot be removed from."); error.Detail.Should().Be("The relationship 'items' on resource type 'workItemGroups' cannot be removed from."); error.Source.Should().BeNull(); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs index 7a8c0cfea1..5f4836cf24 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Relationships/ReplaceToManyRelationshipTests.cs @@ -268,7 +268,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Title.Should().Be("Failed to deserialize request body: Expected an object, instead of 'null'."); error.Detail.Should().BeNull(); error.Source.Should().BeNull(); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -310,7 +310,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data[0]"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -353,7 +353,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be($"Resource type '{Unknown.ResourceType}' does not exist."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data[0]/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -395,7 +395,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data[0]"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -710,7 +710,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("Type 'userAccounts' is not convertible to type 'workTags' of relationship 'tags'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data[0]/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -795,7 +795,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Title.Should().Be("Failed to deserialize request body: The 'data' element is required."); error.Detail.Should().BeNull(); error.Source.Should().BeNull(); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -831,7 +831,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -869,7 +869,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1099,6 +1099,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Title.Should().Be("Failed to deserialize request body: Relationship cannot be assigned."); error.Detail.Should().Be("The relationship 'items' on resource type 'workItemGroups' cannot be assigned to."); error.Source.Should().BeNull(); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Relationships/UpdateToOneRelationshipTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Relationships/UpdateToOneRelationshipTests.cs index e05fda291f..bff2522997 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Relationships/UpdateToOneRelationshipTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Relationships/UpdateToOneRelationshipTests.cs @@ -304,7 +304,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Title.Should().Be("Failed to deserialize request body: Expected an object, instead of 'null'."); error.Detail.Should().BeNull(); error.Source.Should().BeNull(); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -339,7 +339,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Title.Should().Be("Failed to deserialize request body: The 'data' element is required."); error.Detail.Should().BeNull(); error.Source.Should().BeNull(); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -383,7 +383,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -422,7 +422,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -462,7 +462,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be($"Resource type '{Unknown.ResourceType}' does not exist."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -501,7 +501,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -735,7 +735,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("Type 'rgbColors' is not convertible to type 'userAccounts' of relationship 'assignee'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -853,6 +853,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Title.Should().Be("Failed to deserialize request body: Relationship cannot be assigned."); error.Detail.Should().Be("The relationship 'group' on resource type 'workItems' cannot be assigned to."); error.Source.Should().BeNull(); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs index da33ab6dc5..f8317f14ec 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Resources/ReplaceToManyRelationshipTests.cs @@ -443,7 +443,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/subscribers/data[0]"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -497,7 +497,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be($"Resource type '{Unknown.ResourceType}' does not exist."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/subscribers/data[0]/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -550,7 +550,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/subscribers/data[0]"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -697,7 +697,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("Type 'rgbColors' is not convertible to type 'userAccounts' of relationship 'subscribers'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/subscribers/data[0]/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -805,7 +805,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/subscribers"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -852,7 +852,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/tags/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -901,7 +901,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/tags/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1183,6 +1183,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("The relationship 'items' on resource type 'workItemGroups' cannot be assigned to."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/items"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateResourceTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateResourceTests.cs index ee43e42a0d..428c4a30d3 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateResourceTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateResourceTests.cs @@ -125,7 +125,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("Attribute 'doesNotExist' does not exist on resource type 'userAccounts'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/attributes/doesNotExist"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -225,7 +225,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("Relationship 'doesNotExist' does not exist on resource type 'userAccounts'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/doesNotExist"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -706,7 +706,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Title.Should().Be("Failed to deserialize request body: Expected an object, instead of 'null'."); error.Detail.Should().BeNull(); error.Source.Should().BeNull(); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -744,7 +744,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Title.Should().Be("Failed to deserialize request body: The 'data' element is required."); error.Detail.Should().BeNull(); error.Source.Should().BeNull(); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -780,7 +780,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -823,7 +823,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -862,7 +862,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -902,7 +902,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be($"Resource type '{Unknown.ResourceType}' does not exist."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -941,7 +941,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1046,7 +1046,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("Type 'rgbColors' is not convertible to type 'workItems'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1086,7 +1086,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be($"Expected '{existingWorkItems[1].StringId}' instead of '{existingWorkItems[0].StringId}'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/id"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1130,7 +1130,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("Attribute 'isDeprecated' on resource type 'workItemGroups' is read-only."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/attributes/isDeprecated"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1162,7 +1162,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Title.Should().Be("Failed to deserialize request body."); error.Detail.Should().StartWith("Expected end of string, but instead reached end of data."); error.Source.Should().BeNull(); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1206,7 +1206,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/attributes/id"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1248,7 +1248,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Title.Should().Be("Failed to deserialize request body."); error.Detail.Should().Be($"Failed to convert ID '{existingWorkItem.Id}' of type 'Number' to type 'String'."); error.Source.Should().BeNull(); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1296,7 +1296,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Match("Failed to convert attribute 'dueAt' with value '*start*end*' of type 'Object' to type 'Nullable'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/attributes/dueAt"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -1544,6 +1544,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("The attribute 'isImportant' on resource type 'workItems' cannot be assigned to."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/attributes/isImportant"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateToOneRelationshipTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateToOneRelationshipTests.cs index bd0cbd1943..07fedff2ad 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateToOneRelationshipTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Resources/UpdateToOneRelationshipTests.cs @@ -480,7 +480,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/assignee"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -527,7 +527,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/assignee"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -582,7 +582,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/assignee/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -632,7 +632,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/assignee/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -683,7 +683,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be($"Resource type '{Unknown.ResourceType}' does not exist."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/assignee/data/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -733,7 +733,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().BeNull(); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/assignee/data"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -836,7 +836,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("Type 'rgbColors' is not convertible to type 'userAccounts' of relationship 'assignee'."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/assignee/data/type"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } [Fact] @@ -987,6 +987,6 @@ await _testContext.RunOnDatabaseAsync(async dbContext => error.Detail.Should().Be("The relationship 'group' on resource type 'workItems' cannot be assigned to."); error.Source.Should().NotBeNull(); error.Source.Pointer.Should().Be("/data/relationships/group"); - error.Meta.Should().ContainKey("requestBody").WhoseValue.Should().NotBeNull().And.Subject.ToString().Should().NotBeEmpty(); + error.Meta.Should().HaveRequestBody(); } } diff --git a/test/TestBuildingBlocks/FluentAssertionsExtensions.cs b/test/TestBuildingBlocks/FluentAssertionsExtensions.cs deleted file mode 100644 index 79e1ef7582..0000000000 --- a/test/TestBuildingBlocks/FluentAssertionsExtensions.cs +++ /dev/null @@ -1,49 +0,0 @@ -using FluentAssertions; -using FluentAssertions.Collections; -using FluentAssertions.Primitives; -using JetBrains.Annotations; -using SysNotNull = System.Diagnostics.CodeAnalysis.NotNullAttribute; - -// ReSharper disable UnusedMethodReturnValue.Global - -namespace TestBuildingBlocks; - -public static class FluentAssertionsExtensions -{ - // Workaround for source.Should().NotBeNull().And.Subject having declared type 'object'. - [System.Diagnostics.Contracts.Pure] - public static StrongReferenceTypeAssertions RefShould([SysNotNull] this T? actualValue) - where T : class - { - actualValue.Should().NotBeNull(); - return new StrongReferenceTypeAssertions(actualValue); - } - - public static AndConstraint OnlyContainKeys( - this GenericDictionaryAssertions source, params TKey[] expected) - where TCollection : IEnumerable> - where TAssertions : GenericDictionaryAssertions - { - return source.HaveCount(expected.Length).And.ContainKeys(expected); - } - - // Workaround for CS0854: An expression tree may not contain a call or invocation that uses optional arguments. - public static WhoseValueConstraint ContainKey2( - this GenericDictionaryAssertions source, TKey expected) - where TCollection : IEnumerable> - where TAssertions : GenericDictionaryAssertions - { - return source.ContainKey(expected); - } - - public static void With(this T subject, [InstantHandle] Action continuation) - { - continuation(subject); - } - - public sealed class StrongReferenceTypeAssertions(TReference subject) - : ReferenceTypeAssertions>(subject) - { - protected override string Identifier => "subject"; - } -} diff --git a/test/TestBuildingBlocks/ObjectAssertionsExtensions.cs b/test/TestBuildingBlocks/FluentExtensions.cs similarity index 57% rename from test/TestBuildingBlocks/ObjectAssertionsExtensions.cs rename to test/TestBuildingBlocks/FluentExtensions.cs index 47e08b69f1..1061a71765 100644 --- a/test/TestBuildingBlocks/ObjectAssertionsExtensions.cs +++ b/test/TestBuildingBlocks/FluentExtensions.cs @@ -6,11 +6,13 @@ using FluentAssertions.Numeric; using FluentAssertions.Primitives; using JetBrains.Annotations; +using SysNotNull = System.Diagnostics.CodeAnalysis.NotNullAttribute; + +// ReSharper disable UnusedMethodReturnValue.Global namespace TestBuildingBlocks; -[PublicAPI] -public static class ObjectAssertionsExtensions +public static class FluentExtensions { private const decimal NumericPrecision = 0.00000000001M; @@ -69,12 +71,40 @@ private static string ToJsonString(JsonDocument document) return Encoding.UTF8.GetString(stream.ToArray()); } - /// - /// Asserts that a "meta" dictionary contains a single element named "total" with the specified value. - /// - [CustomAssertion] - public static void ContainTotal(this GenericDictionaryAssertions, string, object?> source, int expectedTotal) + // Workaround for source.Should().NotBeNull().And.Subject having declared type 'object'. + [System.Diagnostics.Contracts.Pure] + public static StrongReferenceTypeAssertions RefShould([SysNotNull] this T? actualValue) + where T : class + { + actualValue.Should().NotBeNull(); + return new StrongReferenceTypeAssertions(actualValue); + } + + public static AndConstraint OnlyContainKeys( + this GenericDictionaryAssertions source, params TKey[] expected) + where TCollection : IEnumerable> + where TAssertions : GenericDictionaryAssertions + { + return source.HaveCount(expected.Length).And.ContainKeys(expected); + } + + // Workaround for CS0854: An expression tree may not contain a call or invocation that uses optional arguments. + public static WhoseValueConstraint ContainKey2( + this GenericDictionaryAssertions source, TKey expected) + where TCollection : IEnumerable> + where TAssertions : GenericDictionaryAssertions + { + return source.ContainKey(expected); + } + + public static void With(this T subject, [InstantHandle] Action continuation) + { + continuation(subject); + } + + public sealed class StrongReferenceTypeAssertions(TReference subject) + : ReferenceTypeAssertions>(subject) { - source.ContainKey("total").WhoseValue.Should().BeOfType().Subject.GetInt32().Should().Be(expectedTotal); + protected override string Identifier => "subject"; } } diff --git a/test/TestBuildingBlocks/FluentMetaExtensions.cs b/test/TestBuildingBlocks/FluentMetaExtensions.cs new file mode 100644 index 0000000000..ff81bb47f0 --- /dev/null +++ b/test/TestBuildingBlocks/FluentMetaExtensions.cs @@ -0,0 +1,69 @@ +using System.Text.Json; +using FluentAssertions; +using FluentAssertions.Collections; + +namespace TestBuildingBlocks; + +public static class FluentMetaExtensions +{ + /// + /// Asserts that a "meta" dictionary contains a single element named "total" with the specified value. + /// + [CustomAssertion] +#pragma warning disable AV1553 // Do not use optional parameters with default value null for strings, collections or tasks + public static void ContainTotal(this GenericDictionaryAssertions, string, object?> source, int expected, + string? keyName = null) +#pragma warning restore AV1553 // Do not use optional parameters with default value null for strings, collections or tasks + { + JsonElement element = GetMetaJsonElement(source, keyName ?? "total"); + element.GetInt32().Should().Be(expected); + } + + /// + /// Asserts that a "meta" dictionary contains a single element named "requestBody" that isn't empty. + /// + [CustomAssertion] + public static void HaveRequestBody(this GenericDictionaryAssertions, string, object?> source) + { + JsonElement element = GetMetaJsonElement(source, "requestBody"); + element.ToString().Should().NotBeEmpty(); + } + + /// + /// Asserts that a "meta" dictionary contains a single element named "requestBody" with the specified value. + /// + [CustomAssertion] + public static void ContainRequestBody(this GenericDictionaryAssertions, string, object?> source, string expected) + { + JsonElement element = GetMetaJsonElement(source, "requestBody"); + element.GetString().Should().Be(expected); + } + + /// + /// Asserts that a "meta" dictionary contains a single element named "stackTrace" that isn't empty. + /// + [CustomAssertion] + public static void HaveStackTrace(this GenericDictionaryAssertions, string, object?> source) + { + JsonElement element = GetMetaJsonElement(source, "stackTrace"); + IEnumerable stackTraceLines = element.EnumerateArray().Select(token => token.GetString()); + stackTraceLines.Should().NotBeEmpty(); + } + + /// + /// Asserts that a "meta" dictionary contains a single element named "stackTrace" that contains the specified pattern. + /// + [CustomAssertion] + public static void HaveInStackTrace(this GenericDictionaryAssertions, string, object?> source, string pattern) + { + JsonElement element = GetMetaJsonElement(source, "stackTrace"); + IEnumerable stackTraceLines = element.EnumerateArray().Select(token => token.GetString()); + stackTraceLines.Should().ContainMatch(pattern); + } + + private static JsonElement GetMetaJsonElement(GenericDictionaryAssertions, string, object?> source, string metaKey) + { + object? value = source.ContainKey(metaKey).WhoseValue; + return value.Should().BeOfType().Subject; + } +}