1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
5 defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
6 use Pleroma.Web.ConnCase
7 use Oban.Testing, repo: Pleroma.Repo
10 alias Pleroma.Activity
11 alias Pleroma.Delivery
12 alias Pleroma.Instances
14 alias Pleroma.Tests.ObanHelpers
16 alias Pleroma.Web.ActivityPub.ObjectView
17 alias Pleroma.Web.ActivityPub.Relay
18 alias Pleroma.Web.ActivityPub.UserView
19 alias Pleroma.Web.ActivityPub.Utils
20 alias Pleroma.Web.CommonAPI
21 alias Pleroma.Workers.ReceiverWorker
24 Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
28 clear_config_all([:instance, :federating],
29 do: Pleroma.Config.put([:instance, :federating], true)
33 clear_config([:instance, :allow_relay])
35 test "with the relay active, it returns the relay user", %{conn: conn} do
38 |> get(activity_pub_path(conn, :relay))
41 assert res["id"] =~ "/relay"
44 test "with the relay disabled, it returns 404", %{conn: conn} do
45 Pleroma.Config.put([:instance, :allow_relay], false)
48 |> get(activity_pub_path(conn, :relay))
54 describe "/internal/fetch" do
55 test "it returns the internal fetch user", %{conn: conn} do
58 |> get(activity_pub_path(conn, :internal_fetch))
61 assert res["id"] =~ "/fetch"
65 describe "/users/:nickname" do
66 test "it returns a json representation of the user with accept application/json", %{
73 |> put_req_header("accept", "application/json")
74 |> get("/users/#{user.nickname}")
76 user = User.get_cached_by_id(user.id)
78 assert json_response(conn, 200) == UserView.render("user.json", %{user: user})
81 test "it returns a json representation of the user with accept application/activity+json", %{
88 |> put_req_header("accept", "application/activity+json")
89 |> get("/users/#{user.nickname}")
91 user = User.get_cached_by_id(user.id)
93 assert json_response(conn, 200) == UserView.render("user.json", %{user: user})
96 test "it returns a json representation of the user with accept application/ld+json", %{
105 "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""
107 |> get("/users/#{user.nickname}")
109 user = User.get_cached_by_id(user.id)
111 assert json_response(conn, 200) == UserView.render("user.json", %{user: user})
114 test "it returns 404 for remote users", %{
117 user = insert(:user, local: false, nickname: "remoteuser@example.com")
121 |> put_req_header("accept", "application/json")
122 |> get("/users/#{user.nickname}.json")
124 assert json_response(conn, 404)
128 describe "/object/:uuid" do
129 test "it returns a json representation of the object with accept application/json", %{
133 uuid = String.split(note.data["id"], "/") |> List.last()
137 |> put_req_header("accept", "application/json")
138 |> get("/objects/#{uuid}")
140 assert json_response(conn, 200) == ObjectView.render("object.json", %{object: note})
143 test "it returns a json representation of the object with accept application/activity+json",
146 uuid = String.split(note.data["id"], "/") |> List.last()
150 |> put_req_header("accept", "application/activity+json")
151 |> get("/objects/#{uuid}")
153 assert json_response(conn, 200) == ObjectView.render("object.json", %{object: note})
156 test "it returns a json representation of the object with accept application/ld+json", %{
160 uuid = String.split(note.data["id"], "/") |> List.last()
166 "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""
168 |> get("/objects/#{uuid}")
170 assert json_response(conn, 200) == ObjectView.render("object.json", %{object: note})
173 test "it returns 404 for non-public messages", %{conn: conn} do
174 note = insert(:direct_note)
175 uuid = String.split(note.data["id"], "/") |> List.last()
179 |> put_req_header("accept", "application/activity+json")
180 |> get("/objects/#{uuid}")
182 assert json_response(conn, 404)
185 test "it returns 404 for tombstone objects", %{conn: conn} do
186 tombstone = insert(:tombstone)
187 uuid = String.split(tombstone.data["id"], "/") |> List.last()
191 |> put_req_header("accept", "application/activity+json")
192 |> get("/objects/#{uuid}")
194 assert json_response(conn, 404)
197 test "it caches a response", %{conn: conn} do
199 uuid = String.split(note.data["id"], "/") |> List.last()
203 |> put_req_header("accept", "application/activity+json")
204 |> get("/objects/#{uuid}")
206 assert json_response(conn1, :ok)
207 assert Enum.any?(conn1.resp_headers, &(&1 == {"x-cache", "MISS from Pleroma"}))
211 |> put_req_header("accept", "application/activity+json")
212 |> get("/objects/#{uuid}")
214 assert json_response(conn1, :ok) == json_response(conn2, :ok)
215 assert Enum.any?(conn2.resp_headers, &(&1 == {"x-cache", "HIT from Pleroma"}))
218 test "cached purged after object deletion", %{conn: conn} do
220 uuid = String.split(note.data["id"], "/") |> List.last()
224 |> put_req_header("accept", "application/activity+json")
225 |> get("/objects/#{uuid}")
227 assert json_response(conn1, :ok)
228 assert Enum.any?(conn1.resp_headers, &(&1 == {"x-cache", "MISS from Pleroma"}))
234 |> put_req_header("accept", "application/activity+json")
235 |> get("/objects/#{uuid}")
237 assert "Not found" == json_response(conn2, :not_found)
241 describe "/activities/:uuid" do
242 test "it returns a json representation of the activity", %{conn: conn} do
243 activity = insert(:note_activity)
244 uuid = String.split(activity.data["id"], "/") |> List.last()
248 |> put_req_header("accept", "application/activity+json")
249 |> get("/activities/#{uuid}")
251 assert json_response(conn, 200) == ObjectView.render("object.json", %{object: activity})
254 test "it returns 404 for non-public activities", %{conn: conn} do
255 activity = insert(:direct_note_activity)
256 uuid = String.split(activity.data["id"], "/") |> List.last()
260 |> put_req_header("accept", "application/activity+json")
261 |> get("/activities/#{uuid}")
263 assert json_response(conn, 404)
266 test "it caches a response", %{conn: conn} do
267 activity = insert(:note_activity)
268 uuid = String.split(activity.data["id"], "/") |> List.last()
272 |> put_req_header("accept", "application/activity+json")
273 |> get("/activities/#{uuid}")
275 assert json_response(conn1, :ok)
276 assert Enum.any?(conn1.resp_headers, &(&1 == {"x-cache", "MISS from Pleroma"}))
280 |> put_req_header("accept", "application/activity+json")
281 |> get("/activities/#{uuid}")
283 assert json_response(conn1, :ok) == json_response(conn2, :ok)
284 assert Enum.any?(conn2.resp_headers, &(&1 == {"x-cache", "HIT from Pleroma"}))
287 test "cached purged after activity deletion", %{conn: conn} do
289 {:ok, activity} = CommonAPI.post(user, %{"status" => "cofe"})
291 uuid = String.split(activity.data["id"], "/") |> List.last()
295 |> put_req_header("accept", "application/activity+json")
296 |> get("/activities/#{uuid}")
298 assert json_response(conn1, :ok)
299 assert Enum.any?(conn1.resp_headers, &(&1 == {"x-cache", "MISS from Pleroma"}))
301 Activity.delete_all_by_object_ap_id(activity.object.data["id"])
305 |> put_req_header("accept", "application/activity+json")
306 |> get("/activities/#{uuid}")
308 assert "Not found" == json_response(conn2, :not_found)
313 test "it inserts an incoming activity into the database", %{conn: conn} do
314 data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()
318 |> assign(:valid_signature, true)
319 |> put_req_header("content-type", "application/activity+json")
320 |> post("/inbox", data)
322 assert "ok" == json_response(conn, 200)
324 ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
325 assert Activity.get_by_ap_id(data["id"])
328 test "it clears `unreachable` federation status of the sender", %{conn: conn} do
329 data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()
331 sender_url = data["actor"]
332 Instances.set_consistently_unreachable(sender_url)
333 refute Instances.reachable?(sender_url)
337 |> assign(:valid_signature, true)
338 |> put_req_header("content-type", "application/activity+json")
339 |> post("/inbox", data)
341 assert "ok" == json_response(conn, 200)
342 assert Instances.reachable?(sender_url)
345 test "accept follow activity", %{conn: conn} do
346 Pleroma.Config.put([:instance, :federating], true)
347 relay = Relay.get_actor()
349 assert {:ok, %Activity{} = activity} = Relay.follow("https://relay.mastodon.host/actor")
351 followed_relay = Pleroma.User.get_by_ap_id("https://relay.mastodon.host/actor")
352 relay = refresh_record(relay)
355 File.read!("test/fixtures/relay/accept-follow.json")
356 |> String.replace("{{ap_id}}", relay.ap_id)
357 |> String.replace("{{activity_id}}", activity.data["id"])
361 |> assign(:valid_signature, true)
362 |> put_req_header("content-type", "application/activity+json")
363 |> post("/inbox", accept)
364 |> json_response(200)
366 ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
368 assert Pleroma.FollowingRelationship.following?(
373 Mix.shell(Mix.Shell.Process)
376 Mix.shell(Mix.Shell.IO)
379 :ok = Mix.Tasks.Pleroma.Relay.run(["list"])
380 assert_receive {:mix_shell, :info, ["relay.mastodon.host"]}
384 describe "/users/:nickname/inbox" do
387 File.read!("test/fixtures/mastodon-post-activity.json")
393 test "it inserts an incoming activity into the database", %{conn: conn, data: data} do
395 data = Map.put(data, "bcc", [user.ap_id])
399 |> assign(:valid_signature, true)
400 |> put_req_header("content-type", "application/activity+json")
401 |> post("/users/#{user.nickname}/inbox", data)
403 assert "ok" == json_response(conn, 200)
404 ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
405 assert Activity.get_by_ap_id(data["id"])
408 test "it accepts messages with to as string instead of array", %{conn: conn, data: data} do
412 Map.put(data, "to", user.ap_id)
417 |> assign(:valid_signature, true)
418 |> put_req_header("content-type", "application/activity+json")
419 |> post("/users/#{user.nickname}/inbox", data)
421 assert "ok" == json_response(conn, 200)
422 ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
423 assert Activity.get_by_ap_id(data["id"])
426 test "it accepts messages with cc as string instead of array", %{conn: conn, data: data} do
430 Map.put(data, "cc", user.ap_id)
435 |> assign(:valid_signature, true)
436 |> put_req_header("content-type", "application/activity+json")
437 |> post("/users/#{user.nickname}/inbox", data)
439 assert "ok" == json_response(conn, 200)
440 ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
441 %Activity{} = activity = Activity.get_by_ap_id(data["id"])
442 assert user.ap_id in activity.recipients
445 test "it accepts messages with bcc as string instead of array", %{conn: conn, data: data} do
449 Map.put(data, "bcc", user.ap_id)
455 |> assign(:valid_signature, true)
456 |> put_req_header("content-type", "application/activity+json")
457 |> post("/users/#{user.nickname}/inbox", data)
459 assert "ok" == json_response(conn, 200)
460 ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
461 assert Activity.get_by_ap_id(data["id"])
464 test "it accepts announces with to as string instead of array", %{conn: conn} do
468 "@context" => "https://www.w3.org/ns/activitystreams",
469 "actor" => "http://mastodon.example.org/users/admin",
470 "id" => "http://mastodon.example.org/users/admin/statuses/19512778738411822/activity",
471 "object" => "https://mastodon.social/users/emelie/statuses/101849165031453009",
472 "to" => "https://www.w3.org/ns/activitystreams#Public",
473 "cc" => [user.ap_id],
479 |> assign(:valid_signature, true)
480 |> put_req_header("content-type", "application/activity+json")
481 |> post("/users/#{user.nickname}/inbox", data)
483 assert "ok" == json_response(conn, 200)
484 ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
485 %Activity{} = activity = Activity.get_by_ap_id(data["id"])
486 assert "https://www.w3.org/ns/activitystreams#Public" in activity.recipients
489 test "it accepts messages from actors that are followed by the user", %{
493 recipient = insert(:user)
494 actor = insert(:user, %{ap_id: "http://mastodon.example.org/users/actor"})
496 {:ok, recipient} = User.follow(recipient, actor)
500 |> Map.put("attributedTo", actor.ap_id)
504 |> Map.put("actor", actor.ap_id)
505 |> Map.put("object", object)
509 |> assign(:valid_signature, true)
510 |> put_req_header("content-type", "application/activity+json")
511 |> post("/users/#{recipient.nickname}/inbox", data)
513 assert "ok" == json_response(conn, 200)
514 ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
515 assert Activity.get_by_ap_id(data["id"])
518 test "it rejects reads from other users", %{conn: conn} do
520 otheruser = insert(:user)
524 |> assign(:user, otheruser)
525 |> put_req_header("accept", "application/activity+json")
526 |> get("/users/#{user.nickname}/inbox")
528 assert json_response(conn, 403)
531 test "it doesn't crash without an authenticated user", %{conn: conn} do
536 |> put_req_header("accept", "application/activity+json")
537 |> get("/users/#{user.nickname}/inbox")
539 assert json_response(conn, 403)
542 test "it returns a note activity in a collection", %{conn: conn} do
543 note_activity = insert(:direct_note_activity)
544 note_object = Object.normalize(note_activity)
545 user = User.get_cached_by_ap_id(hd(note_activity.data["to"]))
549 |> assign(:user, user)
550 |> put_req_header("accept", "application/activity+json")
551 |> get("/users/#{user.nickname}/inbox?page=true")
553 assert response(conn, 200) =~ note_object.data["content"]
556 test "it clears `unreachable` federation status of the sender", %{conn: conn, data: data} do
558 data = Map.put(data, "bcc", [user.ap_id])
560 sender_host = URI.parse(data["actor"]).host
561 Instances.set_consistently_unreachable(sender_host)
562 refute Instances.reachable?(sender_host)
566 |> assign(:valid_signature, true)
567 |> put_req_header("content-type", "application/activity+json")
568 |> post("/users/#{user.nickname}/inbox", data)
570 assert "ok" == json_response(conn, 200)
571 assert Instances.reachable?(sender_host)
574 test "it removes all follower collections but actor's", %{conn: conn} do
575 [actor, recipient] = insert_pair(:user)
578 File.read!("test/fixtures/activitypub-client-post-activity.json")
581 object = Map.put(data["object"], "attributedTo", actor.ap_id)
585 |> Map.put("id", Utils.generate_object_id())
586 |> Map.put("actor", actor.ap_id)
587 |> Map.put("object", object)
589 recipient.follower_address,
590 actor.follower_address
594 recipient.follower_address,
595 "https://www.w3.org/ns/activitystreams#Public"
599 |> assign(:valid_signature, true)
600 |> put_req_header("content-type", "application/activity+json")
601 |> post("/users/#{recipient.nickname}/inbox", data)
602 |> json_response(200)
604 ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
606 activity = Activity.get_by_ap_id(data["id"])
609 assert actor.follower_address in activity.recipients
610 assert actor.follower_address in activity.data["cc"]
612 refute recipient.follower_address in activity.recipients
613 refute recipient.follower_address in activity.data["cc"]
614 refute recipient.follower_address in activity.data["to"]
618 describe "/users/:nickname/outbox" do
619 test "it will not bomb when there is no activity", %{conn: conn} do
624 |> put_req_header("accept", "application/activity+json")
625 |> get("/users/#{user.nickname}/outbox")
627 result = json_response(conn, 200)
628 assert user.ap_id <> "/outbox" == result["id"]
631 test "it returns a note activity in a collection", %{conn: conn} do
632 note_activity = insert(:note_activity)
633 note_object = Object.normalize(note_activity)
634 user = User.get_cached_by_ap_id(note_activity.data["actor"])
638 |> put_req_header("accept", "application/activity+json")
639 |> get("/users/#{user.nickname}/outbox?page=true")
641 assert response(conn, 200) =~ note_object.data["content"]
644 test "it returns an announce activity in a collection", %{conn: conn} do
645 announce_activity = insert(:announce_activity)
646 user = User.get_cached_by_ap_id(announce_activity.data["actor"])
650 |> put_req_header("accept", "application/activity+json")
651 |> get("/users/#{user.nickname}/outbox?page=true")
653 assert response(conn, 200) =~ announce_activity.data["object"]
656 test "it rejects posts from other users", %{conn: conn} do
657 data = File.read!("test/fixtures/activitypub-client-post-activity.json") |> Poison.decode!()
659 otheruser = insert(:user)
663 |> assign(:user, otheruser)
664 |> put_req_header("content-type", "application/activity+json")
665 |> post("/users/#{user.nickname}/outbox", data)
667 assert json_response(conn, 403)
670 test "it inserts an incoming create activity into the database", %{conn: conn} do
671 data = File.read!("test/fixtures/activitypub-client-post-activity.json") |> Poison.decode!()
676 |> assign(:user, user)
677 |> put_req_header("content-type", "application/activity+json")
678 |> post("/users/#{user.nickname}/outbox", data)
680 result = json_response(conn, 201)
682 assert Activity.get_by_ap_id(result["id"])
685 test "it rejects an incoming activity with bogus type", %{conn: conn} do
686 data = File.read!("test/fixtures/activitypub-client-post-activity.json") |> Poison.decode!()
691 |> Map.put("type", "BadType")
695 |> assign(:user, user)
696 |> put_req_header("content-type", "application/activity+json")
697 |> post("/users/#{user.nickname}/outbox", data)
699 assert json_response(conn, 400)
702 test "it erects a tombstone when receiving a delete activity", %{conn: conn} do
703 note_activity = insert(:note_activity)
704 note_object = Object.normalize(note_activity)
705 user = User.get_cached_by_ap_id(note_activity.data["actor"])
710 id: note_object.data["id"]
716 |> assign(:user, user)
717 |> put_req_header("content-type", "application/activity+json")
718 |> post("/users/#{user.nickname}/outbox", data)
720 result = json_response(conn, 201)
721 assert Activity.get_by_ap_id(result["id"])
723 assert object = Object.get_by_ap_id(note_object.data["id"])
724 assert object.data["type"] == "Tombstone"
727 test "it rejects delete activity of object from other actor", %{conn: conn} do
728 note_activity = insert(:note_activity)
729 note_object = Object.normalize(note_activity)
735 id: note_object.data["id"]
741 |> assign(:user, user)
742 |> put_req_header("content-type", "application/activity+json")
743 |> post("/users/#{user.nickname}/outbox", data)
745 assert json_response(conn, 400)
748 test "it increases like count when receiving a like action", %{conn: conn} do
749 note_activity = insert(:note_activity)
750 note_object = Object.normalize(note_activity)
751 user = User.get_cached_by_ap_id(note_activity.data["actor"])
756 id: note_object.data["id"]
762 |> assign(:user, user)
763 |> put_req_header("content-type", "application/activity+json")
764 |> post("/users/#{user.nickname}/outbox", data)
766 result = json_response(conn, 201)
767 assert Activity.get_by_ap_id(result["id"])
769 assert object = Object.get_by_ap_id(note_object.data["id"])
770 assert object.data["like_count"] == 1
774 describe "/relay/followers" do
775 test "it returns relay followers", %{conn: conn} do
776 relay_actor = Relay.get_actor()
778 User.follow(user, relay_actor)
782 |> assign(:relay, true)
783 |> get("/relay/followers")
784 |> json_response(200)
786 assert result["first"]["orderedItems"] == [user.ap_id]
790 describe "/relay/following" do
791 test "it returns relay following", %{conn: conn} do
794 |> assign(:relay, true)
795 |> get("/relay/following")
796 |> json_response(200)
798 assert result["first"]["orderedItems"] == []
802 describe "/users/:nickname/followers" do
803 test "it returns the followers in a collection", %{conn: conn} do
805 user_two = insert(:user)
806 User.follow(user, user_two)
810 |> get("/users/#{user_two.nickname}/followers")
811 |> json_response(200)
813 assert result["first"]["orderedItems"] == [user.ap_id]
816 test "it returns returns a uri if the user has 'hide_followers' set", %{conn: conn} do
818 user_two = insert(:user, hide_followers: true)
819 User.follow(user, user_two)
823 |> get("/users/#{user_two.nickname}/followers")
824 |> json_response(200)
826 assert is_binary(result["first"])
829 test "it returns a 403 error on pages, if the user has 'hide_followers' set and the request is not authenticated",
831 user = insert(:user, hide_followers: true)
835 |> get("/users/#{user.nickname}/followers?page=1")
837 assert result.status == 403
838 assert result.resp_body == ""
841 test "it renders the page, if the user has 'hide_followers' set and the request is authenticated with the same user",
843 user = insert(:user, hide_followers: true)
844 other_user = insert(:user)
845 {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
849 |> assign(:user, user)
850 |> get("/users/#{user.nickname}/followers?page=1")
851 |> json_response(200)
853 assert result["totalItems"] == 1
854 assert result["orderedItems"] == [other_user.ap_id]
857 test "it works for more than 10 users", %{conn: conn} do
860 Enum.each(1..15, fn _ ->
861 other_user = insert(:user)
862 User.follow(other_user, user)
867 |> get("/users/#{user.nickname}/followers")
868 |> json_response(200)
870 assert length(result["first"]["orderedItems"]) == 10
871 assert result["first"]["totalItems"] == 15
872 assert result["totalItems"] == 15
876 |> get("/users/#{user.nickname}/followers?page=2")
877 |> json_response(200)
879 assert length(result["orderedItems"]) == 5
880 assert result["totalItems"] == 15
884 describe "/users/:nickname/following" do
885 test "it returns the following in a collection", %{conn: conn} do
887 user_two = insert(:user)
888 User.follow(user, user_two)
892 |> get("/users/#{user.nickname}/following")
893 |> json_response(200)
895 assert result["first"]["orderedItems"] == [user_two.ap_id]
898 test "it returns a uri if the user has 'hide_follows' set", %{conn: conn} do
899 user = insert(:user, hide_follows: true)
900 user_two = insert(:user)
901 User.follow(user, user_two)
905 |> get("/users/#{user.nickname}/following")
906 |> json_response(200)
908 assert is_binary(result["first"])
911 test "it returns a 403 error on pages, if the user has 'hide_follows' set and the request is not authenticated",
913 user = insert(:user, hide_follows: true)
917 |> get("/users/#{user.nickname}/following?page=1")
919 assert result.status == 403
920 assert result.resp_body == ""
923 test "it renders the page, if the user has 'hide_follows' set and the request is authenticated with the same user",
925 user = insert(:user, hide_follows: true)
926 other_user = insert(:user)
927 {:ok, user, _other_user, _activity} = CommonAPI.follow(user, other_user)
931 |> assign(:user, user)
932 |> get("/users/#{user.nickname}/following?page=1")
933 |> json_response(200)
935 assert result["totalItems"] == 1
936 assert result["orderedItems"] == [other_user.ap_id]
939 test "it works for more than 10 users", %{conn: conn} do
942 Enum.each(1..15, fn _ ->
943 user = User.get_cached_by_id(user.id)
944 other_user = insert(:user)
945 User.follow(user, other_user)
950 |> get("/users/#{user.nickname}/following")
951 |> json_response(200)
953 assert length(result["first"]["orderedItems"]) == 10
954 assert result["first"]["totalItems"] == 15
955 assert result["totalItems"] == 15
959 |> get("/users/#{user.nickname}/following?page=2")
960 |> json_response(200)
962 assert length(result["orderedItems"]) == 5
963 assert result["totalItems"] == 15
967 describe "delivery tracking" do
968 test "it tracks a signed object fetch", %{conn: conn} do
969 user = insert(:user, local: false)
970 activity = insert(:note_activity)
971 object = Object.normalize(activity)
973 object_path = String.trim_leading(object.data["id"], Pleroma.Web.Endpoint.url())
976 |> put_req_header("accept", "application/activity+json")
977 |> assign(:user, user)
979 |> json_response(200)
981 assert Delivery.get(object.id, user.id)
984 test "it tracks a signed activity fetch", %{conn: conn} do
985 user = insert(:user, local: false)
986 activity = insert(:note_activity)
987 object = Object.normalize(activity)
989 activity_path = String.trim_leading(activity.data["id"], Pleroma.Web.Endpoint.url())
992 |> put_req_header("accept", "application/activity+json")
993 |> assign(:user, user)
994 |> get(activity_path)
995 |> json_response(200)
997 assert Delivery.get(object.id, user.id)
1000 test "it tracks a signed object fetch when the json is cached", %{conn: conn} do
1001 user = insert(:user, local: false)
1002 other_user = insert(:user, local: false)
1003 activity = insert(:note_activity)
1004 object = Object.normalize(activity)
1006 object_path = String.trim_leading(object.data["id"], Pleroma.Web.Endpoint.url())
1009 |> put_req_header("accept", "application/activity+json")
1010 |> assign(:user, user)
1012 |> json_response(200)
1015 |> put_req_header("accept", "application/activity+json")
1016 |> assign(:user, other_user)
1018 |> json_response(200)
1020 assert Delivery.get(object.id, user.id)
1021 assert Delivery.get(object.id, other_user.id)
1024 test "it tracks a signed activity fetch when the json is cached", %{conn: conn} do
1025 user = insert(:user, local: false)
1026 other_user = insert(:user, local: false)
1027 activity = insert(:note_activity)
1028 object = Object.normalize(activity)
1030 activity_path = String.trim_leading(activity.data["id"], Pleroma.Web.Endpoint.url())
1033 |> put_req_header("accept", "application/activity+json")
1034 |> assign(:user, user)
1035 |> get(activity_path)
1036 |> json_response(200)
1039 |> put_req_header("accept", "application/activity+json")
1040 |> assign(:user, other_user)
1041 |> get(activity_path)
1042 |> json_response(200)
1044 assert Delivery.get(object.id, user.id)
1045 assert Delivery.get(object.id, other_user.id)
1049 describe "Additionnal ActivityPub C2S endpoints" do
1050 test "/api/ap/whoami", %{conn: conn} do
1051 user = insert(:user)
1055 |> assign(:user, user)
1056 |> get("/api/ap/whoami")
1058 user = User.get_cached_by_id(user.id)
1060 assert UserView.render("user.json", %{user: user}) == json_response(conn, 200)
1063 clear_config([:media_proxy])
1064 clear_config([Pleroma.Upload])
1066 test "uploadMedia", %{conn: conn} do
1067 user = insert(:user)
1069 desc = "Description of the image"
1071 image = %Plug.Upload{
1072 content_type: "image/jpg",
1073 path: Path.absname("test/fixtures/image.jpg"),
1074 filename: "an_image.jpg"
1079 |> assign(:user, user)
1080 |> post("/api/ap/upload_media", %{"file" => image, "description" => desc})
1082 assert object = json_response(conn, :created)
1083 assert object["name"] == desc
1084 assert object["type"] == "Document"
1085 assert object["actor"] == user.ap_id