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]) do
29 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)
346 describe "/users/:nickname/inbox" do
349 File.read!("test/fixtures/mastodon-post-activity.json")
355 test "it inserts an incoming activity into the database", %{conn: conn, data: data} do
357 data = Map.put(data, "bcc", [user.ap_id])
361 |> assign(:valid_signature, true)
362 |> put_req_header("content-type", "application/activity+json")
363 |> post("/users/#{user.nickname}/inbox", data)
365 assert "ok" == json_response(conn, 200)
366 ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
367 assert Activity.get_by_ap_id(data["id"])
370 test "it accepts messages with to as string instead of array", %{conn: conn, data: data} do
374 Map.put(data, "to", user.ap_id)
379 |> assign(:valid_signature, true)
380 |> put_req_header("content-type", "application/activity+json")
381 |> post("/users/#{user.nickname}/inbox", data)
383 assert "ok" == json_response(conn, 200)
384 ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
385 assert Activity.get_by_ap_id(data["id"])
388 test "it accepts messages with cc as string instead of array", %{conn: conn, data: data} do
392 Map.put(data, "cc", user.ap_id)
397 |> assign(:valid_signature, true)
398 |> put_req_header("content-type", "application/activity+json")
399 |> post("/users/#{user.nickname}/inbox", data)
401 assert "ok" == json_response(conn, 200)
402 ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
403 %Activity{} = activity = Activity.get_by_ap_id(data["id"])
404 assert user.ap_id in activity.recipients
407 test "it accepts messages with bcc as string instead of array", %{conn: conn, data: data} do
411 Map.put(data, "bcc", 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 announces with to as string instead of array", %{conn: conn} do
430 "@context" => "https://www.w3.org/ns/activitystreams",
431 "actor" => "http://mastodon.example.org/users/admin",
432 "id" => "http://mastodon.example.org/users/admin/statuses/19512778738411822/activity",
433 "object" => "https://mastodon.social/users/emelie/statuses/101849165031453009",
434 "to" => "https://www.w3.org/ns/activitystreams#Public",
435 "cc" => [user.ap_id],
441 |> assign(:valid_signature, true)
442 |> put_req_header("content-type", "application/activity+json")
443 |> post("/users/#{user.nickname}/inbox", data)
445 assert "ok" == json_response(conn, 200)
446 ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
447 %Activity{} = activity = Activity.get_by_ap_id(data["id"])
448 assert "https://www.w3.org/ns/activitystreams#Public" in activity.recipients
451 test "it accepts messages from actors that are followed by the user", %{
455 recipient = insert(:user)
456 actor = insert(:user, %{ap_id: "http://mastodon.example.org/users/actor"})
458 {:ok, recipient} = User.follow(recipient, actor)
462 |> Map.put("attributedTo", actor.ap_id)
466 |> Map.put("actor", actor.ap_id)
467 |> Map.put("object", object)
471 |> assign(:valid_signature, true)
472 |> put_req_header("content-type", "application/activity+json")
473 |> post("/users/#{recipient.nickname}/inbox", data)
475 assert "ok" == json_response(conn, 200)
476 ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
477 assert Activity.get_by_ap_id(data["id"])
480 test "it rejects reads from other users", %{conn: conn} do
482 otheruser = insert(:user)
486 |> assign(:user, otheruser)
487 |> put_req_header("accept", "application/activity+json")
488 |> get("/users/#{user.nickname}/inbox")
490 assert json_response(conn, 403)
493 test "it doesn't crash without an authenticated user", %{conn: conn} do
498 |> put_req_header("accept", "application/activity+json")
499 |> get("/users/#{user.nickname}/inbox")
501 assert json_response(conn, 403)
504 test "it returns a note activity in a collection", %{conn: conn} do
505 note_activity = insert(:direct_note_activity)
506 note_object = Object.normalize(note_activity)
507 user = User.get_cached_by_ap_id(hd(note_activity.data["to"]))
511 |> assign(:user, user)
512 |> put_req_header("accept", "application/activity+json")
513 |> get("/users/#{user.nickname}/inbox?page=true")
515 assert response(conn, 200) =~ note_object.data["content"]
518 test "it clears `unreachable` federation status of the sender", %{conn: conn, data: data} do
520 data = Map.put(data, "bcc", [user.ap_id])
522 sender_host = URI.parse(data["actor"]).host
523 Instances.set_consistently_unreachable(sender_host)
524 refute Instances.reachable?(sender_host)
528 |> assign(:valid_signature, true)
529 |> put_req_header("content-type", "application/activity+json")
530 |> post("/users/#{user.nickname}/inbox", data)
532 assert "ok" == json_response(conn, 200)
533 assert Instances.reachable?(sender_host)
536 test "it removes all follower collections but actor's", %{conn: conn} do
537 [actor, recipient] = insert_pair(:user)
540 File.read!("test/fixtures/activitypub-client-post-activity.json")
543 object = Map.put(data["object"], "attributedTo", actor.ap_id)
547 |> Map.put("id", Utils.generate_object_id())
548 |> Map.put("actor", actor.ap_id)
549 |> Map.put("object", object)
551 recipient.follower_address,
552 actor.follower_address
556 recipient.follower_address,
557 "https://www.w3.org/ns/activitystreams#Public"
561 |> assign(:valid_signature, true)
562 |> put_req_header("content-type", "application/activity+json")
563 |> post("/users/#{recipient.nickname}/inbox", data)
564 |> json_response(200)
566 ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
568 activity = Activity.get_by_ap_id(data["id"])
571 assert actor.follower_address in activity.recipients
572 assert actor.follower_address in activity.data["cc"]
574 refute recipient.follower_address in activity.recipients
575 refute recipient.follower_address in activity.data["cc"]
576 refute recipient.follower_address in activity.data["to"]
580 describe "GET /users/:nickname/outbox" do
581 test "it will not bomb when there is no activity", %{conn: conn} do
586 |> put_req_header("accept", "application/activity+json")
587 |> get("/users/#{user.nickname}/outbox")
589 result = json_response(conn, 200)
590 assert user.ap_id <> "/outbox" == result["id"]
593 test "it returns a note activity in a collection", %{conn: conn} do
594 note_activity = insert(:note_activity)
595 note_object = Object.normalize(note_activity)
596 user = User.get_cached_by_ap_id(note_activity.data["actor"])
600 |> put_req_header("accept", "application/activity+json")
601 |> get("/users/#{user.nickname}/outbox?page=true")
603 assert response(conn, 200) =~ note_object.data["content"]
606 test "it returns an announce activity in a collection", %{conn: conn} do
607 announce_activity = insert(:announce_activity)
608 user = User.get_cached_by_ap_id(announce_activity.data["actor"])
612 |> put_req_header("accept", "application/activity+json")
613 |> get("/users/#{user.nickname}/outbox?page=true")
615 assert response(conn, 200) =~ announce_activity.data["object"]
619 describe "POST /users/:nickname/outbox" do
620 test "it rejects posts from other users", %{conn: conn} do
621 data = File.read!("test/fixtures/activitypub-client-post-activity.json") |> Poison.decode!()
623 otheruser = insert(:user)
627 |> assign(:user, otheruser)
628 |> put_req_header("content-type", "application/activity+json")
629 |> post("/users/#{user.nickname}/outbox", data)
631 assert json_response(conn, 403)
634 test "it inserts an incoming create activity into the database", %{conn: conn} do
635 data = File.read!("test/fixtures/activitypub-client-post-activity.json") |> Poison.decode!()
640 |> assign(:user, user)
641 |> put_req_header("content-type", "application/activity+json")
642 |> post("/users/#{user.nickname}/outbox", data)
644 result = json_response(conn, 201)
646 assert Activity.get_by_ap_id(result["id"])
649 test "it rejects an incoming activity with bogus type", %{conn: conn} do
650 data = File.read!("test/fixtures/activitypub-client-post-activity.json") |> Poison.decode!()
655 |> Map.put("type", "BadType")
659 |> assign(:user, user)
660 |> put_req_header("content-type", "application/activity+json")
661 |> post("/users/#{user.nickname}/outbox", data)
663 assert json_response(conn, 400)
666 test "it erects a tombstone when receiving a delete activity", %{conn: conn} do
667 note_activity = insert(:note_activity)
668 note_object = Object.normalize(note_activity)
669 user = User.get_cached_by_ap_id(note_activity.data["actor"])
674 id: note_object.data["id"]
680 |> assign(:user, user)
681 |> put_req_header("content-type", "application/activity+json")
682 |> post("/users/#{user.nickname}/outbox", data)
684 result = json_response(conn, 201)
685 assert Activity.get_by_ap_id(result["id"])
687 assert object = Object.get_by_ap_id(note_object.data["id"])
688 assert object.data["type"] == "Tombstone"
691 test "it rejects delete activity of object from other actor", %{conn: conn} do
692 note_activity = insert(:note_activity)
693 note_object = Object.normalize(note_activity)
699 id: note_object.data["id"]
705 |> assign(:user, user)
706 |> put_req_header("content-type", "application/activity+json")
707 |> post("/users/#{user.nickname}/outbox", data)
709 assert json_response(conn, 400)
712 test "it increases like count when receiving a like action", %{conn: conn} do
713 note_activity = insert(:note_activity)
714 note_object = Object.normalize(note_activity)
715 user = User.get_cached_by_ap_id(note_activity.data["actor"])
720 id: note_object.data["id"]
726 |> assign(:user, user)
727 |> put_req_header("content-type", "application/activity+json")
728 |> post("/users/#{user.nickname}/outbox", data)
730 result = json_response(conn, 201)
731 assert Activity.get_by_ap_id(result["id"])
733 assert object = Object.get_by_ap_id(note_object.data["id"])
734 assert object.data["like_count"] == 1
738 describe "/relay/followers" do
739 test "it returns relay followers", %{conn: conn} do
740 relay_actor = Relay.get_actor()
742 User.follow(user, relay_actor)
746 |> assign(:relay, true)
747 |> get("/relay/followers")
748 |> json_response(200)
750 assert result["first"]["orderedItems"] == [user.ap_id]
754 describe "/relay/following" do
755 test "it returns relay following", %{conn: conn} do
758 |> assign(:relay, true)
759 |> get("/relay/following")
760 |> json_response(200)
762 assert result["first"]["orderedItems"] == []
766 describe "/users/:nickname/followers" do
767 test "it returns the followers in a collection", %{conn: conn} do
769 user_two = insert(:user)
770 User.follow(user, user_two)
774 |> get("/users/#{user_two.nickname}/followers")
775 |> json_response(200)
777 assert result["first"]["orderedItems"] == [user.ap_id]
780 test "it returns a uri if the user has 'hide_followers' set", %{conn: conn} do
782 user_two = insert(:user, hide_followers: true)
783 User.follow(user, user_two)
787 |> get("/users/#{user_two.nickname}/followers")
788 |> json_response(200)
790 assert is_binary(result["first"])
793 test "it returns a 403 error on pages, if the user has 'hide_followers' set and the request is not authenticated",
795 user = insert(:user, hide_followers: true)
799 |> get("/users/#{user.nickname}/followers?page=1")
801 assert result.status == 403
802 assert result.resp_body == ""
805 test "it renders the page, if the user has 'hide_followers' set and the request is authenticated with the same user",
807 user = insert(:user, hide_followers: true)
808 other_user = insert(:user)
809 {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
813 |> assign(:user, user)
814 |> get("/users/#{user.nickname}/followers?page=1")
815 |> json_response(200)
817 assert result["totalItems"] == 1
818 assert result["orderedItems"] == [other_user.ap_id]
821 test "it works for more than 10 users", %{conn: conn} do
824 Enum.each(1..15, fn _ ->
825 other_user = insert(:user)
826 User.follow(other_user, user)
831 |> get("/users/#{user.nickname}/followers")
832 |> json_response(200)
834 assert length(result["first"]["orderedItems"]) == 10
835 assert result["first"]["totalItems"] == 15
836 assert result["totalItems"] == 15
840 |> get("/users/#{user.nickname}/followers?page=2")
841 |> json_response(200)
843 assert length(result["orderedItems"]) == 5
844 assert result["totalItems"] == 15
848 describe "/users/:nickname/following" do
849 test "it returns the following in a collection", %{conn: conn} do
851 user_two = insert(:user)
852 User.follow(user, user_two)
856 |> get("/users/#{user.nickname}/following")
857 |> json_response(200)
859 assert result["first"]["orderedItems"] == [user_two.ap_id]
862 test "it returns a uri if the user has 'hide_follows' set", %{conn: conn} do
863 user = insert(:user, hide_follows: true)
864 user_two = insert(:user)
865 User.follow(user, user_two)
869 |> get("/users/#{user.nickname}/following")
870 |> json_response(200)
872 assert is_binary(result["first"])
875 test "it returns a 403 error on pages, if the user has 'hide_follows' set and the request is not authenticated",
877 user = insert(:user, hide_follows: true)
881 |> get("/users/#{user.nickname}/following?page=1")
883 assert result.status == 403
884 assert result.resp_body == ""
887 test "it renders the page, if the user has 'hide_follows' set and the request is authenticated with the same user",
889 user = insert(:user, hide_follows: true)
890 other_user = insert(:user)
891 {:ok, user, _other_user, _activity} = CommonAPI.follow(user, other_user)
895 |> assign(:user, user)
896 |> get("/users/#{user.nickname}/following?page=1")
897 |> json_response(200)
899 assert result["totalItems"] == 1
900 assert result["orderedItems"] == [other_user.ap_id]
903 test "it works for more than 10 users", %{conn: conn} do
906 Enum.each(1..15, fn _ ->
907 user = User.get_cached_by_id(user.id)
908 other_user = insert(:user)
909 User.follow(user, other_user)
914 |> get("/users/#{user.nickname}/following")
915 |> json_response(200)
917 assert length(result["first"]["orderedItems"]) == 10
918 assert result["first"]["totalItems"] == 15
919 assert result["totalItems"] == 15
923 |> get("/users/#{user.nickname}/following?page=2")
924 |> json_response(200)
926 assert length(result["orderedItems"]) == 5
927 assert result["totalItems"] == 15
931 describe "delivery tracking" do
932 test "it tracks a signed object fetch", %{conn: conn} do
933 user = insert(:user, local: false)
934 activity = insert(:note_activity)
935 object = Object.normalize(activity)
937 object_path = String.trim_leading(object.data["id"], Pleroma.Web.Endpoint.url())
940 |> put_req_header("accept", "application/activity+json")
941 |> assign(:user, user)
943 |> json_response(200)
945 assert Delivery.get(object.id, user.id)
948 test "it tracks a signed activity fetch", %{conn: conn} do
949 user = insert(:user, local: false)
950 activity = insert(:note_activity)
951 object = Object.normalize(activity)
953 activity_path = String.trim_leading(activity.data["id"], Pleroma.Web.Endpoint.url())
956 |> put_req_header("accept", "application/activity+json")
957 |> assign(:user, user)
958 |> get(activity_path)
959 |> json_response(200)
961 assert Delivery.get(object.id, user.id)
964 test "it tracks a signed object fetch when the json is cached", %{conn: conn} do
965 user = insert(:user, local: false)
966 other_user = insert(:user, local: false)
967 activity = insert(:note_activity)
968 object = Object.normalize(activity)
970 object_path = String.trim_leading(object.data["id"], Pleroma.Web.Endpoint.url())
973 |> put_req_header("accept", "application/activity+json")
974 |> assign(:user, user)
976 |> json_response(200)
979 |> put_req_header("accept", "application/activity+json")
980 |> assign(:user, other_user)
982 |> json_response(200)
984 assert Delivery.get(object.id, user.id)
985 assert Delivery.get(object.id, other_user.id)
988 test "it tracks a signed activity fetch when the json is cached", %{conn: conn} do
989 user = insert(:user, local: false)
990 other_user = insert(:user, local: false)
991 activity = insert(:note_activity)
992 object = Object.normalize(activity)
994 activity_path = String.trim_leading(activity.data["id"], Pleroma.Web.Endpoint.url())
997 |> put_req_header("accept", "application/activity+json")
998 |> assign(:user, user)
999 |> get(activity_path)
1000 |> json_response(200)
1003 |> put_req_header("accept", "application/activity+json")
1004 |> assign(:user, other_user)
1005 |> get(activity_path)
1006 |> json_response(200)
1008 assert Delivery.get(object.id, user.id)
1009 assert Delivery.get(object.id, other_user.id)
1013 describe "Additional ActivityPub C2S endpoints" do
1014 test "/api/ap/whoami", %{conn: conn} do
1015 user = insert(:user)
1019 |> assign(:user, user)
1020 |> get("/api/ap/whoami")
1022 user = User.get_cached_by_id(user.id)
1024 assert UserView.render("user.json", %{user: user}) == json_response(conn, 200)
1027 clear_config([:media_proxy])
1028 clear_config([Pleroma.Upload])
1030 test "uploadMedia", %{conn: conn} do
1031 user = insert(:user)
1033 desc = "Description of the image"
1035 image = %Plug.Upload{
1036 content_type: "image/jpg",
1037 path: Path.absname("test/fixtures/image.jpg"),
1038 filename: "an_image.jpg"
1043 |> assign(:user, user)
1044 |> post("/api/ap/upload_media", %{"file" => image, "description" => desc})
1046 assert object = json_response(conn, :created)
1047 assert object["name"] == desc
1048 assert object["type"] == "Document"
1049 assert object["actor"] == user.ap_id
1053 describe "when instance is not federating," do
1054 clear_config([:instance, :federating]) do
1055 Pleroma.Config.put([:instance, :federating], false)
1058 test "returns 404 for GET routes", %{conn: conn} do
1059 user = insert(:user)
1060 conn = put_req_header(conn, "accept", "application/json")
1063 "/users/#{user.nickname}",
1070 for get_uri <- get_uris do
1073 |> json_response(404)
1076 |> assign(:user, user)
1078 |> json_response(404)
1082 test "returns 404 for activity-related POST routes", %{conn: conn} do
1083 user = insert(:user)
1087 |> assign(:valid_signature, true)
1088 |> put_req_header("content-type", "application/activity+json")
1090 post_activity_data =
1091 "test/fixtures/mastodon-post-activity.json"
1095 post_activity_uris = [
1098 "/users/#{user.nickname}/inbox"
1101 for post_activity_uri <- post_activity_uris do
1103 |> post(post_activity_uri, post_activity_data)
1104 |> json_response(404)
1107 |> assign(:user, user)
1108 |> post(post_activity_uri, post_activity_data)
1109 |> json_response(404)