Improve group refreshment and fixed date signature generation
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
@@ -47,10 +47,17 @@ defmodule Mobilizon.Federation.ActivityPubTest do
|
||||
File.read!("test/fixtures/mastodon-status-2.json")
|
||||
|> Jason.decode!()
|
||||
|
||||
actor_data =
|
||||
File.read!("test/fixtures/mastodon-actor.json")
|
||||
|> Jason.decode!()
|
||||
|
||||
Mock
|
||||
|> expect(:call, fn
|
||||
|> expect(:call, 2, fn
|
||||
%{method: :get, url: ^url}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: data}}
|
||||
|
||||
%{method: :get, url: "https://framapiaf.org/users/Framasoft"}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: actor_data}}
|
||||
end)
|
||||
|
||||
{:ok, object} = ActivityPub.fetch_object_from_url(url)
|
||||
@@ -72,13 +79,20 @@ defmodule Mobilizon.Federation.ActivityPubTest do
|
||||
File.read!("test/fixtures/mastodon-status-4.json")
|
||||
|> Jason.decode!()
|
||||
|
||||
actor_data =
|
||||
File.read!("test/fixtures/mastodon-actor.json")
|
||||
|> Jason.decode!()
|
||||
|
||||
Mock
|
||||
|> expect(:call, 2, fn
|
||||
|> expect(:call, 3, fn
|
||||
%{method: :get, url: ^url}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: data}}
|
||||
|
||||
%{method: :get, url: ^reply_to_url}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: reply_to_data}}
|
||||
|
||||
%{method: :get, url: "https://pirateradio.social/users/captain"}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: actor_data}}
|
||||
end)
|
||||
|
||||
{:ok, object} = ActivityPub.fetch_object_from_url(url)
|
||||
@@ -98,13 +112,26 @@ defmodule Mobilizon.Federation.ActivityPubTest do
|
||||
File.read!("test/fixtures/peertube-video.json")
|
||||
|> Jason.decode!()
|
||||
|
||||
actor_data =
|
||||
File.read!("test/fixtures/mastodon-actor.json")
|
||||
|> Jason.decode!()
|
||||
|
||||
Mock
|
||||
|> expect(:call, 2, fn
|
||||
|> expect(:call, 5, fn
|
||||
%{method: :get, url: ^url}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: data}}
|
||||
|
||||
%{method: :get, url: ^origin_url}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: origin_data}}
|
||||
|
||||
%{method: :get, url: "https://diaspodon.fr/users/dada"}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: actor_data}}
|
||||
|
||||
%{method: :get, url: "https://framatube.org/accounts/framasoft"}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: actor_data}}
|
||||
|
||||
%{method: :get, url: "https://framapiaf.org/users/Pouhiou"}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: actor_data}}
|
||||
end)
|
||||
|
||||
{:ok, object} = ActivityPub.fetch_object_from_url(url)
|
||||
|
||||
@@ -1,39 +1,72 @@
|
||||
defmodule Mobilizon.Federation.ActivityPub.ActorTest do
|
||||
use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney
|
||||
use Mobilizon.DataCase
|
||||
|
||||
import Mox
|
||||
import Mock
|
||||
|
||||
alias Mobilizon.Actors
|
||||
alias Mobilizon.Actors.Actor
|
||||
|
||||
alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor
|
||||
alias Mobilizon.Federation.ActivityPub.{Fetcher, Relay}
|
||||
alias Mobilizon.Federation.ActivityPub.Relay
|
||||
alias Mobilizon.Service.HTTP.ActivityPub.Mock
|
||||
|
||||
describe "fetching actor from its url" do
|
||||
@actor_url "https://framapiaf.org/users/tcit"
|
||||
test "returns an actor from nickname" do
|
||||
use_cassette "activity_pub/fetch_tcit@framapiaf.org" do
|
||||
assert {:ok,
|
||||
%Actor{preferred_username: "tcit", domain: "framapiaf.org", visibility: :public} =
|
||||
_actor} = ActivityPubActor.make_actor_from_nickname("tcit@framapiaf.org")
|
||||
end
|
||||
actor_data =
|
||||
File.read!("test/fixtures/mastodon-actor.json")
|
||||
|> Jason.decode!()
|
||||
|> Map.put("id", @actor_url)
|
||||
|> Map.put("preferredUsername", "tcit")
|
||||
|> Map.put("discoverable", true)
|
||||
|
||||
use_cassette "activity_pub/fetch_tcit@framapiaf.org_not_discoverable" do
|
||||
assert {:ok,
|
||||
%Actor{preferred_username: "tcit", domain: "framapiaf.org", visibility: :unlisted} =
|
||||
_actor} = ActivityPubActor.make_actor_from_nickname("tcit@framapiaf.org")
|
||||
end
|
||||
Mock
|
||||
|> expect(:call, fn
|
||||
%{method: :get, url: @actor_url}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: actor_data}}
|
||||
end)
|
||||
|
||||
assert {:ok,
|
||||
%Actor{preferred_username: "tcit", domain: "framapiaf.org", visibility: :public} =
|
||||
_actor} = ActivityPubActor.make_actor_from_nickname("tcit@framapiaf.org")
|
||||
end
|
||||
|
||||
test "returns an actor from nickname when not discoverable" do
|
||||
actor_data =
|
||||
File.read!("test/fixtures/mastodon-actor.json")
|
||||
|> Jason.decode!()
|
||||
|> Map.put("id", @actor_url)
|
||||
|> Map.put("preferredUsername", "tcit")
|
||||
|
||||
Mock
|
||||
|> expect(:call, fn
|
||||
%{method: :get, url: @actor_url}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: actor_data}}
|
||||
end)
|
||||
|
||||
assert {:ok,
|
||||
%Actor{preferred_username: "tcit", domain: "framapiaf.org", visibility: :unlisted} =
|
||||
_actor} = ActivityPubActor.make_actor_from_nickname("tcit@framapiaf.org")
|
||||
end
|
||||
|
||||
@actor_url "https://framapiaf.org/users/tcit"
|
||||
test "returns an actor from url" do
|
||||
actor_data =
|
||||
File.read!("test/fixtures/mastodon-actor.json")
|
||||
|> Jason.decode!()
|
||||
|> Map.put("id", @actor_url)
|
||||
|> Map.put("preferredUsername", "tcit")
|
||||
|
||||
Mock
|
||||
|> expect(:call, fn
|
||||
%{method: :get, url: @actor_url}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: actor_data}}
|
||||
end)
|
||||
|
||||
# Initial fetch
|
||||
use_cassette "activity_pub/fetch_framapiaf.org_users_tcit" do
|
||||
# Unlisted because discoverable is not present in the JSON payload
|
||||
assert {:ok,
|
||||
%Actor{preferred_username: "tcit", domain: "framapiaf.org", visibility: :unlisted}} =
|
||||
ActivityPubActor.get_or_fetch_actor_by_url(@actor_url)
|
||||
end
|
||||
# Unlisted because discoverable is not present in the JSON payload
|
||||
assert {:ok,
|
||||
%Actor{preferred_username: "tcit", domain: "framapiaf.org", visibility: :unlisted}} =
|
||||
ActivityPubActor.get_or_fetch_actor_by_url(@actor_url)
|
||||
|
||||
# Fetch uses cache if Actors.needs_update? returns false
|
||||
with_mocks([
|
||||
@@ -49,7 +82,7 @@ defmodule Mobilizon.Federation.ActivityPub.ActorTest do
|
||||
needs_update?: fn _ -> false end
|
||||
]},
|
||||
{ActivityPubActor, [:passthrough],
|
||||
make_actor_from_url: fn @actor_url, false ->
|
||||
make_actor_from_url: fn @actor_url, preload: false ->
|
||||
{:ok,
|
||||
%Actor{
|
||||
preferred_username: "tcit",
|
||||
@@ -61,7 +94,7 @@ defmodule Mobilizon.Federation.ActivityPub.ActorTest do
|
||||
ActivityPubActor.get_or_fetch_actor_by_url(@actor_url)
|
||||
|
||||
assert_called(Actors.needs_update?(:_))
|
||||
refute called(ActivityPubActor.make_actor_from_url(@actor_url, false))
|
||||
refute called(ActivityPubActor.make_actor_from_url(@actor_url, preload: false))
|
||||
end
|
||||
|
||||
# Fetch doesn't use cache if Actors.needs_update? returns true
|
||||
@@ -78,7 +111,7 @@ defmodule Mobilizon.Federation.ActivityPub.ActorTest do
|
||||
needs_update?: fn _ -> true end
|
||||
]},
|
||||
{ActivityPubActor, [:passthrough],
|
||||
make_actor_from_url: fn @actor_url, false ->
|
||||
make_actor_from_url: fn @actor_url, preload: false ->
|
||||
{:ok,
|
||||
%Actor{
|
||||
preferred_username: "tcit",
|
||||
@@ -92,24 +125,21 @@ defmodule Mobilizon.Federation.ActivityPub.ActorTest do
|
||||
assert_called(ActivityPubActor.get_or_fetch_actor_by_url(@actor_url))
|
||||
assert_called(Actors.get_actor_by_url(@actor_url, false))
|
||||
assert_called(Actors.needs_update?(:_))
|
||||
assert_called(ActivityPubActor.make_actor_from_url(@actor_url, false))
|
||||
assert_called(ActivityPubActor.make_actor_from_url(@actor_url, preload: false))
|
||||
end
|
||||
end
|
||||
|
||||
test "handles remote actor being deleted" do
|
||||
with_mocks([
|
||||
{Fetcher, [:passthrough],
|
||||
fetch_and_prepare_actor_from_url: fn @actor_url ->
|
||||
{:error, :actor_deleted}
|
||||
end}
|
||||
]) do
|
||||
assert match?(
|
||||
{:error, :actor_deleted},
|
||||
ActivityPubActor.make_actor_from_url(@actor_url, false)
|
||||
)
|
||||
Mock
|
||||
|> expect(:call, fn
|
||||
%{method: :get, url: @actor_url}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 410, body: ""}}
|
||||
end)
|
||||
|
||||
assert_called(Fetcher.fetch_and_prepare_actor_from_url(@actor_url))
|
||||
end
|
||||
assert match?(
|
||||
{:error, :actor_deleted},
|
||||
ActivityPubActor.make_actor_from_url(@actor_url, preload: false)
|
||||
)
|
||||
end
|
||||
|
||||
@public_url "https://www.w3.org/ns/activitystreams#Public"
|
||||
|
||||
@@ -36,12 +36,79 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier.CommentsTest do
|
||||
end
|
||||
|
||||
test "it fetches replied-to activities if we don't have them" do
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
actor_data = File.read!("test/fixtures/mastodon-actor.json") |> Jason.decode!()
|
||||
status_data = File.read!("test/fixtures/mastodon-status-2.json") |> Jason.decode!()
|
||||
|
||||
reply_to_data =
|
||||
File.read!("test/fixtures/pleroma-comment-object.json")
|
||||
|> Jason.decode!()
|
||||
|
||||
reply_to_url = "https://fedi.absturztau.be/objects/1726cdc7-4f2a-4ddb-9c68-03d27c98c3d9"
|
||||
|
||||
Mock
|
||||
|> expect(:call, 5, fn
|
||||
%{method: :get, url: "https://framapiaf.org/users/admin"}, _opts ->
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body:
|
||||
actor_data
|
||||
|> Map.put("id", "https://framapiaf.org/users/admin")
|
||||
|> Map.put("preferredUsername", "admin")
|
||||
}}
|
||||
|
||||
%{method: :get, url: "https://framapiaf.org/users/tcit"}, _opts ->
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body:
|
||||
actor_data
|
||||
|> Map.put("id", "https://framapiaf.org/users/tcit")
|
||||
|> Map.put("preferredUsername", "tcit")
|
||||
}}
|
||||
|
||||
%{method: :get, url: "https://framapiaf.org/users/Framasoft"}, _opts ->
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body:
|
||||
actor_data
|
||||
|> Map.put("id", "https://framapiaf.org/users/Framasoft")
|
||||
|> Map.put("preferredUsername", "Framasoft")
|
||||
}}
|
||||
|
||||
%{
|
||||
method: :get,
|
||||
url: "https://fedi.absturztau.be/objects/1726cdc7-4f2a-4ddb-9c68-03d27c98c3d9"
|
||||
},
|
||||
_opts ->
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body:
|
||||
status_data
|
||||
|> Map.put(
|
||||
"id",
|
||||
"https://fedi.absturztau.be/objects/1726cdc7-4f2a-4ddb-9c68-03d27c98c3d9"
|
||||
)
|
||||
|> Map.put("actor", "https://fedi.absturztau.be/users/dqn")
|
||||
}}
|
||||
|
||||
%{method: :get, url: "https://fedi.absturztau.be/users/dqn"}, _opts ->
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: Map.put(actor_data, "id", "https://fedi.absturztau.be/users/dqn")
|
||||
}}
|
||||
|
||||
%{method: :get, url: ^reply_to_url}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: reply_to_data}}
|
||||
end)
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|> Jason.decode!()
|
||||
|
||||
object =
|
||||
data["object"]
|
||||
|> Map.put("inReplyTo", reply_to_url)
|
||||
@@ -50,16 +117,6 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier.CommentsTest do
|
||||
data
|
||||
|> Map.put("object", object)
|
||||
|
||||
reply_to_data =
|
||||
File.read!("test/fixtures/pleroma-comment-object.json")
|
||||
|> Jason.decode!()
|
||||
|
||||
Mock
|
||||
|> expect(:call, fn
|
||||
%{method: :get, url: ^reply_to_url}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: reply_to_data}}
|
||||
end)
|
||||
|
||||
{:ok, returned_activity, _} = Transmogrifier.handle_incoming(data)
|
||||
|
||||
%Comment{} =
|
||||
@@ -75,6 +132,25 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier.CommentsTest do
|
||||
end
|
||||
|
||||
test "it doesn't saves replies to an event if the event doesn't accept comments" do
|
||||
actor_data = File.read!("test/fixtures/mastodon-actor.json") |> Jason.decode!()
|
||||
|
||||
Mock
|
||||
|> expect(:call, 2, fn
|
||||
%{method: :get, url: "https://framapiaf.org/users/admin"}, _opts ->
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: Map.put(actor_data, "id", "https://framapiaf.org/users/admin")
|
||||
}}
|
||||
|
||||
%{method: :get, url: "https://framapiaf.org/users/tcit"}, _opts ->
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: Map.put(actor_data, "id", "https://framapiaf.org/users/tcit")
|
||||
}}
|
||||
end)
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|> Jason.decode!()
|
||||
@@ -94,6 +170,31 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier.CommentsTest do
|
||||
|
||||
@url_404 "https://404.site/whatever"
|
||||
test "it does not crash if the object in inReplyTo can't be fetched" do
|
||||
actor_data = File.read!("test/fixtures/mastodon-actor.json") |> Jason.decode!()
|
||||
|
||||
Mock
|
||||
|> expect(:call, 2, fn
|
||||
%{method: :get, url: "https://framapiaf.org/users/admin"}, _opts ->
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body:
|
||||
actor_data
|
||||
|> Map.put("id", "https://framapiaf.org/users/admin")
|
||||
|> Map.put("preferredUsername", "admin")
|
||||
}}
|
||||
|
||||
%{method: :get, url: "https://framapiaf.org/users/tcit"}, _opts ->
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body:
|
||||
actor_data
|
||||
|> Map.put("id", "https://framapiaf.org/users/tcit")
|
||||
|> Map.put("preferredUsername", "tcit")
|
||||
}}
|
||||
end)
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|> Jason.decode!()
|
||||
@@ -118,6 +219,31 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier.CommentsTest do
|
||||
end
|
||||
|
||||
test "it ignores incoming private notes" do
|
||||
actor_data = File.read!("test/fixtures/mastodon-actor.json") |> Jason.decode!()
|
||||
|
||||
Mock
|
||||
|> expect(:call, 2, fn
|
||||
%{method: :get, url: "https://framapiaf.org/users/admin"}, _opts ->
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body:
|
||||
actor_data
|
||||
|> Map.put("id", "https://framapiaf.org/users/admin")
|
||||
|> Map.put("preferredUsername", "admin")
|
||||
}}
|
||||
|
||||
%{method: :get, url: "https://framapiaf.org/users/tcit"}, _opts ->
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body:
|
||||
actor_data
|
||||
|> Map.put("id", "https://framapiaf.org/users/tcit")
|
||||
|> Map.put("preferredUsername", "tcit")
|
||||
}}
|
||||
end)
|
||||
|
||||
data = File.read!("test/fixtures/mastodon-post-activity-private.json") |> Jason.decode!()
|
||||
event = insert(:event)
|
||||
object = data["object"]
|
||||
@@ -128,16 +254,33 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier.CommentsTest do
|
||||
end
|
||||
|
||||
test "it works for incoming notices" do
|
||||
actor_data = File.read!("test/fixtures/mastodon-actor.json") |> Jason.decode!()
|
||||
data = File.read!("test/fixtures/mastodon-post-activity.json") |> Jason.decode!()
|
||||
|
||||
Mock
|
||||
|> expect(:call, 2, fn
|
||||
%{method: :get, url: "https://framapiaf.org/users/admin"}, _opts ->
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: Map.put(actor_data, "id", "https://framapiaf.org/users/admin")
|
||||
}}
|
||||
|
||||
%{method: :get, url: "https://framapiaf.org/users/tcit"}, _opts ->
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: Map.put(actor_data, "id", "https://framapiaf.org/users/tcit")
|
||||
}}
|
||||
end)
|
||||
|
||||
{:ok, %Activity{data: data, local: false}, _} = Transmogrifier.handle_incoming(data)
|
||||
|
||||
assert data["id"] ==
|
||||
"https://framapiaf.org/users/admin/statuses/99512778738411822/activity"
|
||||
|
||||
assert data["to"] == [
|
||||
"https://www.w3.org/ns/activitystreams#Public",
|
||||
"https://framapiaf.org/users/tcit"
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
]
|
||||
|
||||
# assert data["cc"] == [
|
||||
@@ -164,6 +307,31 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier.CommentsTest do
|
||||
end
|
||||
|
||||
test "it works for incoming notices with hashtags" do
|
||||
actor_data = File.read!("test/fixtures/mastodon-actor.json") |> Jason.decode!()
|
||||
|
||||
Mock
|
||||
|> expect(:call, 2, fn
|
||||
%{method: :get, url: "https://framapiaf.org/users/admin"}, _opts ->
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body:
|
||||
actor_data
|
||||
|> Map.put("id", "https://framapiaf.org/users/admin")
|
||||
|> Map.put("preferredUsername", "admin")
|
||||
}}
|
||||
|
||||
%{method: :get, url: "https://framapiaf.org/users/tcit"}, _opts ->
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body:
|
||||
actor_data
|
||||
|> Map.put("id", "https://framapiaf.org/users/tcit")
|
||||
|> Map.put("preferredUsername", "tcit")
|
||||
}}
|
||||
end)
|
||||
|
||||
data = File.read!("test/fixtures/mastodon-post-activity-hashtag.json") |> Jason.decode!()
|
||||
|
||||
{:ok, %Activity{data: data, local: false}, _} = Transmogrifier.handle_incoming(data)
|
||||
|
||||
@@ -56,6 +56,19 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier.DeleteTest do
|
||||
end
|
||||
|
||||
test "it fails for incoming deletes with spoofed origin" do
|
||||
actor_data =
|
||||
File.read!("test/fixtures/mastodon-actor.json")
|
||||
|> Jason.decode!()
|
||||
|
||||
Mock
|
||||
|> expect(:call, 2, fn
|
||||
%{method: :get, url: "https://framapiaf.org/users/peertube"}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: actor_data}}
|
||||
|
||||
%{method: :get, url: "http://mastodon.example.org/users/gargron"}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: actor_data}}
|
||||
end)
|
||||
|
||||
comment = insert(:comment)
|
||||
|
||||
announce_data =
|
||||
@@ -77,7 +90,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier.DeleteTest do
|
||||
data
|
||||
|> Map.put("object", object)
|
||||
|
||||
{:error, :unknown_actor} = Transmogrifier.handle_incoming(data)
|
||||
:error = Transmogrifier.handle_incoming(data)
|
||||
|
||||
assert Discussions.get_comment_from_url(comment.url)
|
||||
end
|
||||
@@ -132,12 +145,12 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier.DeleteTest do
|
||||
|> Map.put("id", deleted_actor_url)
|
||||
|
||||
Mock
|
||||
|> expect(:call, fn
|
||||
|> expect(:call, 2, fn
|
||||
%{url: ^deleted_actor_url}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: deleted_actor_data}}
|
||||
end)
|
||||
|
||||
assert :error == Transmogrifier.handle_incoming(data)
|
||||
assert {:error, "Group object URL remote"} == Transmogrifier.handle_incoming(data)
|
||||
|
||||
assert Actors.get_actor_by_url(url)
|
||||
end
|
||||
|
||||
@@ -1,16 +1,31 @@
|
||||
defmodule Mobilizon.Federation.ActivityPub.Transmogrifier.FollowTest do
|
||||
use Mobilizon.DataCase
|
||||
|
||||
import Mox
|
||||
import ExUnit.CaptureLog
|
||||
import Mobilizon.Factory
|
||||
alias Mobilizon.Actors
|
||||
alias Mobilizon.Actors.Follower
|
||||
alias Mobilizon.Federation.ActivityPub.{Actions, Activity, Transmogrifier}
|
||||
alias Mobilizon.Service.HTTP.ActivityPub.Mock
|
||||
|
||||
describe "handle incoming follow requests" do
|
||||
test "it works only for groups" do
|
||||
actor = insert(:actor)
|
||||
|
||||
actor_data =
|
||||
File.read!("test/fixtures/mastodon-actor.json")
|
||||
|> Jason.decode!()
|
||||
|
||||
Mock
|
||||
|> expect(:call, fn
|
||||
%{method: :get, url: "https://social.tcit.fr/users/tcit"}, _opts ->
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: Map.put(actor_data, "id", "https://social.tcit.fr/users/tcit")
|
||||
}}
|
||||
end)
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-follow-activity.json")
|
||||
|> Jason.decode!()
|
||||
@@ -27,6 +42,20 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier.FollowTest do
|
||||
test "it works for incoming follow requests" do
|
||||
actor = insert(:group)
|
||||
|
||||
actor_data =
|
||||
File.read!("test/fixtures/mastodon-actor.json")
|
||||
|> Jason.decode!()
|
||||
|
||||
Mock
|
||||
|> expect(:call, fn
|
||||
%{method: :get, url: "https://social.tcit.fr/users/tcit"}, _opts ->
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: Map.put(actor_data, "id", "https://social.tcit.fr/users/tcit")
|
||||
}}
|
||||
end)
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-follow-activity.json")
|
||||
|> Jason.decode!()
|
||||
|
||||
@@ -22,9 +22,12 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier.UndoTest do
|
||||
|> Jason.decode!()
|
||||
|
||||
Mock
|
||||
|> expect(:call, fn
|
||||
|> expect(:call, 2, fn
|
||||
%{method: :get, url: "https://framapiaf.org/users/Framasoft"}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: actor_data}}
|
||||
|
||||
%{method: :get, url: "https://framapiaf.org/users/peertube"}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: actor_data}}
|
||||
end)
|
||||
|
||||
{:ok, _, %Comment{}} = Transmogrifier.handle_incoming(announce_data)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
defmodule Mobilizon.Federation.ActivityPub.Transmogrifier.UpdateTest do
|
||||
use Mobilizon.DataCase
|
||||
use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney
|
||||
use Oban.Testing, repo: Mobilizon.Storage.Repo
|
||||
import Mobilizon.Factory
|
||||
import Mox
|
||||
|
||||
alias Mobilizon.{Actors, Events, Posts}
|
||||
alias Mobilizon.Actors.{Actor, Member}
|
||||
@@ -10,79 +10,100 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier.UpdateTest do
|
||||
alias Mobilizon.Posts.Post
|
||||
alias Mobilizon.Federation.ActivityPub.{Activity, Transmogrifier}
|
||||
alias Mobilizon.Federation.ActivityStream.Convertible
|
||||
alias Mobilizon.Service.HTTP.ActivityPub.Mock
|
||||
|
||||
describe "handle incoming update activities" do
|
||||
test "it works for incoming update activities on actors" do
|
||||
use_cassette "activity_pub/update_actor_activity" do
|
||||
data = File.read!("test/fixtures/mastodon-post-activity.json") |> Jason.decode!()
|
||||
data = File.read!("test/fixtures/mastodon-post-activity.json") |> Jason.decode!()
|
||||
|
||||
{:ok, %Activity{data: data, local: false}, _} = Transmogrifier.handle_incoming(data)
|
||||
update_data = File.read!("test/fixtures/mastodon-update.json") |> Jason.decode!()
|
||||
actor_data =
|
||||
File.read!("test/fixtures/mastodon-actor.json")
|
||||
|> Jason.decode!()
|
||||
|
||||
object =
|
||||
update_data["object"]
|
||||
|> Map.put("actor", data["actor"])
|
||||
|> Map.put("id", data["actor"])
|
||||
Mock
|
||||
|> expect(:call, 2, fn
|
||||
%{method: :get, url: "https://framapiaf.org/users/admin"}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: actor_data}}
|
||||
|
||||
update_data =
|
||||
update_data
|
||||
|> Map.put("actor", data["actor"])
|
||||
|> Map.put("object", object)
|
||||
%{method: :get, url: "https://framapiaf.org/users/tcit"}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: actor_data}}
|
||||
end)
|
||||
|
||||
{:ok, %Activity{data: _data, local: false}, _} =
|
||||
Transmogrifier.handle_incoming(update_data)
|
||||
{:ok, %Activity{data: data, local: false}, _} = Transmogrifier.handle_incoming(data)
|
||||
update_data = File.read!("test/fixtures/mastodon-update.json") |> Jason.decode!()
|
||||
|
||||
{:ok, %Actor{} = actor} = Actors.get_actor_by_url(update_data["actor"])
|
||||
assert actor.name == "nextsoft"
|
||||
object =
|
||||
update_data["object"]
|
||||
|> Map.put("actor", data["actor"])
|
||||
|> Map.put("id", data["actor"])
|
||||
|
||||
assert actor.summary == "<p>Some bio</p>"
|
||||
end
|
||||
update_data =
|
||||
update_data
|
||||
|> Map.put("actor", data["actor"])
|
||||
|> Map.put("object", object)
|
||||
|
||||
{:ok, %Activity{data: _data, local: false}, _} = Transmogrifier.handle_incoming(update_data)
|
||||
|
||||
{:ok, %Actor{} = actor} = Actors.get_actor_by_url(update_data["actor"])
|
||||
assert actor.name == "nextsoft"
|
||||
|
||||
assert actor.summary == "<p>Some bio</p>"
|
||||
end
|
||||
|
||||
test "it works for incoming update activities on events" do
|
||||
use_cassette "activity_pub/event_update_activities" do
|
||||
data = File.read!("test/fixtures/mobilizon-post-activity.json") |> Jason.decode!()
|
||||
data = File.read!("test/fixtures/mobilizon-post-activity.json") |> Jason.decode!()
|
||||
|
||||
{:ok, %Activity{data: data, local: false}, %Event{id: event_id}} =
|
||||
Transmogrifier.handle_incoming(data)
|
||||
actor_data =
|
||||
File.read!("test/fixtures/mastodon-actor.json")
|
||||
|> Jason.decode!()
|
||||
|
||||
assert_enqueued(
|
||||
worker: Mobilizon.Service.Workers.BuildSearch,
|
||||
args: %{event_id: event_id, op: :insert_search_event}
|
||||
)
|
||||
Mock
|
||||
|> expect(:call, 2, fn
|
||||
%{method: :get, url: "https://mobilizon.fr/@metacartes"}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: actor_data}}
|
||||
|
||||
assert %{success: 1, snoozed: 0, failure: 0} == Oban.drain_queue(queue: :search)
|
||||
%{method: :get, url: "https://framapiaf.org/users/tcit"}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: actor_data}}
|
||||
end)
|
||||
|
||||
update_data = File.read!("test/fixtures/mastodon-update.json") |> Jason.decode!()
|
||||
{:ok, %Activity{data: data, local: false}, %Event{id: event_id}} =
|
||||
Transmogrifier.handle_incoming(data)
|
||||
|
||||
object =
|
||||
data["object"]
|
||||
|> Map.put("actor", data["actor"])
|
||||
|> Map.put("name", "My updated event")
|
||||
|> Map.put("id", data["object"]["id"])
|
||||
|> Map.put("type", "Event")
|
||||
assert_enqueued(
|
||||
worker: Mobilizon.Service.Workers.BuildSearch,
|
||||
args: %{event_id: event_id, op: :insert_search_event}
|
||||
)
|
||||
|
||||
update_data =
|
||||
update_data
|
||||
|> Map.put("actor", data["actor"])
|
||||
|> Map.put("object", object)
|
||||
assert %{success: 1, snoozed: 0, failure: 0} == Oban.drain_queue(queue: :search)
|
||||
|
||||
{:ok, %Activity{data: data, local: false}, _} =
|
||||
Transmogrifier.handle_incoming(update_data)
|
||||
update_data = File.read!("test/fixtures/mastodon-update.json") |> Jason.decode!()
|
||||
|
||||
%Event{} = event = Events.get_event_by_url(data["object"]["id"])
|
||||
object =
|
||||
data["object"]
|
||||
|> Map.put("actor", data["actor"])
|
||||
|> Map.put("name", "My updated event")
|
||||
|> Map.put("id", data["object"]["id"])
|
||||
|> Map.put("type", "Event")
|
||||
|
||||
assert_enqueued(
|
||||
worker: Mobilizon.Service.Workers.BuildSearch,
|
||||
args: %{event_id: event_id, op: :update_search_event}
|
||||
)
|
||||
update_data =
|
||||
update_data
|
||||
|> Map.put("actor", data["actor"])
|
||||
|> Map.put("object", object)
|
||||
|
||||
assert %{success: 1, snoozed: 0, failure: 0} == Oban.drain_queue(queue: :search)
|
||||
{:ok, %Activity{data: data, local: false}, _} = Transmogrifier.handle_incoming(update_data)
|
||||
|
||||
assert event.title == "My updated event"
|
||||
%Event{} = event = Events.get_event_by_url(data["object"]["id"])
|
||||
|
||||
assert event.description == data["object"]["content"]
|
||||
end
|
||||
assert_enqueued(
|
||||
worker: Mobilizon.Service.Workers.BuildSearch,
|
||||
args: %{event_id: event_id, op: :update_search_event}
|
||||
)
|
||||
|
||||
assert %{success: 1, snoozed: 0, failure: 0} == Oban.drain_queue(queue: :search)
|
||||
|
||||
assert event.title == "My updated event"
|
||||
|
||||
assert event.description == data["object"]["content"]
|
||||
end
|
||||
|
||||
# test "it works for incoming update activities which lock the account" do
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
# Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/test/web/activity_pub/transmogrifier_test.exs
|
||||
|
||||
defmodule Mobilizon.Federation.ActivityPub.TransmogrifierTest do
|
||||
use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney
|
||||
|
||||
use Mobilizon.DataCase
|
||||
use Oban.Testing, repo: Mobilizon.Storage.Repo
|
||||
|
||||
@@ -33,54 +31,75 @@ defmodule Mobilizon.Federation.ActivityPub.TransmogrifierTest do
|
||||
|
||||
describe "handle incoming events" do
|
||||
test "it works for incoming events" do
|
||||
use_cassette "activity_pub/fetch_mobilizon_post_activity" do
|
||||
data = File.read!("test/fixtures/mobilizon-post-activity.json") |> Jason.decode!()
|
||||
actor_data = File.read!("test/fixtures/mastodon-actor.json") |> Jason.decode!()
|
||||
|
||||
{:ok, %Activity{data: data, local: false}, %Event{} = event} =
|
||||
Transmogrifier.handle_incoming(data)
|
||||
Mock
|
||||
|> expect(:call, 2, fn
|
||||
%{method: :get, url: url}, _opts ->
|
||||
case url do
|
||||
"https://mobilizon.fr/@metacartes" ->
|
||||
actor_data = Map.put(actor_data, "id", "https://mobilizon.fr/@metacartes")
|
||||
{:ok, %Tesla.Env{status: 200, body: actor_data}}
|
||||
|
||||
assert data["id"] ==
|
||||
"https://mobilizon.fr/events/39a0c4a6-f2b6-41dc-bbe2-fc5bff76cc93/activity"
|
||||
"https://framapiaf.org/users/tcit" ->
|
||||
actor_data = Map.put(actor_data, "id", "https://framapiaf.org/users/tcit")
|
||||
{:ok, %Tesla.Env{status: 200, body: actor_data}}
|
||||
end
|
||||
end)
|
||||
|
||||
assert data["to"] == ["https://www.w3.org/ns/activitystreams#Public"]
|
||||
data = File.read!("test/fixtures/mobilizon-post-activity.json") |> Jason.decode!()
|
||||
|
||||
#
|
||||
# assert data["cc"] == [
|
||||
# "https://framapiaf.org/users/admin/followers",
|
||||
# "http://localtesting.pleroma.lol/users/lain"
|
||||
# ]
|
||||
{:ok, %Activity{data: data, local: false}, %Event{} = event} =
|
||||
Transmogrifier.handle_incoming(data)
|
||||
|
||||
assert data["actor"] == "https://mobilizon.fr/@metacartes"
|
||||
assert data["id"] ==
|
||||
"https://mobilizon.fr/events/39a0c4a6-f2b6-41dc-bbe2-fc5bff76cc93/activity"
|
||||
|
||||
object = data["object"]
|
||||
assert data["to"] == ["https://www.w3.org/ns/activitystreams#Public"]
|
||||
|
||||
assert object["id"] ==
|
||||
"https://mobilizon.fr/events/39a0c4a6-f2b6-41dc-bbe2-fc5bff76cc93"
|
||||
#
|
||||
# assert data["cc"] == [
|
||||
# "https://framapiaf.org/users/admin/followers",
|
||||
# "http://localtesting.pleroma.lol/users/lain"
|
||||
# ]
|
||||
|
||||
assert object["to"] == ["https://www.w3.org/ns/activitystreams#Public"]
|
||||
assert data["actor"] == "https://mobilizon.fr/@metacartes"
|
||||
|
||||
# assert object["cc"] == [
|
||||
# "https://framapiaf.org/users/admin/followers",
|
||||
# "http://localtesting.pleroma.lol/users/lain"
|
||||
# ]
|
||||
object = data["object"]
|
||||
|
||||
assert object["actor"] == "https://mobilizon.fr/@metacartes"
|
||||
assert object["location"]["name"] == "Locaux de Framasoft"
|
||||
# assert object["attributedTo"] == "https://mobilizon.fr/@metacartes"
|
||||
assert object["id"] ==
|
||||
"https://mobilizon.fr/events/39a0c4a6-f2b6-41dc-bbe2-fc5bff76cc93"
|
||||
|
||||
assert event.physical_address.street == "10 Rue Jangot"
|
||||
assert object["to"] == ["https://www.w3.org/ns/activitystreams#Public"]
|
||||
|
||||
assert event.physical_address.url ==
|
||||
"https://event1.tcit.fr/address/eeecc11d-0030-43e8-a897-6422876372jd"
|
||||
# assert object["cc"] == [
|
||||
# "https://framapiaf.org/users/admin/followers",
|
||||
# "http://localtesting.pleroma.lol/users/lain"
|
||||
# ]
|
||||
|
||||
assert event.online_address == "https://google.com"
|
||||
assert object["actor"] == "https://mobilizon.fr/@metacartes"
|
||||
assert object["location"]["name"] == "Locaux de Framasoft"
|
||||
# assert object["attributedTo"] == "https://mobilizon.fr/@metacartes"
|
||||
|
||||
{:ok, %Actor{}} = Actors.get_actor_by_url(object["actor"])
|
||||
end
|
||||
assert event.physical_address.street == "10 Rue Jangot"
|
||||
|
||||
assert event.physical_address.url ==
|
||||
"https://event1.tcit.fr/address/eeecc11d-0030-43e8-a897-6422876372jd"
|
||||
|
||||
assert event.online_address == "https://google.com"
|
||||
|
||||
{:ok, %Actor{}} = Actors.get_actor_by_url(object["actor"])
|
||||
end
|
||||
|
||||
test "it works for incoming events from Gancio" do
|
||||
data = File.read!("test/fixtures/gancio-event-activity.json") |> Jason.decode!()
|
||||
actor_data = File.read!("test/fixtures/gancio-actor.json") |> Jason.decode!()
|
||||
|
||||
Mock
|
||||
|> expect(:call, fn
|
||||
%{method: :get, url: "https://demo.gancio.org/federation/u/gancio"}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: actor_data}}
|
||||
end)
|
||||
|
||||
{:ok, %Activity{data: data, local: false}, %Event{} = event} =
|
||||
Transmogrifier.handle_incoming(data)
|
||||
@@ -524,6 +543,12 @@ defmodule Mobilizon.Federation.ActivityPub.TransmogrifierTest do
|
||||
end
|
||||
|
||||
test "it accepts incoming resources and handles group being not found" do
|
||||
Mock
|
||||
|> expect(:call, fn
|
||||
%{method: :get, url: "https://someurl.com/notfound"}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 404, body: ""}}
|
||||
end)
|
||||
|
||||
creator =
|
||||
insert(:actor,
|
||||
domain: "mobilizon.app",
|
||||
@@ -649,12 +674,18 @@ defmodule Mobilizon.Federation.ActivityPub.TransmogrifierTest do
|
||||
test "it works for incoming announces" do
|
||||
data = File.read!("test/fixtures/mastodon-announce.json") |> Jason.decode!()
|
||||
status_data = File.read!("test/fixtures/mastodon-status.json") |> Jason.decode!()
|
||||
actor_data = File.read!("test/fixtures/mastodon-actor.json") |> Jason.decode!()
|
||||
|
||||
Mock
|
||||
|> expect(:call, fn
|
||||
%{method: :get, url: "https://framapiaf.org/users/peertube/statuses/104584600044284729"},
|
||||
_opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: status_data}}
|
||||
|> expect(:call, 2, fn
|
||||
%{method: :get, url: url}, _opts ->
|
||||
case url do
|
||||
"https://framapiaf.org/users/peertube/statuses/104584600044284729" ->
|
||||
{:ok, %Tesla.Env{status: 200, body: status_data}}
|
||||
|
||||
"https://framapiaf.org/users/peertube" ->
|
||||
{:ok, %Tesla.Env{status: 200, body: actor_data}}
|
||||
end
|
||||
end)
|
||||
|
||||
{:ok, _, %Comment{actor: %Actor{url: actor_url}, url: comment_url}} =
|
||||
@@ -677,10 +708,12 @@ defmodule Mobilizon.Federation.ActivityPub.TransmogrifierTest do
|
||||
File.read!("test/fixtures/mastodon-announce.json")
|
||||
|> Jason.decode!()
|
||||
|> Map.put("object", comment_url)
|
||||
|> Map.put("actor", actor_url)
|
||||
|
||||
Mock
|
||||
|> expect(:call, fn
|
||||
%{method: :get, url: ^actor_url}, _opts ->
|
||||
actor_data = Map.put(actor_data, "id", actor_url)
|
||||
{:ok, %Tesla.Env{status: 200, body: actor_data}}
|
||||
end)
|
||||
|
||||
@@ -926,10 +959,21 @@ defmodule Mobilizon.Federation.ActivityPub.TransmogrifierTest do
|
||||
File.read!("test/fixtures/https__info.pleroma.site_activity.json")
|
||||
|> Jason.decode!()
|
||||
|
||||
actor_data =
|
||||
File.read!("test/fixtures/mastodon-actor.json")
|
||||
|> Jason.decode!()
|
||||
|> Map.put("id", "https://framapiaf.org/users/admin")
|
||||
|
||||
Mock
|
||||
|> expect(:call, fn
|
||||
%{method: :get, url: "https://info.pleroma.site/activity.json"}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: data}}
|
||||
|> expect(:call, 2, fn
|
||||
%{method: :get, url: url}, _opts ->
|
||||
case url do
|
||||
"https://info.pleroma.site/activity.json" ->
|
||||
{:ok, %Tesla.Env{status: 200, body: data}}
|
||||
|
||||
"https://framapiaf.org/users/admin" ->
|
||||
{:ok, %Tesla.Env{status: 200, body: actor_data}}
|
||||
end
|
||||
end)
|
||||
|
||||
data = %{
|
||||
|
||||
36
test/fixtures/gancio-actor.json
vendored
Normal file
36
test/fixtures/gancio-actor.json
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{
|
||||
"toot": "http://joinmastodon.org/ns#",
|
||||
"schema": "http://schema.org#",
|
||||
"ProperyValue": "schema:PropertyValue",
|
||||
"value": "schema:value"
|
||||
}
|
||||
],
|
||||
"id": "https://demo.gancio.org/federation/u/gancio",
|
||||
"type": "Application",
|
||||
"name": "gancio",
|
||||
"preferredUsername": "gancio",
|
||||
"inbox": "https://demo.gancio.org/federation/u/gancio/inbox",
|
||||
"outbox": "https://demo.gancio.org/federation/u/gancio/outbox",
|
||||
"discoverable": true,
|
||||
"attachment": [
|
||||
{
|
||||
"type": "PropertyValue",
|
||||
"name": "Website",
|
||||
"value": "<a href='https://demo.gancio.org'>https://demo.gancio.org</a>"
|
||||
}
|
||||
],
|
||||
"icon": {
|
||||
"type": "Image",
|
||||
"mediaType": "image/png",
|
||||
"url": "https://demo.gancio.org/logo.png"
|
||||
},
|
||||
"publicKey": {
|
||||
"id": "https://demo.gancio.org/federation/u/gancio#main-key",
|
||||
"owner": "https://demo.gancio.org/federation/u/gancio",
|
||||
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxp9BQ8TvVqu+0xXk7VuZ\nnuO42cHxVI+z/3TQ80AfX5aoUnK/uP7lIPy+NiIgRRu0L4hsjEs+HP6Ny9NAKFtC\nddS3pUrgIDz/AUyKeYRsCycw4XyeX7gaqIan4vCx+ANPDVTc3twDenynHhaXbPsP\nzGeKiAsGIFKRUxc5I5xnQBk6Fy6LZvGwfif07AcECER+nzffSOMPYFVbhlRuBwOg\n/tJcut77KOEpJIQSwqzT0FOw4oFtkvJt/nhpQMkXwOjEuiMOVpPoXUIpWjnbvNmy\nIPXdnKN4QqHi0fAE+FvKGbNmr18vqApT/D4Yen6W1ZWCRdUR1jjl8LNFBkPH/Tad\nkOj+UyRRJjRRqY5mXCI72Bmhwmi/YdS4gt9K73okOZ3atM+9Kfj3azZm8pP7fRkK\n/lwRP8RZFSSpz4w9JtzYmR7P8qTaxwMuq8VrxtFmf1IBChFpyNHUDtmC9MzLBRE7\n+fnpr1bARR3OwO83/xtT+vKNE+2SBvsf7zeFRXa+p5dGaih90rQOwL8EsUItiG61\nm4y9n3Q7BM7XwrZ7sGe3Hey5SWveOEgemfP4ANJBiMQpU69LKM9dGW1FcEX4FlwW\nZx/135nzMXE2cF+y+q/yY2FlacXPqJXMY32mIc+rHMzvFY/ZDzjRY/7Gg2ekjXuN\n1o7Ag7a+5k+r+XkWBNKIHp8CAwEAAQ==\n-----END PUBLIC KEY-----\n"
|
||||
}
|
||||
}
|
||||
119
test/fixtures/mastodon-tcit-tcit.json
vendored
Normal file
119
test/fixtures/mastodon-tcit-tcit.json
vendored
Normal file
@@ -0,0 +1,119 @@
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{
|
||||
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
|
||||
"toot": "http://joinmastodon.org/ns#",
|
||||
"featured": {
|
||||
"@id": "toot:featured",
|
||||
"@type": "@id"
|
||||
},
|
||||
"featuredTags": {
|
||||
"@id": "toot:featuredTags",
|
||||
"@type": "@id"
|
||||
},
|
||||
"alsoKnownAs": {
|
||||
"@id": "as:alsoKnownAs",
|
||||
"@type": "@id"
|
||||
},
|
||||
"movedTo": {
|
||||
"@id": "as:movedTo",
|
||||
"@type": "@id"
|
||||
},
|
||||
"schema": "http://schema.org#",
|
||||
"PropertyValue": "schema:PropertyValue",
|
||||
"value": "schema:value",
|
||||
"IdentityProof": "toot:IdentityProof",
|
||||
"discoverable": "toot:discoverable",
|
||||
"Device": "toot:Device",
|
||||
"Ed25519Signature": "toot:Ed25519Signature",
|
||||
"Ed25519Key": "toot:Ed25519Key",
|
||||
"Curve25519Key": "toot:Curve25519Key",
|
||||
"EncryptedMessage": "toot:EncryptedMessage",
|
||||
"publicKeyBase64": "toot:publicKeyBase64",
|
||||
"deviceId": "toot:deviceId",
|
||||
"claim": {
|
||||
"@type": "@id",
|
||||
"@id": "toot:claim"
|
||||
},
|
||||
"fingerprintKey": {
|
||||
"@type": "@id",
|
||||
"@id": "toot:fingerprintKey"
|
||||
},
|
||||
"identityKey": {
|
||||
"@type": "@id",
|
||||
"@id": "toot:identityKey"
|
||||
},
|
||||
"devices": {
|
||||
"@type": "@id",
|
||||
"@id": "toot:devices"
|
||||
},
|
||||
"messageFranking": "toot:messageFranking",
|
||||
"messageType": "toot:messageType",
|
||||
"cipherText": "toot:cipherText",
|
||||
"suspended": "toot:suspended",
|
||||
"focalPoint": {
|
||||
"@container": "@list",
|
||||
"@id": "toot:focalPoint"
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": "https://social.tcit.fr/users/tcit",
|
||||
"type": "Person",
|
||||
"following": "https://social.tcit.fr/users/tcit/following",
|
||||
"followers": "https://social.tcit.fr/users/tcit/followers",
|
||||
"inbox": "https://social.tcit.fr/users/tcit/inbox",
|
||||
"outbox": "https://social.tcit.fr/users/tcit/outbox",
|
||||
"featured": "https://social.tcit.fr/users/tcit/collections/featured",
|
||||
"featuredTags": "https://social.tcit.fr/users/tcit/collections/tags",
|
||||
"preferredUsername": "tcit",
|
||||
"name": "🦄 Thomas Citharel",
|
||||
"summary": "<p>Hoping to make people's life better with free software at <span class=\"h-card\"><a href=\"https://framapiaf.org/@Framasoft\" class=\"u-url mention\">@<span>Framasoft</span></a></span>.</p><p>ᕕ(ᐛ)ᕗ</p>",
|
||||
"url": "https://social.tcit.fr/@tcit",
|
||||
"manuallyApprovesFollowers": false,
|
||||
"discoverable": true,
|
||||
"published": "2017-04-03T00:00:00Z",
|
||||
"devices": "https://social.tcit.fr/users/tcit/collections/devices",
|
||||
"publicKey": {
|
||||
"id": "https://social.tcit.fr/users/tcit#main-key",
|
||||
"owner": "https://social.tcit.fr/users/tcit",
|
||||
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApXwYMUdFg3XUd+bGsh8C\nyiMRGpRGAWuCdM5pDWx5uM4pW2pM3xbHbcI21j9h8BmlAiPg6hbZD73KGly2N8Rt\n5iIS0I+l6i8kA1JCCdlAaDTRd41RKMggZDoQvjVZQtsyE1VzMeU2kbqqTFN6ew7H\nvbd6O0NhixoKoZ5f3jwuBDZoT0p1TAcaMdmG8oqHD97isizkDnRn8cOBA6wtI+xb\n5xP2zxZMsLpTDZLiKU8XcPKZCw4OfQfmDmKkHtrFb77jCAQj/s/FxjVnvxRwmfhN\nnWy0D+LUV/g63nHh/b5zXIeV92QZLvDYbgbezmzUzv9UeA1s70GGbaDqCIy85gw9\n+wIDAQAB\n-----END PUBLIC KEY-----\n"
|
||||
},
|
||||
"tag": [],
|
||||
"attachment": [
|
||||
{
|
||||
"type": "PropertyValue",
|
||||
"name": "Works at",
|
||||
"value": "<span class=\"h-card\"><a href=\"https://framapiaf.org/@Framasoft\" class=\"u-url mention\">@<span>Framasoft@framapiaf.org</span></a></span>"
|
||||
},
|
||||
{
|
||||
"type": "PropertyValue",
|
||||
"name": "Pronouns",
|
||||
"value": "He/Him"
|
||||
},
|
||||
{
|
||||
"type": "PropertyValue",
|
||||
"name": "Work Account",
|
||||
"value": "<a href=\"https://framapiaf.org/@tcit\" rel=\"me nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"\">framapiaf.org/@tcit</span><span class=\"invisible\"></span></a>"
|
||||
},
|
||||
{
|
||||
"type": "PropertyValue",
|
||||
"name": "Site",
|
||||
"value": "<a href=\"https://tcit.fr\" rel=\"me nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"\">tcit.fr</span><span class=\"invisible\"></span></a>"
|
||||
}
|
||||
],
|
||||
"endpoints": {
|
||||
"sharedInbox": "https://social.tcit.fr/inbox"
|
||||
},
|
||||
"icon": {
|
||||
"type": "Image",
|
||||
"mediaType": "image/jpeg",
|
||||
"url": "https://social.tcit.fr/system/accounts/avatars/000/000/001/original/a28c50ce5f2b13fd.jpg"
|
||||
},
|
||||
"image": {
|
||||
"type": "Image",
|
||||
"mediaType": "image/jpeg",
|
||||
"url": "https://social.tcit.fr/system/accounts/headers/000/000/001/original/ac9c4a71083bd9a1.jpg"
|
||||
}
|
||||
}
|
||||
112
test/fixtures/signature/framapiaf_admin.json
vendored
Normal file
112
test/fixtures/signature/framapiaf_admin.json
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{
|
||||
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
|
||||
"toot": "http://joinmastodon.org/ns#",
|
||||
"featured": {
|
||||
"@id": "toot:featured",
|
||||
"@type": "@id"
|
||||
},
|
||||
"alsoKnownAs": {
|
||||
"@id": "as:alsoKnownAs",
|
||||
"@type": "@id"
|
||||
},
|
||||
"movedTo": {
|
||||
"@id": "as:movedTo",
|
||||
"@type": "@id"
|
||||
},
|
||||
"schema": "http://schema.org#",
|
||||
"PropertyValue": "schema:PropertyValue",
|
||||
"value": "schema:value",
|
||||
"IdentityProof": "toot:IdentityProof",
|
||||
"discoverable": "toot:discoverable",
|
||||
"Device": "toot:Device",
|
||||
"Ed25519Signature": "toot:Ed25519Signature",
|
||||
"Ed25519Key": "toot:Ed25519Key",
|
||||
"Curve25519Key": "toot:Curve25519Key",
|
||||
"EncryptedMessage": "toot:EncryptedMessage",
|
||||
"publicKeyBase64": "toot:publicKeyBase64",
|
||||
"deviceId": "toot:deviceId",
|
||||
"claim": {
|
||||
"@type": "@id",
|
||||
"@id": "toot:claim"
|
||||
},
|
||||
"fingerprintKey": {
|
||||
"@type": "@id",
|
||||
"@id": "toot:fingerprintKey"
|
||||
},
|
||||
"identityKey": {
|
||||
"@type": "@id",
|
||||
"@id": "toot:identityKey"
|
||||
},
|
||||
"devices": {
|
||||
"@type": "@id",
|
||||
"@id": "toot:devices"
|
||||
},
|
||||
"messageFranking": "toot:messageFranking",
|
||||
"messageType": "toot:messageType",
|
||||
"cipherText": "toot:cipherText",
|
||||
"focalPoint": {
|
||||
"@container": "@list",
|
||||
"@id": "toot:focalPoint"
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": "https://framapiaf.org/users/admin",
|
||||
"type": "Service",
|
||||
"following": "https://framapiaf.org/users/admin/following",
|
||||
"followers": "https://framapiaf.org/users/admin/followers",
|
||||
"inbox": "https://framapiaf.org/users/admin/inbox",
|
||||
"outbox": "https://framapiaf.org/users/admin/outbox",
|
||||
"featured": "https://framapiaf.org/users/admin/collections/featured",
|
||||
"preferredUsername": "admin",
|
||||
"name": "Administrateur",
|
||||
"summary": "<p>Je ne suis qu'un compte inutile. Merci nous de contacter via <a href=\"https://contact.framasoft.org/\" rel=\"nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"\">contact.framasoft.org/</span><span class=\"invisible\"></span></a></p>",
|
||||
"url": "https://framapiaf.org/@admin",
|
||||
"manuallyApprovesFollowers": false,
|
||||
"discoverable": null,
|
||||
"devices": "https://framapiaf.org/users/admin/collections/devices",
|
||||
"publicKey": {
|
||||
"id": "https://framapiaf.org/users/admin#main-key",
|
||||
"owner": "https://framapiaf.org/users/admin",
|
||||
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyHaU/AZ5dWtSxZXkPa89\nDUQ4z+JQHGGUG/xkGuq0v8P6qJfQqtHPBO5vH0IQJqluXWQS96gqTwjZnYevcpNA\nveYv0K25DWszx5Ehz6JX2/sSvu2rNUcQ3YZvSjdo/Yy1u5Fuc5lLmvw8uFzXYekD\nWovTMOnp4mIKpVEm/G/v4w8jvFEKw88h743vwaEIim88GEQItMxzGAV6zSqV1DWO\nLxtoRsinslJYfAG46ex4YUATFveWvOUeWk5W1sEa5f3c0moaTmBM/PAAo8vLxhlw\nJhsHihsCH+BcXKVMjW8OCqYYqISMxEifUBX63HcJt78ELHpOuc1c2eG59PomtTjQ\nywIDAQAB\n-----END PUBLIC KEY-----\n"
|
||||
},
|
||||
"tag": [],
|
||||
"attachment": [
|
||||
{
|
||||
"type": "PropertyValue",
|
||||
"name": "News",
|
||||
"value": "<span class=\"h-card\"><a href=\"https://framapiaf.org/@Framasoft\" class=\"u-url mention\">@<span>Framasoft</span></a></span>"
|
||||
},
|
||||
{
|
||||
"type": "PropertyValue",
|
||||
"name": "Support",
|
||||
"value": "<a href=\"https://contact.framasoft.org/\" rel=\"me nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"\">contact.framasoft.org/</span><span class=\"invisible\"></span></a>"
|
||||
},
|
||||
{
|
||||
"type": "PropertyValue",
|
||||
"name": "Soutenir",
|
||||
"value": "<a href=\"https://soutenir.framasoft.org/\" rel=\"me nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"\">soutenir.framasoft.org/</span><span class=\"invisible\"></span></a>"
|
||||
},
|
||||
{
|
||||
"type": "PropertyValue",
|
||||
"name": "Site",
|
||||
"value": "<a href=\"https://framasoft.org/\" rel=\"me nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"\">framasoft.org/</span><span class=\"invisible\"></span></a>"
|
||||
}
|
||||
],
|
||||
"endpoints": {
|
||||
"sharedInbox": "https://framapiaf.org/inbox"
|
||||
},
|
||||
"icon": {
|
||||
"type": "Image",
|
||||
"mediaType": "image/jpeg",
|
||||
"url": "https://framapiaf.s3.framasoft.org/framapiaf/accounts/avatars/000/000/002/original/85fbb27ad5e3cf71.jpg"
|
||||
},
|
||||
"image": {
|
||||
"type": "Image",
|
||||
"mediaType": "image/jpeg",
|
||||
"url": "https://framapiaf.s3.framasoft.org/framapiaf/accounts/headers/000/000/002/original/6aba75f1ab1ab6de.jpg"
|
||||
}
|
||||
}
|
||||
55
test/fixtures/signature/nyu_rye.json
vendored
Normal file
55
test/fixtures/signature/nyu_rye.json
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{
|
||||
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
|
||||
"toot": "http://joinmastodon.org/ns#",
|
||||
"featured": { "@id": "toot:featured", "@type": "@id" },
|
||||
"alsoKnownAs": { "@id": "as:alsoKnownAs", "@type": "@id" },
|
||||
"movedTo": { "@id": "as:movedTo", "@type": "@id" },
|
||||
"schema": "http://schema.org#",
|
||||
"PropertyValue": "schema:PropertyValue",
|
||||
"value": "schema:value",
|
||||
"IdentityProof": "toot:IdentityProof",
|
||||
"discoverable": "toot:discoverable",
|
||||
"Device": "toot:Device",
|
||||
"Ed25519Signature": "toot:Ed25519Signature",
|
||||
"Ed25519Key": "toot:Ed25519Key",
|
||||
"Curve25519Key": "toot:Curve25519Key",
|
||||
"EncryptedMessage": "toot:EncryptedMessage",
|
||||
"publicKeyBase64": "toot:publicKeyBase64",
|
||||
"deviceId": "toot:deviceId",
|
||||
"claim": { "@type": "@id", "@id": "toot:claim" },
|
||||
"fingerprintKey": { "@type": "@id", "@id": "toot:fingerprintKey" },
|
||||
"identityKey": { "@type": "@id", "@id": "toot:identityKey" },
|
||||
"devices": { "@type": "@id", "@id": "toot:devices" },
|
||||
"messageFranking": "toot:messageFranking",
|
||||
"messageType": "toot:messageType",
|
||||
"cipherText": "toot:cipherText",
|
||||
"focalPoint": { "@container": "@list", "@id": "toot:focalPoint" }
|
||||
}
|
||||
],
|
||||
"id": "https://niu.moe/users/rye",
|
||||
"type": "Person",
|
||||
"following": "https://niu.moe/users/rye/following",
|
||||
"followers": "https://niu.moe/users/rye/followers",
|
||||
"inbox": "https://niu.moe/users/rye/inbox",
|
||||
"outbox": "https://niu.moe/users/rye/outbox",
|
||||
"featured": "https://niu.moe/users/rye/collections/featured",
|
||||
"preferredUsername": "rye",
|
||||
"name": "♡ rye ♡",
|
||||
"summary": "\\u003cp\\u003ecome back with a warrant\\u003c/p\\u003e",
|
||||
"url": "https://niu.moe/@rye",
|
||||
"manuallyApprovesFollowers": false,
|
||||
"discoverable": false,
|
||||
"devices": "https://niu.moe/users/rye/collections/devices",
|
||||
"publicKey": {
|
||||
"id": "https://niu.moe/users/rye#main-key",
|
||||
"owner": "https://niu.moe/users/rye",
|
||||
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA83uRWjCFO35FwfA38mzv\\nEL0TUaXB7+2hYvPwNrn1WY6me5DRbqB5zzMrzWMGr0HSooqNqEYBafGsmVTWUqIk\\nKM9ehtIBraJI+mT5X7DPR3LrXOJF4a9EEslg8XvAk8MN9IrAhm6UljnvB67RtDcA\\nTNB01VWy9yWnxFRtz9o/EMoBPyw5giOaXE2ibVNP8lQIqGKuuBKPzPjSJygdvQ5q\\nxfow2z1TpKRqdsNDqn4n6U6zCXYTzkr0J71/tGw7fsgfv78l0Wjrc7EcuBk74OaG\\nC65UDiu3X4Q6kxCfCEhPSfuwLN+UZkzxcn6goWR0iYpWs57+4tFKu9nJYP4QJ0K9\\nTwIDAQAB\\n-----END PUBLIC KEY-----\\n"
|
||||
},
|
||||
"tag": [],
|
||||
"attachment": [],
|
||||
"endpoints": { "sharedInbox": "https://niu.moe/inbox" }
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,20 +1,19 @@
|
||||
defmodule Mobilizon.ActorsTest do
|
||||
use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney
|
||||
use Mobilizon.DataCase
|
||||
use Oban.Testing, repo: Mobilizon.Storage.Repo
|
||||
|
||||
import Mox
|
||||
import Mobilizon.Factory
|
||||
|
||||
alias Mobilizon.{Actors, Config, Discussions, Events, Users}
|
||||
alias Mobilizon.Actors.{Actor, Bot, Follower, Member}
|
||||
alias Mobilizon.Discussions.Comment
|
||||
alias Mobilizon.Events.Event
|
||||
alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor
|
||||
alias Mobilizon.Medias.File, as: FileModel
|
||||
alias Mobilizon.Service.HTTP.ActivityPub.Mock
|
||||
alias Mobilizon.Service.Workers
|
||||
alias Mobilizon.Storage.Page
|
||||
|
||||
alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor
|
||||
|
||||
alias Mobilizon.Web.Upload.Uploader
|
||||
|
||||
describe "actors" do
|
||||
@@ -99,25 +98,32 @@ defmodule Mobilizon.ActorsTest do
|
||||
end
|
||||
|
||||
test "get_actor_by_name/1 returns a remote actor" do
|
||||
use_cassette "actors/remote_actor_mastodon_tcit" do
|
||||
{:ok,
|
||||
%Actor{
|
||||
id: actor_id,
|
||||
preferred_username: preferred_username,
|
||||
domain: domain,
|
||||
avatar: %FileModel{name: picture_name} = _picture
|
||||
} = _actor} = ActivityPubActor.get_or_fetch_actor_by_url(@remote_account_url)
|
||||
tcit_social_tcit =
|
||||
"test/fixtures/mastodon-tcit-tcit.json" |> File.read!() |> Jason.decode!()
|
||||
|
||||
assert picture_name == "a28c50ce5f2b13fd.jpg"
|
||||
Mock
|
||||
|> expect(:call, fn
|
||||
%{method: :get, url: @remote_account_url}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: tcit_social_tcit}}
|
||||
end)
|
||||
|
||||
%Actor{
|
||||
id: actor_found_id,
|
||||
avatar: %FileModel{name: picture_name} = _picture
|
||||
} = Actors.get_actor_by_name("#{preferred_username}@#{domain}")
|
||||
{:ok,
|
||||
%Actor{
|
||||
id: actor_id,
|
||||
preferred_username: preferred_username,
|
||||
domain: domain,
|
||||
avatar: %FileModel{name: picture_name} = _picture
|
||||
} = _actor} = ActivityPubActor.get_or_fetch_actor_by_url(@remote_account_url)
|
||||
|
||||
assert actor_found_id == actor_id
|
||||
assert picture_name == "a28c50ce5f2b13fd.jpg"
|
||||
end
|
||||
assert picture_name == "a28c50ce5f2b13fd.jpg"
|
||||
|
||||
%Actor{
|
||||
id: actor_found_id,
|
||||
avatar: %FileModel{name: picture_name} = _picture
|
||||
} = Actors.get_actor_by_name("#{preferred_username}@#{domain}")
|
||||
|
||||
assert actor_found_id == actor_id
|
||||
assert picture_name == "a28c50ce5f2b13fd.jpg"
|
||||
end
|
||||
|
||||
test "get_local_actor_by_name_with_preload!/1 returns the local actor with its organized events",
|
||||
@@ -155,22 +161,29 @@ defmodule Mobilizon.ActorsTest do
|
||||
end
|
||||
|
||||
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} <-
|
||||
ActivityPubActor.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 == []
|
||||
tcit_social_tcit =
|
||||
"test/fixtures/mastodon-tcit-tcit.json" |> File.read!() |> Jason.decode!()
|
||||
|
||||
event = insert(:event, organizer_actor: actor)
|
||||
Mock
|
||||
|> expect(:call, fn
|
||||
%{method: :get, url: @remote_account_url}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: tcit_social_tcit}}
|
||||
end)
|
||||
|
||||
event_found_id =
|
||||
Actors.get_actor_by_name_with_preload("#{actor.preferred_username}@#{actor.domain}").organized_events
|
||||
|> hd
|
||||
|> Map.get(:id)
|
||||
with {:ok, %Actor{} = actor} <-
|
||||
ActivityPubActor.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 == []
|
||||
|
||||
assert event_found_id == event.id
|
||||
end
|
||||
event = insert(:event, organizer_actor: actor)
|
||||
|
||||
event_found_id =
|
||||
Actors.get_actor_by_name_with_preload("#{actor.preferred_username}@#{actor.domain}").organized_events
|
||||
|> hd
|
||||
|> Map.get(:id)
|
||||
|
||||
assert event_found_id == event.id
|
||||
end
|
||||
end
|
||||
|
||||
@@ -185,19 +198,26 @@ defmodule Mobilizon.ActorsTest do
|
||||
|
||||
test "test search_actors/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}} <-
|
||||
ActivityPubActor.get_or_fetch_actor_by_url(@remote_account_url) do
|
||||
%Page{total: 2, elements: actors} =
|
||||
Actors.search_actors("tcit",
|
||||
actor_type: :Person,
|
||||
minimum_visibility: :private
|
||||
)
|
||||
tcit_social_tcit =
|
||||
"test/fixtures/mastodon-tcit-tcit.json" |> File.read!() |> Jason.decode!()
|
||||
|
||||
actors_ids = actors |> Enum.map(& &1.id)
|
||||
Mock
|
||||
|> expect(:call, fn
|
||||
%{method: :get, url: @remote_account_url}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: tcit_social_tcit}}
|
||||
end)
|
||||
|
||||
assert MapSet.new(actors_ids) == MapSet.new([actor2_id, actor_id])
|
||||
end
|
||||
with {:ok, %Actor{id: actor2_id}} <-
|
||||
ActivityPubActor.get_or_fetch_actor_by_url(@remote_account_url) do
|
||||
%Page{total: 2, elements: actors} =
|
||||
Actors.search_actors("tcit",
|
||||
actor_type: :Person,
|
||||
minimum_visibility: :private
|
||||
)
|
||||
|
||||
actors_ids = actors |> Enum.map(& &1.id)
|
||||
|
||||
assert MapSet.new(actors_ids) == MapSet.new([actor2_id, actor_id])
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -120,7 +120,6 @@ defmodule Mobilizon.Web.ActivityPubControllerTest do
|
||||
|
||||
describe "/@:preferred_username/inbox" do
|
||||
test "it inserts an incoming event into the database", %{conn: conn} do
|
||||
# use_cassette "activity_pub_controller/mastodon-post-activity_actor_call" do
|
||||
data = File.read!("test/fixtures/mastodon-post-activity.json") |> Jason.decode!()
|
||||
|
||||
%Actor{url: remote_actor_url} =
|
||||
@@ -151,6 +150,9 @@ defmodule Mobilizon.Web.ActivityPubControllerTest do
|
||||
^local_actor_url ->
|
||||
{:ok, %Tesla.Env{status: 200, body: local_actor_data}}
|
||||
|
||||
"https://framapiaf.org/users/tcit" ->
|
||||
{:ok, %Tesla.Env{status: 404, body: ""}}
|
||||
|
||||
"https://framapiaf.org/users/admin/statuses/99512778738411822" ->
|
||||
{:ok, %Tesla.Env{status: 404, body: ""}}
|
||||
end
|
||||
@@ -168,7 +170,6 @@ defmodule Mobilizon.Web.ActivityPubControllerTest do
|
||||
ActivityPub.fetch_object_from_url(data["object"]["id"])
|
||||
|
||||
assert comment.actor.id == remote_actor.id
|
||||
# end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -5,8 +5,9 @@
|
||||
|
||||
defmodule Mobilizon.Web.Plugs.MappedSignatureToIdentityTest do
|
||||
use Mobilizon.Web.ConnCase
|
||||
use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney
|
||||
import Mox
|
||||
|
||||
alias Mobilizon.Service.HTTP.ActivityPub.Mock
|
||||
alias Mobilizon.Web.Plugs.MappedSignatureToIdentity
|
||||
|
||||
defp set_signature(conn, key_id) do
|
||||
@@ -15,47 +16,100 @@ defmodule Mobilizon.Web.Plugs.MappedSignatureToIdentityTest do
|
||||
|> assign(:valid_signature, true)
|
||||
end
|
||||
|
||||
test "it successfully maps a valid identity with a valid signature" do
|
||||
use_cassette "activity_pub/signature/valid" do
|
||||
conn =
|
||||
build_conn(:get, "/doesntmattter")
|
||||
|> set_signature("https://framapiaf.org/users/admin")
|
||||
|> MappedSignatureToIdentity.call(%{})
|
||||
defp framapiaf_admin do
|
||||
"test/fixtures/signature/framapiaf_admin.json"
|
||||
|> File.read!()
|
||||
|> Jason.decode!()
|
||||
end
|
||||
|
||||
refute is_nil(conn.assigns.actor)
|
||||
end
|
||||
defp nyu_rye do
|
||||
"test/fixtures/signature/nyu_rye.json"
|
||||
|> File.read!()
|
||||
|> Jason.decode!()
|
||||
end
|
||||
|
||||
test "it successfully maps a valid identity with a valid signature" do
|
||||
Mock
|
||||
|> expect(:call, fn
|
||||
%{method: :get, url: "https://framapiaf.org/users/admin"}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: framapiaf_admin()}}
|
||||
end)
|
||||
|
||||
Mock
|
||||
|> expect(:call, fn
|
||||
%{method: :get, url: "/doesntmattter"}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: ""}}
|
||||
end)
|
||||
|
||||
conn =
|
||||
build_conn(:get, "/doesntmattter")
|
||||
|> set_signature("https://framapiaf.org/users/admin")
|
||||
|> MappedSignatureToIdentity.call(%{})
|
||||
|
||||
refute is_nil(conn.assigns.actor)
|
||||
end
|
||||
|
||||
test "it successfully maps a valid identity with a valid signature with payload" do
|
||||
use_cassette "activity_pub/signature/valid_payload" do
|
||||
conn =
|
||||
build_conn(:post, "/doesntmattter", %{"actor" => "https://framapiaf.org/users/admin"})
|
||||
|> set_signature("https://framapiaf.org/users/admin")
|
||||
|> MappedSignatureToIdentity.call(%{})
|
||||
Mock
|
||||
|> expect(:call, fn
|
||||
%{method: :get, url: "https://framapiaf.org/users/admin"}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: framapiaf_admin()}}
|
||||
end)
|
||||
|
||||
refute is_nil(conn.assigns.actor)
|
||||
end
|
||||
Mock
|
||||
|> expect(:call, fn
|
||||
%{method: :post, url: "/doesntmattter"}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: ""}}
|
||||
end)
|
||||
|
||||
conn =
|
||||
build_conn(:post, "/doesntmattter", %{"actor" => "https://framapiaf.org/users/admin"})
|
||||
|> set_signature("https://framapiaf.org/users/admin")
|
||||
|> MappedSignatureToIdentity.call(%{})
|
||||
|
||||
refute is_nil(conn.assigns.actor)
|
||||
end
|
||||
|
||||
test "it considers a mapped identity to be invalid when it mismatches a payload" do
|
||||
use_cassette "activity_pub/signature/invalid_payload" do
|
||||
conn =
|
||||
build_conn(:post, "/doesntmattter", %{"actor" => "https://framapiaf.org/users/admin"})
|
||||
|> set_signature("https://niu.moe/users/rye")
|
||||
|> MappedSignatureToIdentity.call(%{})
|
||||
Mock
|
||||
|> expect(:call, fn
|
||||
%{method: :get, url: "https://niu.moe/users/rye"}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: nyu_rye()}}
|
||||
end)
|
||||
|
||||
assert %{valid_signature: false} == conn.assigns
|
||||
end
|
||||
Mock
|
||||
|> expect(:call, fn
|
||||
%{method: :post, url: "/doesntmattter"}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: ""}}
|
||||
end)
|
||||
|
||||
conn =
|
||||
build_conn(:post, "/doesntmattter", %{"actor" => "https://framapiaf.org/users/admin"})
|
||||
|> set_signature("https://niu.moe/users/rye")
|
||||
|> MappedSignatureToIdentity.call(%{})
|
||||
|
||||
assert %{valid_signature: false} == conn.assigns
|
||||
end
|
||||
|
||||
@tag skip: "Available again when lib/web/plugs/mapped_signature_to_identity.ex#62 is fixed"
|
||||
test "it considers a mapped identity to be invalid when the identity cannot be found" do
|
||||
use_cassette "activity_pub/signature/invalid_not_found" do
|
||||
conn =
|
||||
build_conn(:post, "/doesntmattter", %{"actor" => "https://framapiaf.org/users/admin"})
|
||||
|> set_signature("https://mastodon.social/users/gargron")
|
||||
|> MappedSignatureToIdentity.call(%{})
|
||||
Mock
|
||||
|> expect(:call, fn
|
||||
%{method: :get, url: "https://mastodon.social/users/gargron"}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 404, body: ""}}
|
||||
end)
|
||||
|
||||
assert %{valid_signature: false} == conn.assigns
|
||||
end
|
||||
Mock
|
||||
|> expect(:call, fn
|
||||
%{method: :post, url: "/doesntmattter"}, _opts ->
|
||||
{:ok, %Tesla.Env{status: 200, body: ""}}
|
||||
end)
|
||||
|
||||
conn =
|
||||
build_conn(:post, "/doesntmattter", %{"actor" => "https://framapiaf.org/users/admin"})
|
||||
|> set_signature("https://mastodon.social/users/gargron")
|
||||
|> MappedSignatureToIdentity.call(%{})
|
||||
|
||||
assert %{valid_signature: false} == conn.assigns
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user