Skip to content

Commit 38e7996

Browse files
committed
Add sample project and unit tests
1 parent 00377d6 commit 38e7996

9 files changed

+194
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using Microsoft.AspNetCore.Mvc;
2+
3+
namespace F23.Hateoas.Sample.NewtonsoftJson;
4+
5+
public abstract class AppBaseController : ControllerBase
6+
{
7+
protected IActionResult HypermediaOk(object content, IList<HypermediaLink>? links = null)
8+
{
9+
return Ok(new HypermediaResponse(content) { Links = links });
10+
}
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using Microsoft.AspNetCore.Mvc;
2+
3+
namespace F23.Hateoas.Sample.NewtonsoftJson;
4+
5+
public class ExampleController : AppBaseController
6+
{
7+
[HttpGet("api/example")]
8+
public IActionResult GetExample()
9+
{
10+
var data = new
11+
{
12+
Message = "Hello World!",
13+
};
14+
15+
return HypermediaOk(data, [
16+
new HypermediaLink("self", "/api/example"),
17+
new HypermediaLink("google", "https://www.google.com"),
18+
]);
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net8.0</TargetFramework>
5+
<Nullable>enable</Nullable>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.14" />
11+
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.14" />
12+
<PackageReference Include="Swashbuckle.AspNetCore" Version="7.3.1" />
13+
</ItemGroup>
14+
15+
<ItemGroup>
16+
<ProjectReference Include="..\F23.Hateoas\F23.Hateoas.csproj" />
17+
</ItemGroup>
18+
19+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using F23.Hateoas;
2+
3+
var builder = WebApplication.CreateBuilder(args);
4+
5+
// Add services to the container.
6+
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
7+
builder.Services.AddEndpointsApiExplorer();
8+
builder.Services.AddSwaggerGen();
9+
10+
builder.Services.AddControllers()
11+
.AddNewtonsoftJson();
12+
13+
var app = builder.Build();
14+
15+
// Configure the HTTP request pipeline.
16+
if (app.Environment.IsDevelopment())
17+
{
18+
app.UseSwagger();
19+
app.UseSwaggerUI();
20+
}
21+
22+
app.UseHttpsRedirection();
23+
24+
app.MapControllers();
25+
26+
app.Run();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"$schema": "http://json.schemastore.org/launchsettings.json",
3+
"iisSettings": {
4+
"windowsAuthentication": false,
5+
"anonymousAuthentication": true,
6+
"iisExpress": {
7+
"applicationUrl": "http://localhost:10201",
8+
"sslPort": 44369
9+
}
10+
},
11+
"profiles": {
12+
"http": {
13+
"commandName": "Project",
14+
"dotnetRunMessages": true,
15+
"launchBrowser": true,
16+
"launchUrl": "swagger",
17+
"applicationUrl": "http://localhost:5099",
18+
"environmentVariables": {
19+
"ASPNETCORE_ENVIRONMENT": "Development"
20+
}
21+
},
22+
"https": {
23+
"commandName": "Project",
24+
"dotnetRunMessages": true,
25+
"launchBrowser": true,
26+
"launchUrl": "swagger",
27+
"applicationUrl": "https://localhost:7193;http://localhost:5099",
28+
"environmentVariables": {
29+
"ASPNETCORE_ENVIRONMENT": "Development"
30+
}
31+
},
32+
"IIS Express": {
33+
"commandName": "IISExpress",
34+
"launchBrowser": true,
35+
"launchUrl": "swagger",
36+
"environmentVariables": {
37+
"ASPNETCORE_ENVIRONMENT": "Development"
38+
}
39+
}
40+
}
41+
}
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net8.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
8+
<IsPackable>false</IsPackable>
9+
<IsTestProject>true</IsTestProject>
10+
</PropertyGroup>
11+
12+
<ItemGroup>
13+
<PackageReference Include="coverlet.collector" Version="6.0.4">
14+
<PrivateAssets>all</PrivateAssets>
15+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
16+
</PackageReference>
17+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
18+
<PackageReference Include="xunit" Version="2.9.3" />
19+
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.2" />
20+
</ItemGroup>
21+
22+
<ItemGroup>
23+
<Using Include="Xunit"/>
24+
</ItemGroup>
25+
26+
<ItemGroup>
27+
<ProjectReference Include="..\F23.Hateoas\F23.Hateoas.csproj" />
28+
</ItemGroup>
29+
30+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using Newtonsoft.Json;
2+
3+
namespace F23.Hateoas.Tests;
4+
5+
public class NewtonsoftJsonSerializationTests
6+
{
7+
[Fact]
8+
public void Serialize_WithNullLinks_ShouldNotIncludeLinks()
9+
{
10+
var response = new HypermediaResponse(42);
11+
12+
var json = JsonConvert.SerializeObject(response);
13+
14+
Assert.Equal("""{"content":42}""", json);
15+
}
16+
17+
[Fact]
18+
public void Serialize_WithLinks_ShouldIncludeLinks()
19+
{
20+
var response = new HypermediaResponse(42)
21+
{
22+
Links = new List<HypermediaLink>
23+
{
24+
new HypermediaLink("self", "/api/example"),
25+
new HypermediaLink("google", "https://www.google.com"),
26+
}
27+
};
28+
29+
var json = JsonConvert.SerializeObject(response);
30+
31+
Assert.Equal("""{"content":42,"_links":[{"rel":"self","href":"/api/example"},{"rel":"google","href":"https://www.google.com"}]}""", json);
32+
}
33+
}

F23.Hateoas.sln

+12
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ VisualStudioVersion = 17.0.31903.59
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "F23.Hateoas", "F23.Hateoas\F23.Hateoas.csproj", "{20A3B02F-4153-4CA8-80D7-88196B974D61}"
77
EndProject
8+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "F23.Hateoas.Sample.NewtonsoftJson", "F23.Hateoas.Sample.NewtonsoftJson\F23.Hateoas.Sample.NewtonsoftJson.csproj", "{B827C132-7AE9-48EB-B8B1-56DD029D242E}"
9+
EndProject
10+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "F23.Hateoas.Tests", "F23.Hateoas.Tests\F23.Hateoas.Tests.csproj", "{39735FE1-5D95-4BA9-AF6F-86143888CDF0}"
11+
EndProject
812
Global
913
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1014
Debug|Any CPU = Debug|Any CPU
@@ -18,5 +22,13 @@ Global
1822
{20A3B02F-4153-4CA8-80D7-88196B974D61}.Debug|Any CPU.Build.0 = Debug|Any CPU
1923
{20A3B02F-4153-4CA8-80D7-88196B974D61}.Release|Any CPU.ActiveCfg = Release|Any CPU
2024
{20A3B02F-4153-4CA8-80D7-88196B974D61}.Release|Any CPU.Build.0 = Release|Any CPU
25+
{B827C132-7AE9-48EB-B8B1-56DD029D242E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
26+
{B827C132-7AE9-48EB-B8B1-56DD029D242E}.Debug|Any CPU.Build.0 = Debug|Any CPU
27+
{B827C132-7AE9-48EB-B8B1-56DD029D242E}.Release|Any CPU.ActiveCfg = Release|Any CPU
28+
{B827C132-7AE9-48EB-B8B1-56DD029D242E}.Release|Any CPU.Build.0 = Release|Any CPU
29+
{39735FE1-5D95-4BA9-AF6F-86143888CDF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
30+
{39735FE1-5D95-4BA9-AF6F-86143888CDF0}.Debug|Any CPU.Build.0 = Debug|Any CPU
31+
{39735FE1-5D95-4BA9-AF6F-86143888CDF0}.Release|Any CPU.ActiveCfg = Release|Any CPU
32+
{39735FE1-5D95-4BA9-AF6F-86143888CDF0}.Release|Any CPU.Build.0 = Release|Any CPU
2133
EndGlobalSection
2234
EndGlobal

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ You might also find it helpful to create a helper method in a controller base cl
3838
```csharp
3939
public class MyBaseController : ControllerBase
4040
{
41-
protected IActionResult HypermediaOk(object data, IList<HypermediaLink> links = null)
41+
protected IActionResult HypermediaOk(object content, IList<HypermediaLink>? links = null)
4242

4343
{
44-
return Ok(new HypermediaResponse(data) { Links = links });
44+
return Ok(new HypermediaResponse(content) { Links = links });
4545
}
4646
}
4747
```

0 commit comments

Comments
 (0)