Skip to content

Commit a797c95

Browse files
committed
Add simple integration tests
1 parent 8a1c4fd commit a797c95

File tree

4 files changed

+132
-7
lines changed

4 files changed

+132
-7
lines changed

Build.ps1

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,16 +53,16 @@ try {
5353
Pop-Location
5454
}
5555

56-
# foreach ($test in Get-ChildItem tests/) {
57-
# Push-Location $test
56+
foreach ($test in Get-ChildItem tests/) {
57+
Push-Location $test
5858

59-
# Write-Output "build: Testing project in $test"
59+
Write-Output "build: Testing project in $test"
6060

61-
# & dotnet test -c Release --no-build --no-restore
62-
# if($LASTEXITCODE -ne 0) { throw "Testing failed" }
61+
& dotnet test -c Release --no-build --no-restore
62+
if($LASTEXITCODE -ne 0) { throw "Testing failed" }
6363

64-
# Pop-Location
65-
# }
64+
Pop-Location
65+
}
6666

6767
if ($skipPackaging -eq $false) {
6868
Write-Output "build: Publishing NuGet package"

ByteGuard.SecurityHeaders.slnx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,8 @@
77
<File Path="README.md" />
88
<File Path=".github/workflows/ci.yml" />
99
</Folder>
10+
<Folder Name="/tests/">
11+
<Project Path="tests/ByteGuard.SecurityHeaders.Tests/ByteGuard.SecurityHeaders.Tests.csproj" />
12+
</Folder>
1013
<Project Path="src/ByteGuard.SecurityHeaders/ByteGuard.SecurityHeaders.csproj" />
1114
</Solution>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net10.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
<GenerateDocumentationFile>false</GenerateDocumentationFile>
8+
9+
<IsPackable>false</IsPackable>
10+
<IsTestProject>true</IsTestProject>
11+
</PropertyGroup>
12+
13+
<ItemGroup>
14+
<PackageReference Include="coverlet.collector" Version="6.0.4" />
15+
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="10.0.1" />
16+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
17+
<PackageReference Include="xunit" Version="2.9.3" />
18+
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.4" />
19+
</ItemGroup>
20+
21+
<ItemGroup>
22+
<ProjectReference Include="../../src/ByteGuard.SecurityHeaders/ByteGuard.SecurityHeaders.csproj" />
23+
</ItemGroup>
24+
25+
<ItemGroup>
26+
<Using Include="Xunit" />
27+
</ItemGroup>
28+
29+
</Project>
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
using Microsoft.AspNetCore.Builder;
2+
using Microsoft.AspNetCore.Hosting;
3+
using Microsoft.AspNetCore.Http;
4+
using Microsoft.AspNetCore.TestHost;
5+
using Microsoft.Extensions.Hosting;
6+
7+
namespace ByteGuard.SecurityHeaders.Tests;
8+
9+
public class SecurityHeadersMiddlewareTests
10+
{
11+
[Fact(DisplayName = "UseDefaultApiSecurityHeaders add the expected headers")]
12+
public async Task UseDefaultApiSecurityHeaders_AddsExpectedHeaders()
13+
{
14+
using var host = await new HostBuilder()
15+
.ConfigureWebHost(builder =>
16+
{
17+
builder.UseTestServer();
18+
builder.Configure(app =>
19+
{
20+
app.UseDefaultApiSecurityHeaders();
21+
app.Run(async context => await context.Response.WriteAsync("response"));
22+
});
23+
}).StartAsync();
24+
25+
using var client = host.GetTestClient();
26+
using var response = await client.GetAsync("/");
27+
28+
AssertHeader(response, "Cache-Control", "no-store");
29+
AssertHeader(response, "Content-Security-Policy", "frame-ancestors 'none'");
30+
AssertHeader(response, "X-Content-Type-Options", "nosniff");
31+
AssertHeader(response, "X-Frame-Options", "DENY");
32+
}
33+
34+
[Fact]
35+
public async Task EnforceFalse_DoesNotOverrideExistingHeaderValues()
36+
{
37+
using var host = await new HostBuilder()
38+
.ConfigureWebHost(builder =>
39+
{
40+
builder.UseTestServer();
41+
builder.Configure(app =>
42+
{
43+
app.UseDefaultApiSecurityHeaders(options => options.Enforce = false);
44+
45+
app.Use(async (ctx, next) =>
46+
{
47+
ctx.Response.Headers["Cache-Control"] = "public, max-age=60";
48+
await next();
49+
});
50+
51+
app.Run(async context => await context.Response.WriteAsync("response"));
52+
});
53+
}).StartAsync();
54+
55+
using var client = host.GetTestClient();
56+
using var response = await client.GetAsync("/");
57+
58+
AssertHeader(response, "Cache-Control", "public, max-age=60");
59+
}
60+
61+
[Fact]
62+
public async Task EnforceTrue_OverridesExistingHeaderValues()
63+
{
64+
using var host = await new HostBuilder()
65+
.ConfigureWebHost(builder =>
66+
{
67+
builder.UseTestServer();
68+
builder.Configure(app =>
69+
{
70+
app.UseDefaultApiSecurityHeaders(options => options.Enforce = true);
71+
72+
app.Use(async (ctx, next) =>
73+
{
74+
ctx.Response.Headers["Cache-Control"] = "public, max-age=60";
75+
await next();
76+
});
77+
78+
app.Run(async context => await context.Response.WriteAsync("response"));
79+
});
80+
}).StartAsync();
81+
82+
using HttpClient client = host.GetTestClient();
83+
using var response = await client.GetAsync("/");
84+
85+
AssertHeader(response, "Cache-Control", "no-store");
86+
}
87+
88+
private static void AssertHeader(HttpResponseMessage response, string name, string expectedValue)
89+
{
90+
Assert.True(response.Headers.TryGetValues(name, out var values), $"Missing header: {name}");
91+
Assert.Equal(expectedValue, values.Single());
92+
}
93+
}

0 commit comments

Comments
 (0)