using System.Net; using System.Net.Http.Headers; using System.Net.Http.Json; using System.Text.Json.Nodes; using decePubClient.E2E.Support; using Microsoft.Playwright; namespace decePubClient.E2E.Actions { // A login of its own, made for the test: its password changed in Settings, then the whole of it deleted there, each // checked against PrivaPub's own login public sealed class AccountTests(Browser browser) { const string FirstPassword = "Pasture-Pass-1!"; const string SecondPassword = "Pasture-Pass-2!"; static async Task Login(string root, string password) { using var http = Pasture.Http(); using var response = await http.PostAsJsonAsync(Pasture.Api + "/clientapi/user/login", new { userName = root, password }); return response.StatusCode; } [Fact] public async Task A_logins_password_is_changed_and_the_login_deleted_from_settings() { var stamp = DateTime.UtcNow.ToString("MMddHHmmss"); var root = $"e2eroot{stamp}"; using (var http = Pasture.Http()) { using var signup = await http.PostAsJsonAsync(Pasture.Api + "/clientapi/user/signup", new { userName = root, password = FirstPassword }); Assert.SkipWhen(!signup.IsSuccessStatusCode, $"PrivaPub refuses sign-ups ({(int)signup.StatusCode})"); var jwt = JsonNode.Parse(await signup.Content.ReadAsStringAsync())!["token"]!.GetValue(); using var insert = new HttpRequestMessage(HttpMethod.Post, Pasture.Api + "/clientapi/avatar/private/insert") { Content = JsonContent.Create(new { userName = $"e2eacct{stamp}", name = "an e2e persona", biography = "for the account test" }) }; insert.Headers.Authorization = new AuthenticationHeaderValue("Bearer", jwt); using var inserted = await http.SendAsync(insert); Assert.True(inserted.IsSuccessStatusCode, $"the persona could not be made ({(int)inserted.StatusCode})"); } var persona = new Pasture.Persona($"e2eacct{stamp}", "an e2e persona", root, FirstPassword, null, null, null); await using var session = await SignIn.As(browser, persona, fresh: true); var page = session.Page; await Results.Cell("client.action.account", "privapub", root, async () => { await page.GotoAsync($"{Pasture.Site}/settings"); await page.Locator("[data-settings-account]").ClickAsync(); await page.Locator("input[data-account-current]").FillAsync(FirstPassword); await page.Locator("input[data-account-new]").FillAsync(SecondPassword); await page.Locator("input[data-account-repeat]").FillAsync(SecondPassword); await page.Locator("[data-account-password-save]").ClickAsync(); Assert.True(await Pasture.Eventually(async () => await Login(root, SecondPassword) == HttpStatusCode.OK, 15), "the new password never worked"); Assert.NotEqual(HttpStatusCode.OK, await Login(root, FirstPassword)); await page.Locator("input[data-account-delete-password]").FillAsync(SecondPassword); await page.Locator("input[data-account-delete-understood]").CheckAsync(); await page.Locator("[data-account-delete-confirm]").ClickAsync(); await page.WaitForURLAsync(url => new Uri(url).AbsolutePath == "/login", new() { Timeout = 30000 }); Assert.True(await Pasture.Eventually(async () => await Login(root, SecondPassword) != HttpStatusCode.OK, 15), "the deleted login still signs in"); await session.AssertGuards(); }, page); } } }