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