Skip to content

Commit 07c9d7d

Browse files
committed
Improve NSwag tests
1 parent 9dee70f commit 07c9d7d

File tree

5 files changed

+176
-738
lines changed

5 files changed

+176
-738
lines changed

Diff for: test/OpenApiNSwagEndToEndTests/ModelValidation/ModelValidationTests.cs

+98-28
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
using TestBuildingBlocks;
99
using Xunit;
1010

11-
namespace OpenApiEndToEndTests.ModelValidation;
11+
namespace OpenApiNSwagEndToEndTests.ModelValidation;
1212

1313
public sealed class ModelValidationTests : IClassFixture<IntegrationTestContext<OpenApiStartup<ModelValidationDbContext>, ModelValidationDbContext>>
1414
{
@@ -26,7 +26,7 @@ public ModelValidationTests(IntegrationTestContext<OpenApiStartup<ModelValidatio
2626
public async Task Omitting_a_required_attribute_should_return_an_error()
2727
{
2828
using HttpClient httpClient = _testContext.Factory.CreateClient();
29-
var apiClient = new ModelValidationClient(httpClient);
29+
ModelValidationClient apiClient = new(httpClient);
3030

3131
// Act
3232
Func<Task<FingerprintPrimaryResponseDocument>> action = () => apiClient.PostFingerprintAsync(null, new FingerprintPostRequestDocument
@@ -47,13 +47,13 @@ public async Task Omitting_a_required_attribute_should_return_an_error()
4747
[Theory]
4848
[InlineData("ab")]
4949
[InlineData("abcdefghijklmnopqrs")]
50-
public async Task imbadathis(string userName)
50+
public async Task Not_fitting_the_length_constraint_should_return_an_error(string userName)
5151
{
5252
// Arrange
5353
Fingerprint fingerprint = _fakers.Fingerprint.Generate();
5454

5555
using HttpClient httpClient = _testContext.Factory.CreateClient();
56-
var apiClient = new ModelValidationClient(httpClient);
56+
ModelValidationClient apiClient = new(httpClient);
5757

5858
// Act
5959
Func<Task<FingerprintPrimaryResponseDocument>> action = () => apiClient.PostFingerprintAsync(null, new FingerprintPostRequestDocument
@@ -80,13 +80,13 @@ public async Task imbadathis(string userName)
8080
}
8181

8282
[Fact]
83-
public async Task imbadathis2()
83+
public async Task Not_matching_a_regex_should_return_an_error()
8484
{
8585
// Arrange
8686
Fingerprint fingerprint = _fakers.Fingerprint.Generate();
8787

8888
using HttpClient httpClient = _testContext.Factory.CreateClient();
89-
var apiClient = new ModelValidationClient(httpClient);
89+
ModelValidationClient apiClient = new(httpClient);
9090

9191
// Act
9292
Func<Task<FingerprintPrimaryResponseDocument>> action = () => apiClient.PostFingerprintAsync(null, new FingerprintPostRequestDocument
@@ -113,13 +113,13 @@ public async Task imbadathis2()
113113
}
114114

115115
[Fact]
116-
public async Task imbadathis3()
116+
public async Task Invalid_credit_card_should_return_an_error()
117117
{
118118
// Arrange
119119
Fingerprint fingerprint = _fakers.Fingerprint.Generate();
120120

121121
using HttpClient httpClient = _testContext.Factory.CreateClient();
122-
var apiClient = new ModelValidationClient(httpClient);
122+
ModelValidationClient apiClient = new(httpClient);
123123

124124
// Act
125125
Func<Task<FingerprintPrimaryResponseDocument>> action = () => apiClient.PostFingerprintAsync(null, new FingerprintPostRequestDocument
@@ -146,13 +146,13 @@ public async Task imbadathis3()
146146
}
147147

148148
[Fact]
149-
public async Task imbadathis5()
149+
public async Task Invalid_email_should_return_an_error()
150150
{
151151
// Arrange
152152
Fingerprint fingerprint = _fakers.Fingerprint.Generate();
153153

154154
using HttpClient httpClient = _testContext.Factory.CreateClient();
155-
var apiClient = new ModelValidationClient(httpClient);
155+
ModelValidationClient apiClient = new(httpClient);
156156

157157
// Act
158158
Func<Task<FingerprintPrimaryResponseDocument>> action = () => apiClient.PostFingerprintAsync(null, new FingerprintPostRequestDocument
@@ -181,13 +181,13 @@ public async Task imbadathis5()
181181
[Theory]
182182
[InlineData(-1)]
183183
[InlineData(124)]
184-
public async Task imbadathis6(int age)
184+
public async Task Out_of_range_integer_should_return_an_error(int age)
185185
{
186186
// Arrange
187187
Fingerprint fingerprint = _fakers.Fingerprint.Generate();
188188

189189
using HttpClient httpClient = _testContext.Factory.CreateClient();
190-
var apiClient = new ModelValidationClient(httpClient);
190+
ModelValidationClient apiClient = new(httpClient);
191191

192192
// Act
193193
Func<Task<FingerprintPrimaryResponseDocument>> action = () => apiClient.PostFingerprintAsync(null, new FingerprintPostRequestDocument
@@ -214,13 +214,13 @@ public async Task imbadathis6(int age)
214214
}
215215

216216
[Fact]
217-
public async Task imbadathis7()
217+
public async Task Invalid_url_should_return_an_error()
218218
{
219219
// Arrange
220220
Fingerprint fingerprint = _fakers.Fingerprint.Generate();
221221

222222
using HttpClient httpClient = _testContext.Factory.CreateClient();
223-
var apiClient = new ModelValidationClient(httpClient);
223+
ModelValidationClient apiClient = new(httpClient);
224224

225225
// Act
226226
Func<Task<FingerprintPrimaryResponseDocument>> action = () => apiClient.PostFingerprintAsync(null, new FingerprintPostRequestDocument
@@ -247,13 +247,13 @@ public async Task imbadathis7()
247247
}
248248

249249
[Fact]
250-
public async Task imbadathis8()
250+
public async Task Invalid_url_as_string_should_return_an_error()
251251
{
252252
// Arrange
253253
Fingerprint fingerprint = _fakers.Fingerprint.Generate();
254254

255255
using HttpClient httpClient = _testContext.Factory.CreateClient();
256-
var apiClient = new ModelValidationClient(httpClient);
256+
ModelValidationClient apiClient = new(httpClient);
257257

258258
// Act
259259
Func<Task<FingerprintPrimaryResponseDocument>> action = () => apiClient.PostFingerprintAsync(null, new FingerprintPostRequestDocument
@@ -263,7 +263,7 @@ public async Task imbadathis8()
263263
Attributes = new FingerprintAttributesInPostRequest
264264
{
265265
LastName = fingerprint.LastName,
266-
NextRevalidation = new OpenApiNSwagEndToEndTests.ModelValidation.GeneratedCode.TimeSpan { TotalSeconds = 1 }
266+
BackgroundPicture = new Uri("/justapath", UriKind.Relative)
267267
}
268268
}
269269
});
@@ -274,19 +274,52 @@ public async Task imbadathis8()
274274

275275
ErrorObject errorObject = document.Errors.First();
276276
errorObject.Title.Should().Be("Input validation failed.");
277-
errorObject.Detail.Should().Be("");
277+
errorObject.Detail.Should().Be("The BackgroundPicture field is not a valid fully-qualified http, https, or ftp URL.");
278+
errorObject.Source.ShouldNotBeNull();
279+
errorObject.Source.Pointer.Should().Be("/data/attributes/backgroundPicture");
280+
}
281+
282+
[Fact]
283+
public async Task Out_of_range_timespan_should_return_an_error()
284+
{
285+
// Arrange
286+
Fingerprint fingerprint = _fakers.Fingerprint.Generate();
287+
288+
using HttpClient httpClient = _testContext.Factory.CreateClient();
289+
ModelValidationClient apiClient = new(httpClient);
290+
291+
// Act
292+
Func<Task<FingerprintPrimaryResponseDocument>> action = () => apiClient.PostFingerprintAsync(null, new FingerprintPostRequestDocument
293+
{
294+
Data = new FingerprintDataInPostRequest
295+
{
296+
Attributes = new FingerprintAttributesInPostRequest
297+
{
298+
LastName = fingerprint.LastName,
299+
NextRevalidation = "00:00:01",
300+
}
301+
}
302+
});
303+
304+
// Assert
305+
ErrorResponseDocument document = (await action.Should().ThrowExactlyAsync<ApiException<ErrorResponseDocument>>()).Which.Result;
306+
document.Errors.ShouldHaveCount(1);
307+
308+
ErrorObject errorObject = document.Errors.First();
309+
errorObject.Title.Should().Be("Input validation failed.");
310+
errorObject.Detail.Should().Be("The field NextRevalidation must be between 01:00:00 and 05:00:00.");
278311
errorObject.Source.ShouldNotBeNull();
279312
errorObject.Source.Pointer.Should().Be("/data/attributes/nextRevalidation");
280313
}
281314

282315
[Fact]
283-
public async Task imbadathis10()
316+
public async Task Invalid_datetime_should_return_an_error()
284317
{
285318
// Arrange
286319
Fingerprint fingerprint = _fakers.Fingerprint.Generate();
287320

288321
using HttpClient httpClient = _testContext.Factory.CreateClient();
289-
var apiClient = new ModelValidationClient(httpClient);
322+
ModelValidationClient apiClient = new(httpClient);
290323

291324
// Act
292325
Func<Task<FingerprintPrimaryResponseDocument>> action = () => apiClient.PostFingerprintAsync(null, new FingerprintPostRequestDocument
@@ -313,13 +346,13 @@ public async Task imbadathis10()
313346
}
314347

315348
[Fact]
316-
public async Task imbadathis11()
349+
public async Task Invalid_date_should_return_an_error()
317350
{
318351
// Arrange
319352
Fingerprint fingerprint = _fakers.Fingerprint.Generate();
320353

321354
using HttpClient httpClient = _testContext.Factory.CreateClient();
322-
var apiClient = new ModelValidationClient(httpClient);
355+
ModelValidationClient apiClient = new(httpClient);
323356

324357
// Act
325358
Func<Task<FingerprintPrimaryResponseDocument>> action = () => apiClient.PostFingerprintAsync(null, new FingerprintPostRequestDocument
@@ -346,13 +379,13 @@ public async Task imbadathis11()
346379
}
347380

348381
[Fact]
349-
public async Task imbadathis9()
382+
public async Task Invalid_time_only_should_return_an_error()
350383
{
351384
// Arrange
352385
Fingerprint fingerprint = _fakers.Fingerprint.Generate();
353386

354387
using HttpClient httpClient = _testContext.Factory.CreateClient();
355-
var apiClient = new ModelValidationClient(httpClient);
388+
ModelValidationClient apiClient = new(httpClient);
356389

357390
// Act
358391
Func<Task<FingerprintPrimaryResponseDocument>> action = () => apiClient.PostFingerprintAsync(null, new FingerprintPostRequestDocument
@@ -362,7 +395,7 @@ public async Task imbadathis9()
362395
Attributes = new FingerprintAttributesInPostRequest
363396
{
364397
LastName = fingerprint.LastName,
365-
ValidatedTimeAt = System.TimeSpan.FromSeconds(-1)
398+
ValidatedTimeAt = TimeSpan.FromSeconds(-1)
366399
}
367400
}
368401
});
@@ -372,9 +405,46 @@ public async Task imbadathis9()
372405
document.Errors.ShouldHaveCount(1);
373406

374407
ErrorObject errorObject = document.Errors.First();
375-
errorObject.Title.Should().Be("Input validation failed.");
376-
errorObject.Detail.Should().Be("");
408+
errorObject.Title.Should().Be("Failed to deserialize request body: Incompatible attribute value found.");
409+
errorObject.Detail.Should().Be("Failed to convert attribute 'validatedTimeAt' with value '-00:00:01' of type 'String' to type 'Nullable<TimeOnly>'.");
377410
errorObject.Source.ShouldNotBeNull();
378-
errorObject.Source.Pointer.Should().Be("/data/attributes/");
411+
errorObject.Source.Pointer.Should().Be("/data/attributes/validatedTimeAt");
412+
}
413+
414+
[Fact]
415+
public async Task Fitting_all_the_constraints_should_work()
416+
{
417+
// Arrange
418+
Fingerprint fingerprint = _fakers.Fingerprint.Generate();
419+
420+
using HttpClient httpClient = _testContext.Factory.CreateClient();
421+
ModelValidationClient apiClient = new(httpClient);
422+
423+
// Act
424+
Func<Task<FingerprintPrimaryResponseDocument>> action = () => apiClient.PostFingerprintAsync(null, new FingerprintPostRequestDocument
425+
{
426+
Data = new FingerprintDataInPostRequest
427+
{
428+
Attributes = new FingerprintAttributesInPostRequest
429+
{
430+
FirstName = fingerprint.FirstName,
431+
LastName = fingerprint.LastName,
432+
UserName = fingerprint.UserName,
433+
CreditCard = fingerprint.CreditCard,
434+
Email = fingerprint.Email,
435+
Phone = fingerprint.Phone,
436+
Age = fingerprint.Age,
437+
ProfilePicture = fingerprint.ProfilePicture,
438+
BackgroundPicture = new Uri(fingerprint.BackgroundPicture!),
439+
NextRevalidation = "02:00:00",
440+
ValidatedAt = fingerprint.ValidatedAt!.Value.ToUniversalTime(),
441+
// TODO: ValidatedDateAt = new DateTimeOffset(fingerprint.ValidatedDateAt!.Value.ToDateTime(new TimeOnly()).ToUniversalTime()),
442+
ValidatedTimeAt = fingerprint.ValidatedTimeAt!.Value.ToTimeSpan()
443+
}
444+
}
445+
});
446+
447+
// Assert
448+
await action.Should().NotThrowAsync();
379449
}
380450
}

Diff for: test/OpenApiTests/ModelValidation/Fingerprint.cs

+5-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
namespace OpenApiTests.ModelValidation;
88

99
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
10-
[Resource(ControllerNamespace = "OpenApiTests.ModelValidation", GenerateControllerEndpoints = JsonApiEndpoints.Post)]
10+
[Resource(ControllerNamespace = "OpenApiTests.ModelValidation", GenerateControllerEndpoints = JsonApiEndpoints.Post | JsonApiEndpoints.Patch)]
1111
public sealed class Fingerprint : Identifiable<Guid>
1212
{
1313
[Attr]
@@ -39,9 +39,12 @@ public sealed class Fingerprint : Identifiable<Guid>
3939
public int? Age { get; set; }
4040

4141
[Attr]
42-
[Url]
4342
public Uri? ProfilePicture { get; set; }
4443

44+
[Attr]
45+
[Url]
46+
public string? BackgroundPicture { get; set; }
47+
4548
[Attr]
4649
[Range(typeof(TimeSpan), "01:00", "05:00")]
4750
public TimeSpan? NextRevalidation { get; set; }

0 commit comments

Comments
 (0)