Skip to content

Commit 8534691

Browse files
committed
test(post): can create entities with client generated ids
1 parent 9c38749 commit 8534691

File tree

2 files changed

+153
-9
lines changed

2 files changed

+153
-9
lines changed

test/JsonApiDotNetCoreExampleTests/Acceptance/Spec/CreatingDataTests.cs

Lines changed: 107 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
using System.Collections.Generic;
1818
using System.Linq;
1919
using Microsoft.EntityFrameworkCore;
20+
using JsonApiDotNetCoreExampleTests.Startups;
21+
using System;
2022

2123
namespace JsonApiDotNetCoreExampleTests.Acceptance.Spec
2224
{
@@ -37,7 +39,7 @@ public CreatingDataTests(DocsFixture<Startup, JsonDocWriter> fixture)
3739
}
3840

3941
[Fact]
40-
public async Task Can_Create_Guid_Identifiable_Entities()
42+
public async Task Can_Create_Guid_Identifiable_Entity()
4143
{
4244
// arrange
4345
var builder = new WebHostBuilder()
@@ -74,7 +76,7 @@ public async Task Can_Create_Guid_Identifiable_Entities()
7476
};
7577
request.Content = new StringContent(JsonConvert.SerializeObject(content));
7678
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.api+json");
77-
79+
7880
// act
7981
var response = await client.SendAsync(request);
8082

@@ -83,9 +85,10 @@ public async Task Can_Create_Guid_Identifiable_Entities()
8385
}
8486

8587
[Fact]
86-
public async Task Request_With_ClientGeneratedId_Returns_403()
88+
public async Task Cannot_Create_Entity_With_Client_Generate_Id()
8789
{
8890
// arrange
91+
var context = _fixture.GetService<AppDbContext>();
8992
var builder = new WebHostBuilder()
9093
.UseStartup<Startup>();
9194
var httpMethod = new HttpMethod("POST");
@@ -94,29 +97,124 @@ public async Task Request_With_ClientGeneratedId_Returns_403()
9497
var client = server.CreateClient();
9598
var request = new HttpRequestMessage(httpMethod, route);
9699
var todoItem = _todoItemFaker.Generate();
100+
const int clientDefinedId = 9999;
97101
var content = new
98102
{
99103
data = new
100104
{
101105
type = "todo-items",
102-
id = "9999",
106+
id = $"{clientDefinedId}",
103107
attributes = new
104108
{
105109
description = todoItem.Description,
106110
ordinal = todoItem.Ordinal
107111
}
108112
}
109113
};
114+
110115
request.Content = new StringContent(JsonConvert.SerializeObject(content));
111116
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.api+json");
112-
117+
113118
// act
114119
var response = await client.SendAsync(request);
115120

116121
// assert
117122
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
118123
}
119124

125+
[Fact]
126+
public async Task Can_Create_Entity_With_Client_Defined_Id_If_Configured()
127+
{
128+
// arrange
129+
var context = _fixture.GetService<AppDbContext>();
130+
var builder = new WebHostBuilder()
131+
.UseStartup<ClientGeneratedIdsStartup>();
132+
var httpMethod = new HttpMethod("POST");
133+
var route = "/api/v1/todo-items";
134+
var server = new TestServer(builder);
135+
var client = server.CreateClient();
136+
var request = new HttpRequestMessage(httpMethod, route);
137+
var todoItem = _todoItemFaker.Generate();
138+
const int clientDefinedId = 9999;
139+
var content = new
140+
{
141+
data = new
142+
{
143+
type = "todo-items",
144+
id = $"{clientDefinedId}",
145+
attributes = new
146+
{
147+
description = todoItem.Description,
148+
ordinal = todoItem.Ordinal
149+
}
150+
}
151+
};
152+
153+
request.Content = new StringContent(JsonConvert.SerializeObject(content));
154+
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.api+json");
155+
156+
// act
157+
var response = await client.SendAsync(request);
158+
var body = await response.Content.ReadAsStringAsync();
159+
var deserializedBody = (TodoItem)JsonApiDeSerializer.Deserialize(body, _jsonApiContext, context);
160+
161+
// assert
162+
Assert.Equal(HttpStatusCode.Created, response.StatusCode);
163+
Assert.Equal(clientDefinedId, deserializedBody.Id);
164+
}
165+
166+
167+
[Fact]
168+
public async Task Can_Create_Guid_Identifiable_Entity_With_Client_Defined_Id_If_Configured()
169+
{
170+
// arrange
171+
var builder = new WebHostBuilder()
172+
.UseStartup<ClientGeneratedIdsStartup>();
173+
var httpMethod = new HttpMethod("POST");
174+
var server = new TestServer(builder);
175+
var client = server.CreateClient();
176+
177+
var context = _fixture.GetService<AppDbContext>();
178+
179+
var owner = new JsonApiDotNetCoreExample.Models.Person();
180+
context.People.Add(owner);
181+
await context.SaveChangesAsync();
182+
183+
var route = "/api/v1/todo-item-collections";
184+
var request = new HttpRequestMessage(httpMethod, route);
185+
var clientDefinedId = Guid.NewGuid();
186+
var content = new
187+
{
188+
data = new
189+
{
190+
type = "todo-item-collections",
191+
id = $"{clientDefinedId}",
192+
relationships = new
193+
{
194+
owner = new
195+
{
196+
data = new
197+
{
198+
type = "people",
199+
id = owner.Id.ToString()
200+
}
201+
}
202+
}
203+
}
204+
};
205+
request.Content = new StringContent(JsonConvert.SerializeObject(content));
206+
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.api+json");
207+
208+
// act
209+
var response = await client.SendAsync(request);
210+
var body = await response.Content.ReadAsStringAsync();
211+
var deserializedBody = (TodoItemCollection)JsonApiDeSerializer.Deserialize(body, _jsonApiContext, context);
212+
213+
// assert
214+
Assert.Equal(HttpStatusCode.Created, response.StatusCode);
215+
Assert.Equal(clientDefinedId, deserializedBody.Id);
216+
}
217+
120218
[Fact]
121219
public async Task Can_Create_And_Set_HasMany_Relationships()
122220
{
@@ -167,14 +265,14 @@ public async Task Can_Create_And_Set_HasMany_Relationships()
167265

168266
request.Content = new StringContent(JsonConvert.SerializeObject(content));
169267
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.api+json");
170-
268+
171269
// act
172270
var response = await client.SendAsync(request);
173271
var body = await response.Content.ReadAsStringAsync();
174272
var deserializedBody = (TodoItemCollection)JsonApiDeSerializer.Deserialize(body, _jsonApiContext, context);
175273
var newId = deserializedBody.Id;
176274
var contextCollection = context.TodoItemCollections
177-
.Include(c=> c.Owner)
275+
.Include(c => c.Owner)
178276
.Include(c => c.TodoItems)
179277
.SingleOrDefault(c => c.Id == newId);
180278

@@ -210,7 +308,7 @@ public async Task ShouldReceiveLocationHeader_InResponse()
210308
};
211309
request.Content = new StringContent(JsonConvert.SerializeObject(content));
212310
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.api+json");
213-
311+
214312
// act
215313
var response = await client.SendAsync(request);
216314
var body = await response.Content.ReadAsStringAsync();
@@ -247,7 +345,7 @@ public async Task Respond_409_ToIncorrectEntityType()
247345
};
248346
request.Content = new StringContent(JsonConvert.SerializeObject(content));
249347
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.api+json");
250-
348+
251349
// act
252350
var response = await client.SendAsync(request);
253351

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using Microsoft.AspNetCore.Hosting;
2+
using Microsoft.Extensions.DependencyInjection;
3+
using Microsoft.Extensions.Logging;
4+
using JsonApiDotNetCoreExample.Data;
5+
using Microsoft.EntityFrameworkCore;
6+
using JsonApiDotNetCore.Extensions;
7+
using DotNetCoreDocs.Configuration;
8+
using System;
9+
using JsonApiDotNetCoreExample;
10+
11+
namespace JsonApiDotNetCoreExampleTests.Startups
12+
{
13+
public class ClientGeneratedIdsStartup : Startup
14+
{
15+
public ClientGeneratedIdsStartup(IHostingEnvironment env)
16+
: base (env)
17+
{ }
18+
19+
public override IServiceProvider ConfigureServices(IServiceCollection services)
20+
{
21+
var loggerFactory = new LoggerFactory();
22+
23+
loggerFactory
24+
.AddConsole(LogLevel.Trace);
25+
26+
services.AddSingleton<ILoggerFactory>(loggerFactory);
27+
28+
services.AddDbContext<AppDbContext>(options =>
29+
{
30+
options.UseNpgsql(GetDbConnectionString());
31+
}, ServiceLifetime.Transient);
32+
33+
services.AddJsonApi<AppDbContext>(opt =>
34+
{
35+
opt.Namespace = "api/v1";
36+
opt.DefaultPageSize = 5;
37+
opt.IncludeTotalRecordCount = true;
38+
opt.AllowClientGeneratedIds = true;
39+
});
40+
41+
services.AddDocumentationConfiguration(Config);
42+
43+
return services.BuildServiceProvider();
44+
}
45+
}
46+
}

0 commit comments

Comments
 (0)