Refactor Core things, including Ecto handling, ActivityPub & Transmogrifier modules

* Data doesn't need anymore to be converted to ActivityStream format to
be saved (this was taken from Pleroma and not at all a good idea here)
* Everything saved when creating an event is inserted into PostgreSQL in
a single transaction
This commit is contained in:
Thomas Citharel
2019-10-25 17:43:37 +02:00
parent 814cfbc8eb
commit cc820d6b63
69 changed files with 1881 additions and 1424 deletions

View File

@@ -99,7 +99,7 @@ defmodule Mobilizon.ActorsTest do
preferred_username: preferred_username,
domain: domain,
avatar: %FileModel{name: picture_name} = _picture
} = _actor} = ActivityPub.get_or_fetch_by_url(@remote_account_url)
} = _actor} = ActivityPub.get_or_fetch_actor_by_url(@remote_account_url)
assert picture_name == "avatar"
@@ -149,7 +149,7 @@ defmodule Mobilizon.ActorsTest do
test "get_actor_by_name_with_preload!/1 returns the remote actor with its organized events" do
use_cassette "actors/remote_actor_mastodon_tcit" do
with {:ok, %Actor{} = actor} <- ActivityPub.get_or_fetch_by_url(@remote_account_url) do
with {:ok, %Actor{} = actor} <- ActivityPub.get_or_fetch_actor_by_url(@remote_account_url) do
assert Actors.get_actor_by_name_with_preload(
"#{actor.preferred_username}@#{actor.domain}"
).organized_events == []
@@ -178,7 +178,8 @@ defmodule Mobilizon.ActorsTest do
test "test build_actors_by_username_or_name_page/4 returns actors with similar usernames",
%{actor: %Actor{id: actor_id}} do
use_cassette "actors/remote_actor_mastodon_tcit" do
with {:ok, %Actor{id: actor2_id}} <- ActivityPub.get_or_fetch_by_url(@remote_account_url) do
with {:ok, %Actor{id: actor2_id}} <-
ActivityPub.get_or_fetch_actor_by_url(@remote_account_url) do
%Page{total: 2, elements: actors} =
Actors.build_actors_by_username_or_name_page("tcit", [:Person])
@@ -253,12 +254,11 @@ defmodule Mobilizon.ActorsTest do
}
{:ok, data} = MobilizonWeb.Upload.store(file)
url = hd(data["url"])["href"]
assert {:ok, actor} =
Actors.update_actor(
actor,
Map.put(@update_attrs, :avatar, %{name: file.filename, url: url})
Map.put(@update_attrs, :avatar, %{name: file.filename, url: data.url})
)
assert %Actor{} = actor

View File

@@ -115,7 +115,7 @@ defmodule Mobilizon.EventsTest do
end
test "create_event/1 with invalid data returns error changeset" do
assert {:error, %Ecto.Changeset{}} = Events.create_event(@invalid_attrs)
assert {:error, :insert, %Ecto.Changeset{}, _} = Events.create_event(@invalid_attrs)
end
test "update_event/2 with valid data updates the event", %{event: event} do
@@ -128,7 +128,7 @@ defmodule Mobilizon.EventsTest do
end
test "update_event/2 with invalid data returns error changeset", %{event: event} do
assert {:error, %Ecto.Changeset{}} = Events.update_event(event, @invalid_attrs)
assert {:error, :update, %Ecto.Changeset{}, _} = Events.update_event(event, @invalid_attrs)
assert event.title == Events.get_event!(event.id).title
end
@@ -345,7 +345,8 @@ defmodule Mobilizon.EventsTest do
end
test "create_participant/1 with invalid data returns error changeset" do
assert {:error, %Ecto.Changeset{}} = Events.create_participant(@invalid_attrs)
assert {:error, :participant, %Ecto.Changeset{}, _} =
Events.create_participant(@invalid_attrs)
end
test "update_participant/2 with valid data updates the participant", %{

View File

@@ -14,12 +14,10 @@ defmodule Mobilizon.Service.ActivityPub.ActivityPubTest do
alias Mobilizon.Actors.Actor
alias Mobilizon.Events
alias Mobilizon.Events.Event
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Service.ActivityPub.Converter
alias Mobilizon.Service.HTTPSignatures.Signature
alias MobilizonWeb.ActivityPub.ActorView
@activity_pub_public_audience "https://www.w3.org/ns/activitystreams#Public"
setup_all do
HTTPoison.start()
@@ -53,7 +51,7 @@ defmodule Mobilizon.Service.ActivityPub.ActivityPubTest do
test "returns an actor from url" do
use_cassette "activity_pub/fetch_framapiaf.org_users_tcit" do
assert {:ok, %Actor{preferred_username: "tcit", domain: "framapiaf.org"}} =
ActivityPub.get_or_fetch_by_url("https://framapiaf.org/users/tcit")
ActivityPub.get_or_fetch_actor_by_url("https://framapiaf.org/users/tcit")
end
end
end
@@ -165,28 +163,15 @@ defmodule Mobilizon.Service.ActivityPub.ActivityPubTest do
test "it creates an update activity with the new actor data" do
actor = insert(:actor)
actor_data = ActorView.render("actor.json", %{actor: actor})
actor_data = Map.put(actor_data, "summary", @updated_actor_summary)
actor_data = %{summary: @updated_actor_summary}
{:ok, update, updated_actor} =
ActivityPub.update(%{
actor: actor_data["url"],
to: [actor.url <> "/followers"],
cc: [],
object: actor_data
})
{:ok, update, _} = ActivityPub.update(:actor, actor, actor_data, false)
assert update.data["actor"] == actor.url
assert update.data["to"] == [actor.url <> "/followers"]
assert update.data["object"]["id"] == actor_data["id"]
assert update.data["object"]["type"] == actor_data["type"]
assert update.data["to"] == [@activity_pub_public_audience]
assert update.data["object"]["id"] == actor.url
assert update.data["object"]["type"] == "Person"
assert update.data["object"]["summary"] == @updated_actor_summary
refute updated_actor.summary == actor.summary
{:ok, %Actor{} = database_actor} = Mobilizon.Actors.get_actor_by_url(actor.url)
assert database_actor.summary == @updated_actor_summary
assert database_actor.preferred_username == actor.preferred_username
end
@updated_start_time DateTime.utc_now() |> DateTime.truncate(:second)
@@ -194,28 +179,15 @@ defmodule Mobilizon.Service.ActivityPub.ActivityPubTest do
test "it creates an update activity with the new event data" do
actor = insert(:actor)
event = insert(:event, organizer_actor: actor)
event_data = Converter.Event.model_to_as(event)
event_data = Map.put(event_data, "startTime", @updated_start_time)
event_data = %{begins_on: @updated_start_time}
{:ok, update, updated_event} =
ActivityPub.update(%{
actor: actor.url,
to: [actor.url <> "/followers"],
cc: [],
object: event_data
})
{:ok, update, _} = ActivityPub.update(:event, event, event_data)
assert update.data["actor"] == actor.url
assert update.data["to"] == [actor.url <> "/followers"]
assert update.data["object"]["id"] == event_data["id"]
assert update.data["object"]["type"] == event_data["type"]
assert update.data["object"]["startTime"] == @updated_start_time
refute updated_event.begins_on == event.begins_on
%Event{} = database_event = Mobilizon.Events.get_event_by_url(event.url)
assert database_event.begins_on == @updated_start_time
assert database_event.title == event.title
assert update.data["to"] == [@activity_pub_public_audience]
assert update.data["object"]["id"] == event.url
assert update.data["object"]["type"] == "Event"
assert update.data["object"]["startTime"] == DateTime.to_iso8601(@updated_start_time)
end
end
end

View File

@@ -15,7 +15,7 @@ defmodule Mobilizon.Service.ActivityPub.Converter.ActorTest do
describe "AS to Actor" do
test "valid as data to model" do
actor =
{:ok, actor} =
ActorConverter.as_to_model_data(%{
"type" => "Person",
"preferredUsername" => "test_account"

View File

@@ -124,10 +124,10 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
assert data["to"] == ["https://www.w3.org/ns/activitystreams#Public"]
assert data["cc"] == [
"https://framapiaf.org/users/admin/followers",
"http://mobilizon.com/@tcit"
]
# assert data["cc"] == [
# "https://framapiaf.org/users/admin/followers",
# "http://mobilizon.com/@tcit"
# ]
assert data["actor"] == "https://framapiaf.org/users/admin"
@@ -136,16 +136,14 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
assert object["to"] == ["https://www.w3.org/ns/activitystreams#Public"]
assert object["cc"] == [
"https://framapiaf.org/users/admin/followers",
"http://localtesting.pleroma.lol/users/lain"
]
# assert object["cc"] == [
# "https://framapiaf.org/users/admin/followers",
# "http://localtesting.pleroma.lol/users/lain"
# ]
assert object["actor"] == "https://framapiaf.org/users/admin"
assert object["attributedTo"] == "https://framapiaf.org/users/admin"
assert object["sensitive"] == true
{:ok, %Actor{}} = Actors.get_actor_by_url(object["actor"])
end
@@ -153,6 +151,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
data = File.read!("test/fixtures/mastodon-post-activity-hashtag.json") |> Jason.decode!()
{:ok, %Activity{data: data, local: false}, _} = Transmogrifier.handle_incoming(data)
assert Enum.at(data["object"]["tag"], 0)["name"] == "@tcit@framapiaf.org"
assert Enum.at(data["object"]["tag"], 1)["name"] == "#moo"
end
@@ -347,9 +346,9 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
|> Map.put("actor", data["actor"])
|> Map.put("object", object)
{:ok, %Activity{data: data, local: false}, _} = Transmogrifier.handle_incoming(update_data)
{:ok, %Activity{data: _data, local: false}, _} = Transmogrifier.handle_incoming(update_data)
{:ok, %Actor{} = actor} = Actors.get_actor_by_url(data["actor"])
{:ok, %Actor{} = actor} = Actors.get_actor_by_url(update_data["actor"])
assert actor.name == "nextsoft"
assert actor.summary == "<p>Some bio</p>"
@@ -406,7 +405,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
test "it works for incoming deletes" do
%Actor{url: actor_url} = actor = insert(:actor)
%Comment{url: comment_url} = insert(:comment, actor: actor)
%Comment{url: comment_url} = insert(:comment, actor: nil, actor_id: actor.id)
data =
File.read!("test/fixtures/mastodon-delete.json")
@@ -622,8 +621,8 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
|> Map.put("object", follow_activity.data["id"])
{:ok, activity, _} = Transmogrifier.handle_incoming(accept_data)
assert activity.data["object"] == follow_activity.data["id"]
assert activity.data["object"] =~ "/follow/"
assert activity.data["object"]["id"] == follow_activity.data["id"]
assert activity.data["object"]["id"] =~ "/follow/"
assert activity.data["id"] =~ "/accept/follow/"
{:ok, follower} = Actors.get_actor_by_url(follower.url)
@@ -756,8 +755,8 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
|> Map.put("object", participation.url)
{:ok, accept_activity, _} = Transmogrifier.handle_incoming(accept_data)
assert accept_activity.data["object"] == join_activity.data["id"]
assert accept_activity.data["object"] =~ "/join/"
assert accept_activity.data["object"]["id"] == join_activity.data["id"]
assert accept_activity.data["object"]["id"] =~ "/join/"
assert accept_activity.data["id"] =~ "/accept/join/"
# We don't accept already accepted Accept activities
@@ -847,10 +846,10 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
other_actor = insert(:actor)
{:ok, activity, _} =
API.Comments.create_comment(
actor.preferred_username,
"hey, @#{other_actor.preferred_username}, how are ya? #2hu"
)
API.Comments.create_comment(%{
actor_id: actor.id,
text: "hey, @#{other_actor.preferred_username}, how are ya? #2hu"
})
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
object = modified["object"]
@@ -883,7 +882,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
test "it adds the json-ld context and the conversation property" do
actor = insert(:actor)
{:ok, activity, _} = API.Comments.create_comment(actor.preferred_username, "hey")
{:ok, activity, _} = API.Comments.create_comment(%{actor_id: actor.id, text: "hey"})
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
@@ -893,7 +892,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
test "it sets the 'attributedTo' property to the actor of the object if it doesn't have one" do
actor = insert(:actor)
{:ok, activity, _} = API.Comments.create_comment(actor.preferred_username, "hey")
{:ok, activity, _} = API.Comments.create_comment(%{actor_id: actor.id, text: "hey"})
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
@@ -903,7 +902,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
test "it strips internal hashtag data" do
actor = insert(:actor)
{:ok, activity, _} = API.Comments.create_comment(actor.preferred_username, "#2hu")
{:ok, activity, _} = API.Comments.create_comment(%{actor_id: actor.id, text: "#2hu"})
expected_tag = %{
"href" => MobilizonWeb.Endpoint.url() <> "/tags/2hu",
@@ -919,7 +918,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
test "it strips internal fields" do
actor = insert(:actor)
{:ok, activity, _} = API.Comments.create_comment(actor.preferred_username, "#2hu")
{:ok, activity, _} = API.Comments.create_comment(%{actor_id: actor.id, text: "#2hu"})
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)

View File

@@ -17,12 +17,21 @@ defmodule Mobilizon.Service.ActivityPub.UtilsTest do
describe "make" do
test "comment data from struct" do
comment = insert(:comment)
reply = insert(:comment, in_reply_to_comment: comment)
tag = insert(:tag, title: "MyTag")
reply = insert(:comment, in_reply_to_comment: comment, tags: [tag])
assert %{
"type" => "Note",
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
"content" => reply.text,
"cc" => [],
"tag" => [
%{
"href" => "http://mobilizon.test/tags/#{tag.slug}",
"name" => "#MyTag",
"type" => "Hashtag"
}
],
"content" => "My Comment",
"actor" => reply.actor.url,
"uuid" => reply.uuid,
"id" => Routes.page_url(Endpoint, :comment, reply.uuid),