Skip to content

Commit

Permalink
Test improvements
Browse files Browse the repository at this point in the history
- xunit.core and xunit.abstractions instead of full xunit (don't need the assertions)
- add Meziantou.Extensions.Logging.Xunit to include logs in test output when failures occur in integration tests
- stop dumping all  integration test output to console all the time
  • Loading branch information
josephdecock committed Oct 24, 2024
1 parent 14c45f1 commit d880f4b
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 117 deletions.
71 changes: 34 additions & 37 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -1,41 +1,38 @@
<Project>
<PropertyGroup Condition=" '$(TargetFramework)' == 'net8.0'">
<!-- We depend on the most permissive version of the JwtBearer handler
<PropertyGroup Condition=" '$(TargetFramework)' == 'net8.0'">
<!-- We depend on the most permissive version of the JwtBearer handler
that doesn't give us a transitive depedency on a vulnerable package. -->
<FrameworkVersion>8.0.1</FrameworkVersion>
<ExtensionsVersion>8.0.0</ExtensionsVersion>
<WilsonVersion>7.1.2</WilsonVersion>
</PropertyGroup>

<PropertyGroup Condition=" '$(TargetFramework)' == 'net9.0'">
<!-- We depend on the most permissive version of the JwtBearer handler
<FrameworkVersion>8.0.1</FrameworkVersion>
<ExtensionsVersion>8.0.0</ExtensionsVersion>
<WilsonVersion>7.1.2</WilsonVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'net9.0'">
<!-- We depend on the most permissive version of the JwtBearer handler
that doesn't give us a transitive depedency on a vulnerable package. -->
<FrameworkVersion>9.0.0-rc.2.24474.3</FrameworkVersion>
<ExtensionsVersion>9.0.0-rc.2.24473.5</ExtensionsVersion>
<WilsonVersion>8.0.1</WilsonVersion>
</PropertyGroup>

<ItemGroup>
<!-- <PackageVersion Include="Duende.AccessTokenManagement" Version="3.0.0" /> -->
<PackageVersion Include="Duende.AccessTokenManagement.OpenIdConnect" Version="3.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="$(FrameworkVersion)"/>
<PackageVersion Include="IdentityModel" Version="7.0.0" />

<!-- Build -->
<PackageVersion Include="MinVer" Version="6.0.0" />

<!-- Test -->
<PackageVersion Include="AngleSharp" Version="1.1.2" />
<PackageVersion Include="coverlet.collector" Version="6.0.2" />
<PackageVersion Include="Duende.IdentityServer" Version="7.0.7" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="$(FrameworkVersion)" />
<PackageVersion Include="Microsoft.Extensions.TimeProvider.Testing" Version="8.7.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<PackageVersion Include="NSubstitute" Version="5.1.0" />
<PackageVersion Include="RichardSzalay.MockHttp" Version="7.0.0" />
<PackageVersion Include="Shouldly" Version="4.2.1" />
<PackageVersion Include="System.Text.Json" Version="8.0.5" />
<PackageVersion Include="xunit" Version="2.9.2" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2" />
</ItemGroup>
<FrameworkVersion>9.0.0-rc.2.24474.3</FrameworkVersion>
<ExtensionsVersion>9.0.0-rc.2.24473.5</ExtensionsVersion>
<WilsonVersion>8.0.1</WilsonVersion>
</PropertyGroup>
<ItemGroup>
<!-- <PackageVersion Include="Duende.AccessTokenManagement" Version="3.0.0" /> -->
<PackageVersion Include="Duende.AccessTokenManagement.OpenIdConnect" Version="3.0.0" />
<PackageVersion Include="Meziantou.Extensions.Logging.Xunit" Version="1.0.7" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="$(FrameworkVersion)" />
<PackageVersion Include="IdentityModel" Version="7.0.0" />
<!-- Build -->
<PackageVersion Include="MinVer" Version="6.0.0" />
<!-- Test -->
<PackageVersion Include="AngleSharp" Version="1.1.2" />
<PackageVersion Include="coverlet.collector" Version="6.0.2" />
<PackageVersion Include="Duende.IdentityServer" Version="7.0.7" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="$(FrameworkVersion)" />
<PackageVersion Include="Microsoft.Extensions.TimeProvider.Testing" Version="8.7.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<PackageVersion Include="NSubstitute" Version="5.1.0" />
<PackageVersion Include="RichardSzalay.MockHttp" Version="7.0.0" />
<PackageVersion Include="Shouldly" Version="4.2.1" />
<PackageVersion Include="System.Text.Json" Version="8.0.5" />
<PackageVersion Include="xunit.core" Version="2.9.2" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,15 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<!-- <PackageReference Include="Duende.AccessTokenManagement" /> -->
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="xunit" />
<PackageReference Include="Microsoft.Extensions.TimeProvider.Testing" />
<PackageReference Include="NSubstitute" />
<PackageReference Include="Shouldly"/>
<PackageReference Include="xunit.core" />
<PackageReference Include="xunit.runner.visualstudio" >
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.TimeProvider.Testing" />
<PackageReference Include="NSubstitute" />
<PackageReference Include="Shouldly"/>
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.IdentityModel.Tokens;
using Shouldly;
using Xunit.Abstractions;

namespace Duende.AspNetCore.Authentication.JwtBearer;

public class DPoPIntegrationTests
public class DPoPIntegrationTests(ITestOutputHelper testOutputHelper)
{
Client DPoPOnlyClient = new()
{
Expand Down Expand Up @@ -66,8 +67,8 @@ public async Task valid_token_and_proof_succeeds()
var jwk = CreateJwk();
var api = await CreateDPoPApi();

var app = new AppHost(identityServer, api, "client1", configureUserTokenManagementOptions: opt =>
opt.DPoPJsonWebKey = jwk);
var app = new AppHost(identityServer, api, "client1", testOutputHelper,
configureUserTokenManagementOptions: opt => opt.DPoPJsonWebKey = jwk);
await app.Initialize();

// Login and get token for api call
Expand Down Expand Up @@ -110,8 +111,8 @@ public async Task excessively_large_proof_fails()
var maxLength = 50;
var api = await CreateDPoPApi(opt => opt.ProofTokenMaxLength = maxLength);

var app = new AppHost(identityServer, api, "client1", configureUserTokenManagementOptions: opt =>
opt.DPoPJsonWebKey = jwk);
var app = new AppHost(identityServer, api, "client1", testOutputHelper,
configureUserTokenManagementOptions: opt => opt.DPoPJsonWebKey = jwk);
await app.Initialize();

// Login and get token for api call
Expand Down Expand Up @@ -142,19 +143,19 @@ public async Task excessively_large_proof_fails()
result.StatusCode.ShouldBe(HttpStatusCode.Unauthorized);
}

public static async Task<IdentityServerHost> CreateIdentityServer(Action<IdentityServerHost>? setup = null)
public async Task<IdentityServerHost> CreateIdentityServer(Action<IdentityServerHost>? setup = null)
{
var host = new IdentityServerHost();
var host = new IdentityServerHost(testOutputHelper);
setup?.Invoke(host);
await host.Initialize();
return host;
}

private static async Task<ApiHost> CreateDPoPApi(Action<DPoPOptions>? configureDPoP = null)
private async Task<ApiHost> CreateDPoPApi(Action<DPoPOptions>? configureDPoP = null)
{
var baseAddress = "https://api";
var identityServer = await CreateIdentityServer();
var api = new ApiHost(identityServer, baseAddress);
var api = new ApiHost(identityServer, testOutputHelper, baseAddress);
api.OnConfigureServices += services =>
services.ConfigureDPoPTokensForScheme(ApiHost.AuthenticationScheme,
opt =>
Expand Down
5 changes: 3 additions & 2 deletions test/TestFramework/ApiHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Xunit.Abstractions;

namespace Duende.AspNetCore.TestFramework;

Expand All @@ -17,8 +18,8 @@ public class ApiHost : GenericHost
private readonly IdentityServerHost _identityServerHost;
public event Action<HttpContext> ApiInvoked = ctx => { };

public ApiHost(IdentityServerHost identityServerHost, string baseAddress = "https://api")
: base(baseAddress)
public ApiHost(IdentityServerHost identityServerHost, ITestOutputHelper testOutputHelper, string baseAddress = "https://api")
: base(testOutputHelper, baseAddress)
{
_identityServerHost = identityServerHost;

Expand Down
6 changes: 4 additions & 2 deletions test/TestFramework/AppHost.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Duende Software. All rights reserved.
// Copyright (c) Duende Software. All rights reserved.
// See LICENSE in the project root for license information.

using System.Net;
Expand All @@ -11,6 +11,7 @@
using Microsoft.Extensions.DependencyInjection;
using RichardSzalay.MockHttp;
using Shouldly;
using Xunit.Abstractions;

namespace Duende.AspNetCore.TestFramework;

Expand All @@ -25,9 +26,10 @@ public AppHost(
IdentityServerHost identityServerHost,
ApiHost apiHost,
string clientId,
ITestOutputHelper testOutputHelper,
string baseAddress = "https://app",
Action<UserTokenManagementOptions>? configureUserTokenManagementOptions = default)
: base(baseAddress)
: base(testOutputHelper, baseAddress)
{
_identityServerHost = identityServerHost;
_apiHost = apiHost;
Expand Down
24 changes: 18 additions & 6 deletions test/TestFramework/GenericHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,24 @@
using System.Net;
using System.Reflection;
using System.Security.Claims;
using Meziantou.Extensions.Logging.Xunit;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Shouldly;
using Xunit.Abstractions;

namespace Duende.AspNetCore.TestFramework;

public class GenericHost
{
public GenericHost(string baseAddress = "https://server")
public GenericHost(ITestOutputHelper testOutputHelper, string baseAddress = "https://server")
{
if (baseAddress.EndsWith("/")) baseAddress = baseAddress.Substring(0, baseAddress.Length - 1);
_baseAddress = baseAddress;
_testOutputHelper = testOutputHelper;
}

protected readonly string _baseAddress;
Expand Down Expand Up @@ -55,8 +58,7 @@ public HttpClient HttpClient
private set => _httpClient = value;
}

public TestLoggerProvider Logger { get; set; } = new TestLoggerProvider();

private readonly ITestOutputHelper _testOutputHelper;

public T Resolve<T>()
where T : notnull
Expand All @@ -75,7 +77,7 @@ public string Url(string? path = null)

public async Task Initialize()
{
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
var builder = WebApplication.CreateEmptyBuilder(new WebApplicationOptions
{
EnvironmentName = IsDevelopment ? "Development" : "Production",
ApplicationName = HostAssembly?.GetName()?.Name
Expand All @@ -99,10 +101,20 @@ public async Task Initialize()

void ConfigureServices(IServiceCollection services)
{
// This adds log messages to the output of our tests when they fail.
// See https://www.meziantou.net/how-to-view-logs-from-ilogger-in-xunitdotnet.htm
services.AddLogging(options =>
{
options.SetMinimumLevel(LogLevel.Debug);
options.AddProvider(Logger);
// If you need different log output to understand a test failure, configure it here
options.SetMinimumLevel(LogLevel.Error);
options.AddFilter("Duende", LogLevel.Information);
options.AddFilter("Duende.IdentityServer.License", LogLevel.Error);
options.AddFilter("Duende.IdentityServer.Startup", LogLevel.Error);
options.AddProvider(new XUnitLoggerProvider(_testOutputHelper, new XUnitLoggerOptions
{
IncludeCategory = true,
}));
});

OnConfigureServices(services);
Expand Down
9 changes: 3 additions & 6 deletions test/TestFramework/IdentityServerHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.JsonWebTokens;
using Microsoft.IdentityModel.Tokens;
using Xunit.Abstractions;

namespace Duende.AspNetCore.TestFramework;

public class IdentityServerHost : GenericHost
{
public IdentityServerHost(string baseAddress = "https://identityserver")
: base(baseAddress)
public IdentityServerHost(ITestOutputHelper testOutputHelper, string baseAddress = "https://identityserver")
: base(testOutputHelper, baseAddress)
{
OnConfigureServices += ConfigureServices;
OnConfigure += Configure;
Expand Down Expand Up @@ -44,10 +45,6 @@ private void ConfigureServices(IServiceCollection services)
services.AddRouting();
services.AddAuthorization();

services.AddLogging(logging => {
logging.AddFilter("Duende", LogLevel.Debug);
});

services.AddIdentityServer(options=>
{
options.EmitStaticAudienceClaim = true;
Expand Down
3 changes: 2 additions & 1 deletion test/TestFramework/TestFramework.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@
<PackageReference Include="AngleSharp" />
<PackageReference Include="Duende.AccessTokenManagement.OpenIdConnect" />
<PackageReference Include="Duende.IdentityServer" />
<PackageReference Include="Meziantou.Extensions.Logging.Xunit" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" />
<PackageReference Include="System.Text.Json" />
<PackageReference Include="RichardSzalay.MockHttp" />
<PackageReference Include="Shouldly" />
<PackageReference Include="System.Text.Json" />
</ItemGroup>

</Project>
49 changes: 0 additions & 49 deletions test/TestFramework/TestLoggerProvider.cs

This file was deleted.

0 comments on commit d880f4b

Please sign in to comment.