First
[anni] / test / pleroma / web / static_fe / static_fe_controller_test.exs
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.StaticFE.StaticFEControllerTest do
6   use Pleroma.Web.ConnCase
7
8   alias Pleroma.Activity
9   alias Pleroma.Web.ActivityPub.Transmogrifier
10   alias Pleroma.Web.ActivityPub.Utils
11   alias Pleroma.Web.CommonAPI
12
13   import Pleroma.Factory
14
15   setup_all do: clear_config([:static_fe, :enabled], true)
16
17   setup %{conn: conn} do
18     conn = put_req_header(conn, "accept", "text/html")
19     user = insert(:user)
20
21     %{conn: conn, user: user}
22   end
23
24   describe "user profile html" do
25     test "just the profile as HTML", %{conn: conn, user: user} do
26       conn = get(conn, "/users/#{user.nickname}")
27
28       assert html_response(conn, 200) =~ user.nickname
29     end
30
31     test "404 when user not found", %{conn: conn} do
32       conn = get(conn, "/users/limpopo")
33
34       assert html_response(conn, 404) =~ "not found"
35     end
36
37     test "profile does not include private messages", %{conn: conn, user: user} do
38       CommonAPI.post(user, %{status: "public"})
39       CommonAPI.post(user, %{status: "private", visibility: "private"})
40
41       conn = get(conn, "/users/#{user.nickname}")
42
43       html = html_response(conn, 200)
44
45       assert html =~ ">public<"
46       refute html =~ ">private<"
47     end
48
49     test "pagination", %{conn: conn, user: user} do
50       Enum.map(1..30, fn i -> CommonAPI.post(user, %{status: "test#{i}"}) end)
51
52       conn = get(conn, "/users/#{user.nickname}")
53
54       html = html_response(conn, 200)
55
56       assert html =~ ">test30<"
57       assert html =~ ">test11<"
58       refute html =~ ">test10<"
59       refute html =~ ">test1<"
60     end
61
62     test "pagination, page 2", %{conn: conn, user: user} do
63       activities = Enum.map(1..30, fn i -> CommonAPI.post(user, %{status: "test#{i}"}) end)
64       {:ok, a11} = Enum.at(activities, 11)
65
66       conn = get(conn, "/users/#{user.nickname}?max_id=#{a11.id}")
67
68       html = html_response(conn, 200)
69
70       assert html =~ ">test1<"
71       assert html =~ ">test10<"
72       refute html =~ ">test20<"
73       refute html =~ ">test29<"
74     end
75
76     test "does not require authentication on non-federating instances", %{
77       conn: conn,
78       user: user
79     } do
80       clear_config([:instance, :federating], false)
81
82       conn = get(conn, "/users/#{user.nickname}")
83
84       assert html_response(conn, 200) =~ user.nickname
85     end
86
87     test "returns 404 for local user with `restrict_unauthenticated/profiles/local` setting", %{
88       conn: conn
89     } do
90       clear_config([:restrict_unauthenticated, :profiles, :local], true)
91
92       local_user = insert(:user, local: true)
93
94       conn
95       |> get("/users/#{local_user.nickname}")
96       |> html_response(404)
97     end
98   end
99
100   describe "notice html" do
101     test "single notice page", %{conn: conn, user: user} do
102       {:ok, activity} = CommonAPI.post(user, %{status: "testing a thing!"})
103
104       conn = get(conn, "/notice/#{activity.id}")
105
106       html = html_response(conn, 200)
107       assert html =~ "<header>"
108       assert html =~ user.nickname
109       assert html =~ "testing a thing!"
110     end
111
112     test "redirects to json if requested", %{conn: conn, user: user} do
113       {:ok, activity} = CommonAPI.post(user, %{status: "testing a thing!"})
114
115       conn =
116         conn
117         |> put_req_header(
118           "accept",
119           "Accept: application/activity+json, application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\", text/html"
120         )
121         |> get("/notice/#{activity.id}")
122
123       assert redirected_to(conn, 302) =~ activity.data["object"]
124     end
125
126     test "filters HTML tags", %{conn: conn} do
127       user = insert(:user)
128       {:ok, activity} = CommonAPI.post(user, %{status: "<script>alert('xss')</script>"})
129
130       conn =
131         conn
132         |> put_req_header("accept", "text/html")
133         |> get("/notice/#{activity.id}")
134
135       html = html_response(conn, 200)
136       assert html =~ ~s[&lt;script&gt;alert(&#39;xss&#39;)&lt;/script&gt;]
137     end
138
139     test "shows the whole thread", %{conn: conn, user: user} do
140       {:ok, activity} = CommonAPI.post(user, %{status: "space: the final frontier"})
141
142       CommonAPI.post(user, %{
143         status: "these are the voyages or something",
144         in_reply_to_status_id: activity.id
145       })
146
147       conn = get(conn, "/notice/#{activity.id}")
148
149       html = html_response(conn, 200)
150       assert html =~ "the final frontier"
151       assert html =~ "voyages"
152     end
153
154     test "redirect by AP object ID", %{conn: conn, user: user} do
155       {:ok, %Activity{data: %{"object" => object_url}}} =
156         CommonAPI.post(user, %{status: "beam me up"})
157
158       conn = get(conn, URI.parse(object_url).path)
159
160       assert html_response(conn, 302) =~ "redirected"
161     end
162
163     test "redirect by activity ID", %{conn: conn, user: user} do
164       {:ok, %Activity{data: %{"id" => id}}} =
165         CommonAPI.post(user, %{status: "I'm a doctor, not a devops!"})
166
167       conn = get(conn, URI.parse(id).path)
168
169       assert html_response(conn, 302) =~ "redirected"
170     end
171
172     test "404 when notice not found", %{conn: conn} do
173       conn = get(conn, "/notice/88c9c317")
174
175       assert html_response(conn, 404) =~ "not found"
176     end
177
178     test "404 for private status", %{conn: conn, user: user} do
179       {:ok, activity} = CommonAPI.post(user, %{status: "don't show me!", visibility: "private"})
180
181       conn = get(conn, "/notice/#{activity.id}")
182
183       assert html_response(conn, 404) =~ "not found"
184     end
185
186     test "302 for remote cached status", %{conn: conn, user: user} do
187       message = %{
188         "@context" => "https://www.w3.org/ns/activitystreams",
189         "type" => "Create",
190         "actor" => user.ap_id,
191         "object" => %{
192           "to" => user.follower_address,
193           "cc" => "https://www.w3.org/ns/activitystreams#Public",
194           "id" => Utils.generate_object_id(),
195           "content" => "blah blah blah",
196           "type" => "Note",
197           "attributedTo" => user.ap_id
198         }
199       }
200
201       assert {:ok, activity} = Transmogrifier.handle_incoming(message)
202
203       conn = get(conn, "/notice/#{activity.id}")
204
205       assert html_response(conn, 302) =~ "redirected"
206     end
207
208     test "does not require authentication on non-federating instances", %{
209       conn: conn,
210       user: user
211     } do
212       clear_config([:instance, :federating], false)
213
214       {:ok, activity} = CommonAPI.post(user, %{status: "testing a thing!"})
215
216       conn = get(conn, "/notice/#{activity.id}")
217
218       assert html_response(conn, 200) =~ "testing a thing!"
219     end
220
221     test "returns 404 for local public activity with `restrict_unauthenticated/activities/local` setting",
222          %{conn: conn, user: user} do
223       clear_config([:restrict_unauthenticated, :activities, :local], true)
224
225       {:ok, activity} = CommonAPI.post(user, %{status: "testing a thing!"})
226
227       conn
228       |> get("/notice/#{activity.id}")
229       |> html_response(404)
230     end
231   end
232 end