Skip to content

Commit a824bd0

Browse files
authored
openapi: support client-generated id (#1475)
1 parent 54c401c commit a824bd0

File tree

9 files changed

+1561
-0
lines changed

9 files changed

+1561
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
using FluentAssertions;
2+
using FluentAssertions.Specialized;
3+
using JsonApiDotNetCore.OpenApi.Client;
4+
using Newtonsoft.Json;
5+
using OpenApiEndToEndTests.ClientIdGenerationModes.GeneratedCode;
6+
using OpenApiTests;
7+
using OpenApiTests.ClientIdGenerationModes;
8+
using TestBuildingBlocks;
9+
using Xunit;
10+
11+
namespace OpenApiEndToEndTests.ClientIdGenerationModes;
12+
13+
public sealed class ClientIdGenerationModesTests
14+
: IClassFixture<IntegrationTestContext<OpenApiStartup<ClientIdGenerationModesDbContext>, ClientIdGenerationModesDbContext>>
15+
{
16+
private readonly IntegrationTestContext<OpenApiStartup<ClientIdGenerationModesDbContext>, ClientIdGenerationModesDbContext> _testContext;
17+
private readonly ClientIdGenerationModesFakers _fakers = new();
18+
19+
public ClientIdGenerationModesTests(IntegrationTestContext<OpenApiStartup<ClientIdGenerationModesDbContext>, ClientIdGenerationModesDbContext> testContext)
20+
{
21+
_testContext = testContext;
22+
23+
testContext.UseController<PlayersController>();
24+
testContext.UseController<GamesController>();
25+
testContext.UseController<PlayerGroupsController>();
26+
}
27+
28+
[Fact]
29+
public async Task Cannot_create_resource_without_ID_when_supplying_ID_is_required()
30+
{
31+
// Arrange
32+
Player player = _fakers.Player.Generate();
33+
34+
using HttpClient httpClient = _testContext.Factory.CreateClient();
35+
ClientIdGenerationModesClient apiClient = new(httpClient);
36+
37+
// Act
38+
Func<Task<PlayerPrimaryResponseDocument?>> action = () => ApiResponse.TranslateAsync(() => apiClient.PostPlayerAsync(null, new PlayerPostRequestDocument
39+
{
40+
Data = new PlayerDataInPostRequest
41+
{
42+
Id = null!,
43+
Attributes = new PlayerAttributesInPostRequest
44+
{
45+
UserName = player.UserName
46+
}
47+
}
48+
}));
49+
50+
// Assert
51+
ExceptionAssertions<JsonSerializationException> assertion = await action.Should().ThrowExactlyAsync<JsonSerializationException>();
52+
assertion.Which.Message.Should().Be("Cannot write a null value for property 'id'. Property requires a value. Path 'data'.");
53+
}
54+
55+
[Fact]
56+
public async Task Can_create_resource_with_ID_when_supplying_ID_is_required()
57+
{
58+
// Arrange
59+
Player player = _fakers.Player.Generate();
60+
player.Id = Guid.NewGuid();
61+
62+
using HttpClient httpClient = _testContext.Factory.CreateClient();
63+
ClientIdGenerationModesClient apiClient = new(httpClient);
64+
65+
// Act
66+
PlayerPrimaryResponseDocument? document = await ApiResponse.TranslateAsync(() => apiClient.PostPlayerAsync(null, new PlayerPostRequestDocument
67+
{
68+
Data = new PlayerDataInPostRequest
69+
{
70+
Id = player.StringId!,
71+
Attributes = new PlayerAttributesInPostRequest
72+
{
73+
UserName = player.UserName
74+
}
75+
}
76+
}));
77+
78+
// Assert
79+
document.Should().BeNull();
80+
81+
await _testContext.RunOnDatabaseAsync(async dbContext =>
82+
{
83+
Player playerInDatabase = await dbContext.Players.FirstWithIdAsync(player.Id);
84+
85+
playerInDatabase.UserName.Should().Be(player.UserName);
86+
});
87+
}
88+
89+
[Fact]
90+
public async Task Can_create_resource_without_ID_when_supplying_ID_is_allowed()
91+
{
92+
// Arrange
93+
Game game = _fakers.Game.Generate();
94+
95+
using HttpClient httpClient = _testContext.Factory.CreateClient();
96+
ClientIdGenerationModesClient apiClient = new(httpClient);
97+
98+
// Act
99+
GamePrimaryResponseDocument? document = await ApiResponse.TranslateAsync(() => apiClient.PostGameAsync(null, new GamePostRequestDocument
100+
{
101+
Data = new GameDataInPostRequest
102+
{
103+
Id = null!,
104+
Attributes = new GameAttributesInPostRequest
105+
{
106+
Title = game.Title,
107+
PurchasePrice = (double)game.PurchasePrice
108+
}
109+
}
110+
}));
111+
112+
// Assert
113+
document.ShouldNotBeNull();
114+
document.Data.Id.Should().NotBeNullOrEmpty();
115+
116+
await _testContext.RunOnDatabaseAsync(async dbContext =>
117+
{
118+
Game gameInDatabase = await dbContext.Games.FirstWithIdAsync(Guid.Parse(document.Data.Id));
119+
120+
gameInDatabase.Title.Should().Be(game.Title);
121+
gameInDatabase.PurchasePrice.Should().Be(game.PurchasePrice);
122+
});
123+
}
124+
125+
[Fact]
126+
public async Task Can_create_resource_with_ID_when_supplying_ID_is_allowed()
127+
{
128+
// Arrange
129+
Game game = _fakers.Game.Generate();
130+
game.Id = Guid.NewGuid();
131+
132+
using HttpClient httpClient = _testContext.Factory.CreateClient();
133+
ClientIdGenerationModesClient apiClient = new(httpClient);
134+
135+
// Act
136+
GamePrimaryResponseDocument? document = await ApiResponse.TranslateAsync(() => apiClient.PostGameAsync(null, new GamePostRequestDocument
137+
{
138+
Data = new GameDataInPostRequest
139+
{
140+
Id = game.StringId!,
141+
Attributes = new GameAttributesInPostRequest
142+
{
143+
Title = game.Title,
144+
PurchasePrice = (double)game.PurchasePrice
145+
}
146+
}
147+
}));
148+
149+
// Assert
150+
document.Should().BeNull();
151+
152+
await _testContext.RunOnDatabaseAsync(async dbContext =>
153+
{
154+
Game gameInDatabase = await dbContext.Games.FirstWithIdAsync(game.Id);
155+
156+
gameInDatabase.Title.Should().Be(game.Title);
157+
gameInDatabase.PurchasePrice.Should().Be(game.PurchasePrice);
158+
});
159+
}
160+
161+
[Fact]
162+
public async Task Can_create_resource_without_ID_when_supplying_ID_is_forbidden()
163+
{
164+
// Arrange
165+
PlayerGroup playerGroup = _fakers.Group.Generate();
166+
167+
using HttpClient httpClient = _testContext.Factory.CreateClient();
168+
ClientIdGenerationModesClient apiClient = new(httpClient);
169+
170+
// Act
171+
PlayerGroupPrimaryResponseDocument? document = await ApiResponse.TranslateAsync(() => apiClient.PostPlayerGroupAsync(null,
172+
new PlayerGroupPostRequestDocument
173+
{
174+
Data = new PlayerGroupDataInPostRequest
175+
{
176+
Attributes = new PlayerGroupAttributesInPostRequest
177+
{
178+
Name = playerGroup.Name
179+
}
180+
}
181+
}));
182+
183+
// Assert
184+
document.ShouldNotBeNull();
185+
document.Data.Id.Should().NotBeNullOrEmpty();
186+
187+
await _testContext.RunOnDatabaseAsync(async dbContext =>
188+
{
189+
PlayerGroup playerGroupInDatabase = await dbContext.PlayerGroups.FirstWithIdAsync(long.Parse(document.Data.Id));
190+
191+
playerGroupInDatabase.Name.Should().Be(playerGroup.Name);
192+
});
193+
}
194+
}

0 commit comments

Comments
 (0)