GetOpenIdConfiguration_returns_ok against testing host
This commit is contained in:
parent
3836faf872
commit
5b48e0bfdb
5 changed files with 70 additions and 75 deletions
|
|
@ -10,7 +10,7 @@ namespace Yavsc.Org.Tests
|
||||||
{
|
{
|
||||||
[Collection("Yavsc Server")]
|
[Collection("Yavsc Server")]
|
||||||
[Trait("regression", "oui")]
|
[Trait("regression", "oui")]
|
||||||
public class BaseTestContext: IClassFixture<WebServerFixture>, IDisposable
|
public class BaseTestContext : IClassFixture<WebServerFixture>, IDisposable
|
||||||
{
|
{
|
||||||
public readonly WebServerFixture _serverFixture;
|
public readonly WebServerFixture _serverFixture;
|
||||||
private readonly ITestOutputHelper _output;
|
private readonly ITestOutputHelper _output;
|
||||||
|
|
@ -21,6 +21,45 @@ namespace Yavsc.Org.Tests
|
||||||
this._output = output;
|
this._output = output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public HttpClient CreateHttpClient()
|
||||||
|
{
|
||||||
|
return new HttpClient(new BypassSslValidationHandler())
|
||||||
|
{
|
||||||
|
BaseAddress = new Uri(this._serverFixture.HttpsAuthority ?? throw new InvalidOperationException("Missing HttpsAuthority"))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Issue a GET against <paramref name="relativePath"/> on the
|
||||||
|
/// in-memory test server. Returns the raw HttpResponseMessage
|
||||||
|
/// without following redirects — the test asserts on the first
|
||||||
|
/// hop, not the eventual page.
|
||||||
|
/// </summary>
|
||||||
|
protected static async Task<HttpResponseMessage> GetRaw(
|
||||||
|
HttpClient client, string relativePath)
|
||||||
|
{
|
||||||
|
Assert.NotNull(client);
|
||||||
|
var request = new HttpRequestMessage(HttpMethod.Get, relativePath);
|
||||||
|
return await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Smoke assertion: a GET on <paramref name="relativePath"/>
|
||||||
|
/// returns 2xx (page served) or 3xx (redirect to login) or
|
||||||
|
/// 401/403 (anonymous rejected by [Authorize]). Anything else
|
||||||
|
/// — 404 (route missing), 5xx (server crash), connection
|
||||||
|
/// refused (host not started) — fails the test.
|
||||||
|
/// </summary>
|
||||||
|
protected static async Task AssertResponds(
|
||||||
|
HttpClient client, string relativePath)
|
||||||
|
{
|
||||||
|
var response = await GetRaw(client, relativePath);
|
||||||
|
var status = (int)response.StatusCode;
|
||||||
|
Assert.True(
|
||||||
|
status >= 200 && status < 400 || status == 401 || status == 403,
|
||||||
|
$"GET {relativePath} returned {status} {response.StatusCode}, " +
|
||||||
|
"expected 2xx/3xx (page or redirect) or 401/403 (auth required).");
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME write a scenario from an empty database [Fact]
|
// FIXME write a scenario from an empty database [Fact]
|
||||||
public void GitClone()
|
public void GitClone()
|
||||||
{
|
{
|
||||||
|
|
@ -36,7 +75,7 @@ namespace Yavsc.Org.Tests
|
||||||
var firstProject = dbContext.Project.Include(p => p.Repository).FirstOrDefault(
|
var firstProject = dbContext.Project.Include(p => p.Repository).FirstOrDefault(
|
||||||
p => p.Name == "Yavsc"
|
p => p.Name == "Yavsc"
|
||||||
);
|
);
|
||||||
Assert.NotNull (firstProject);
|
Assert.NotNull(firstProject);
|
||||||
var di = new DirectoryInfo(_serverFixture.SiteSettings.GitRepository);
|
var di = new DirectoryInfo(_serverFixture.SiteSettings.GitRepository);
|
||||||
if (!di.Exists) di.Create();
|
if (!di.Exists) di.Create();
|
||||||
|
|
||||||
|
|
@ -44,7 +83,7 @@ namespace Yavsc.Org.Tests
|
||||||
clone.Launch(firstProject);
|
clone.Launch(firstProject);
|
||||||
gitRepo = di.FullName;
|
gitRepo = di.FullName;
|
||||||
}
|
}
|
||||||
string gitRepo=null;
|
string gitRepo = null;
|
||||||
private IConfigurationRoot configurationRoot;
|
private IConfigurationRoot configurationRoot;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -57,9 +96,9 @@ namespace Yavsc.Org.Tests
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
if (gitRepo!=null)
|
if (gitRepo != null)
|
||||||
{
|
{
|
||||||
Directory.Delete(Path.Combine(gitRepo,"yavsc"), true);
|
Directory.Delete(Path.Combine(gitRepo, "yavsc"), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,29 @@ namespace Yavsc.Org.Tests
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetSignin_returns_a_page()
|
||||||
|
{
|
||||||
|
using var client = new HttpClient(new BypassSslValidationHandler())
|
||||||
|
{
|
||||||
|
BaseAddress = new Uri(this._serverFixture.HttpsAuthority ?? throw new InvalidOperationException("Missing HttpsAuthority"))
|
||||||
|
};
|
||||||
|
await AssertResponds(client, "/signin");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetOpenIdConfiguration_returns_ok()
|
||||||
|
{
|
||||||
|
using var client = _serverFixture.CreateHttpClient();
|
||||||
|
var response = await GetRaw(client, "/.well-known/openid-configuration");
|
||||||
|
var payload = await response.Content.ReadAsStringAsync();
|
||||||
|
|
||||||
|
Assert.True(
|
||||||
|
response.IsSuccessStatusCode,
|
||||||
|
$"GET /.well-known/openid-configuration returned {(int)response.StatusCode} {response.StatusCode}. Body: {payload}");
|
||||||
|
}
|
||||||
public static IEnumerable<object[]> GetLoginIntentData()
|
public static IEnumerable<object[]> GetLoginIntentData()
|
||||||
{
|
{
|
||||||
return new object[][] { new object[] { "testuser", "test" } };
|
return new object[][] { new object[] { "testuser", "test" } };
|
||||||
|
|
@ -124,4 +147,5 @@ namespace Yavsc.Org.Tests
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ namespace Yavsc.Org.Tests.Smoke;
|
||||||
/// entire pipeline (routing + Razor + IdentityServer + EF + DI)
|
/// entire pipeline (routing + Razor + IdentityServer + EF + DI)
|
||||||
/// is wired correctly end-to-end.
|
/// is wired correctly end-to-end.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class AccountSmokeTests : SmokeTestBase, IClassFixture<TestWebApplicationFactory>
|
public class AccountSmokeTests : IClassFixture<TestWebApplicationFactory>
|
||||||
{
|
{
|
||||||
private readonly TestWebApplicationFactory _factory;
|
private readonly TestWebApplicationFactory _factory;
|
||||||
|
|
||||||
|
|
@ -27,24 +27,7 @@ public class AccountSmokeTests : SmokeTestBase, IClassFixture<TestWebApplication
|
||||||
_factory = factory;
|
_factory = factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task GetSignin_returns_a_page()
|
|
||||||
{
|
|
||||||
using var client = _factory.CreateClient();
|
|
||||||
await AssertResponds(client, "/signin");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task GetOpenIdConfiguration_returns_ok()
|
|
||||||
{
|
|
||||||
using var client = _factory.CreateClient();
|
|
||||||
var response = await GetRaw(client, "/.well-known/openid-configuration");
|
|
||||||
var payload = await response.Content.ReadAsStringAsync();
|
|
||||||
|
|
||||||
Assert.True(
|
|
||||||
response.IsSuccessStatusCode,
|
|
||||||
$"GET /.well-known/openid-configuration returned {(int)response.StatusCode} {response.StatusCode}. Body: {payload}");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ResourceStore_get_all_resources_does_not_throw()
|
public async Task ResourceStore_get_all_resources_does_not_throw()
|
||||||
|
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
namespace Yavsc.Org.Tests.Smoke;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Base for the smoke tests covering the production hosts
|
|
||||||
/// (Yavsc.Org / Yavsc.Api / Yavsc.Blogs). One smoke test per
|
|
||||||
/// bounded context (BC): each test hits one GET endpoint and
|
|
||||||
/// asserts a 2xx or 3xx status, with no follow-up redirect.
|
|
||||||
/// Together they satisfy the 'Tests d'intégration smoke par BC'
|
|
||||||
/// item of Jalon 0 in <c>ROADMAP.md</c>.
|
|
||||||
///
|
|
||||||
/// Status code policy:
|
|
||||||
/// - 200 OK : endpoint serves a page.
|
|
||||||
/// - 302 / 301 : endpoint requires auth and redirects to login
|
|
||||||
/// (acceptable smoke signal: routing + middleware are wired).
|
|
||||||
/// - 401 / 403 : endpoint exists but rejects anonymous (acceptable
|
|
||||||
/// for API smoke tests where the smoke is "the host boots").
|
|
||||||
/// Anything else (404, 500, connection refused) is a failure.
|
|
||||||
/// </summary>
|
|
||||||
public abstract class SmokeTestBase
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Issue a GET against <paramref name="relativePath"/> on the
|
|
||||||
/// in-memory test server. Returns the raw HttpResponseMessage
|
|
||||||
/// without following redirects — the test asserts on the first
|
|
||||||
/// hop, not the eventual page.
|
|
||||||
/// </summary>
|
|
||||||
protected static async Task<HttpResponseMessage> GetRaw(
|
|
||||||
HttpClient client, string relativePath)
|
|
||||||
{
|
|
||||||
Assert.NotNull(client);
|
|
||||||
var request = new HttpRequestMessage(HttpMethod.Get, relativePath);
|
|
||||||
return await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Smoke assertion: a GET on <paramref name="relativePath"/>
|
|
||||||
/// returns 2xx (page served) or 3xx (redirect to login) or
|
|
||||||
/// 401/403 (anonymous rejected by [Authorize]). Anything else
|
|
||||||
/// — 404 (route missing), 5xx (server crash), connection
|
|
||||||
/// refused (host not started) — fails the test.
|
|
||||||
/// </summary>
|
|
||||||
protected static async Task AssertResponds(
|
|
||||||
HttpClient client, string relativePath)
|
|
||||||
{
|
|
||||||
var response = await GetRaw(client, relativePath);
|
|
||||||
var status = (int)response.StatusCode;
|
|
||||||
Assert.True(
|
|
||||||
status >= 200 && status < 400 || status == 401 || status == 403,
|
|
||||||
$"GET {relativePath} returned {status} {response.StatusCode}, " +
|
|
||||||
"expected 2xx/3xx (page or redirect) or 401/403 (auth required).");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -78,6 +78,7 @@ public sealed class WebServerFixture : WebHostFixture
|
||||||
public RecordingSmtpClientFactory? SmtpClientFactory { get; private set; }
|
public RecordingSmtpClientFactory? SmtpClientFactory { get; private set; }
|
||||||
public ILogger? Logger { get; internal set; }
|
public ILogger? Logger { get; internal set; }
|
||||||
|
|
||||||
|
public string? HttpsAuthority => Addresses.FirstOrDefault(u => u.StartsWith("https:"));
|
||||||
protected override WebApplication BuildApp(WebApplicationBuilder builder)
|
protected override WebApplication BuildApp(WebApplicationBuilder builder)
|
||||||
{
|
{
|
||||||
var authority = $"https://localhost:{_httpsPort}";
|
var authority = $"https://localhost:{_httpsPort}";
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue