First
[anni] / test / pleroma / web / mastodon_api / controllers / subscription_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.MastodonAPI.SubscriptionControllerTest do
6   use Pleroma.Web.ConnCase, async: true
7
8   import Pleroma.Factory
9
10   alias Pleroma.Web.Push
11   alias Pleroma.Web.Push.Subscription
12
13   @sub %{
14     "endpoint" => "https://example.com/example/1234",
15     "keys" => %{
16       "auth" => "8eDyX_uCN0XRhSbY5hs7Hg==",
17       "p256dh" =>
18         "BCIWgsnyXDv1VkhqL2P7YRBvdeuDnlwAPT2guNhdIoW3IP7GmHh1SMKPLxRf7x8vJy6ZFK3ol2ohgn_-0yP7QQA="
19     }
20   }
21   @server_key Keyword.get(Push.vapid_config(), :public_key)
22
23   setup do
24     user = insert(:user)
25     token = insert(:oauth_token, user: user, scopes: ["push"])
26
27     conn =
28       build_conn()
29       |> assign(:user, user)
30       |> assign(:token, token)
31       |> put_req_header("content-type", "application/json")
32
33     %{conn: conn, user: user, token: token}
34   end
35
36   defmacro assert_error_when_disable_push(do: yield) do
37     quote do
38       vapid_details = Application.get_env(:web_push_encryption, :vapid_details, [])
39       Application.put_env(:web_push_encryption, :vapid_details, [])
40
41       assert %{"error" => "Web push subscription is disabled on this Pleroma instance"} ==
42                unquote(yield)
43
44       Application.put_env(:web_push_encryption, :vapid_details, vapid_details)
45     end
46   end
47
48   describe "when disabled" do
49     test "POST returns error", %{conn: conn} do
50       assert_error_when_disable_push do
51         conn
52         |> post("/api/v1/push/subscription", %{
53           "data" => %{"alerts" => %{"mention" => true}},
54           "subscription" => @sub
55         })
56         |> json_response_and_validate_schema(403)
57       end
58     end
59
60     test "GET returns error", %{conn: conn} do
61       assert_error_when_disable_push do
62         conn
63         |> get("/api/v1/push/subscription", %{})
64         |> json_response_and_validate_schema(403)
65       end
66     end
67
68     test "PUT returns error", %{conn: conn} do
69       assert_error_when_disable_push do
70         conn
71         |> put("/api/v1/push/subscription", %{data: %{"alerts" => %{"mention" => false}}})
72         |> json_response_and_validate_schema(403)
73       end
74     end
75
76     test "DELETE returns error", %{conn: conn} do
77       assert_error_when_disable_push do
78         conn
79         |> delete("/api/v1/push/subscription", %{})
80         |> json_response_and_validate_schema(403)
81       end
82     end
83   end
84
85   describe "creates push subscription" do
86     test "ignores unsupported types", %{conn: conn} do
87       result =
88         conn
89         |> post("/api/v1/push/subscription", %{
90           "data" => %{
91             "alerts" => %{
92               "fake_unsupported_type" => true
93             }
94           },
95           "subscription" => @sub
96         })
97         |> json_response_and_validate_schema(200)
98
99       refute %{
100                "alerts" => %{
101                  "fake_unsupported_type" => true
102                }
103              } == result
104     end
105
106     test "successful creation", %{conn: conn} do
107       result =
108         conn
109         |> post("/api/v1/push/subscription", %{
110           "data" => %{
111             "alerts" => %{
112               "mention" => true,
113               "favourite" => true,
114               "follow" => true,
115               "reblog" => true,
116               "pleroma:chat_mention" => true,
117               "pleroma:emoji_reaction" => true
118             }
119           },
120           "subscription" => @sub
121         })
122         |> json_response_and_validate_schema(200)
123
124       [subscription] = Pleroma.Repo.all(Subscription)
125
126       assert %{
127                "alerts" => %{
128                  "mention" => true,
129                  "favourite" => true,
130                  "follow" => true,
131                  "reblog" => true,
132                  "pleroma:chat_mention" => true,
133                  "pleroma:emoji_reaction" => true
134                },
135                "endpoint" => subscription.endpoint,
136                "id" => to_string(subscription.id),
137                "server_key" => @server_key
138              } == result
139     end
140   end
141
142   describe "gets a user subscription" do
143     test "returns error when user hasn't subscription", %{conn: conn} do
144       res =
145         conn
146         |> get("/api/v1/push/subscription", %{})
147         |> json_response_and_validate_schema(404)
148
149       assert %{"error" => "Record not found"} == res
150     end
151
152     test "returns a user subsciption", %{conn: conn, user: user, token: token} do
153       subscription =
154         insert(:push_subscription,
155           user: user,
156           token: token,
157           data: %{"alerts" => %{"mention" => true}}
158         )
159
160       res =
161         conn
162         |> get("/api/v1/push/subscription", %{})
163         |> json_response_and_validate_schema(200)
164
165       expect = %{
166         "alerts" => %{"mention" => true},
167         "endpoint" => "https://example.com/example/1234",
168         "id" => to_string(subscription.id),
169         "server_key" => @server_key
170       }
171
172       assert expect == res
173     end
174   end
175
176   describe "updates a user subsciption" do
177     setup %{conn: conn, user: user, token: token} do
178       subscription =
179         insert(:push_subscription,
180           user: user,
181           token: token,
182           data: %{
183             "alerts" => %{
184               "mention" => true,
185               "favourite" => true,
186               "follow" => true,
187               "reblog" => true,
188               "pleroma:chat_mention" => true,
189               "pleroma:emoji_reaction" => true
190             }
191           }
192         )
193
194       %{conn: conn, user: user, token: token, subscription: subscription}
195     end
196
197     test "returns updated subsciption", %{conn: conn, subscription: subscription} do
198       res =
199         conn
200         |> put("/api/v1/push/subscription", %{
201           data: %{
202             "alerts" => %{
203               "mention" => false,
204               "favourite" => false,
205               "follow" => false,
206               "reblog" => false,
207               "pleroma:chat_mention" => false,
208               "pleroma:emoji_reaction" => false
209             }
210           }
211         })
212         |> json_response_and_validate_schema(200)
213
214       expect = %{
215         "alerts" => %{
216           "mention" => false,
217           "favourite" => false,
218           "follow" => false,
219           "reblog" => false,
220           "pleroma:chat_mention" => false,
221           "pleroma:emoji_reaction" => false
222         },
223         "endpoint" => "https://example.com/example/1234",
224         "id" => to_string(subscription.id),
225         "server_key" => @server_key
226       }
227
228       assert expect == res
229     end
230   end
231
232   describe "deletes the user subscription" do
233     test "returns error when user hasn't subscription", %{conn: conn} do
234       res =
235         conn
236         |> delete("/api/v1/push/subscription", %{})
237         |> json_response_and_validate_schema(404)
238
239       assert %{"error" => "Record not found"} == res
240     end
241
242     test "returns empty result and delete user subsciption", %{
243       conn: conn,
244       user: user,
245       token: token
246     } do
247       subscription =
248         insert(:push_subscription,
249           user: user,
250           token: token,
251           data: %{"alerts" => %{"mention" => true}}
252         )
253
254       res =
255         conn
256         |> delete("/api/v1/push/subscription", %{})
257         |> json_response_and_validate_schema(200)
258
259       assert %{} == res
260       refute Pleroma.Repo.get(Subscription, subscription.id)
261     end
262   end
263 end