A follow of a persona's profile page; an Update under its Create's id
Forte follows a persona by its profile page (/@name, WebFinger's alias) rather than its actor's id: Follow and
Undo{Follow} now find the persona by either (it was a 404). Forte also sends an edit only added to the thread's context
(FEP-171b), under the same activity id as the post's Create: the unwrapping now tells two activities that share an id
apart by what they carry, as the inbox does, so the Update is not taken for a copy.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
This commit is contained in:
1 parent
d06f684f0d
commit
99b5e2dbf3
6 files changed
+67
-8
No files matched your search
@@ -90,6 +90,39 @@ namespace PrivaPub.Tests.Federation
|
||||
Assert.Equal((await DB.Default.Find<PostEntity>().Match(p => p.ObjectURI == rootId).ExecuteFirstAsync(Token)).ID, stored.AnsweringToPostId);
|
||||
}
|
||||
|
||||
// Forte gives a post's Update the id of its Create, and sends it only added to the thread's context
|
||||
[Fact]
|
||||
public async Task An_update_added_under_its_creates_id_is_taken_as_the_edit()
|
||||
{
|
||||
var (_, alice) = await _harness.Persona("alice");
|
||||
var owner = new RemoteActor(_harness.Peer, "owner", ed25519: true);
|
||||
await DB.Default.SaveAsync(new Following { AvatarId = alice.Id, TargetActorURI = owner.Id, TargetInboxURL = owner.Id + "/inbox", State = FollowState.Accepted }, Token);
|
||||
var context = $"{Origin(owner)}/conversation/{Guid.NewGuid():N}";
|
||||
var create = owner.Prove(Create(owner, "as first written", context));
|
||||
JsonObject Added(JsonObject inner) => owner.Prove(new JsonObject
|
||||
{
|
||||
["id"] = $"{Origin(owner)}/activity/{Guid.NewGuid():N}", ["type"] = "Add", ["actor"] = owner.Id, ["object"] = inner,
|
||||
["target"] = new JsonObject { ["id"] = context, ["type"] = "Collection", ["attributedTo"] = owner.Id }
|
||||
});
|
||||
await _harness.Deliver(owner, "/human-centipede", Added(create));
|
||||
await RunQueued(create["id"]!.GetValue<string>());
|
||||
var update = create.DeepClone().AsObject();
|
||||
update.Remove("proof");
|
||||
update["type"] = "Update";
|
||||
update["object"]!["content"] = "<p>as edited</p>";
|
||||
update["object"]!["updated"] = DateTime.UtcNow.AddSeconds(1).ToString("O");
|
||||
owner.Prove(update);
|
||||
|
||||
await _harness.Deliver(owner, "/human-centipede", Added(update));
|
||||
var job = await DB.Default.Find<Job>().Match(j => j.DedupeKey.StartsWith("inbox|forwarded|" + update["id"]!.GetValue<string>() + "|") && j.State == JobState.Pending)
|
||||
.ExecuteFirstAsync(Token);
|
||||
Assert.NotNull(job);
|
||||
Assert.Equal(JobResult.Done, (await _harness.Processor.Handle(job, Token)).Result);
|
||||
|
||||
var noteId = create["object"]!["id"]!.GetValue<string>();
|
||||
Assert.Contains("as edited", (await DB.Default.Find<PostEntity>().Match(p => p.ObjectURI == noteId).ExecuteFirstAsync(Token)).ContentHtml);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task An_add_to_a_collection_on_another_server_is_no_threads()
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user