Merge branch 'phase/38-session'
# Conflicts: # docs/phases/README.md # tests/HSchool.AppHost.Tests/PortraitApiTests.cs
This commit is contained in:
@@ -110,6 +110,7 @@ public class SchoolApiTests(AppHostFixture fixture)
|
||||
public async Task DeleteSchool_ThatDoesNotExist_IsNotFound()
|
||||
{
|
||||
using var client = fixture.App.CreateHttpClient("server");
|
||||
await LoginAsync(client);
|
||||
|
||||
using var response = await client.DeleteAsync("/api/schools/999999", TestContext.Current.CancellationToken);
|
||||
|
||||
@@ -486,6 +487,7 @@ public class SchoolApiTests(AppHostFixture fixture)
|
||||
public async Task Status_ReportsTheLoopAndTheLimit()
|
||||
{
|
||||
using var client = fixture.App.CreateHttpClient("server");
|
||||
await LoginAsync(client);
|
||||
|
||||
var status = await client.GetFromJsonAsync<StatusResponse>("/api/status", TestContext.Current.CancellationToken);
|
||||
|
||||
@@ -510,8 +512,72 @@ public class SchoolApiTests(AppHostFixture fixture)
|
||||
Assert.True(restored.Running);
|
||||
}
|
||||
|
||||
internal const string TestPassword = "test-alpha";
|
||||
internal const string TestUserName = "TestPlayer";
|
||||
|
||||
internal static async Task LoginAsync(HttpClient client, string userName = TestUserName)
|
||||
{
|
||||
using var current = await client.GetAsync("/api/session", TestContext.Current.CancellationToken);
|
||||
if (current.IsSuccessStatusCode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_ = await LoginAndGetCookieAsync(client, userName);
|
||||
}
|
||||
|
||||
internal static async Task<string> LoginAndGetCookieAsync(HttpClient client, string userName = TestUserName)
|
||||
{
|
||||
using var first = await client.PostAsJsonAsync(
|
||||
"/api/session",
|
||||
new { password = TestPassword, userName },
|
||||
TestContext.Current.CancellationToken);
|
||||
|
||||
if (first.IsSuccessStatusCode)
|
||||
{
|
||||
return ExtractSessionCookie(first);
|
||||
}
|
||||
|
||||
if (first.StatusCode == HttpStatusCode.Conflict)
|
||||
{
|
||||
userName = $"T-{Guid.NewGuid():N}"[..10];
|
||||
using var retry = await client.PostAsJsonAsync(
|
||||
"/api/session",
|
||||
new { password = TestPassword, userName },
|
||||
TestContext.Current.CancellationToken);
|
||||
retry.EnsureSuccessStatusCode();
|
||||
return ExtractSessionCookie(retry);
|
||||
}
|
||||
|
||||
first.EnsureSuccessStatusCode();
|
||||
return ExtractSessionCookie(first);
|
||||
}
|
||||
|
||||
internal static string ExtractSessionCookie(HttpResponseMessage response)
|
||||
{
|
||||
if (!response.Headers.TryGetValues("Set-Cookie", out var values))
|
||||
{
|
||||
throw new InvalidOperationException("Login did not return a session cookie.");
|
||||
}
|
||||
|
||||
foreach (var value in values)
|
||||
{
|
||||
if (!value.StartsWith("hschool.session=", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var end = value.IndexOf(';');
|
||||
return end >= 0 ? value[..end] : value;
|
||||
}
|
||||
|
||||
throw new InvalidOperationException("Login did not return a session cookie.");
|
||||
}
|
||||
|
||||
internal static async Task ResetAsync(HttpClient client)
|
||||
{
|
||||
await LoginAsync(client);
|
||||
|
||||
var state = await GetSchoolsAsync(client);
|
||||
|
||||
foreach (var school in state.Schools)
|
||||
|
||||
Reference in New Issue
Block a user