using PrivaPub.Domain.Statuses; using PrivaPub.Tests.Support; using System.Text.Json.Nodes; namespace PrivaPub.Tests.Federation { // one delivery a server: a reply to a follower's post goes to its server's shared inbox once, not also to the // follower's own inbox (BookWyrm kept two copies of a post that reached both at once) [Trait("Category", "Integration")] public sealed class SharedInboxTests : IAsyncLifetime { Harness _harness; public async ValueTask InitializeAsync() { Assert.SkipUnless(MongoFixture.Enabled, MongoFixture.Skip); _harness = await Harness.Start(); } public async ValueTask DisposeAsync() { if (_harness != default) await _harness.DisposeAsync(); } [Fact] public async Task A_reply_to_a_followers_post_reaches_its_server_once_through_the_shared_inbox() { var token = TestContext.Current.CancellationToken; var (_, alice) = await _harness.Persona("alice"); var bob = new RemoteActor(_harness.Peer, "bob", sharedInbox: true); await _harness.FollowedBy(alice, bob); var path = $"/notes/{Guid.NewGuid():N}"; var noteId = new Uri(bob.Id).GetLeftPart(UriPartial.Authority) + path; _harness.Peer.Serve(path, new JsonObject { ["id"] = noteId, ["type"] = "Note", ["attributedTo"] = bob.Id, ["content"] = "

a question

", ["to"] = new JsonArray("https://www.w3.org/ns/activitystreams#Public"), ["published"] = DateTime.UtcNow.ToString("O") }.ToJsonString()); var parent = await _harness.RemotePosts.StoreContext(noteId, 0, token); var reply = await _harness.Statuses.Publish(alice, new StatusDraft { Text = "an answer", InReplyTo = parent.ID }, token); Assert.True(reply.Ok, reply.Error); Assert.Single(await _harness.Outgoing(bob.SharedInbox), a => a["type"]!.GetValue() == "Create"); Assert.Empty(await _harness.Outgoing(bob.Id + "/inbox")); } } }