using Microsoft.Extensions.Configuration; using System.Net.Http.Json; using System.Text.Json; namespace Shogi.AcceptanceTests.TestSetup; /// /// Acceptance Test fixture for tests which assert features for Microsoft accounts. /// 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())?.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())?.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; } }