Add unliking to activitypub.
[akkoma] / test / web / activity_pub / activity_pub_test.exs
1 defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
2 use Pleroma.DataCase
3 alias Pleroma.Web.ActivityPub.ActivityPub
4 alias Pleroma.{Activity, Object, User}
5 alias Pleroma.Builders.ActivityBuilder
6
7 import Pleroma.Factory
8
9 describe "insertion" do
10 test "inserts a given map into the activity database, giving it an id if it has none." do
11 data = %{
12 "ok" => true
13 }
14
15 {:ok, %Activity{} = activity} = ActivityPub.insert(data)
16 assert activity.data["ok"] == data["ok"]
17 assert is_binary(activity.data["id"])
18
19 given_id = "bla"
20 data = %{
21 "ok" => true,
22 "id" => given_id
23 }
24
25 {:ok, %Activity{} = activity} = ActivityPub.insert(data)
26 assert activity.data["ok"] == data["ok"]
27 assert activity.data["id"] == given_id
28 end
29
30 test "adds an id to a given object if it lacks one and inserts it to the object database" do
31 data = %{
32 "object" => %{
33 "ok" => true
34 }
35 }
36
37 {:ok, %Activity{} = activity} = ActivityPub.insert(data)
38 assert is_binary(activity.data["object"]["id"])
39 assert %Object{} = Object.get_by_ap_id(activity.data["object"]["id"])
40 end
41 end
42
43 describe "fetch activities for recipients" do
44 test "retrieve the activities for certain recipients" do
45 {:ok, activity_one} = ActivityBuilder.insert(%{"to" => ["someone"]})
46 {:ok, activity_two} = ActivityBuilder.insert(%{"to" => ["someone_else"]})
47 {:ok, _activity_three} = ActivityBuilder.insert(%{"to" => ["noone"]})
48
49 activities = ActivityPub.fetch_activities(["someone", "someone_else"])
50 assert length(activities) == 2
51 assert activities == [activity_one, activity_two]
52 end
53 end
54
55 describe "fetch activities in context" do
56 test "retrieves activities that have a given context" do
57 {:ok, activity} = ActivityBuilder.insert(%{"context" => "2hu"})
58 {:ok, activity_two} = ActivityBuilder.insert(%{"context" => "2hu"})
59 {:ok, _activity_three} = ActivityBuilder.insert(%{"context" => "3hu"})
60
61 activities = ActivityPub.fetch_activities_for_context("2hu")
62
63 assert activities == [activity, activity_two]
64 end
65 end
66
67 describe "public fetch activities" do
68 test "retrieves public activities" do
69 %{public: public} = ActivityBuilder.public_and_non_public
70
71 activities = ActivityPub.fetch_public_activities
72 assert length(activities) == 1
73 assert Enum.at(activities, 0) == public
74 end
75
76 test "retrieves a maximum of 20 activities" do
77 activities = ActivityBuilder.insert_list(30)
78 last_expected = List.last(activities)
79
80 activities = ActivityPub.fetch_public_activities
81 last = List.last(activities)
82
83 assert length(activities) == 20
84 assert last == last_expected
85 end
86
87 test "retrieves ids starting from a since_id" do
88 activities = ActivityBuilder.insert_list(30)
89 later_activities = ActivityBuilder.insert_list(10)
90 since_id = List.last(activities).id
91 last_expected = List.last(later_activities)
92
93 activities = ActivityPub.fetch_public_activities(%{"since_id" => since_id})
94 last = List.last(activities)
95
96 assert length(activities) == 10
97 assert last == last_expected
98 end
99
100 test "retrieves ids up to max_id" do
101 _first_activities = ActivityBuilder.insert_list(10)
102 activities = ActivityBuilder.insert_list(20)
103 later_activities = ActivityBuilder.insert_list(10)
104 max_id = List.first(later_activities).id
105 last_expected = List.last(activities)
106
107 activities = ActivityPub.fetch_public_activities(%{"max_id" => max_id})
108 last = List.last(activities)
109
110 assert length(activities) == 20
111 assert last == last_expected
112 end
113 end
114
115 describe "like an object" do
116 test "adds a like activity to the db" do
117 note_activity = insert(:note_activity)
118 object = Object.get_by_ap_id(note_activity.data["object"]["id"])
119 user = insert(:user)
120 user_two = insert(:user)
121
122 {:ok, like_activity, object} = ActivityPub.like(user, object)
123
124 assert like_activity.data["actor"] == user.ap_id
125 assert like_activity.data["type"] == "Like"
126 assert like_activity.data["object"] == object.data["id"]
127 assert like_activity.data["to"] == [User.ap_followers(user)]
128 assert object.data["like_count"] == 1
129 assert object.data["likes"] == [user.ap_id]
130
131 # Just return the original activity if the user already liked it.
132 {:ok, same_like_activity, object} = ActivityPub.like(user, object)
133
134 assert like_activity == same_like_activity
135 assert object.data["likes"] == [user.ap_id]
136
137 [note_activity] = Activity.all_by_object_ap_id(object.data["id"])
138 assert note_activity.data["object"]["like_count"] == 1
139
140 {:ok, _like_activity, object} = ActivityPub.like(user_two, object)
141 assert object.data["like_count"] == 2
142 end
143 end
144
145 describe "unliking" do
146 test "unliking a previously liked object" do
147 note_activity = insert(:note_activity)
148 object = Object.get_by_ap_id(note_activity.data["object"]["id"])
149 user = insert(:user)
150
151 # Unliking something that hasn't been liked does nothing
152 {:ok, object} = ActivityPub.unlike(user, object)
153 assert object.data["like_count"] == 0
154
155 {:ok, like_activity, object} = ActivityPub.like(user, object)
156 assert object.data["like_count"] == 1
157
158 {:ok, object} = ActivityPub.unlike(user, object)
159 assert object.data["like_count"] == 0
160
161 assert Repo.get(Activity, like_activity.id) == nil
162 end
163 end
164
165 describe "uploading files" do
166 test "copies the file to the configured folder" do
167 file = %Plug.Upload{content_type: "image/jpg", path: Path.absname("test/fixtures/image.jpg"), filename: "an_image.jpg"}
168
169 {:ok, %Object{} = object} = ActivityPub.upload(file)
170 assert object.data["name"] == "an_image.jpg"
171 end
172 end
173 end