summaryrefslogtreecommitdiff
path: root/test/web/activity_pub
diff options
context:
space:
mode:
Diffstat (limited to 'test/web/activity_pub')
-rw-r--r--test/web/activity_pub/activity_pub_controller_test.exs273
-rw-r--r--test/web/activity_pub/activity_pub_test.exs99
-rw-r--r--test/web/activity_pub/mrf/mediaproxy_warming_policy_test.exs6
-rw-r--r--test/web/activity_pub/publisher_test.exs94
-rw-r--r--test/web/activity_pub/relay_test.exs52
-rw-r--r--test/web/activity_pub/transmogrifier/follow_handling_test.exs21
-rw-r--r--test/web/activity_pub/transmogrifier_test.exs326
-rw-r--r--test/web/activity_pub/utils_test.exs334
-rw-r--r--test/web/activity_pub/views/user_view_test.exs71
9 files changed, 1242 insertions, 34 deletions
diff --git a/test/web/activity_pub/activity_pub_controller_test.exs b/test/web/activity_pub/activity_pub_controller_test.exs
index 77f5e39fa..1ffa91b70 100644
--- a/test/web/activity_pub/activity_pub_controller_test.exs
+++ b/test/web/activity_pub/activity_pub_controller_test.exs
@@ -1,18 +1,24 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
use Pleroma.Web.ConnCase
+ use Oban.Testing, repo: Pleroma.Repo
+
import Pleroma.Factory
alias Pleroma.Activity
+ alias Pleroma.Delivery
alias Pleroma.Instances
alias Pleroma.Object
+ alias Pleroma.Tests.ObanHelpers
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ObjectView
+ alias Pleroma.Web.ActivityPub.Relay
alias Pleroma.Web.ActivityPub.UserView
alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.CommonAPI
+ alias Pleroma.Workers.ReceiverWorker
setup_all do
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
@@ -174,6 +180,49 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
assert json_response(conn, 404)
end
+
+ test "it caches a response", %{conn: conn} do
+ note = insert(:note)
+ uuid = String.split(note.data["id"], "/") |> List.last()
+
+ conn1 =
+ conn
+ |> put_req_header("accept", "application/activity+json")
+ |> get("/objects/#{uuid}")
+
+ assert json_response(conn1, :ok)
+ assert Enum.any?(conn1.resp_headers, &(&1 == {"x-cache", "MISS from Pleroma"}))
+
+ conn2 =
+ conn
+ |> put_req_header("accept", "application/activity+json")
+ |> get("/objects/#{uuid}")
+
+ assert json_response(conn1, :ok) == json_response(conn2, :ok)
+ assert Enum.any?(conn2.resp_headers, &(&1 == {"x-cache", "HIT from Pleroma"}))
+ end
+
+ test "cached purged after object deletion", %{conn: conn} do
+ note = insert(:note)
+ uuid = String.split(note.data["id"], "/") |> List.last()
+
+ conn1 =
+ conn
+ |> put_req_header("accept", "application/activity+json")
+ |> get("/objects/#{uuid}")
+
+ assert json_response(conn1, :ok)
+ assert Enum.any?(conn1.resp_headers, &(&1 == {"x-cache", "MISS from Pleroma"}))
+
+ Object.delete(note)
+
+ conn2 =
+ conn
+ |> put_req_header("accept", "application/activity+json")
+ |> get("/objects/#{uuid}")
+
+ assert "Not found" == json_response(conn2, :not_found)
+ end
end
describe "/object/:uuid/likes" do
@@ -263,6 +312,51 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
assert json_response(conn, 404)
end
+
+ test "it caches a response", %{conn: conn} do
+ activity = insert(:note_activity)
+ uuid = String.split(activity.data["id"], "/") |> List.last()
+
+ conn1 =
+ conn
+ |> put_req_header("accept", "application/activity+json")
+ |> get("/activities/#{uuid}")
+
+ assert json_response(conn1, :ok)
+ assert Enum.any?(conn1.resp_headers, &(&1 == {"x-cache", "MISS from Pleroma"}))
+
+ conn2 =
+ conn
+ |> put_req_header("accept", "application/activity+json")
+ |> get("/activities/#{uuid}")
+
+ assert json_response(conn1, :ok) == json_response(conn2, :ok)
+ assert Enum.any?(conn2.resp_headers, &(&1 == {"x-cache", "HIT from Pleroma"}))
+ end
+
+ test "cached purged after activity deletion", %{conn: conn} do
+ user = insert(:user)
+ {:ok, activity} = CommonAPI.post(user, %{"status" => "cofe"})
+
+ uuid = String.split(activity.data["id"], "/") |> List.last()
+
+ conn1 =
+ conn
+ |> put_req_header("accept", "application/activity+json")
+ |> get("/activities/#{uuid}")
+
+ assert json_response(conn1, :ok)
+ assert Enum.any?(conn1.resp_headers, &(&1 == {"x-cache", "MISS from Pleroma"}))
+
+ Activity.delete_by_ap_id(activity.object.data["id"])
+
+ conn2 =
+ conn
+ |> put_req_header("accept", "application/activity+json")
+ |> get("/activities/#{uuid}")
+
+ assert "Not found" == json_response(conn2, :not_found)
+ end
end
describe "/inbox" do
@@ -276,7 +370,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|> post("/inbox", data)
assert "ok" == json_response(conn, 200)
- :timer.sleep(500)
+
+ ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
assert Activity.get_by_ap_id(data["id"])
end
@@ -318,7 +413,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|> post("/users/#{user.nickname}/inbox", data)
assert "ok" == json_response(conn, 200)
- :timer.sleep(500)
+ ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
assert Activity.get_by_ap_id(data["id"])
end
@@ -347,7 +442,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|> post("/users/#{recipient.nickname}/inbox", data)
assert "ok" == json_response(conn, 200)
- :timer.sleep(500)
+ ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
assert Activity.get_by_ap_id(data["id"])
end
@@ -364,6 +459,17 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
assert json_response(conn, 403)
end
+ test "it doesn't crash without an authenticated user", %{conn: conn} do
+ user = insert(:user)
+
+ conn =
+ conn
+ |> put_req_header("accept", "application/activity+json")
+ |> get("/users/#{user.nickname}/inbox")
+
+ assert json_response(conn, 403)
+ end
+
test "it returns a note activity in a collection", %{conn: conn} do
note_activity = insert(:direct_note_activity)
note_object = Object.normalize(note_activity)
@@ -373,7 +479,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
conn
|> assign(:user, user)
|> put_req_header("accept", "application/activity+json")
- |> get("/users/#{user.nickname}/inbox")
+ |> get("/users/#{user.nickname}/inbox?page=true")
assert response(conn, 200) =~ note_object.data["content"]
end
@@ -426,6 +532,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|> post("/users/#{recipient.nickname}/inbox", data)
|> json_response(200)
+ ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
+
activity = Activity.get_by_ap_id(data["id"])
assert activity.id
@@ -459,7 +567,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
conn =
conn
|> put_req_header("accept", "application/activity+json")
- |> get("/users/#{user.nickname}/outbox")
+ |> get("/users/#{user.nickname}/outbox?page=true")
assert response(conn, 200) =~ note_object.data["content"]
end
@@ -471,7 +579,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
conn =
conn
|> put_req_header("accept", "application/activity+json")
- |> get("/users/#{user.nickname}/outbox")
+ |> get("/users/#{user.nickname}/outbox?page=true")
assert response(conn, 200) =~ announce_activity.data["object"]
end
@@ -501,6 +609,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|> post("/users/#{user.nickname}/outbox", data)
result = json_response(conn, 201)
+
assert Activity.get_by_ap_id(result["id"])
end
@@ -593,6 +702,34 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
end
end
+ describe "/relay/followers" do
+ test "it returns relay followers", %{conn: conn} do
+ relay_actor = Relay.get_actor()
+ user = insert(:user)
+ User.follow(user, relay_actor)
+
+ result =
+ conn
+ |> assign(:relay, true)
+ |> get("/relay/followers")
+ |> json_response(200)
+
+ assert result["first"]["orderedItems"] == [user.ap_id]
+ end
+ end
+
+ describe "/relay/following" do
+ test "it returns relay following", %{conn: conn} do
+ result =
+ conn
+ |> assign(:relay, true)
+ |> get("/relay/following")
+ |> json_response(200)
+
+ assert result["first"]["orderedItems"] == []
+ end
+ end
+
describe "/users/:nickname/followers" do
test "it returns the followers in a collection", %{conn: conn} do
user = insert(:user)
@@ -757,4 +894,126 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
assert result["totalItems"] == 15
end
end
+
+ describe "delivery tracking" do
+ test "it tracks a signed object fetch", %{conn: conn} do
+ user = insert(:user, local: false)
+ activity = insert(:note_activity)
+ object = Object.normalize(activity)
+
+ object_path = String.trim_leading(object.data["id"], Pleroma.Web.Endpoint.url())
+
+ conn
+ |> put_req_header("accept", "application/activity+json")
+ |> assign(:user, user)
+ |> get(object_path)
+ |> json_response(200)
+
+ assert Delivery.get(object.id, user.id)
+ end
+
+ test "it tracks a signed activity fetch", %{conn: conn} do
+ user = insert(:user, local: false)
+ activity = insert(:note_activity)
+ object = Object.normalize(activity)
+
+ activity_path = String.trim_leading(activity.data["id"], Pleroma.Web.Endpoint.url())
+
+ conn
+ |> put_req_header("accept", "application/activity+json")
+ |> assign(:user, user)
+ |> get(activity_path)
+ |> json_response(200)
+
+ assert Delivery.get(object.id, user.id)
+ end
+
+ test "it tracks a signed object fetch when the json is cached", %{conn: conn} do
+ user = insert(:user, local: false)
+ other_user = insert(:user, local: false)
+ activity = insert(:note_activity)
+ object = Object.normalize(activity)
+
+ object_path = String.trim_leading(object.data["id"], Pleroma.Web.Endpoint.url())
+
+ conn
+ |> put_req_header("accept", "application/activity+json")
+ |> assign(:user, user)
+ |> get(object_path)
+ |> json_response(200)
+
+ build_conn()
+ |> put_req_header("accept", "application/activity+json")
+ |> assign(:user, other_user)
+ |> get(object_path)
+ |> json_response(200)
+
+ assert Delivery.get(object.id, user.id)
+ assert Delivery.get(object.id, other_user.id)
+ end
+
+ test "it tracks a signed activity fetch when the json is cached", %{conn: conn} do
+ user = insert(:user, local: false)
+ other_user = insert(:user, local: false)
+ activity = insert(:note_activity)
+ object = Object.normalize(activity)
+
+ activity_path = String.trim_leading(activity.data["id"], Pleroma.Web.Endpoint.url())
+
+ conn
+ |> put_req_header("accept", "application/activity+json")
+ |> assign(:user, user)
+ |> get(activity_path)
+ |> json_response(200)
+
+ build_conn()
+ |> put_req_header("accept", "application/activity+json")
+ |> assign(:user, other_user)
+ |> get(activity_path)
+ |> json_response(200)
+
+ assert Delivery.get(object.id, user.id)
+ assert Delivery.get(object.id, other_user.id)
+ end
+ end
+
+ describe "Additionnal ActivityPub C2S endpoints" do
+ test "/api/ap/whoami", %{conn: conn} do
+ user = insert(:user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> get("/api/ap/whoami")
+
+ user = User.get_cached_by_id(user.id)
+
+ assert UserView.render("user.json", %{user: user}) == json_response(conn, 200)
+ end
+
+ clear_config([:media_proxy])
+ clear_config([Pleroma.Upload])
+
+ test "uploadMedia", %{conn: conn} do
+ user = insert(:user)
+
+ desc = "Description of the image"
+
+ image = %Plug.Upload{
+ content_type: "image/jpg",
+ path: Path.absname("test/fixtures/image.jpg"),
+ filename: "an_image.jpg"
+ }
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/ap/upload_media", %{"file" => image, "description" => desc})
+
+ assert object = json_response(conn, :created)
+ assert object["name"] == desc
+ assert object["type"] == "Document"
+ assert object["actor"] == user.ap_id
+ end
+ end
end
diff --git a/test/web/activity_pub/activity_pub_test.exs b/test/web/activity_pub/activity_pub_test.exs
index 1515f4eb6..a203d1d30 100644
--- a/test/web/activity_pub/activity_pub_test.exs
+++ b/test/web/activity_pub/activity_pub_test.exs
@@ -21,6 +21,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
:ok
end
+ clear_config([:instance, :federating])
+
describe "streaming out participations" do
test "it streams them out" do
user = insert(:user)
@@ -36,9 +38,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
stream: fn _, _ -> nil end do
ActivityPub.stream_out_participations(conversation.participations)
- Enum.each(participations, fn participation ->
- assert called(Pleroma.Web.Streamer.stream("participation", participation))
- end)
+ assert called(Pleroma.Web.Streamer.stream("participation", participations))
end
end
end
@@ -257,6 +257,42 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
end
end
+ describe "listen activities" do
+ test "does not increase user note count" do
+ user = insert(:user)
+
+ {:ok, activity} =
+ ActivityPub.listen(%{
+ to: ["https://www.w3.org/ns/activitystreams#Public"],
+ actor: user,
+ context: "",
+ object: %{
+ "actor" => user.ap_id,
+ "to" => ["https://www.w3.org/ns/activitystreams#Public"],
+ "artist" => "lain",
+ "title" => "lain radio episode 1",
+ "length" => 180_000,
+ "type" => "Audio"
+ }
+ })
+
+ assert activity.actor == user.ap_id
+
+ user = User.get_cached_by_id(user.id)
+ assert user.info.note_count == 0
+ end
+
+ test "can be fetched into a timeline" do
+ _listen_activity_1 = insert(:listen)
+ _listen_activity_2 = insert(:listen)
+ _listen_activity_3 = insert(:listen)
+
+ timeline = ActivityPub.fetch_activities([], %{"type" => ["Listen"]})
+
+ assert length(timeline) == 3
+ end
+ end
+
describe "create activities" do
test "removes doubled 'to' recipients" do
user = insert(:user)
@@ -647,6 +683,21 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
assert last == last_expected
end
+ test "paginates via offset/limit" do
+ _first_activities = ActivityBuilder.insert_list(10)
+ activities = ActivityBuilder.insert_list(10)
+ _later_activities = ActivityBuilder.insert_list(10)
+ first_expected = List.first(activities)
+
+ activities =
+ ActivityPub.fetch_public_activities(%{"page" => "2", "page_size" => "20"}, :offset)
+
+ first = List.first(activities)
+
+ assert length(activities) == 20
+ assert first == first_expected
+ end
+
test "doesn't return reblogs for users for whom reblogs have been muted" do
activity = insert(:note_activity)
user = insert(:user)
@@ -676,6 +727,29 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
end
describe "like an object" do
+ test_with_mock "sends an activity to federation", Pleroma.Web.Federator, [:passthrough], [] do
+ Pleroma.Config.put([:instance, :federating], true)
+ note_activity = insert(:note_activity)
+ assert object_activity = Object.normalize(note_activity)
+
+ user = insert(:user)
+
+ {:ok, like_activity, _object} = ActivityPub.like(user, object_activity)
+ assert called(Pleroma.Web.Federator.publish(like_activity))
+ end
+
+ test "returns exist activity if object already liked" do
+ note_activity = insert(:note_activity)
+ assert object_activity = Object.normalize(note_activity)
+
+ user = insert(:user)
+
+ {:ok, like_activity, _object} = ActivityPub.like(user, object_activity)
+
+ {:ok, like_activity_exist, _object} = ActivityPub.like(user, object_activity)
+ assert like_activity == like_activity_exist
+ end
+
test "adds a like activity to the db" do
note_activity = insert(:note_activity)
assert object = Object.normalize(note_activity)
@@ -706,6 +780,25 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
end
describe "unliking" do
+ test_with_mock "sends an activity to federation", Pleroma.Web.Federator, [:passthrough], [] do
+ Pleroma.Config.put([:instance, :federating], true)
+
+ note_activity = insert(:note_activity)
+ object = Object.normalize(note_activity)
+ user = insert(:user)
+
+ {:ok, object} = ActivityPub.unlike(user, object)
+ refute called(Pleroma.Web.Federator.publish())
+
+ {:ok, _like_activity, object} = ActivityPub.like(user, object)
+ assert object.data["like_count"] == 1
+
+ {:ok, unlike_activity, _, object} = ActivityPub.unlike(user, object)
+ assert object.data["like_count"] == 0
+
+ assert called(Pleroma.Web.Federator.publish(unlike_activity))
+ end
+
test "unliking a previously liked object" do
note_activity = insert(:note_activity)
object = Object.normalize(note_activity)
diff --git a/test/web/activity_pub/mrf/mediaproxy_warming_policy_test.exs b/test/web/activity_pub/mrf/mediaproxy_warming_policy_test.exs
index 372e789be..95a809d25 100644
--- a/test/web/activity_pub/mrf/mediaproxy_warming_policy_test.exs
+++ b/test/web/activity_pub/mrf/mediaproxy_warming_policy_test.exs
@@ -6,6 +6,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicyTest do
use Pleroma.DataCase
alias Pleroma.HTTP
+ alias Pleroma.Tests.ObanHelpers
alias Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy
import Mock
@@ -24,6 +25,11 @@ defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicyTest do
test "it prefetches media proxy URIs" do
with_mock HTTP, get: fn _, _, _ -> {:ok, []} end do
MediaProxyWarmingPolicy.filter(@message)
+
+ ObanHelpers.perform_all()
+ # Performing jobs which has been just enqueued
+ ObanHelpers.perform_all()
+
assert called(HTTP.get(:_, :_, :_))
end
end
diff --git a/test/web/activity_pub/publisher_test.exs b/test/web/activity_pub/publisher_test.exs
index 36a39c84c..df03b4008 100644
--- a/test/web/activity_pub/publisher_test.exs
+++ b/test/web/activity_pub/publisher_test.exs
@@ -3,15 +3,18 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.PublisherTest do
- use Pleroma.DataCase
+ use Pleroma.Web.ConnCase
+ import ExUnit.CaptureLog
import Pleroma.Factory
import Tesla.Mock
import Mock
alias Pleroma.Activity
alias Pleroma.Instances
+ alias Pleroma.Object
alias Pleroma.Web.ActivityPub.Publisher
+ alias Pleroma.Web.CommonAPI
@as_public "https://www.w3.org/ns/activitystreams#Public"
@@ -188,7 +191,10 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
actor = insert(:user)
inbox = "http://connrefused.site/users/nick1/inbox"
- assert {:error, _} = Publisher.publish_one(%{inbox: inbox, json: "{}", actor: actor, id: 1})
+ assert capture_log(fn ->
+ assert {:error, _} =
+ Publisher.publish_one(%{inbox: inbox, json: "{}", actor: actor, id: 1})
+ end) =~ "connrefused"
assert called(Instances.set_unreachable(inbox))
end
@@ -212,14 +218,16 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
actor = insert(:user)
inbox = "http://connrefused.site/users/nick1/inbox"
- assert {:error, _} =
- Publisher.publish_one(%{
- inbox: inbox,
- json: "{}",
- actor: actor,
- id: 1,
- unreachable_since: NaiveDateTime.utc_now()
- })
+ assert capture_log(fn ->
+ assert {:error, _} =
+ Publisher.publish_one(%{
+ inbox: inbox,
+ json: "{}",
+ actor: actor,
+ id: 1,
+ unreachable_since: NaiveDateTime.utc_now()
+ })
+ end) =~ "connrefused"
refute called(Instances.set_unreachable(inbox))
end
@@ -257,10 +265,74 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
assert called(
Pleroma.Web.Federator.Publisher.enqueue_one(Publisher, %{
inbox: "https://domain.com/users/nick1/inbox",
- actor: actor,
+ actor_id: actor.id,
id: note_activity.data["id"]
})
)
end
+
+ test_with_mock "publishes a delete activity to peers who signed fetch requests to the create acitvity/object.",
+ Pleroma.Web.Federator.Publisher,
+ [:passthrough],
+ [] do
+ fetcher =
+ insert(:user,
+ local: false,
+ info: %{
+ ap_enabled: true,
+ source_data: %{"inbox" => "https://domain.com/users/nick1/inbox"}
+ }
+ )
+
+ another_fetcher =
+ insert(:user,
+ local: false,
+ info: %{
+ ap_enabled: true,
+ source_data: %{"inbox" => "https://domain2.com/users/nick1/inbox"}
+ }
+ )
+
+ actor = insert(:user)
+
+ note_activity = insert(:note_activity, user: actor)
+ object = Object.normalize(note_activity)
+
+ activity_path = String.trim_leading(note_activity.data["id"], Pleroma.Web.Endpoint.url())
+ object_path = String.trim_leading(object.data["id"], Pleroma.Web.Endpoint.url())
+
+ build_conn()
+ |> put_req_header("accept", "application/activity+json")
+ |> assign(:user, fetcher)
+ |> get(object_path)
+ |> json_response(200)
+
+ build_conn()
+ |> put_req_header("accept", "application/activity+json")
+ |> assign(:user, another_fetcher)
+ |> get(activity_path)
+ |> json_response(200)
+
+ {:ok, delete} = CommonAPI.delete(note_activity.id, actor)
+
+ res = Publisher.publish(actor, delete)
+ assert res == :ok
+
+ assert called(
+ Pleroma.Web.Federator.Publisher.enqueue_one(Publisher, %{
+ inbox: "https://domain.com/users/nick1/inbox",
+ actor_id: actor.id,
+ id: delete.data["id"]
+ })
+ )
+
+ assert called(
+ Pleroma.Web.Federator.Publisher.enqueue_one(Publisher, %{
+ inbox: "https://domain2.com/users/nick1/inbox",
+ actor_id: actor.id,
+ id: delete.data["id"]
+ })
+ )
+ end
end
end
diff --git a/test/web/activity_pub/relay_test.exs b/test/web/activity_pub/relay_test.exs
index e10b808f7..0f7556538 100644
--- a/test/web/activity_pub/relay_test.exs
+++ b/test/web/activity_pub/relay_test.exs
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.RelayTest do
@@ -10,7 +10,9 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Relay
+ import ExUnit.CaptureLog
import Pleroma.Factory
+ import Mock
test "gets an actor for the relay" do
user = Relay.get_actor()
@@ -19,7 +21,9 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do
describe "follow/1" do
test "returns errors when user not found" do
- assert Relay.follow("test-ap-id") == {:error, "Could not fetch by AP id"}
+ assert capture_log(fn ->
+ assert Relay.follow("test-ap-id") == {:error, "Could not fetch by AP id"}
+ end) =~ "Could not fetch by AP id"
end
test "returns activity" do
@@ -36,23 +40,30 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do
describe "unfollow/1" do
test "returns errors when user not found" do
- assert Relay.unfollow("test-ap-id") == {:error, "Could not fetch by AP id"}
+ assert capture_log(fn ->
+ assert Relay.unfollow("test-ap-id") == {:error, "Could not fetch by AP id"}
+ end) =~ "Could not fetch by AP id"
end
test "returns activity" do
user = insert(:user)
service_actor = Relay.get_actor()
ActivityPub.follow(service_actor, user)
+ Pleroma.User.follow(service_actor, user)
+ assert "#{user.ap_id}/followers" in refresh_record(service_actor).following
assert {:ok, %Activity{} = activity} = Relay.unfollow(user.ap_id)
assert activity.actor == "#{Pleroma.Web.Endpoint.url()}/relay"
assert user.ap_id in activity.recipients
assert activity.data["type"] == "Undo"
assert activity.data["actor"] == service_actor.ap_id
assert activity.data["to"] == [user.ap_id]
+ refute "#{user.ap_id}/followers" in refresh_record(service_actor).following
end
end
describe "publish/1" do
+ clear_config([:instance, :federating])
+
test "returns error when activity not `Create` type" do
activity = insert(:like_activity)
assert Relay.publish(activity) == {:error, "Not implemented"}
@@ -63,13 +74,46 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do
assert Relay.publish(activity) == {:error, false}
end
- test "returns announce activity" do
+ test "returns error when object is unknown" do
+ activity =
+ insert(:note_activity,
+ data: %{
+ "type" => "Create",
+ "object" => "http://mastodon.example.org/eee/99541947525187367"
+ }
+ )
+
+ assert capture_log(fn ->
+ assert Relay.publish(activity) == {:error, nil}
+ end) =~ "[error] error: nil"
+ end
+
+ test_with_mock "returns announce activity and publish to federate",
+ Pleroma.Web.Federator,
+ [:passthrough],
+ [] do
+ Pleroma.Config.put([:instance, :federating], true)
+ service_actor = Relay.get_actor()
+ note = insert(:note_activity)
+ assert {:ok, %Activity{} = activity, %Object{} = obj} = Relay.publish(note)
+ assert activity.data["type"] == "Announce"
+ assert activity.data["actor"] == service_actor.ap_id
+ assert activity.data["object"] == obj.data["id"]
+ assert called(Pleroma.Web.Federator.publish(activity))
+ end
+
+ test_with_mock "returns announce activity and not publish to federate",
+ Pleroma.Web.Federator,
+ [:passthrough],
+ [] do
+ Pleroma.Config.put([:instance, :federating], false)
service_actor = Relay.get_actor()
note = insert(:note_activity)
assert {:ok, %Activity{} = activity, %Object{} = obj} = Relay.publish(note)
assert activity.data["type"] == "Announce"
assert activity.data["actor"] == service_actor.ap_id
assert activity.data["object"] == obj.data["id"]
+ refute called(Pleroma.Web.Federator.publish(activity))
end
end
end
diff --git a/test/web/activity_pub/transmogrifier/follow_handling_test.exs b/test/web/activity_pub/transmogrifier/follow_handling_test.exs
index 857d65564..99ab573c5 100644
--- a/test/web/activity_pub/transmogrifier/follow_handling_test.exs
+++ b/test/web/activity_pub/transmogrifier/follow_handling_test.exs
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do
@@ -19,6 +19,25 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do
end
describe "handle_incoming" do
+ test "it works for osada follow request" do
+ user = insert(:user)
+
+ data =
+ File.read!("test/fixtures/osada-follow-activity.json")
+ |> Poison.decode!()
+ |> Map.put("object", user.ap_id)
+
+ {:ok, %Activity{data: data, local: false} = activity} = Transmogrifier.handle_incoming(data)
+
+ assert data["actor"] == "https://apfed.club/channel/indio"
+ assert data["type"] == "Follow"
+ assert data["id"] == "https://apfed.club/follow/9"
+
+ activity = Repo.get(Activity, activity.id)
+ assert activity.data["state"] == "accept"
+ assert User.following?(User.get_cached_by_ap_id(data["actor"]), user)
+ end
+
test "it works for incoming follow requests" do
user = insert(:user)
diff --git a/test/web/activity_pub/transmogrifier_test.exs b/test/web/activity_pub/transmogrifier_test.exs
index 629c76c97..193d6d301 100644
--- a/test/web/activity_pub/transmogrifier_test.exs
+++ b/test/web/activity_pub/transmogrifier_test.exs
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
@@ -8,6 +8,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
alias Pleroma.Object
alias Pleroma.Object.Fetcher
alias Pleroma.Repo
+ alias Pleroma.Tests.ObanHelpers
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Transmogrifier
@@ -102,7 +103,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
assert capture_log(fn ->
{:ok, _returned_activity} = Transmogrifier.handle_incoming(data)
- end) =~ "[error] Couldn't fetch \"\"https://404.site/whatever\"\", error: nil"
+ end) =~ "[error] Couldn't fetch \"https://404.site/whatever\", error: nil"
end
test "it works for incoming notices" do
@@ -176,6 +177,35 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
end)
end
+ test "it works for incoming listens" do
+ data = %{
+ "@context" => "https://www.w3.org/ns/activitystreams",
+ "to" => ["https://www.w3.org/ns/activitystreams#Public"],
+ "cc" => [],
+ "type" => "Listen",
+ "id" => "http://mastodon.example.org/users/admin/listens/1234/activity",
+ "actor" => "http://mastodon.example.org/users/admin",
+ "object" => %{
+ "type" => "Audio",
+ "id" => "http://mastodon.example.org/users/admin/listens/1234",
+ "attributedTo" => "http://mastodon.example.org/users/admin",
+ "title" => "lain radio episode 1",
+ "artist" => "lain",
+ "album" => "lain radio",
+ "length" => 180_000
+ }
+ }
+
+ {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
+
+ object = Object.normalize(activity)
+
+ assert object.data["title"] == "lain radio episode 1"
+ assert object.data["artist"] == "lain"
+ assert object.data["album"] == "lain radio"
+ assert object.data["length"] == 180_000
+ end
+
test "it rewrites Note votes to Answers and increments vote counters on question activities" do
user = insert(:user)
@@ -563,6 +593,14 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
%{"name" => "foo", "value" => "updated"},
%{"name" => "foo1", "value" => "updated"}
]
+
+ update_data = put_in(update_data, ["object", "attachment"], [])
+
+ {:ok, _} = Transmogrifier.handle_incoming(update_data)
+
+ user = User.get_cached_by_ap_id(user.ap_id)
+
+ assert User.Info.fields(user.info) == []
end
test "it works for incoming update activities which lock the account" do
@@ -640,6 +678,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|> Poison.decode!()
{:ok, _} = Transmogrifier.handle_incoming(data)
+ ObanHelpers.perform_all()
refute User.get_cached_by_ap_id(ap_id)
end
@@ -1180,6 +1219,20 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
assert is_nil(modified["bcc"])
end
+
+ test "it can handle Listen activities" do
+ listen_activity = insert(:listen)
+
+ {:ok, modified} = Transmogrifier.prepare_outgoing(listen_activity.data)
+
+ assert modified["type"] == "Listen"
+
+ user = insert(:user)
+
+ {:ok, activity} = CommonAPI.listen(user, %{"title" => "lain radio episode 1"})
+
+ {:ok, _modified} = Transmogrifier.prepare_outgoing(activity.data)
+ end
end
describe "user upgrade" do
@@ -1202,6 +1255,8 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
assert user.info.note_count == 1
{:ok, user} = Transmogrifier.upgrade_user_from_ap_id("https://niu.moe/users/rye")
+ ObanHelpers.perform_all()
+
assert user.info.ap_enabled
assert user.info.note_count == 1
assert user.follower_address == "https://niu.moe/users/rye/followers"
@@ -1443,4 +1498,271 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
refute recipient.follower_address in fixed_object["to"]
end
end
+
+ describe "fix_summary/1" do
+ test "returns fixed object" do
+ assert Transmogrifier.fix_summary(%{"summary" => nil}) == %{"summary" => ""}
+ assert Transmogrifier.fix_summary(%{"summary" => "ok"}) == %{"summary" => "ok"}
+ assert Transmogrifier.fix_summary(%{}) == %{"summary" => ""}
+ end
+ end
+
+ describe "fix_in_reply_to/2" do
+ clear_config([:instance, :federation_incoming_replies_max_depth])
+
+ setup do
+ data = Poison.decode!(File.read!("test/fixtures/mastodon-post-activity.json"))
+ [data: data]
+ end
+
+ test "returns not modified object when hasn't containts inReplyTo field", %{data: data} do
+ assert Transmogrifier.fix_in_reply_to(data) == data
+ end
+
+ test "returns object with inReplyToAtomUri when denied incoming reply", %{data: data} do
+ Pleroma.Config.put([:instance, :federation_incoming_replies_max_depth], 0)
+
+ object_with_reply =
+ Map.put(data["object"], "inReplyTo", "https://shitposter.club/notice/2827873")
+
+ modified_object = Transmogrifier.fix_in_reply_to(object_with_reply)
+ assert modified_object["inReplyTo"] == "https://shitposter.club/notice/2827873"
+ assert modified_object["inReplyToAtomUri"] == "https://shitposter.club/notice/2827873"
+
+ object_with_reply =
+ Map.put(data["object"], "inReplyTo", %{"id" => "https://shitposter.club/notice/2827873"})
+
+ modified_object = Transmogrifier.fix_in_reply_to(object_with_reply)
+ assert modified_object["inReplyTo"] == %{"id" => "https://shitposter.club/notice/2827873"}
+ assert modified_object["inReplyToAtomUri"] == "https://shitposter.club/notice/2827873"
+
+ object_with_reply =
+ Map.put(data["object"], "inReplyTo", ["https://shitposter.club/notice/2827873"])
+
+ modified_object = Transmogrifier.fix_in_reply_to(object_with_reply)
+ assert modified_object["inReplyTo"] == ["https://shitposter.club/notice/2827873"]
+ assert modified_object["inReplyToAtomUri"] == "https://shitposter.club/notice/2827873"
+
+ object_with_reply = Map.put(data["object"], "inReplyTo", [])
+ modified_object = Transmogrifier.fix_in_reply_to(object_with_reply)
+ assert modified_object["inReplyTo"] == []
+ assert modified_object["inReplyToAtomUri"] == ""
+ end
+
+ test "returns modified object when allowed incoming reply", %{data: data} do
+ object_with_reply =
+ Map.put(
+ data["object"],
+ "inReplyTo",
+ "https://shitposter.club/notice/2827873"
+ )
+
+ Pleroma.Config.put([:instance, :federation_incoming_replies_max_depth], 5)
+ modified_object = Transmogrifier.fix_in_reply_to(object_with_reply)
+
+ assert modified_object["inReplyTo"] ==
+ "tag:shitposter.club,2017-05-05:noticeId=2827873:objectType=comment"
+
+ assert modified_object["inReplyToAtomUri"] == "https://shitposter.club/notice/2827873"
+
+ assert modified_object["conversation"] ==
+ "tag:shitposter.club,2017-05-05:objectType=thread:nonce=3c16e9c2681f6d26"
+
+ assert modified_object["context"] ==
+ "tag:shitposter.club,2017-05-05:objectType=thread:nonce=3c16e9c2681f6d26"
+ end
+ end
+
+ describe "fix_url/1" do
+ test "fixes data for object when url is map" do
+ object = %{
+ "url" => %{
+ "type" => "Link",
+ "mimeType" => "video/mp4",
+ "href" => "https://peede8d-46fb-ad81-2d4c2d1630e3-480.mp4"
+ }
+ }
+
+ assert Transmogrifier.fix_url(object) == %{
+ "url" => "https://peede8d-46fb-ad81-2d4c2d1630e3-480.mp4"
+ }
+ end
+
+ test "fixes data for video object" do
+ object = %{
+ "type" => "Video",
+ "url" => [
+ %{
+ "type" => "Link",
+ "mimeType" => "video/mp4",
+ "href" => "https://peede8d-46fb-ad81-2d4c2d1630e3-480.mp4"
+ },
+ %{
+ "type" => "Link",
+ "mimeType" => "video/mp4",
+ "href" => "https://peertube46fb-ad81-2d4c2d1630e3-240.mp4"
+ },
+ %{
+ "type" => "Link",
+ "mimeType" => "text/html",
+ "href" => "https://peertube.-2d4c2d1630e3"
+ },
+ %{
+ "type" => "Link",
+ "mimeType" => "text/html",
+ "href" => "https://peertube.-2d4c2d16377-42"
+ }
+ ]
+ }
+
+ assert Transmogrifier.fix_url(object) == %{
+ "attachment" => [
+ %{
+ "href" => "https://peede8d-46fb-ad81-2d4c2d1630e3-480.mp4",
+ "mimeType" => "video/mp4",
+ "type" => "Link"
+ }
+ ],
+ "type" => "Video",
+ "url" => "https://peertube.-2d4c2d1630e3"
+ }
+ end
+
+ test "fixes url for not Video object" do
+ object = %{
+ "type" => "Text",
+ "url" => [
+ %{
+ "type" => "Link",
+ "mimeType" => "text/html",
+ "href" => "https://peertube.-2d4c2d1630e3"
+ },
+ %{
+ "type" => "Link",
+ "mimeType" => "text/html",
+ "href" => "https://peertube.-2d4c2d16377-42"
+ }
+ ]
+ }
+
+ assert Transmogrifier.fix_url(object) == %{
+ "type" => "Text",
+ "url" => "https://peertube.-2d4c2d1630e3"
+ }
+
+ assert Transmogrifier.fix_url(%{"type" => "Text", "url" => []}) == %{
+ "type" => "Text",
+ "url" => ""
+ }
+ end
+
+ test "retunrs not modified object" do
+ assert Transmogrifier.fix_url(%{"type" => "Text"}) == %{"type" => "Text"}
+ end
+ end
+
+ describe "get_obj_helper/2" do
+ test "returns nil when cannot normalize object" do
+ refute Transmogrifier.get_obj_helper("test-obj-id")
+ end
+
+ test "returns {:ok, %Object{}} for success case" do
+ assert {:ok, %Object{}} =
+ Transmogrifier.get_obj_helper("https://shitposter.club/notice/2827873")
+ end
+ end
+
+ describe "fix_attachments/1" do
+ test "returns not modified object" do
+ data = Poison.decode!(File.read!("test/fixtures/mastodon-post-activity.json"))
+ assert Transmogrifier.fix_attachments(data) == data
+ end
+
+ test "returns modified object when attachment is map" do
+ assert Transmogrifier.fix_attachments(%{
+ "attachment" => %{
+ "mediaType" => "video/mp4",
+ "url" => "https://peertube.moe/stat-480.mp4"
+ }
+ }) == %{
+ "attachment" => [
+ %{
+ "mediaType" => "video/mp4",
+ "url" => [
+ %{
+ "href" => "https://peertube.moe/stat-480.mp4",
+ "mediaType" => "video/mp4",
+ "type" => "Link"
+ }
+ ]
+ }
+ ]
+ }
+ end
+
+ test "returns modified object when attachment is list" do
+ assert Transmogrifier.fix_attachments(%{
+ "attachment" => [
+ %{"mediaType" => "video/mp4", "url" => "https://pe.er/stat-480.mp4"},
+ %{"mimeType" => "video/mp4", "href" => "https://pe.er/stat-480.mp4"}
+ ]
+ }) == %{
+ "attachment" => [
+ %{
+ "mediaType" => "video/mp4",
+ "url" => [
+ %{
+ "href" => "https://pe.er/stat-480.mp4",
+ "mediaType" => "video/mp4",
+ "type" => "Link"
+ }
+ ]
+ },
+ %{
+ "href" => "https://pe.er/stat-480.mp4",
+ "mediaType" => "video/mp4",
+ "mimeType" => "video/mp4",
+ "url" => [
+ %{
+ "href" => "https://pe.er/stat-480.mp4",
+ "mediaType" => "video/mp4",
+ "type" => "Link"
+ }
+ ]
+ }
+ ]
+ }
+ end
+ end
+
+ describe "fix_emoji/1" do
+ test "returns not modified object when object not contains tags" do
+ data = Poison.decode!(File.read!("test/fixtures/mastodon-post-activity.json"))
+ assert Transmogrifier.fix_emoji(data) == data
+ end
+
+ test "returns object with emoji when object contains list tags" do
+ assert Transmogrifier.fix_emoji(%{
+ "tag" => [
+ %{"type" => "Emoji", "name" => ":bib:", "icon" => %{"url" => "/test"}},
+ %{"type" => "Hashtag"}
+ ]
+ }) == %{
+ "emoji" => %{"bib" => "/test"},
+ "tag" => [
+ %{"icon" => %{"url" => "/test"}, "name" => ":bib:", "type" => "Emoji"},
+ %{"type" => "Hashtag"}
+ ]
+ }
+ end
+
+ test "returns object with emoji when object contains map tag" do
+ assert Transmogrifier.fix_emoji(%{
+ "tag" => %{"type" => "Emoji", "name" => ":bib:", "icon" => %{"url" => "/test"}}
+ }) == %{
+ "emoji" => %{"bib" => "/test"},
+ "tag" => %{"icon" => %{"url" => "/test"}, "name" => ":bib:", "type" => "Emoji"}
+ }
+ end
+ end
end
diff --git a/test/web/activity_pub/utils_test.exs b/test/web/activity_pub/utils_test.exs
index ca5f057a7..b1c1d6f71 100644
--- a/test/web/activity_pub/utils_test.exs
+++ b/test/web/activity_pub/utils_test.exs
@@ -14,6 +14,8 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
import Pleroma.Factory
+ require Pleroma.Constants
+
describe "fetch the latest Follow" do
test "fetches the latest Follow activity" do
%Activity{data: %{"type" => "Follow"}} = activity = insert(:follow_activity)
@@ -85,6 +87,44 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
assert Utils.determine_explicit_mentions(object) == []
end
+
+ test "works with an object has tags as map" do
+ object = %{
+ "tag" => %{
+ "type" => "Mention",
+ "href" => "https://example.com/~alyssa",
+ "name" => "Alyssa P. Hacker"
+ }
+ }
+
+ assert Utils.determine_explicit_mentions(object) == ["https://example.com/~alyssa"]
+ end
+ end
+
+ describe "make_unlike_data/3" do
+ test "returns data for unlike activity" do
+ user = insert(:user)
+ like_activity = insert(:like_activity, data_attrs: %{"context" => "test context"})
+
+ assert Utils.make_unlike_data(user, like_activity, nil) == %{
+ "type" => "Undo",
+ "actor" => user.ap_id,
+ "object" => like_activity.data,
+ "to" => [user.follower_address, like_activity.data["actor"]],
+ "cc" => [Pleroma.Constants.as_public()],
+ "context" => like_activity.data["context"]
+ }
+
+ assert Utils.make_unlike_data(user, like_activity, "9mJEZK0tky1w2xD2vY") == %{
+ "type" => "Undo",
+ "actor" => user.ap_id,
+ "object" => like_activity.data,
+ "to" => [user.follower_address, like_activity.data["actor"]],
+ "cc" => [Pleroma.Constants.as_public()],
+ "context" => like_activity.data["context"],
+ "id" => "9mJEZK0tky1w2xD2vY"
+ }
+ end
end
describe "make_like_data" do
@@ -272,8 +312,8 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
{:ok, follow_activity_two} =
Utils.update_follow_state_for_all(follow_activity_two, "accept")
- assert Repo.get(Activity, follow_activity.id).data["state"] == "accept"
- assert Repo.get(Activity, follow_activity_two.id).data["state"] == "accept"
+ assert refresh_record(follow_activity).data["state"] == "accept"
+ assert refresh_record(follow_activity_two).data["state"] == "accept"
end
end
@@ -295,8 +335,294 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
{:ok, follow_activity_two} = Utils.update_follow_state(follow_activity_two, "reject")
- assert Repo.get(Activity, follow_activity.id).data["state"] == "pending"
- assert Repo.get(Activity, follow_activity_two.id).data["state"] == "reject"
+ assert refresh_record(follow_activity).data["state"] == "pending"
+ assert refresh_record(follow_activity_two).data["state"] == "reject"
+ end
+ end
+
+ describe "update_element_in_object/3" do
+ test "updates likes" do
+ user = insert(:user)
+ activity = insert(:note_activity)
+ object = Object.normalize(activity)
+
+ assert {:ok, updated_object} =
+ Utils.update_element_in_object(
+ "like",
+ [user.ap_id],
+ object
+ )
+
+ assert updated_object.data["likes"] == [user.ap_id]
+ assert updated_object.data["like_count"] == 1
+ end
+ end
+
+ describe "add_like_to_object/2" do
+ test "add actor to likes" do
+ user = insert(:user)
+ user2 = insert(:user)
+ object = insert(:note)
+
+ assert {:ok, updated_object} =
+ Utils.add_like_to_object(
+ %Activity{data: %{"actor" => user.ap_id}},
+ object
+ )
+
+ assert updated_object.data["likes"] == [user.ap_id]
+ assert updated_object.data["like_count"] == 1
+
+ assert {:ok, updated_object2} =
+ Utils.add_like_to_object(
+ %Activity{data: %{"actor" => user2.ap_id}},
+ updated_object
+ )
+
+ assert updated_object2.data["likes"] == [user2.ap_id, user.ap_id]
+ assert updated_object2.data["like_count"] == 2
+ end
+ end
+
+ describe "remove_like_from_object/2" do
+ test "removes ap_id from likes" do
+ user = insert(:user)
+ user2 = insert(:user)
+ object = insert(:note, data: %{"likes" => [user.ap_id, user2.ap_id], "like_count" => 2})
+
+ assert {:ok, updated_object} =
+ Utils.remove_like_from_object(
+ %Activity{data: %{"actor" => user.ap_id}},
+ object
+ )
+
+ assert updated_object.data["likes"] == [user2.ap_id]
+ assert updated_object.data["like_count"] == 1
+ end
+ end
+
+ describe "get_existing_like/2" do
+ test "fetches existing like" do
+ note_activity = insert(:note_activity)
+ assert object = Object.normalize(note_activity)
+
+ user = insert(:user)
+ refute Utils.get_existing_like(user.ap_id, object)
+ {:ok, like_activity, _object} = ActivityPub.like(user, object)
+
+ assert ^like_activity = Utils.get_existing_like(user.ap_id, object)
+ end
+ end
+
+ describe "get_get_existing_announce/2" do
+ test "returns nil if announce not found" do
+ actor = insert(:user)
+ refute Utils.get_existing_announce(actor.ap_id, %{data: %{"id" => "test"}})
+ end
+
+ test "fetches existing announce" do
+ note_activity = insert(:note_activity)
+ assert object = Object.normalize(note_activity)
+ actor = insert(:user)
+
+ {:ok, announce, _object} = ActivityPub.announce(actor, object)
+ assert Utils.get_existing_announce(actor.ap_id, object) == announce
+ end
+ end
+
+ describe "fetch_latest_block/2" do
+ test "fetches last block activities" do
+ user1 = insert(:user)
+ user2 = insert(:user)
+
+ assert {:ok, %Activity{} = _} = ActivityPub.block(user1, user2)
+ assert {:ok, %Activity{} = _} = ActivityPub.block(user1, user2)
+ assert {:ok, %Activity{} = activity} = ActivityPub.block(user1, user2)
+
+ assert Utils.fetch_latest_block(user1, user2) == activity
+ end
+ end
+
+ describe "recipient_in_message/3" do
+ test "returns true when recipient in `to`" do
+ recipient = insert(:user)
+ actor = insert(:user)
+ assert Utils.recipient_in_message(recipient, actor, %{"to" => recipient.ap_id})
+
+ assert Utils.recipient_in_message(
+ recipient,
+ actor,
+ %{"to" => [recipient.ap_id], "cc" => ""}
+ )
+ end
+
+ test "returns true when recipient in `cc`" do
+ recipient = insert(:user)
+ actor = insert(:user)
+ assert Utils.recipient_in_message(recipient, actor, %{"cc" => recipient.ap_id})
+
+ assert Utils.recipient_in_message(
+ recipient,
+ actor,
+ %{"cc" => [recipient.ap_id], "to" => ""}
+ )
+ end
+
+ test "returns true when recipient in `bto`" do
+ recipient = insert(:user)
+ actor = insert(:user)
+ assert Utils.recipient_in_message(recipient, actor, %{"bto" => recipient.ap_id})
+
+ assert Utils.recipient_in_message(
+ recipient,
+ actor,
+ %{"bcc" => "", "bto" => [recipient.ap_id]}
+ )
+ end
+
+ test "returns true when recipient in `bcc`" do
+ recipient = insert(:user)
+ actor = insert(:user)
+ assert Utils.recipient_in_message(recipient, actor, %{"bcc" => recipient.ap_id})
+
+ assert Utils.recipient_in_message(
+ recipient,
+ actor,
+ %{"bto" => "", "bcc" => [recipient.ap_id]}
+ )
+ end
+
+ test "returns true when message without addresses fields" do
+ recipient = insert(:user)
+ actor = insert(:user)
+ assert Utils.recipient_in_message(recipient, actor, %{"bccc" => recipient.ap_id})
+
+ assert Utils.recipient_in_message(
+ recipient,
+ actor,
+ %{"btod" => "", "bccc" => [recipient.ap_id]}
+ )
+ end
+
+ test "returns false" do
+ recipient = insert(:user)
+ actor = insert(:user)
+ refute Utils.recipient_in_message(recipient, actor, %{"to" => "ap_id"})
+ end
+ end
+
+ describe "lazy_put_activity_defaults/2" do
+ test "returns map with id and published data" do
+ note_activity = insert(:note_activity)
+ object = Object.normalize(note_activity)
+ res = Utils.lazy_put_activity_defaults(%{"context" => object.data["id"]})
+ assert res["context"] == object.data["id"]
+ assert res["context_id"] == object.id
+ assert res["id"]
+ assert res["published"]
+ end
+
+ test "returns map with fake id and published data" do
+ assert %{
+ "context" => "pleroma:fakecontext",
+ "context_id" => -1,
+ "id" => "pleroma:fakeid",
+ "published" => _
+ } = Utils.lazy_put_activity_defaults(%{}, true)
+ end
+
+ test "returns activity data with object" do
+ note_activity = insert(:note_activity)
+ object = Object.normalize(note_activity)
+
+ res =
+ Utils.lazy_put_activity_defaults(%{
+ "context" => object.data["id"],
+ "object" => %{}
+ })
+
+ assert res["context"] == object.data["id"]
+ assert res["context_id"] == object.id
+ assert res["id"]
+ assert res["published"]
+ assert res["object"]["id"]
+ assert res["object"]["published"]
+ assert res["object"]["context"] == object.data["id"]
+ assert res["object"]["context_id"] == object.id
+ end
+ end
+
+ describe "make_flag_data" do
+ test "returns empty map when params is invalid" do
+ assert Utils.make_flag_data(%{}, %{}) == %{}
+ end
+
+ test "returns map with Flag object" do
+ reporter = insert(:user)
+ target_account = insert(:user)
+ {:ok, activity} = CommonAPI.post(target_account, %{"status" => "foobar"})
+ context = Utils.generate_context_id()
+ content = "foobar"
+
+ target_ap_id = target_account.ap_id
+ activity_ap_id = activity.data["id"]
+
+ res =
+ Utils.make_flag_data(
+ %{
+ actor: reporter,
+ context: context,
+ account: target_account,
+ statuses: [%{"id" => activity.data["id"]}],
+ content: content
+ },
+ %{}
+ )
+
+ assert %{
+ "type" => "Flag",
+ "content" => ^content,
+ "context" => ^context,
+ "object" => [^target_ap_id, ^activity_ap_id],
+ "state" => "open"
+ } = res
+ end
+ end
+
+ describe "add_announce_to_object/2" do
+ test "adds actor to announcement" do
+ user = insert(:user)
+ object = insert(:note)
+
+ activity =
+ insert(:note_activity,
+ data: %{
+ "actor" => user.ap_id,
+ "cc" => [Pleroma.Constants.as_public()]
+ }
+ )
+
+ assert {:ok, updated_object} = Utils.add_announce_to_object(activity, object)
+ assert updated_object.data["announcements"] == [user.ap_id]
+ assert updated_object.data["announcement_count"] == 1
+ end
+ end
+
+ describe "remove_announce_from_object/2" do
+ test "removes actor from announcements" do
+ user = insert(:user)
+ user2 = insert(:user)
+
+ object =
+ insert(:note,
+ data: %{"announcements" => [user.ap_id, user2.ap_id], "announcement_count" => 2}
+ )
+
+ activity = insert(:note_activity, data: %{"actor" => user.ap_id})
+
+ assert {:ok, updated_object} = Utils.remove_announce_from_object(activity, object)
+ assert updated_object.data["announcements"] == [user2.ap_id]
+ assert updated_object.data["announcement_count"] == 1
end
end
end
diff --git a/test/web/activity_pub/views/user_view_test.exs b/test/web/activity_pub/views/user_view_test.exs
index fb7fd9e79..3155749aa 100644
--- a/test/web/activity_pub/views/user_view_test.exs
+++ b/test/web/activity_pub/views/user_view_test.exs
@@ -37,6 +37,22 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do
} = UserView.render("user.json", %{user: user})
end
+ test "Renders with emoji tags" do
+ user = insert(:user, %{info: %{emoji: [%{"bib" => "/test"}]}})
+
+ assert %{
+ "tag" => [
+ %{
+ "icon" => %{"type" => "Image", "url" => "/test"},
+ "id" => "/test",
+ "name" => ":bib:",
+ "type" => "Emoji",
+ "updated" => "1970-01-01T00:00:00Z"
+ }
+ ]
+ } = UserView.render("user.json", %{user: user})
+ end
+
test "Does not add an avatar image if the user hasn't set one" do
user = insert(:user)
{:ok, user} = User.ensure_keys_present(user)
@@ -105,10 +121,20 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do
other_user = insert(:user)
{:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
assert %{"totalItems" => 1} = UserView.render("followers.json", %{user: user})
- info = Map.put(user.info, :hide_followers, true)
+ info = Map.merge(user.info, %{hide_followers_count: true, hide_followers: true})
user = Map.put(user, :info, info)
assert %{"totalItems" => 0} = UserView.render("followers.json", %{user: user})
end
+
+ test "sets correct totalItems when followers are hidden but the follower counter is not" do
+ user = insert(:user)
+ other_user = insert(:user)
+ {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
+ assert %{"totalItems" => 1} = UserView.render("followers.json", %{user: user})
+ info = Map.merge(user.info, %{hide_followers_count: false, hide_followers: true})
+ user = Map.put(user, :info, info)
+ assert %{"totalItems" => 1} = UserView.render("followers.json", %{user: user})
+ end
end
describe "following" do
@@ -117,9 +143,50 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do
other_user = insert(:user)
{:ok, user, _other_user, _activity} = CommonAPI.follow(user, other_user)
assert %{"totalItems" => 1} = UserView.render("following.json", %{user: user})
- info = Map.put(user.info, :hide_follows, true)
+ info = Map.merge(user.info, %{hide_follows_count: true, hide_follows: true})
user = Map.put(user, :info, info)
assert %{"totalItems" => 0} = UserView.render("following.json", %{user: user})
end
+
+ test "sets correct totalItems when follows are hidden but the follow counter is not" do
+ user = insert(:user)
+ other_user = insert(:user)
+ {:ok, user, _other_user, _activity} = CommonAPI.follow(user, other_user)
+ assert %{"totalItems" => 1} = UserView.render("following.json", %{user: user})
+ info = Map.merge(user.info, %{hide_follows_count: false, hide_follows: true})
+ user = Map.put(user, :info, info)
+ assert %{"totalItems" => 1} = UserView.render("following.json", %{user: user})
+ end
+ end
+
+ test "activity collection page aginates correctly" do
+ user = insert(:user)
+
+ posts =
+ for i <- 0..25 do
+ {:ok, activity} = CommonAPI.post(user, %{"status" => "post #{i}"})
+ activity
+ end
+
+ # outbox sorts chronologically, newest first, with ten per page
+ posts = Enum.reverse(posts)
+
+ %{"next" => next_url} =
+ UserView.render("activity_collection_page.json", %{
+ iri: "#{user.ap_id}/outbox",
+ activities: Enum.take(posts, 10)
+ })
+
+ next_id = Enum.at(posts, 9).id
+ assert next_url =~ next_id
+
+ %{"next" => next_url} =
+ UserView.render("activity_collection_page.json", %{
+ iri: "#{user.ap_id}/outbox",
+ activities: Enum.take(Enum.drop(posts, 10), 10)
+ })
+
+ next_id = Enum.at(posts, 19).id
+ assert next_url =~ next_id
end
end