Skip to content

Commit 2d7f8b9

Browse files
committed
Centralize code for property assignment in tests
1 parent dcdf5a5 commit 2d7f8b9

File tree

10 files changed

+161
-192
lines changed

10 files changed

+161
-192
lines changed

test/OpenApiClientTests/BaseOpenApiClientTests.cs

+66
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using System.Linq.Expressions;
2+
using System.Reflection;
3+
using JsonApiDotNetCore.OpenApi.Client;
24

35
namespace OpenApiClientTests;
46

@@ -17,4 +19,68 @@ public abstract class BaseOpenApiClientTests
1719

1820
return Expression.Lambda<Func<TAttributesObject, object?>>(toObjectConversion, parameter);
1921
}
22+
23+
/// <summary>
24+
/// Sets the property on the specified source to its default value (null for string, 0 for int, false for bool, etc).
25+
/// </summary>
26+
protected static void SetPropertyToDefaultValue<T>(T source, string propertyName)
27+
where T : class
28+
{
29+
ArgumentGuard.NotNull(source);
30+
ArgumentGuard.NotNull(propertyName);
31+
32+
PropertyInfo property = GetExistingProperty(typeof(T), propertyName);
33+
34+
object? defaultValue = property.PropertyType.IsValueType ? Activator.CreateInstance(property.PropertyType) : null;
35+
property.SetValue(source, defaultValue);
36+
}
37+
38+
/// <summary>
39+
/// Sets the property on the specified source to its initial value, when the type was constructed. This takes the presence of a type initializer into
40+
/// account.
41+
/// </summary>
42+
protected static void SetPropertyToInitialValue<T>(T source, string propertyName)
43+
where T : class, new()
44+
{
45+
ArgumentGuard.NotNull(source);
46+
ArgumentGuard.NotNull(propertyName);
47+
48+
var emptyRelationshipsObject = new T();
49+
object? defaultValue = emptyRelationshipsObject.GetPropertyValue(propertyName);
50+
51+
source.SetPropertyValue(propertyName, defaultValue);
52+
}
53+
54+
/// <summary>
55+
/// Sets the 'Data' property of the specified relationship to <c>null</c>.
56+
/// </summary>
57+
protected static void SetDataPropertyToNull<T>(T source, string relationshipPropertyName)
58+
where T : class
59+
{
60+
ArgumentGuard.NotNull(source);
61+
ArgumentGuard.NotNull(relationshipPropertyName);
62+
63+
PropertyInfo relationshipProperty = GetExistingProperty(typeof(T), relationshipPropertyName);
64+
object? relationshipValue = relationshipProperty.GetValue(source);
65+
66+
if (relationshipValue == null)
67+
{
68+
throw new InvalidOperationException($"Property '{typeof(T).Name}.{relationshipPropertyName}' is null.");
69+
}
70+
71+
PropertyInfo dataProperty = GetExistingProperty(relationshipProperty.PropertyType, "Data");
72+
dataProperty.SetValue(relationshipValue, null);
73+
}
74+
75+
private static PropertyInfo GetExistingProperty(Type type, string propertyName)
76+
{
77+
PropertyInfo? property = type.GetProperty(propertyName);
78+
79+
if (property == null)
80+
{
81+
throw new InvalidOperationException($"Type '{type.Name}' does not contain a property named '{propertyName}'.");
82+
}
83+
84+
return property;
85+
}
2086
}

test/OpenApiClientTests/ObjectExtensions.cs

-9
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,6 @@ public static void SetPropertyValue(this object source, string propertyName, obj
2323
propertyInfo.SetValue(source, value);
2424
}
2525

26-
public static object? GetDefaultValueForProperty(this object source, string propertyName)
27-
{
28-
ArgumentGuard.NotNull(source);
29-
ArgumentGuard.NotNull(propertyName);
30-
31-
PropertyInfo propertyInfo = GetExistingProperty(source.GetType(), propertyName);
32-
return propertyInfo.PropertyType.IsValueType ? Activator.CreateInstance(propertyInfo.PropertyType) : null;
33-
}
34-
3526
private static PropertyInfo GetExistingProperty(Type type, string propertyName)
3627
{
3728
PropertyInfo? propertyInfo = type.GetProperty(propertyName);

test/OpenApiClientTests/ResourceFieldValidation/NullableReferenceTypesOff/ModelStateValidationOff/CreateResourceTests.cs

+14-28
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ namespace OpenApiClientTests.ResourceFieldValidation.NullableReferenceTypesOff.M
1212

1313
public sealed class CreateResourceTests : BaseOpenApiClientTests
1414
{
15-
private const string DataPropertyName = "Data";
1615
private readonly NrtOffMsvOffFakers _fakers = new();
1716

1817
[Theory]
@@ -38,7 +37,7 @@ public async Task Can_clear_attribute(string attributePropertyName, string jsonP
3837
}
3938
};
4039

41-
requestDocument.Data.Attributes.SetPropertyValue(attributePropertyName, null);
40+
SetPropertyToDefaultValue(requestDocument.Data.Attributes, attributePropertyName);
4241

4342
using var wrapper = FakeHttpClientWrapper.Create(HttpStatusCode.NoContent, null);
4443
var apiClient = new NrtOffMsvOffClient(wrapper.HttpClient);
@@ -81,8 +80,7 @@ public async Task Can_set_attribute_to_default_value(string attributePropertyNam
8180
}
8281
};
8382

84-
object? defaultValue = requestDocument.Data.Attributes.GetDefaultValueForProperty(attributePropertyName);
85-
requestDocument.Data.Attributes.SetPropertyValue(attributePropertyName, defaultValue);
83+
SetPropertyToDefaultValue(requestDocument.Data.Attributes, attributePropertyName);
8684

8785
using var wrapper = FakeHttpClientWrapper.Create(HttpStatusCode.NoContent, null);
8886
var apiClient = new NrtOffMsvOffClient(wrapper.HttpClient);
@@ -108,7 +106,7 @@ public async Task Can_set_attribute_to_default_value(string attributePropertyNam
108106
[InlineData(nameof(ResourceAttributesInPostRequest.ReferenceType), "referenceType")]
109107
[InlineData(nameof(ResourceAttributesInPostRequest.ValueType), "valueType")]
110108
[InlineData(nameof(ResourceAttributesInPostRequest.NullableValueType), "nullableValueType")]
111-
public async Task Can_exclude_attribute(string attributePropertyName, string jsonPropertyName)
109+
public async Task Can_omit_attribute(string attributePropertyName, string jsonPropertyName)
112110
{
113111
// Arrange
114112
var requestDocument = new ResourcePostRequestDocument
@@ -126,9 +124,7 @@ public async Task Can_exclude_attribute(string attributePropertyName, string jso
126124
}
127125
};
128126

129-
ResourceAttributesInPostRequest emptyAttributesObject = new();
130-
object? defaultValue = emptyAttributesObject.GetPropertyValue(attributePropertyName);
131-
requestDocument.Data.Attributes.SetPropertyValue(attributePropertyName, defaultValue);
127+
SetPropertyToInitialValue(requestDocument.Data.Attributes, attributePropertyName);
132128

133129
using var wrapper = FakeHttpClientWrapper.Create(HttpStatusCode.NoContent, null);
134130
var apiClient = new NrtOffMsvOffClient(wrapper.HttpClient);
@@ -151,7 +147,7 @@ public async Task Can_exclude_attribute(string attributePropertyName, string jso
151147
[InlineData(nameof(ResourceAttributesInPostRequest.RequiredReferenceType), "requiredReferenceType")]
152148
[InlineData(nameof(ResourceAttributesInPostRequest.RequiredValueType), "requiredValueType")]
153149
[InlineData(nameof(ResourceAttributesInPostRequest.RequiredNullableValueType), "requiredNullableValueType")]
154-
public async Task Cannot_exclude_attribute(string attributePropertyName, string jsonPropertyName)
150+
public async Task Cannot_omit_attribute(string attributePropertyName, string jsonPropertyName)
155151
{
156152
// Arrange
157153
var requestDocument = new ResourcePostRequestDocument
@@ -169,9 +165,7 @@ public async Task Cannot_exclude_attribute(string attributePropertyName, string
169165
}
170166
};
171167

172-
ResourceAttributesInPostRequest emptyAttributesObject = new();
173-
object? defaultValue = emptyAttributesObject.GetPropertyValue(attributePropertyName);
174-
requestDocument.Data.Attributes.SetPropertyValue(attributePropertyName, defaultValue);
168+
SetPropertyToInitialValue(requestDocument.Data.Attributes, attributePropertyName);
175169

176170
using var wrapper = FakeHttpClientWrapper.Create(HttpStatusCode.NoContent, null);
177171
var apiClient = new NrtOffMsvOffClient(wrapper.HttpClient);
@@ -210,8 +204,7 @@ public async Task Can_clear_relationship_with_partial_attribute_serialization(st
210204
}
211205
};
212206

213-
object? relationshipObject = requestDocument.Data.Relationships.GetPropertyValue(relationshipPropertyName);
214-
relationshipObject!.SetPropertyValue(DataPropertyName, null);
207+
SetDataPropertyToNull(requestDocument.Data.Relationships, relationshipPropertyName);
215208

216209
using var wrapper = FakeHttpClientWrapper.Create(HttpStatusCode.NoContent, null);
217210
var apiClient = new NrtOffMsvOffClient(wrapper.HttpClient);
@@ -251,8 +244,7 @@ public async Task Can_clear_relationship_without_partial_attribute_serialization
251244
}
252245
};
253246

254-
object? relationshipObject = requestDocument.Data.Relationships.GetPropertyValue(relationshipPropertyName);
255-
relationshipObject!.SetPropertyValue(DataPropertyName, null);
247+
SetDataPropertyToNull(requestDocument.Data.Relationships, relationshipPropertyName);
256248

257249
using var wrapper = FakeHttpClientWrapper.Create(HttpStatusCode.NoContent, null);
258250
var apiClient = new NrtOffMsvOffClient(wrapper.HttpClient);
@@ -290,8 +282,7 @@ public async Task Cannot_clear_relationship_with_partial_attribute_serialization
290282
}
291283
};
292284

293-
object? relationshipObject = requestDocument.Data.Relationships.GetPropertyValue(relationshipPropertyName);
294-
relationshipObject!.SetPropertyValue(DataPropertyName, null);
285+
SetDataPropertyToNull(requestDocument.Data.Relationships, relationshipPropertyName);
295286

296287
using var wrapper = FakeHttpClientWrapper.Create(HttpStatusCode.NoContent, null);
297288
var apiClient = new NrtOffMsvOffClient(wrapper.HttpClient);
@@ -330,8 +321,7 @@ public async Task Cannot_clear_relationship_without_partial_attribute_serializat
330321
}
331322
};
332323

333-
object? relationshipObject = requestDocument.Data.Relationships.GetPropertyValue(relationshipPropertyName);
334-
relationshipObject!.SetPropertyValue(DataPropertyName, null);
324+
SetDataPropertyToNull(requestDocument.Data.Relationships, relationshipPropertyName);
335325

336326
using var wrapper = FakeHttpClientWrapper.Create(HttpStatusCode.NoContent, null);
337327
var apiClient = new NrtOffMsvOffClient(wrapper.HttpClient);
@@ -350,7 +340,7 @@ public async Task Cannot_clear_relationship_without_partial_attribute_serializat
350340
[Theory]
351341
[InlineData(nameof(ResourceRelationshipsInPostRequest.ToOne), "toOne")]
352342
[InlineData(nameof(ResourceRelationshipsInPostRequest.ToMany), "toMany")]
353-
public async Task Can_exclude_relationship_with_partial_attribute_serialization(string relationshipPropertyName, string jsonPropertyName)
343+
public async Task Can_omit_relationship_with_partial_attribute_serialization(string relationshipPropertyName, string jsonPropertyName)
354344
{
355345
// Arrange
356346
var requestDocument = new ResourcePostRequestDocument
@@ -368,9 +358,7 @@ public async Task Can_exclude_relationship_with_partial_attribute_serialization(
368358
}
369359
};
370360

371-
ResourceRelationshipsInPostRequest emptyRelationshipsObject = new();
372-
object? defaultValue = emptyRelationshipsObject.GetPropertyValue(relationshipPropertyName);
373-
requestDocument.Data.Relationships.SetPropertyValue(relationshipPropertyName, defaultValue);
361+
SetPropertyToInitialValue(requestDocument.Data.Relationships, relationshipPropertyName);
374362

375363
using var wrapper = FakeHttpClientWrapper.Create(HttpStatusCode.NoContent, null);
376364
var apiClient = new NrtOffMsvOffClient(wrapper.HttpClient);
@@ -392,7 +380,7 @@ public async Task Can_exclude_relationship_with_partial_attribute_serialization(
392380
[Theory]
393381
[InlineData(nameof(ResourceRelationshipsInPostRequest.ToOne), "toOne")]
394382
[InlineData(nameof(ResourceRelationshipsInPostRequest.ToMany), "toMany")]
395-
public async Task Can_exclude_relationship_without_partial_attribute_serialization(string relationshipPropertyName, string jsonPropertyName)
383+
public async Task Can_omit_relationship_without_partial_attribute_serialization(string relationshipPropertyName, string jsonPropertyName)
396384
{
397385
// Arrange
398386
var requestDocument = new ResourcePostRequestDocument
@@ -410,9 +398,7 @@ public async Task Can_exclude_relationship_without_partial_attribute_serializati
410398
}
411399
};
412400

413-
ResourceRelationshipsInPostRequest emptyRelationshipsObject = new();
414-
object? defaultValue = emptyRelationshipsObject.GetPropertyValue(relationshipPropertyName);
415-
requestDocument.Data.Relationships.SetPropertyValue(relationshipPropertyName, defaultValue);
401+
SetPropertyToInitialValue(requestDocument.Data.Relationships, relationshipPropertyName);
416402

417403
using var wrapper = FakeHttpClientWrapper.Create(HttpStatusCode.NoContent, null);
418404
var apiClient = new NrtOffMsvOffClient(wrapper.HttpClient);

test/OpenApiClientTests/ResourceFieldValidation/NullableReferenceTypesOff/ModelStateValidationOff/UpdateResourceTests.cs

+6-11
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,18 @@
99

1010
namespace OpenApiClientTests.ResourceFieldValidation.NullableReferenceTypesOff.ModelStateValidationOff;
1111

12-
public sealed class UpdateResourceTests
12+
public sealed class UpdateResourceTests : BaseOpenApiClientTests
1313
{
1414
private readonly NrtOffMsvOffFakers _fakers = new();
1515

1616
[Fact]
17-
public async Task Cannot_exclude_Id()
17+
public async Task Cannot_omit_Id()
1818
{
1919
// Arrange
2020
var requestDocument = new ResourcePatchRequestDocument
2121
{
2222
Data = new ResourceDataInPatchRequest
2323
{
24-
Id = null,
2524
Attributes = _fakers.PatchAttributes.Generate(),
2625
Relationships = new ResourceRelationshipsInPatchRequest
2726
{
@@ -53,7 +52,7 @@ public async Task Cannot_exclude_Id()
5352
[InlineData(nameof(ResourceAttributesInPatchRequest.RequiredValueType), "requiredValueType")]
5453
[InlineData(nameof(ResourceAttributesInPatchRequest.NullableValueType), "nullableValueType")]
5554
[InlineData(nameof(ResourceAttributesInPatchRequest.RequiredNullableValueType), "requiredNullableValueType")]
56-
public async Task Can_exclude_attribute(string attributePropertyName, string jsonPropertyName)
55+
public async Task Can_omit_attribute(string attributePropertyName, string jsonPropertyName)
5756
{
5857
// Arrange
5958
var requestDocument = new ResourcePatchRequestDocument
@@ -72,9 +71,7 @@ public async Task Can_exclude_attribute(string attributePropertyName, string jso
7271
}
7372
};
7473

75-
ResourceAttributesInPatchRequest emptyAttributesObject = new();
76-
object? defaultValue = emptyAttributesObject.GetPropertyValue(attributePropertyName);
77-
requestDocument.Data.Attributes.SetPropertyValue(attributePropertyName, defaultValue);
74+
SetPropertyToInitialValue(requestDocument.Data.Attributes, attributePropertyName);
7875

7976
using var wrapper = FakeHttpClientWrapper.Create(HttpStatusCode.NoContent, null);
8077
var apiClient = new NrtOffMsvOffClient(wrapper.HttpClient);
@@ -98,7 +95,7 @@ public async Task Can_exclude_attribute(string attributePropertyName, string jso
9895
[InlineData(nameof(ResourceRelationshipsInPatchRequest.RequiredToOne), "requiredToOne")]
9996
[InlineData(nameof(ResourceRelationshipsInPatchRequest.ToMany), "toMany")]
10097
[InlineData(nameof(ResourceRelationshipsInPatchRequest.RequiredToMany), "requiredToMany")]
101-
public async Task Can_exclude_relationship(string relationshipPropertyName, string jsonPropertyName)
98+
public async Task Can_omit_relationship(string relationshipPropertyName, string jsonPropertyName)
10299
{
103100
// Arrange
104101
var requestDocument = new ResourcePatchRequestDocument
@@ -117,9 +114,7 @@ public async Task Can_exclude_relationship(string relationshipPropertyName, stri
117114
}
118115
};
119116

120-
ResourceRelationshipsInPatchRequest emptyRelationshipsObject = new();
121-
object? defaultValue = emptyRelationshipsObject.GetPropertyValue(relationshipPropertyName);
122-
requestDocument.Data.Relationships.SetPropertyValue(relationshipPropertyName, defaultValue);
117+
SetPropertyToInitialValue(requestDocument.Data.Relationships, relationshipPropertyName);
123118

124119
using var wrapper = FakeHttpClientWrapper.Create(HttpStatusCode.NoContent, null);
125120
var apiClient = new NrtOffMsvOffClient(wrapper.HttpClient);

0 commit comments

Comments
 (0)