Record edit history for Note and Question Updates

This commit is contained in:
Tusooa Zhu 2022-05-29 13:54:16 -04:00
parent 0f6a5eb9a2
commit 5e8aac0e07
No known key found for this signature in database
GPG Key ID: 7B467EDE43A08224
3 changed files with 72 additions and 2 deletions

View File

@ -410,6 +410,26 @@ defp handle_update_user(
{:ok, object, meta} {:ok, object, meta}
end end
defp history_for_object(object) do
with history <- Map.get(object, "formerRepresentations"),
true <- is_map(history),
"OrderedCollection" <- Map.get(history, "type"),
true <- is_list(Map.get(history, "orderedItems")),
true <- is_integer(Map.get(history, "totalItems")) do
history
else
_ -> history_skeleton()
end
end
defp history_skeleton do
%{
"type" => "OrderedCollection",
"totalItems" => 0,
"orderedItems" => []
}
end
@updatable_object_types ["Note", "Question"] @updatable_object_types ["Note", "Question"]
# We do not allow poll options to be changed, but the poll description can be. # We do not allow poll options to be changed, but the poll description can be.
@updatable_fields [ @updatable_fields [
@ -431,6 +451,19 @@ defp handle_update_object(
orig_object_data = orig_object.data orig_object_data = orig_object.data
if orig_object_data["type"] in @updatable_object_types do if orig_object_data["type"] in @updatable_object_types do
# Put edit history
# Note that we may have got the edit history by first fetching the object
history = history_for_object(orig_object_data)
latest_history_item =
orig_object_data
|> Map.drop(["id", "formerRepresentations"])
new_history =
history
|> Map.put("orderedItems", [latest_history_item | history["orderedItems"]])
|> Map.put("totalItems", history["totalItems"] + 1)
updated_object_data = updated_object_data =
@updatable_fields @updatable_fields
|> Enum.reduce( |> Enum.reduce(
@ -443,6 +476,7 @@ defp handle_update_object(
end end
end end
) )
|> Map.put("formerRepresentations", new_history)
orig_object orig_object
|> Object.change(%{data: updated_object_data}) |> Object.change(%{data: updated_object_data})

View File

@ -36,7 +36,8 @@
"@id": "as:alsoKnownAs", "@id": "as:alsoKnownAs",
"@type": "@id" "@type": "@id"
}, },
"vcard": "http://www.w3.org/2006/vcard/ns#" "vcard": "http://www.w3.org/2006/vcard/ns#",
"formerRepresentations": "litepub:formerRepresentations"
} }
] ]
} }

View File

@ -153,7 +153,7 @@ test "it uses a given changeset to update", %{user: user, update: update} do
{:ok, update_data, []} = Builder.update(user, updated_note) {:ok, update_data, []} = Builder.update(user, updated_note)
{:ok, update, _meta} = ActivityPub.persist(update_data, local: true) {:ok, update, _meta} = ActivityPub.persist(update_data, local: true)
%{user: user, object_id: note.id, update_data: update_data, update: update} %{user: user, note: note, object_id: note.id, update_data: update_data, update: update}
end end
test "it updates the note", %{object_id: object_id, update: update} do test "it updates the note", %{object_id: object_id, update: update} do
@ -161,6 +161,41 @@ test "it updates the note", %{object_id: object_id, update: update} do
new_note = Pleroma.Object.get_by_id(object_id) new_note = Pleroma.Object.get_by_id(object_id)
assert %{"summary" => "edited summary", "content" => "edited content"} = new_note.data assert %{"summary" => "edited summary", "content" => "edited content"} = new_note.data
end end
test "it records the original note in formerRepresentations", %{
note: note,
object_id: object_id,
update: update
} do
{:ok, _, _} = SideEffects.handle(update)
%{data: new_note} = Pleroma.Object.get_by_id(object_id)
assert %{"summary" => "edited summary", "content" => "edited content"} = new_note
assert [Map.drop(note.data, ["id", "formerRepresentations"])] ==
new_note["formerRepresentations"]["orderedItems"]
assert new_note["formerRepresentations"]["totalItems"] == 1
end
test "it puts the original note at the front of formerRepresentations", %{
note: note,
object_id: object_id,
update: update
} do
{:ok, _, _} = SideEffects.handle(update)
%{data: first_edit} = Pleroma.Object.get_by_id(object_id)
{:ok, _, _} = SideEffects.handle(update)
%{data: new_note} = Pleroma.Object.get_by_id(object_id)
assert %{"summary" => "edited summary", "content" => "edited content"} = new_note
original_version = Map.drop(note.data, ["id", "formerRepresentations"])
first_edit = Map.drop(first_edit, ["id", "formerRepresentations"])
assert [first_edit, original_version] ==
new_note["formerRepresentations"]["orderedItems"]
assert new_note["formerRepresentations"]["totalItems"] == 2
end
end end
describe "EmojiReact objects" do describe "EmojiReact objects" do