70 lines
3.9 KiB
C#
70 lines
3.9 KiB
C#
using System.Diagnostics;
|
|||
|
|
using System.Text.Json.Nodes;
|
||
|
|
|
||
|
|
using decePubClient.E2E.Support;
|
||
|
|
|
||
|
|
using Microsoft.Playwright;
|
||
|
|
|
||
|
|
namespace decePubClient.E2E.Actions
|
||
|
|
{
|
||
|
|
// Joining another server's event from its card (an owner decision): the persona is asked once that taking part is
|
||
|
|
// public, Mobilizon makes it a participant and accepts, and leaving takes it off there. The event is the one
|
||
|
|
// SocialPub's tools/pasture/scenarios/mobilizon.sh keeps for these tests.
|
||
|
|
public sealed class EventTests(Browser browser)
|
||
|
|
{
|
||
|
|
[Fact]
|
||
|
|
public async Task A_persona_joins_a_mobilizon_event_from_its_card_and_leaves_it()
|
||
|
|
{
|
||
|
|
var kept = Path.Combine(Pasture.Root, ".state", "mobilizon-kept-event.json");
|
||
|
|
Assert.SkipUnless(File.Exists(kept), "no Mobilizon event kept for the client: run tools/pasture/interop.sh mobilizon");
|
||
|
|
var url = JsonNode.Parse(File.ReadAllText(kept))!["url"]!.GetValue<string>();
|
||
|
|
var personas = Pasture.Personas();
|
||
|
|
Assert.SkipWhen(personas.Count == 0, "the town has no personas");
|
||
|
|
var reader = personas[0];
|
||
|
|
var status = (await PersonaApi.Call(reader, $"/api/v2/search?q={Uri.EscapeDataString(url)}&resolve=true&type=statuses"))?["statuses"]?.AsArray().FirstOrDefault();
|
||
|
|
Assert.SkipWhen(status is null, "PrivaPub cannot resolve the kept Mobilizon event");
|
||
|
|
var id = status!["id"]!.GetValue<string>();
|
||
|
|
async Task<string> Participation() =>
|
||
|
|
(await PersonaApi.Call(reader, $"/api/v1/statuses/{id}"))?["privapub"]?["event"]?["participation"]?.GetValue<string>();
|
||
|
|
// a run cut short may have left the persona in: start from outside
|
||
|
|
if (await Participation() is not null)
|
||
|
|
await PersonaApi.Call(reader, $"/api/privapub/v1/statuses/{id}/leave", HttpMethod.Post);
|
||
|
|
await using var session = await SignIn.As(browser, reader);
|
||
|
|
var page = session.Page;
|
||
|
|
await Results.Cell("client.action.join", "mobilizon", "kept-event", async () =>
|
||
|
|
{
|
||
|
|
await page.GotoAsync($"{Pasture.Site}/expand/{id}");
|
||
|
|
var card = page.Locator($"article[data-uri='{status["uri"]!.GetValue<string>()}']").First;
|
||
|
|
await card.Locator("[data-event-join]").ClickAsync(new() { Timeout = 30000 });
|
||
|
|
await VoteAndReactTests.AcceptNoticeIfAsked(page);
|
||
|
|
await card.Locator("[data-event-leave]").WaitForAsync(new() { Timeout = 15000 });
|
||
|
|
Assert.True(await Pasture.Eventually(async () => await Participation() == "accepted", 45), "Mobilizon never accepted the Join");
|
||
|
|
Assert.Equal("participant", await MobilizonRole(reader.ActorUri, url));
|
||
|
|
|
||
|
|
await page.ReloadAsync();
|
||
|
|
await Assertions.Expect(card.Locator("[data-participation]")).ToHaveAttributeAsync("data-participation", "accepted", new() { Timeout = 30000 });
|
||
|
|
await card.Locator("[data-event-leave]").ClickAsync();
|
||
|
|
await Assertions.Expect(card.Locator("[data-participation]")).ToHaveAttributeAsync("data-participation", "none", new() { Timeout = 15000 });
|
||
|
|
Assert.Null(await Participation());
|
||
|
|
Assert.True(await Pasture.Eventually(async () => await MobilizonRole(reader.ActorUri, url) == "", 45),
|
||
|
|
"the persona is still a participant on Mobilizon");
|
||
|
|
await session.AssertGuards();
|
||
|
|
}, page);
|
||
|
|
}
|
||
|
|
|
||
|
|
// the persona's role in the event, from Mobilizon's database; empty when it takes no part
|
||
|
|
static async Task<string> MobilizonRole(string actorUri, string eventUrl)
|
||
|
|
{
|
||
|
|
static string Quoted(string value) => "'" + value.Replace("'", "''") + "'";
|
||
|
|
var start = new ProcessStartInfo("podman") { RedirectStandardOutput = true, RedirectStandardError = true };
|
||
|
|
foreach (var arg in new[] { "exec", "pasture-postgis", "psql", "-U", "pasture", "-d", "mobilizon", "-tAc",
|
||
|
|
"select p.role from participants p join actors a on a.id = p.actor_id join events e on e.id = p.event_id " +
|
||
|
|
$"where a.url = {Quoted(actorUri)} and e.url = {Quoted(eventUrl)}" })
|
||
|
|
start.ArgumentList.Add(arg);
|
||
|
|
using var process = Process.Start(start)!;
|
||
|
|
var output = await process.StandardOutput.ReadToEndAsync();
|
||
|
|
await process.WaitForExitAsync();
|
||
|
|
return output.Trim();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|