Replace custom socket implementation with SignalR.

Replace MSAL and custom cookie auth with Microsoft.Identity.EntityFramework
Also some UI redesign to accommodate different login experience.
This commit is contained in:
2024-08-25 03:46:44 +00:00
parent d688afaeae
commit 51d234d871
172 changed files with 3857 additions and 4045 deletions

View File

@@ -0,0 +1,114 @@
using Microsoft.Extensions.Configuration;
using System.Net.Http.Json;
using System.Text.Json;
namespace Shogi.AcceptanceTests.TestSetup;
/// <summary>
/// Acceptance Test fixture for tests which assert features for Microsoft accounts.
/// </summary>
public class AatTestFixture : IAsyncLifetime, IDisposable
{
protected static readonly JsonSerializerOptions SerializerOptions = new(JsonSerializerDefaults.Web);
private readonly string testAccountPassword;
private bool disposedValue;
public AatTestFixture()
{
this.Configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddJsonFile("appsettings.Development.json", optional: true)
.Build();
var baseUrl = this.Configuration["ServiceUrl"] ?? throw new InvalidOperationException();
this.HttpClient = new HttpClient
{
BaseAddress = new Uri(baseUrl, UriKind.Absolute)
};
this.OtherHttpClient = new HttpClient
{
BaseAddress = new Uri(baseUrl, UriKind.Absolute)
};
this.testAccountPassword = this.Configuration["TestUserPassword"]!;
if (string.IsNullOrWhiteSpace(this.testAccountPassword))
{
throw new InvalidOperationException("TestUserPassword is not configured.");
}
}
public IConfiguration Configuration { get; private set; }
public HttpClient HttpClient { get; }
public HttpClient OtherHttpClient { get; }
protected async Task LoginToTestAccounts()
{
var response = await this.HttpClient.PostAsJsonAsync(
RelativeUri("login"),
new
{
email = "aat-account",
password = this.testAccountPassword,
},
options: SerializerOptions);
response.IsSuccessStatusCode.Should().BeTrue(because: "The test account should exist. If it does not, use the /Account/TestAccount route to create it.");
var bearerToken = (await response.Content.ReadFromJsonAsync<LoginResponse>())?.AccessToken;
this.HttpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", bearerToken);
response = await this.HttpClient.PostAsJsonAsync(
RelativeUri("login"),
new
{
email = "aat-account-2",
password = this.testAccountPassword,
},
options: SerializerOptions);
response.IsSuccessStatusCode.Should().BeTrue(because: "The test account should exist. If it does not, use the /Account/TestAccount route to create it.");
bearerToken = (await response.Content.ReadFromJsonAsync<LoginResponse>())?.AccessToken;
this.OtherHttpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", bearerToken);
}
public async Task InitializeAsync()
{
await this.LoginToTestAccounts();
}
protected virtual void Dispose(bool disposing)
{
if (!this.disposedValue)
{
if (disposing)
{
this.HttpClient.Dispose();
}
this.disposedValue = true;
}
}
public Task DisposeAsync()
{
this.Dispose(true);
return Task.CompletedTask;
}
public void Dispose()
{
this.Dispose(disposing: true);
GC.SuppressFinalize(this);
}
protected static Uri RelativeUri(string s) => new(s, UriKind.Relative);
private class LoginResponse
{
public string AccessToken { get; set; } = string.Empty;
}
}