1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2019 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})
115 describe "/object/:uuid" do
116 test "it returns a json representation of the object with accept application/json", %{
120 uuid = String.split(note.data["id"], "/") |> List.last()
124 |> put_req_header("accept", "application/json")
125 |> get("/objects/#{uuid}")
127 assert json_response(conn, 200) == ObjectView.render("object.json", %{object: note})
130 test "it returns a json representation of the object with accept application/activity+json",
133 uuid = String.split(note.data["id"], "/") |> List.last()
137 |> put_req_header("accept", "application/activity+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/ld+json", %{
147 uuid = String.split(note.data["id"], "/") |> List.last()
153 "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""
155 |> get("/objects/#{uuid}")
157 assert json_response(conn, 200) == ObjectView.render("object.json", %{object: note})
160 test "it returns 404 for non-public messages", %{conn: conn} do
161 note = insert(:direct_note)
162 uuid = String.split(note.data["id"], "/") |> List.last()
166 |> put_req_header("accept", "application/activity+json")
167 |> get("/objects/#{uuid}")
169 assert json_response(conn, 404)
172 test "it returns 404 for tombstone objects", %{conn: conn} do
173 tombstone = insert(:tombstone)
174 uuid = String.split(tombstone.data["id"], "/") |> List.last()
178 |> put_req_header("accept", "application/activity+json")
179 |> get("/objects/#{uuid}")
181 assert json_response(conn, 404)
184 test "it caches a response", %{conn: conn} do
186 uuid = String.split(note.data["id"], "/") |> List.last()
190 |> put_req_header("accept", "application/activity+json")
191 |> get("/objects/#{uuid}")
193 assert json_response(conn1, :ok)
194 assert Enum.any?(conn1.resp_headers, &(&1 == {"x-cache", "MISS from Pleroma"}))
198 |> put_req_header("accept", "application/activity+json")
199 |> get("/objects/#{uuid}")
201 assert json_response(conn1, :ok) == json_response(conn2, :ok)
202 assert Enum.any?(conn2.resp_headers, &(&1 == {"x-cache", "HIT from Pleroma"}))
205 test "cached purged after object deletion", %{conn: conn} do
207 uuid = String.split(note.data["id"], "/") |> List.last()
211 |> put_req_header("accept", "application/activity+json")
212 |> get("/objects/#{uuid}")
214 assert json_response(conn1, :ok)
215 assert Enum.any?(conn1.resp_headers, &(&1 == {"x-cache", "MISS from Pleroma"}))
221 |> put_req_header("accept", "application/activity+json")
222 |> get("/objects/#{uuid}")
224 assert "Not found" == json_response(conn2, :not_found)
228 describe "/activities/:uuid" do
229 test "it returns a json representation of the activity", %{conn: conn} do
230 activity = insert(:note_activity)
231 uuid = String.split(activity.data["id"], "/") |> List.last()
235 |> put_req_header("accept", "application/activity+json")
236 |> get("/activities/#{uuid}")
238 assert json_response(conn, 200) == ObjectView.render("object.json", %{object: activity})
241 test "it returns 404 for non-public activities", %{conn: conn} do
242 activity = insert(:direct_note_activity)
243 uuid = String.split(activity.data["id"], "/") |> List.last()
247 |> put_req_header("accept", "application/activity+json")
248 |> get("/activities/#{uuid}")
250 assert json_response(conn, 404)
253 test "it caches a response", %{conn: conn} do
254 activity = insert(:note_activity)
255 uuid = String.split(activity.data["id"], "/") |> List.last()
259 |> put_req_header("accept", "application/activity+json")
260 |> get("/activities/#{uuid}")
262 assert json_response(conn1, :ok)
263 assert Enum.any?(conn1.resp_headers, &(&1 == {"x-cache", "MISS from Pleroma"}))
267 |> put_req_header("accept", "application/activity+json")
268 |> get("/activities/#{uuid}")
270 assert json_response(conn1, :ok) == json_response(conn2, :ok)
271 assert Enum.any?(conn2.resp_headers, &(&1 == {"x-cache", "HIT from Pleroma"}))
274 test "cached purged after activity deletion", %{conn: conn} do
276 {:ok, activity} = CommonAPI.post(user, %{"status" => "cofe"})
278 uuid = String.split(activity.data["id"], "/") |> List.last()
282 |> put_req_header("accept", "application/activity+json")
283 |> get("/activities/#{uuid}")
285 assert json_response(conn1, :ok)
286 assert Enum.any?(conn1.resp_headers, &(&1 == {"x-cache", "MISS from Pleroma"}))
288 Activity.delete_by_ap_id(activity.object.data["id"])
292 |> put_req_header("accept", "application/activity+json")
293 |> get("/activities/#{uuid}")
295 assert "Not found" == json_response(conn2, :not_found)
300 test "it inserts an incoming activity into the database", %{conn: conn} do
301 data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()
305 |> assign(:valid_signature, true)
306 |> put_req_header("content-type", "application/activity+json")
307 |> post("/inbox", data)
309 assert "ok" == json_response(conn, 200)
311 ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
312 assert Activity.get_by_ap_id(data["id"])
315 test "it clears `unreachable` federation status of the sender", %{conn: conn} do
316 data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()
318 sender_url = data["actor"]
319 Instances.set_consistently_unreachable(sender_url)
320 refute Instances.reachable?(sender_url)
324 |> assign(:valid_signature, true)
325 |> put_req_header("content-type", "application/activity+json")
326 |> post("/inbox", data)
328 assert "ok" == json_response(conn, 200)
329 assert Instances.reachable?(sender_url)
333 describe "/users/:nickname/inbox" do
336 File.read!("test/fixtures/mastodon-post-activity.json")
342 test "it inserts an incoming activity into the database", %{conn: conn, data: data} do
344 data = Map.put(data, "bcc", [user.ap_id])
348 |> assign(:valid_signature, true)
349 |> put_req_header("content-type", "application/activity+json")
350 |> post("/users/#{user.nickname}/inbox", data)
352 assert "ok" == json_response(conn, 200)
353 ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
354 assert Activity.get_by_ap_id(data["id"])
357 test "it accepts messages with to as string instead of array", %{conn: conn, data: data} do
361 Map.put(data, "to", user.ap_id)
366 |> assign(:valid_signature, true)
367 |> put_req_header("content-type", "application/activity+json")
368 |> post("/users/#{user.nickname}/inbox", data)
370 assert "ok" == json_response(conn, 200)
371 ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
372 assert Activity.get_by_ap_id(data["id"])
375 test "it accepts messages with cc as string instead of array", %{conn: conn, data: data} do
379 Map.put(data, "cc", user.ap_id)
384 |> assign(:valid_signature, true)
385 |> put_req_header("content-type", "application/activity+json")
386 |> post("/users/#{user.nickname}/inbox", data)
388 assert "ok" == json_response(conn, 200)
389 ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
390 %Activity{} = activity = Activity.get_by_ap_id(data["id"])
391 assert user.ap_id in activity.recipients
394 test "it accepts messages with bcc as string instead of array", %{conn: conn, data: data} do
398 Map.put(data, "bcc", user.ap_id)
404 |> assign(:valid_signature, true)
405 |> put_req_header("content-type", "application/activity+json")
406 |> post("/users/#{user.nickname}/inbox", data)
408 assert "ok" == json_response(conn, 200)
409 ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
410 assert Activity.get_by_ap_id(data["id"])
413 test "it accepts announces with to as string instead of array", %{conn: conn} do
417 "@context" => "https://www.w3.org/ns/activitystreams",
418 "actor" => "http://mastodon.example.org/users/admin",
419 "id" => "http://mastodon.example.org/users/admin/statuses/19512778738411822/activity",
420 "object" => "https://mastodon.social/users/emelie/statuses/101849165031453009",
421 "to" => "https://www.w3.org/ns/activitystreams#Public",
422 "cc" => [user.ap_id],
428 |> assign(:valid_signature, true)
429 |> put_req_header("content-type", "application/activity+json")
430 |> post("/users/#{user.nickname}/inbox", data)
432 assert "ok" == json_response(conn, 200)
433 ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
434 %Activity{} = activity = Activity.get_by_ap_id(data["id"])
435 assert "https://www.w3.org/ns/activitystreams#Public" in activity.recipients
438 test "it accepts messages from actors that are followed by the user", %{
442 recipient = insert(:user)
443 actor = insert(:user, %{ap_id: "http://mastodon.example.org/users/actor"})
445 {:ok, recipient} = User.follow(recipient, actor)
449 |> Map.put("attributedTo", actor.ap_id)
453 |> Map.put("actor", actor.ap_id)
454 |> Map.put("object", object)
458 |> assign(:valid_signature, true)
459 |> put_req_header("content-type", "application/activity+json")
460 |> post("/users/#{recipient.nickname}/inbox", data)
462 assert "ok" == json_response(conn, 200)
463 ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
464 assert Activity.get_by_ap_id(data["id"])
467 test "it rejects reads from other users", %{conn: conn} do
469 otheruser = insert(:user)
473 |> assign(:user, otheruser)
474 |> put_req_header("accept", "application/activity+json")
475 |> get("/users/#{user.nickname}/inbox")
477 assert json_response(conn, 403)
480 test "it doesn't crash without an authenticated user", %{conn: conn} do
485 |> put_req_header("accept", "application/activity+json")
486 |> get("/users/#{user.nickname}/inbox")
488 assert json_response(conn, 403)
491 test "it returns a note activity in a collection", %{conn: conn} do
492 note_activity = insert(:direct_note_activity)
493 note_object = Object.normalize(note_activity)
494 user = User.get_cached_by_ap_id(hd(note_activity.data["to"]))
498 |> assign(:user, user)
499 |> put_req_header("accept", "application/activity+json")
500 |> get("/users/#{user.nickname}/inbox?page=true")
502 assert response(conn, 200) =~ note_object.data["content"]
505 test "it clears `unreachable` federation status of the sender", %{conn: conn, data: data} do
507 data = Map.put(data, "bcc", [user.ap_id])
509 sender_host = URI.parse(data["actor"]).host
510 Instances.set_consistently_unreachable(sender_host)
511 refute Instances.reachable?(sender_host)
515 |> assign(:valid_signature, true)
516 |> put_req_header("content-type", "application/activity+json")
517 |> post("/users/#{user.nickname}/inbox", data)
519 assert "ok" == json_response(conn, 200)
520 assert Instances.reachable?(sender_host)
523 test "it removes all follower collections but actor's", %{conn: conn} do
524 [actor, recipient] = insert_pair(:user)
527 File.read!("test/fixtures/activitypub-client-post-activity.json")
530 object = Map.put(data["object"], "attributedTo", actor.ap_id)
534 |> Map.put("id", Utils.generate_object_id())
535 |> Map.put("actor", actor.ap_id)
536 |> Map.put("object", object)
538 recipient.follower_address,
539 actor.follower_address
543 recipient.follower_address,
544 "https://www.w3.org/ns/activitystreams#Public"
548 |> assign(:valid_signature, true)
549 |> put_req_header("content-type", "application/activity+json")
550 |> post("/users/#{recipient.nickname}/inbox", data)
551 |> json_response(200)
553 ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
555 activity = Activity.get_by_ap_id(data["id"])
558 assert actor.follower_address in activity.recipients
559 assert actor.follower_address in activity.data["cc"]
561 refute recipient.follower_address in activity.recipients
562 refute recipient.follower_address in activity.data["cc"]
563 refute recipient.follower_address in activity.data["to"]
567 describe "/users/:nickname/outbox" do
568 test "it will not bomb when there is no activity", %{conn: conn} do
573 |> put_req_header("accept", "application/activity+json")
574 |> get("/users/#{user.nickname}/outbox")
576 result = json_response(conn, 200)
577 assert user.ap_id <> "/outbox" == result["id"]
580 test "it returns a note activity in a collection", %{conn: conn} do
581 note_activity = insert(:note_activity)
582 note_object = Object.normalize(note_activity)
583 user = User.get_cached_by_ap_id(note_activity.data["actor"])
587 |> put_req_header("accept", "application/activity+json")
588 |> get("/users/#{user.nickname}/outbox?page=true")
590 assert response(conn, 200) =~ note_object.data["content"]
593 test "it returns an announce activity in a collection", %{conn: conn} do
594 announce_activity = insert(:announce_activity)
595 user = User.get_cached_by_ap_id(announce_activity.data["actor"])
599 |> put_req_header("accept", "application/activity+json")
600 |> get("/users/#{user.nickname}/outbox?page=true")
602 assert response(conn, 200) =~ announce_activity.data["object"]
605 test "it rejects posts from other users", %{conn: conn} do
606 data = File.read!("test/fixtures/activitypub-client-post-activity.json") |> Poison.decode!()
608 otheruser = insert(:user)
612 |> assign(:user, otheruser)
613 |> put_req_header("content-type", "application/activity+json")
614 |> post("/users/#{user.nickname}/outbox", data)
616 assert json_response(conn, 403)
619 test "it inserts an incoming create activity into the database", %{conn: conn} do
620 data = File.read!("test/fixtures/activitypub-client-post-activity.json") |> Poison.decode!()
625 |> assign(:user, user)
626 |> put_req_header("content-type", "application/activity+json")
627 |> post("/users/#{user.nickname}/outbox", data)
629 result = json_response(conn, 201)
631 assert Activity.get_by_ap_id(result["id"])
634 test "it rejects an incoming activity with bogus type", %{conn: conn} do
635 data = File.read!("test/fixtures/activitypub-client-post-activity.json") |> Poison.decode!()
640 |> Map.put("type", "BadType")
644 |> assign(:user, user)
645 |> put_req_header("content-type", "application/activity+json")
646 |> post("/users/#{user.nickname}/outbox", data)
648 assert json_response(conn, 400)
651 test "it erects a tombstone when receiving a delete activity", %{conn: conn} do
652 note_activity = insert(:note_activity)
653 note_object = Object.normalize(note_activity)
654 user = User.get_cached_by_ap_id(note_activity.data["actor"])
659 id: note_object.data["id"]
665 |> assign(:user, user)
666 |> put_req_header("content-type", "application/activity+json")
667 |> post("/users/#{user.nickname}/outbox", data)
669 result = json_response(conn, 201)
670 assert Activity.get_by_ap_id(result["id"])
672 assert object = Object.get_by_ap_id(note_object.data["id"])
673 assert object.data["type"] == "Tombstone"
676 test "it rejects delete activity of object from other actor", %{conn: conn} do
677 note_activity = insert(:note_activity)
678 note_object = Object.normalize(note_activity)
684 id: note_object.data["id"]
690 |> assign(:user, user)
691 |> put_req_header("content-type", "application/activity+json")
692 |> post("/users/#{user.nickname}/outbox", data)
694 assert json_response(conn, 400)
697 test "it increases like count when receiving a like action", %{conn: conn} do
698 note_activity = insert(:note_activity)
699 note_object = Object.normalize(note_activity)
700 user = User.get_cached_by_ap_id(note_activity.data["actor"])
705 id: note_object.data["id"]
711 |> assign(:user, user)
712 |> put_req_header("content-type", "application/activity+json")
713 |> post("/users/#{user.nickname}/outbox", data)
715 result = json_response(conn, 201)
716 assert Activity.get_by_ap_id(result["id"])
718 assert object = Object.get_by_ap_id(note_object.data["id"])
719 assert object.data["like_count"] == 1
723 describe "/relay/followers" do
724 test "it returns relay followers", %{conn: conn} do
725 relay_actor = Relay.get_actor()
727 User.follow(user, relay_actor)
731 |> assign(:relay, true)
732 |> get("/relay/followers")
733 |> json_response(200)
735 assert result["first"]["orderedItems"] == [user.ap_id]
739 describe "/relay/following" do
740 test "it returns relay following", %{conn: conn} do
743 |> assign(:relay, true)
744 |> get("/relay/following")
745 |> json_response(200)
747 assert result["first"]["orderedItems"] == []
751 describe "/users/:nickname/followers" do
752 test "it returns the followers in a collection", %{conn: conn} do
754 user_two = insert(:user)
755 User.follow(user, user_two)
759 |> get("/users/#{user_two.nickname}/followers")
760 |> json_response(200)
762 assert result["first"]["orderedItems"] == [user.ap_id]
765 test "it returns returns a uri if the user has 'hide_followers' set", %{conn: conn} do
767 user_two = insert(:user, hide_followers: true)
768 User.follow(user, user_two)
772 |> get("/users/#{user_two.nickname}/followers")
773 |> json_response(200)
775 assert is_binary(result["first"])
778 test "it returns a 403 error on pages, if the user has 'hide_followers' set and the request is not authenticated",
780 user = insert(:user, hide_followers: true)
784 |> get("/users/#{user.nickname}/followers?page=1")
786 assert result.status == 403
787 assert result.resp_body == ""
790 test "it renders the page, if the user has 'hide_followers' set and the request is authenticated with the same user",
792 user = insert(:user, hide_followers: true)
793 other_user = insert(:user)
794 {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
798 |> assign(:user, user)
799 |> get("/users/#{user.nickname}/followers?page=1")
800 |> json_response(200)
802 assert result["totalItems"] == 1
803 assert result["orderedItems"] == [other_user.ap_id]
806 test "it works for more than 10 users", %{conn: conn} do
809 Enum.each(1..15, fn _ ->
810 other_user = insert(:user)
811 User.follow(other_user, user)
816 |> get("/users/#{user.nickname}/followers")
817 |> json_response(200)
819 assert length(result["first"]["orderedItems"]) == 10
820 assert result["first"]["totalItems"] == 15
821 assert result["totalItems"] == 15
825 |> get("/users/#{user.nickname}/followers?page=2")
826 |> json_response(200)
828 assert length(result["orderedItems"]) == 5
829 assert result["totalItems"] == 15
833 describe "/users/:nickname/following" do
834 test "it returns the following in a collection", %{conn: conn} do
836 user_two = insert(:user)
837 User.follow(user, user_two)
841 |> get("/users/#{user.nickname}/following")
842 |> json_response(200)
844 assert result["first"]["orderedItems"] == [user_two.ap_id]
847 test "it returns a uri if the user has 'hide_follows' set", %{conn: conn} do
848 user = insert(:user, hide_follows: true)
849 user_two = insert(:user)
850 User.follow(user, user_two)
854 |> get("/users/#{user.nickname}/following")
855 |> json_response(200)
857 assert is_binary(result["first"])
860 test "it returns a 403 error on pages, if the user has 'hide_follows' set and the request is not authenticated",
862 user = insert(:user, hide_follows: true)
866 |> get("/users/#{user.nickname}/following?page=1")
868 assert result.status == 403
869 assert result.resp_body == ""
872 test "it renders the page, if the user has 'hide_follows' set and the request is authenticated with the same user",
874 user = insert(:user, hide_follows: true)
875 other_user = insert(:user)
876 {:ok, user, _other_user, _activity} = CommonAPI.follow(user, other_user)
880 |> assign(:user, user)
881 |> get("/users/#{user.nickname}/following?page=1")
882 |> json_response(200)
884 assert result["totalItems"] == 1
885 assert result["orderedItems"] == [other_user.ap_id]
888 test "it works for more than 10 users", %{conn: conn} do
891 Enum.each(1..15, fn _ ->
892 user = User.get_cached_by_id(user.id)
893 other_user = insert(:user)
894 User.follow(user, other_user)
899 |> get("/users/#{user.nickname}/following")
900 |> json_response(200)
902 assert length(result["first"]["orderedItems"]) == 10
903 assert result["first"]["totalItems"] == 15
904 assert result["totalItems"] == 15
908 |> get("/users/#{user.nickname}/following?page=2")
909 |> json_response(200)
911 assert length(result["orderedItems"]) == 5
912 assert result["totalItems"] == 15
916 describe "delivery tracking" do
917 test "it tracks a signed object fetch", %{conn: conn} do
918 user = insert(:user, local: false)
919 activity = insert(:note_activity)
920 object = Object.normalize(activity)
922 object_path = String.trim_leading(object.data["id"], Pleroma.Web.Endpoint.url())
925 |> put_req_header("accept", "application/activity+json")
926 |> assign(:user, user)
928 |> json_response(200)
930 assert Delivery.get(object.id, user.id)
933 test "it tracks a signed activity fetch", %{conn: conn} do
934 user = insert(:user, local: false)
935 activity = insert(:note_activity)
936 object = Object.normalize(activity)
938 activity_path = String.trim_leading(activity.data["id"], Pleroma.Web.Endpoint.url())
941 |> put_req_header("accept", "application/activity+json")
942 |> assign(:user, user)
943 |> get(activity_path)
944 |> json_response(200)
946 assert Delivery.get(object.id, user.id)
949 test "it tracks a signed object fetch when the json is cached", %{conn: conn} do
950 user = insert(:user, local: false)
951 other_user = insert(:user, local: false)
952 activity = insert(:note_activity)
953 object = Object.normalize(activity)
955 object_path = String.trim_leading(object.data["id"], Pleroma.Web.Endpoint.url())
958 |> put_req_header("accept", "application/activity+json")
959 |> assign(:user, user)
961 |> json_response(200)
964 |> put_req_header("accept", "application/activity+json")
965 |> assign(:user, other_user)
967 |> json_response(200)
969 assert Delivery.get(object.id, user.id)
970 assert Delivery.get(object.id, other_user.id)
973 test "it tracks a signed activity fetch when the json is cached", %{conn: conn} do
974 user = insert(:user, local: false)
975 other_user = insert(:user, local: false)
976 activity = insert(:note_activity)
977 object = Object.normalize(activity)
979 activity_path = String.trim_leading(activity.data["id"], Pleroma.Web.Endpoint.url())
982 |> put_req_header("accept", "application/activity+json")
983 |> assign(:user, user)
984 |> get(activity_path)
985 |> json_response(200)
988 |> put_req_header("accept", "application/activity+json")
989 |> assign(:user, other_user)
990 |> get(activity_path)
991 |> json_response(200)
993 assert Delivery.get(object.id, user.id)
994 assert Delivery.get(object.id, other_user.id)
998 describe "Additionnal ActivityPub C2S endpoints" do
999 test "/api/ap/whoami", %{conn: conn} do
1000 user = insert(:user)
1004 |> assign(:user, user)
1005 |> get("/api/ap/whoami")
1007 user = User.get_cached_by_id(user.id)
1009 assert UserView.render("user.json", %{user: user}) == json_response(conn, 200)
1012 clear_config([:media_proxy])
1013 clear_config([Pleroma.Upload])
1015 test "uploadMedia", %{conn: conn} do
1016 user = insert(:user)
1018 desc = "Description of the image"
1020 image = %Plug.Upload{
1021 content_type: "image/jpg",
1022 path: Path.absname("test/fixtures/image.jpg"),
1023 filename: "an_image.jpg"
1028 |> assign(:user, user)
1029 |> post("/api/ap/upload_media", %{"file" => image, "description" => desc})
1031 assert object = json_response(conn, :created)
1032 assert object["name"] == desc
1033 assert object["type"] == "Document"
1034 assert object["actor"] == user.ap_id