Add templates to aspire environment, add first end to end template test

This commit is contained in:
Joe DeCock 2025-10-01 14:13:13 -05:00
parent d6129e8ab0
commit eadee2e68d
7 changed files with 63 additions and 22 deletions

View file

@ -60,6 +60,12 @@
<ProjectReference Include="..\..\..\hosts\Main\Main9\Host.Main9.csproj" />
<ProjectReference Include="..\..\..\migrations\AspNetIdentityDb\AspNetIdentityDb.csproj" />
<ProjectReference Include="..\..\..\migrations\IdentityServerDb\IdentityServerDb.csproj" />
<ProjectReference Include="..\..\..\templates\src\IdentityServerAspNetIdentity\IdentityServerAspNetIdentity.csproj" />
<ProjectReference Include="..\..\..\templates\src\IdentityServerEmpty\IdentityServerEmpty.csproj" />
<ProjectReference Include="..\..\..\templates\src\IdentityServerEntityFramework\IdentityServerEntityFramework.csproj" />
<ProjectReference Include="..\..\..\templates\src\IdentityServerInMem\IdentityServerInMem.csproj" />
<ProjectReference Include="..\..\..\templates\src\IdentityServer\IdentityServerTemplate.csproj" />
<ProjectReference Include="..\..\..\templates\src\WebApp\TemplateWebApp.csproj" />
</ItemGroup>
</Project>

View file

@ -163,6 +163,11 @@ void ConfigureWebClients()
RegisterClientIfEnabled<Projects.MvcJarJwt>("mvc-jar-jwt");
RegisterClientIfEnabled<Projects.MvcJarUriJwt>("mvc-jar-uri-jwt");
RegisterClientIfEnabled<Projects.Web>("web");
RegisterTemplateIfEnabled<Projects.IdentityServerTemplate>("template-is", 7001);
RegisterTemplateIfEnabled<Projects.IdentityServerEmpty>("template-is-empty", 7002);
RegisterTemplateIfEnabled<Projects.IdentityServerInMem>("template-is-inmem", 7003);
RegisterTemplateIfEnabled<Projects.IdentityServerAspNetIdentity>("template-is-aspid", 7004);
RegisterTemplateIfEnabled<Projects.IdentityServerEntityFramework>("template-is-ef", 7005);
}
void ConfigureConsoleClients()
@ -224,15 +229,24 @@ bool ApiIsEnabled(string name)
return appConfig.UseApis.TryGetValue(name, out var enabled) && enabled;
}
void RegisterClientIfEnabled<T>(string name, bool explicitStart = false) where T : IProjectMetadata, new()
IResourceBuilder<ProjectResource>? RegisterTemplateIfEnabled<T>(string name, int port) where T : IProjectMetadata, new() =>
RegisterClientIfEnabled<T>(name, useLaunchProfile: false)?.WithHttpsEndpoint(port: port, name: name);
IResourceBuilder<ProjectResource>? RegisterClientIfEnabled<T>(string name, bool explicitStart = false, bool useLaunchProfile = true) where T : IProjectMetadata, new()
{
if (ClientIsEnabled(typeof(T).Name))
{
var resourceBuilder = builder.AddProject<T>(name)
.AddIdentityAndApiReferences(projectRegistry);
var resourceBuilder = useLaunchProfile ?
builder.AddProject<T>(name) :
builder.AddProject<T>(name, launchProfileName: null);
resourceBuilder.AddIdentityAndApiReferences(projectRegistry);
if (explicitStart)
{
resourceBuilder.WithExplicitStart();
}
return resourceBuilder;
}
return null;
}

View file

@ -30,6 +30,11 @@
"ConsoleResourceOwnerFlowRefreshToken": false,
"ConsoleResourceOwnerFlowUserInfo": false,
"ConsoleScopesResources": false,
"IdentityServerTemplate": true,
"IdentityServerEmpty": true,
"IdentityServerInMem": true,
"IdentityServerAspNetIdentity": true,
"IdentityServerEntityFramework": true,
"JsOidc": false,
"MvcAutomaticTokenManagement": true,
"MvcCode": true,

View file

@ -24,6 +24,11 @@ public class IdentityServerAppHostRoutes : IAppHostServiceRoutes
AppHostServices.MvcJarJwt => "https://localhost:44304",
AppHostServices.MvcJarUriJwt => "https://localhost:44305",
AppHostServices.Web => "https://localhost:44306",
AppHostServices.TemplateIs => "https://localhost:7001",
AppHostServices.TemplateIsEmpty => "https://localhost:7002",
AppHostServices.TemplateIsInMem => "https://localhost:7003",
AppHostServices.TemplateIsAspid => "https://localhost:7004",
AppHostServices.TemplateIsEF => "https://localhost:7005",
_ => throw new InvalidOperationException("client not configured")
};
return new Uri(url);
@ -40,4 +45,9 @@ public class AppHostServices
public const string MvcJarJwt = "mvc-jar-jwt";
public const string MvcJarUriJwt = "mvc-jar-uri-jwt";
public const string Web = "web";
public const string TemplateIs = "template-is";
public const string TemplateIsEmpty = "template-is-empty";
public const string TemplateIsInMem = "template-is-inmem";
public const string TemplateIsAspid = "template-is-aspid";
public const string TemplateIsEF = "template-is-ef";
}

View file

@ -10,17 +10,9 @@ using Xunit.Abstractions;
namespace Duende.IdentityServer.EndToEndTests;
[Collection(IdentityServerAppHostCollection.CollectionName)]
public class IdentityServerTests : PlaywrightTestBase<All>
public class IdentityServerTests(ITestOutputHelper output, IdentityServerHostTestFixture fixture)
: PlaywrightTestBase<All>(output, fixture)
{
private readonly HttpClient _identityServerClient;
private readonly HttpClient _webClient;
public IdentityServerTests(ITestOutputHelper output, IdentityServerHostTestFixture fixture) : base(output, fixture)
{
_identityServerClient = CreateHttpClient(AppHostServices.IdentityServer);
_webClient = CreateHttpClient(AppHostServices.Web);
}
[Theory]
[InlineData(AppHostServices.MvcAutomaticTokenManagement)]
[InlineData(AppHostServices.MvcCode)]
@ -29,7 +21,7 @@ public class IdentityServerTests : PlaywrightTestBase<All>
[InlineData(AppHostServices.MvcJarJwt)]
[InlineData(AppHostServices.MvcJarUriJwt)]
[InlineData(AppHostServices.Web)]
public async Task can_login_use_tokens_and_logout(string clientName)
public async Task clients_can_login_use_tokens_and_logout(string clientName)
{
await Page.GotoAsync(Fixture.GetUrlTo(clientName).ToString());
await Page.Login();
@ -38,4 +30,18 @@ public class IdentityServerTests : PlaywrightTestBase<All>
await Page.CallApi();
await Page.Logout();
}
[Theory]
[InlineData(AppHostServices.TemplateIs)]
[InlineData(AppHostServices.TemplateIsEmpty)]
[InlineData(AppHostServices.TemplateIsInMem)]
[InlineData(AppHostServices.TemplateIsAspid)]
// The EF template is disabled because we would need to run the migrations
// [InlineData(AppHostServices.TemplateIsEF)]
public async Task templates_can_serve_discovery(string templateName)
{
var client = CreateHttpClient(templateName);
var response = await client.GetAsync(".well-known/openid-configuration");
response.IsSuccessStatusCode.ShouldBeTrue();
}
}

View file

@ -148,16 +148,16 @@ public class AppHostFixture<THost>(IAppHostServiceRoutes routes) : IAsyncLifetim
/// <summary>
/// This method builds an http client.
/// </summary>
/// <param name="clientName"></param>
/// <param name="hostName"></param>
/// <returns></returns>
public HttpClient CreateHttpClient(string clientName)
public HttpClient CreateHttpClient(string hostName)
{
HttpMessageHandler inner;
Uri? baseAddress;
if (UsingAlreadyRunningInstance)
{
var url = GetUrlTo(clientName);
var url = GetUrlTo(hostName);
baseAddress = url;
inner = new SocketsHttpHandler
@ -182,7 +182,7 @@ public class AppHostFixture<THost>(IAppHostServiceRoutes routes) : IAsyncLifetim
throw new NotSupportedException("App should not be null");
}
var client = _app.CreateHttpClient(clientName);
var client = _app.CreateHttpClient(hostName);
baseAddress = client.BaseAddress;
// We can't directly use the HTTP Client, because we need cookie support, but if we
@ -221,11 +221,11 @@ public class AppHostFixture<THost>(IAppHostServiceRoutes routes) : IAsyncLifetim
};
}
public Uri GetUrlTo(string clientName)
public Uri GetUrlTo(string hostName)
{
if (UsingAlreadyRunningInstance)
{
return routes.UrlTo(clientName);
return routes.UrlTo(hostName);
}
else
{
@ -235,7 +235,7 @@ public class AppHostFixture<THost>(IAppHostServiceRoutes routes) : IAsyncLifetim
throw new NullReferenceException("App should not be null");
}
return _app.GetEndpoint(clientName);
return _app.GetEndpoint(hostName);
#else
Skip.If(true, "When running the Host.Tests using NCrunch, you must start the Hosts.AppHost project manually. IE: dotnet run -p bff/samples/Hosts.AppHost. Or start without debugging from the UI. ");
return null!;

View file

@ -9,5 +9,5 @@ namespace Duende.Xunit.Playwright;
public interface IAppHostServiceRoutes
{
public string[] ServiceNames { get; }
public Uri UrlTo(string clientName);
public Uri UrlTo(string hostName);
}