Skip to content

Commit aec7e1c

Browse files
author
Jan Mattner
committed
test(extensibility): add tests for dasherized routes for inherited and custom route controllers and links
1 parent 517367b commit aec7e1c

File tree

4 files changed

+343
-21
lines changed

4 files changed

+343
-21
lines changed

JsonApiDotnetCore.sln

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
21
Microsoft Visual Studio Solution File, Format Version 12.00
32
# Visual Studio 15
4-
VisualStudioVersion = 15.0.26228.4
3+
VisualStudioVersion = 15.0.26228.9
54
MinimumVisualStudioVersion = 10.0.40219.1
65
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JsonApiDotNetCore", "src\JsonApiDotNetCore\JsonApiDotNetCore.csproj", "{C0EC9E70-EB2E-436F-9D94-FA16FA774123}"
76
EndProject
@@ -25,49 +24,61 @@ EndProject
2524
Global
2625
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2726
Debug|Any CPU = Debug|Any CPU
28-
Release|Any CPU = Release|Any CPU
2927
Debug|x64 = Debug|x64
3028
Debug|x86 = Debug|x86
29+
Release|Any CPU = Release|Any CPU
3130
Release|x64 = Release|x64
3231
Release|x86 = Release|x86
3332
EndGlobalSection
3433
GlobalSection(ProjectConfigurationPlatforms) = postSolution
3534
{C0EC9E70-EB2E-436F-9D94-FA16FA774123}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
3635
{C0EC9E70-EB2E-436F-9D94-FA16FA774123}.Debug|Any CPU.Build.0 = Debug|Any CPU
36+
{C0EC9E70-EB2E-436F-9D94-FA16FA774123}.Debug|x64.ActiveCfg = Debug|Any CPU
37+
{C0EC9E70-EB2E-436F-9D94-FA16FA774123}.Debug|x86.ActiveCfg = Debug|Any CPU
3738
{C0EC9E70-EB2E-436F-9D94-FA16FA774123}.Release|Any CPU.ActiveCfg = Release|Any CPU
3839
{C0EC9E70-EB2E-436F-9D94-FA16FA774123}.Release|Any CPU.Build.0 = Release|Any CPU
40+
{C0EC9E70-EB2E-436F-9D94-FA16FA774123}.Release|x64.ActiveCfg = Release|Any CPU
41+
{C0EC9E70-EB2E-436F-9D94-FA16FA774123}.Release|x86.ActiveCfg = Release|Any CPU
3942
{97EE048B-16C0-43F6-BDA9-4E762B2F579F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
4043
{97EE048B-16C0-43F6-BDA9-4E762B2F579F}.Debug|Any CPU.Build.0 = Debug|Any CPU
44+
{97EE048B-16C0-43F6-BDA9-4E762B2F579F}.Debug|x64.ActiveCfg = Debug|Any CPU
45+
{97EE048B-16C0-43F6-BDA9-4E762B2F579F}.Debug|x86.ActiveCfg = Debug|Any CPU
4146
{97EE048B-16C0-43F6-BDA9-4E762B2F579F}.Release|Any CPU.ActiveCfg = Release|Any CPU
4247
{97EE048B-16C0-43F6-BDA9-4E762B2F579F}.Release|Any CPU.Build.0 = Release|Any CPU
48+
{97EE048B-16C0-43F6-BDA9-4E762B2F579F}.Release|x64.ActiveCfg = Release|Any CPU
49+
{97EE048B-16C0-43F6-BDA9-4E762B2F579F}.Release|x86.ActiveCfg = Release|Any CPU
4350
{0B959765-40D2-43B5-87EE-FE2FEF9DBED5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
4451
{0B959765-40D2-43B5-87EE-FE2FEF9DBED5}.Debug|Any CPU.Build.0 = Debug|Any CPU
52+
{0B959765-40D2-43B5-87EE-FE2FEF9DBED5}.Debug|x64.ActiveCfg = Debug|Any CPU
53+
{0B959765-40D2-43B5-87EE-FE2FEF9DBED5}.Debug|x86.ActiveCfg = Debug|Any CPU
4554
{0B959765-40D2-43B5-87EE-FE2FEF9DBED5}.Release|Any CPU.ActiveCfg = Release|Any CPU
4655
{0B959765-40D2-43B5-87EE-FE2FEF9DBED5}.Release|Any CPU.Build.0 = Release|Any CPU
56+
{0B959765-40D2-43B5-87EE-FE2FEF9DBED5}.Release|x64.ActiveCfg = Release|Any CPU
57+
{0B959765-40D2-43B5-87EE-FE2FEF9DBED5}.Release|x86.ActiveCfg = Release|Any CPU
4758
{570165EC-62B5-4684-A139-8D2A30DD4475}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
4859
{570165EC-62B5-4684-A139-8D2A30DD4475}.Debug|Any CPU.Build.0 = Debug|Any CPU
49-
{570165EC-62B5-4684-A139-8D2A30DD4475}.Debug|x64.ActiveCfg = Debug|x64
50-
{570165EC-62B5-4684-A139-8D2A30DD4475}.Debug|x64.Build.0 = Debug|x64
51-
{570165EC-62B5-4684-A139-8D2A30DD4475}.Debug|x86.ActiveCfg = Debug|x86
52-
{570165EC-62B5-4684-A139-8D2A30DD4475}.Debug|x86.Build.0 = Debug|x86
60+
{570165EC-62B5-4684-A139-8D2A30DD4475}.Debug|x64.ActiveCfg = Debug|Any CPU
61+
{570165EC-62B5-4684-A139-8D2A30DD4475}.Debug|x64.Build.0 = Debug|Any CPU
62+
{570165EC-62B5-4684-A139-8D2A30DD4475}.Debug|x86.ActiveCfg = Debug|Any CPU
63+
{570165EC-62B5-4684-A139-8D2A30DD4475}.Debug|x86.Build.0 = Debug|Any CPU
5364
{570165EC-62B5-4684-A139-8D2A30DD4475}.Release|Any CPU.ActiveCfg = Release|Any CPU
5465
{570165EC-62B5-4684-A139-8D2A30DD4475}.Release|Any CPU.Build.0 = Release|Any CPU
55-
{570165EC-62B5-4684-A139-8D2A30DD4475}.Release|x64.ActiveCfg = Release|x64
56-
{570165EC-62B5-4684-A139-8D2A30DD4475}.Release|x64.Build.0 = Release|x64
57-
{570165EC-62B5-4684-A139-8D2A30DD4475}.Release|x86.ActiveCfg = Release|x86
58-
{570165EC-62B5-4684-A139-8D2A30DD4475}.Release|x86.Build.0 = Release|x86
66+
{570165EC-62B5-4684-A139-8D2A30DD4475}.Release|x64.ActiveCfg = Release|Any CPU
67+
{570165EC-62B5-4684-A139-8D2A30DD4475}.Release|x64.Build.0 = Release|Any CPU
68+
{570165EC-62B5-4684-A139-8D2A30DD4475}.Release|x86.ActiveCfg = Release|Any CPU
69+
{570165EC-62B5-4684-A139-8D2A30DD4475}.Release|x86.Build.0 = Release|Any CPU
5970
{73DA578D-A63F-4956-83ED-6D7102E09140}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
6071
{73DA578D-A63F-4956-83ED-6D7102E09140}.Debug|Any CPU.Build.0 = Debug|Any CPU
61-
{73DA578D-A63F-4956-83ED-6D7102E09140}.Debug|x64.ActiveCfg = Debug|x64
62-
{73DA578D-A63F-4956-83ED-6D7102E09140}.Debug|x64.Build.0 = Debug|x64
63-
{73DA578D-A63F-4956-83ED-6D7102E09140}.Debug|x86.ActiveCfg = Debug|x86
64-
{73DA578D-A63F-4956-83ED-6D7102E09140}.Debug|x86.Build.0 = Debug|x86
72+
{73DA578D-A63F-4956-83ED-6D7102E09140}.Debug|x64.ActiveCfg = Debug|Any CPU
73+
{73DA578D-A63F-4956-83ED-6D7102E09140}.Debug|x64.Build.0 = Debug|Any CPU
74+
{73DA578D-A63F-4956-83ED-6D7102E09140}.Debug|x86.ActiveCfg = Debug|Any CPU
75+
{73DA578D-A63F-4956-83ED-6D7102E09140}.Debug|x86.Build.0 = Debug|Any CPU
6576
{73DA578D-A63F-4956-83ED-6D7102E09140}.Release|Any CPU.ActiveCfg = Release|Any CPU
6677
{73DA578D-A63F-4956-83ED-6D7102E09140}.Release|Any CPU.Build.0 = Release|Any CPU
67-
{73DA578D-A63F-4956-83ED-6D7102E09140}.Release|x64.ActiveCfg = Release|x64
68-
{73DA578D-A63F-4956-83ED-6D7102E09140}.Release|x64.Build.0 = Release|x64
69-
{73DA578D-A63F-4956-83ED-6D7102E09140}.Release|x86.ActiveCfg = Release|x86
70-
{73DA578D-A63F-4956-83ED-6D7102E09140}.Release|x86.Build.0 = Release|x86
78+
{73DA578D-A63F-4956-83ED-6D7102E09140}.Release|x64.ActiveCfg = Release|Any CPU
79+
{73DA578D-A63F-4956-83ED-6D7102E09140}.Release|x64.Build.0 = Release|Any CPU
80+
{73DA578D-A63F-4956-83ED-6D7102E09140}.Release|x86.ActiveCfg = Release|Any CPU
81+
{73DA578D-A63F-4956-83ED-6D7102E09140}.Release|x86.Build.0 = Release|Any CPU
7182
EndGlobalSection
7283
GlobalSection(SolutionProperties) = preSolution
7384
HideSolutionNode = FALSE
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
using System.Collections.Generic;
2+
using System.Threading.Tasks;
3+
using JsonApiDotNetCore.Controllers;
4+
using JsonApiDotNetCore.Models;
5+
using JsonApiDotNetCore.Services;
6+
using JsonApiDotNetCoreExample.Models;
7+
using Microsoft.AspNetCore.Mvc;
8+
using Microsoft.Extensions.Logging;
9+
10+
namespace JsonApiDotNetCoreExample.Controllers
11+
{
12+
[Route("custom/route/todoitems")]
13+
public class TodoItemsCustomController : CustomJsonApiController<TodoItem>
14+
{
15+
public TodoItemsCustomController(
16+
IJsonApiContext jsonApiContext,
17+
IResourceService<TodoItem> resourceService,
18+
ILoggerFactory loggerFactory)
19+
: base(jsonApiContext, resourceService, loggerFactory)
20+
{ }
21+
}
22+
23+
public class CustomJsonApiController<T>
24+
: CustomJsonApiController<T, int> where T : class, IIdentifiable<int>
25+
{
26+
public CustomJsonApiController(
27+
IJsonApiContext jsonApiContext,
28+
IResourceService<T, int> resourceService,
29+
ILoggerFactory loggerFactory)
30+
: base(jsonApiContext, resourceService, loggerFactory)
31+
{ }
32+
}
33+
34+
public class CustomJsonApiController<T, TId>
35+
: Controller where T : class, IIdentifiable<TId>
36+
{
37+
private readonly ILogger _logger;
38+
private readonly IResourceService<T, TId> _resourceService;
39+
private readonly IJsonApiContext _jsonApiContext;
40+
41+
protected IActionResult UnprocessableEntity()
42+
{
43+
return new StatusCodeResult(422);
44+
}
45+
46+
protected IActionResult Forbidden()
47+
{
48+
return new StatusCodeResult(403);
49+
}
50+
51+
public CustomJsonApiController(
52+
IJsonApiContext jsonApiContext,
53+
IResourceService<T, TId> resourceService,
54+
ILoggerFactory loggerFactory)
55+
{
56+
_jsonApiContext = jsonApiContext.ApplyContext<T>();
57+
_resourceService = resourceService;
58+
_logger = loggerFactory.CreateLogger<JsonApiDotNetCore.Controllers.JsonApiController<T, TId>>();
59+
}
60+
61+
public CustomJsonApiController(
62+
IJsonApiContext jsonApiContext,
63+
IResourceService<T, TId> resourceService)
64+
{
65+
_jsonApiContext = jsonApiContext.ApplyContext<T>();
66+
_resourceService = resourceService;
67+
}
68+
69+
[HttpGet]
70+
public virtual async Task<IActionResult> GetAsync()
71+
{
72+
var entities = await _resourceService.GetAsync();
73+
return Ok(entities);
74+
}
75+
76+
[HttpGet("{id}")]
77+
public virtual async Task<IActionResult> GetAsync(TId id)
78+
{
79+
var entity = await _resourceService.GetAsync(id);
80+
81+
if (entity == null)
82+
return NotFound();
83+
84+
return Ok(entity);
85+
}
86+
87+
[HttpGet("{id}/relationships/{relationshipName}")]
88+
public virtual async Task<IActionResult> GetRelationshipsAsync(TId id, string relationshipName)
89+
{
90+
var relationship = _resourceService.GetRelationshipAsync(id, relationshipName);
91+
if (relationship == null)
92+
return NotFound();
93+
94+
return await GetRelationshipAsync(id, relationshipName);
95+
}
96+
97+
[HttpGet("{id}/{relationshipName}")]
98+
public virtual async Task<IActionResult> GetRelationshipAsync(TId id, string relationshipName)
99+
{
100+
var relationship = await _resourceService.GetRelationshipAsync(id, relationshipName);
101+
return Ok(relationship);
102+
}
103+
104+
[HttpPost]
105+
public virtual async Task<IActionResult> PostAsync([FromBody] T entity)
106+
{
107+
if (entity == null)
108+
return UnprocessableEntity();
109+
110+
if (!_jsonApiContext.Options.AllowClientGeneratedIds && !string.IsNullOrEmpty(entity.StringId))
111+
return Forbidden();
112+
113+
entity = await _resourceService.CreateAsync(entity);
114+
115+
return Created($"{HttpContext.Request.Path}/{entity.Id}", entity);
116+
}
117+
118+
[HttpPatch("{id}")]
119+
public virtual async Task<IActionResult> PatchAsync(TId id, [FromBody] T entity)
120+
{
121+
if (entity == null)
122+
return UnprocessableEntity();
123+
124+
var updatedEntity = await _resourceService.UpdateAsync(id, entity);
125+
126+
if (updatedEntity == null)
127+
return NotFound();
128+
129+
return Ok(updatedEntity);
130+
}
131+
132+
[HttpPatch("{id}/relationships/{relationshipName}")]
133+
public virtual async Task<IActionResult> PatchRelationshipsAsync(TId id, string relationshipName, [FromBody] List<DocumentData> relationships)
134+
{
135+
await _resourceService.UpdateRelationshipsAsync(id, relationshipName, relationships);
136+
return Ok();
137+
}
138+
139+
[HttpDelete("{id}")]
140+
public virtual async Task<IActionResult> DeleteAsync(TId id)
141+
{
142+
var wasDeleted = await _resourceService.DeleteAsync(id);
143+
144+
if (!wasDeleted)
145+
return NotFound();
146+
147+
return NoContent();
148+
}
149+
}
150+
}

src/NoEntityFrameworkExample/NoEntityFrameworkExample.csproj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
<Project Sdk="Microsoft.NET.Sdk.Web">
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
22

33
<PropertyGroup>
44
<TargetFramework>netcoreapp1.0</TargetFramework>
5+
<RuntimeFrameworkVersion>1.1.1</RuntimeFrameworkVersion>
6+
<PackageTargetFallback>$(PackageTargetFallback);dotnet5.6;portable-net45+win8</PackageTargetFallback>
57
</PropertyGroup>
68

79
<ItemGroup>

0 commit comments

Comments
 (0)