Merge branch 'develop' into issue/1218
[akkoma] / test / conversation_test.exs
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.ConversationTest do
6 use Pleroma.DataCase
7 alias Pleroma.Activity
8 alias Pleroma.Conversation
9 alias Pleroma.Object
10 alias Pleroma.Web.CommonAPI
11
12 import Pleroma.Factory
13
14 clear_config_all([:instance, :federating]) do
15 Pleroma.Config.put([:instance, :federating], true)
16 end
17
18 test "it goes through old direct conversations" do
19 user = insert(:user)
20 other_user = insert(:user)
21
22 {:ok, _activity} =
23 CommonAPI.post(user, %{"visibility" => "direct", "status" => "hey @#{other_user.nickname}"})
24
25 Pleroma.Tests.ObanHelpers.perform_all()
26
27 Repo.delete_all(Conversation)
28 Repo.delete_all(Conversation.Participation)
29
30 refute Repo.one(Conversation)
31
32 Conversation.bump_for_all_activities()
33
34 assert Repo.one(Conversation)
35 [participation, _p2] = Repo.all(Conversation.Participation)
36
37 assert participation.read
38 end
39
40 test "it creates a conversation for given ap_id" do
41 assert {:ok, %Conversation{} = conversation} =
42 Conversation.create_for_ap_id("https://some_ap_id")
43
44 # Inserting again returns the same
45 assert {:ok, conversation_two} = Conversation.create_for_ap_id("https://some_ap_id")
46 assert conversation_two.id == conversation.id
47 end
48
49 test "public posts don't create conversations" do
50 user = insert(:user)
51 {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey"})
52
53 object = Pleroma.Object.normalize(activity)
54 context = object.data["context"]
55
56 conversation = Conversation.get_for_ap_id(context)
57
58 refute conversation
59 end
60
61 test "it creates or updates a conversation and participations for a given DM" do
62 har = insert(:user)
63 jafnhar = insert(:user, local: false)
64 tridi = insert(:user)
65
66 {:ok, activity} =
67 CommonAPI.post(har, %{"status" => "Hey @#{jafnhar.nickname}", "visibility" => "direct"})
68
69 object = Pleroma.Object.normalize(activity)
70 context = object.data["context"]
71
72 conversation =
73 Conversation.get_for_ap_id(context)
74 |> Repo.preload(:participations)
75
76 assert conversation
77
78 assert Enum.find(conversation.participations, fn %{user_id: user_id} -> har.id == user_id end)
79
80 assert Enum.find(conversation.participations, fn %{user_id: user_id} ->
81 jafnhar.id == user_id
82 end)
83
84 {:ok, activity} =
85 CommonAPI.post(jafnhar, %{
86 "status" => "Hey @#{har.nickname}",
87 "visibility" => "direct",
88 "in_reply_to_status_id" => activity.id
89 })
90
91 object = Pleroma.Object.normalize(activity)
92 context = object.data["context"]
93
94 conversation_two =
95 Conversation.get_for_ap_id(context)
96 |> Repo.preload(:participations)
97
98 assert conversation_two.id == conversation.id
99
100 assert Enum.find(conversation_two.participations, fn %{user_id: user_id} ->
101 har.id == user_id
102 end)
103
104 assert Enum.find(conversation_two.participations, fn %{user_id: user_id} ->
105 jafnhar.id == user_id
106 end)
107
108 {:ok, activity} =
109 CommonAPI.post(tridi, %{
110 "status" => "Hey @#{har.nickname}",
111 "visibility" => "direct",
112 "in_reply_to_status_id" => activity.id
113 })
114
115 object = Pleroma.Object.normalize(activity)
116 context = object.data["context"]
117
118 conversation_three =
119 Conversation.get_for_ap_id(context)
120 |> Repo.preload([:participations, :users])
121
122 assert conversation_three.id == conversation.id
123
124 assert Enum.find(conversation_three.participations, fn %{user_id: user_id} ->
125 har.id == user_id
126 end)
127
128 assert Enum.find(conversation_three.participations, fn %{user_id: user_id} ->
129 jafnhar.id == user_id
130 end)
131
132 assert Enum.find(conversation_three.participations, fn %{user_id: user_id} ->
133 tridi.id == user_id
134 end)
135
136 assert Enum.find(conversation_three.users, fn %{id: user_id} ->
137 har.id == user_id
138 end)
139
140 assert Enum.find(conversation_three.users, fn %{id: user_id} ->
141 jafnhar.id == user_id
142 end)
143
144 assert Enum.find(conversation_three.users, fn %{id: user_id} ->
145 tridi.id == user_id
146 end)
147 end
148
149 test "create_or_bump_for returns the conversation with participations" do
150 har = insert(:user)
151 jafnhar = insert(:user, local: false)
152
153 {:ok, activity} =
154 CommonAPI.post(har, %{"status" => "Hey @#{jafnhar.nickname}", "visibility" => "direct"})
155
156 {:ok, conversation} = Conversation.create_or_bump_for(activity)
157
158 assert length(conversation.participations) == 2
159
160 {:ok, activity} =
161 CommonAPI.post(har, %{"status" => "Hey @#{jafnhar.nickname}", "visibility" => "public"})
162
163 assert {:error, _} = Conversation.create_or_bump_for(activity)
164 end
165
166 test "create_or_bump_for does not normalize objects before checking the activity type" do
167 note = insert(:note)
168 note_id = note.data["id"]
169 Repo.delete(note)
170 refute Object.get_by_ap_id(note_id)
171
172 Tesla.Mock.mock(fn env ->
173 case env.url do
174 ^note_id ->
175 # TODO: add attributedTo and tag to the note factory
176 body =
177 note.data
178 |> Map.put("attributedTo", note.data["actor"])
179 |> Map.put("tag", [])
180 |> Jason.encode!()
181
182 %Tesla.Env{status: 200, body: body}
183 end
184 end)
185
186 undo = %Activity{
187 id: "fake",
188 data: %{
189 "id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(),
190 "actor" => note.data["actor"],
191 "to" => [note.data["actor"]],
192 "object" => note_id,
193 "type" => "Undo"
194 }
195 }
196
197 Conversation.create_or_bump_for(undo)
198
199 refute Object.get_by_ap_id(note_id)
200 end
201 end