little fixes and typos fix
[akkoma] / test / web / admin_api / config_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.Web.AdminAPI.ConfigTest do
6 use Pleroma.DataCase, async: true
7 import Pleroma.Factory
8 alias Pleroma.Web.AdminAPI.Config
9
10 test "get_by_key/1" do
11 config = insert(:config)
12 insert(:config)
13
14 assert config == Config.get_by_params(%{group: config.group, key: config.key})
15 end
16
17 test "create/1" do
18 {:ok, config} = Config.create(%{group: "pleroma", key: "some_key", value: "some_value"})
19 assert config == Config.get_by_params(%{group: "pleroma", key: "some_key"})
20 end
21
22 test "update/1" do
23 config = insert(:config)
24 {:ok, updated} = Config.update(config, %{value: "some_value"})
25 loaded = Config.get_by_params(%{group: config.group, key: config.key})
26 assert loaded == updated
27 end
28
29 describe "update_or_create/1" do
30 test "common" do
31 config = insert(:config)
32 key2 = "another_key"
33
34 params = [
35 %{group: "pleroma", key: key2, value: "another_value"},
36 %{group: config.group, key: config.key, value: "new_value"}
37 ]
38
39 assert Repo.all(Config) |> length() == 1
40
41 Enum.each(params, &Config.update_or_create(&1))
42
43 assert Repo.all(Config) |> length() == 2
44
45 config1 = Config.get_by_params(%{group: config.group, key: config.key})
46 config2 = Config.get_by_params(%{group: "pleroma", key: key2})
47
48 assert config1.value == Config.transform("new_value")
49 assert config2.value == Config.transform("another_value")
50 end
51
52 test "partial update" do
53 config = insert(:config, value: Config.to_binary(key1: "val1", key2: :val2))
54
55 {:ok, _config} =
56 Config.update_or_create(%{
57 group: config.group,
58 key: config.key,
59 value: [key1: :val1, key3: :val3]
60 })
61
62 updated = Config.get_by_params(%{group: config.group, key: config.key})
63
64 value = Config.from_binary(updated.value)
65 assert length(value) == 3
66 assert value[:key1] == :val1
67 assert value[:key2] == :val2
68 assert value[:key3] == :val3
69 end
70
71 test "only full update for some keys" do
72 config1 = insert(:config, key: ":ecto_repos", value: Config.to_binary(repo: Pleroma.Repo))
73 config2 = insert(:config, group: ":cors_plug", key: ":max_age", value: Config.to_binary(18))
74
75 {:ok, _config} =
76 Config.update_or_create(%{
77 group: config1.group,
78 key: config1.key,
79 value: [another_repo: [Pleroma.Repo]]
80 })
81
82 {:ok, _config} =
83 Config.update_or_create(%{
84 group: config2.group,
85 key: config2.key,
86 value: 777
87 })
88
89 updated1 = Config.get_by_params(%{group: config1.group, key: config1.key})
90 updated2 = Config.get_by_params(%{group: config2.group, key: config2.key})
91
92 assert Config.from_binary(updated1.value) == [another_repo: [Pleroma.Repo]]
93 assert Config.from_binary(updated2.value) == 777
94 end
95
96 test "full update if value is not keyword" do
97 config =
98 insert(:config,
99 group: ":tesla",
100 key: ":adapter",
101 value: Config.to_binary(Tesla.Adapter.Hackney)
102 )
103
104 {:ok, _config} =
105 Config.update_or_create(%{
106 group: config.group,
107 key: config.key,
108 value: Tesla.Adapter.Httpc
109 })
110
111 updated = Config.get_by_params(%{group: config.group, key: config.key})
112
113 assert Config.from_binary(updated.value) == Tesla.Adapter.Httpc
114 end
115 end
116
117 test "delete/1" do
118 config = insert(:config)
119 {:ok, _} = Config.delete(%{key: config.key, group: config.group})
120 refute Config.get_by_params(%{key: config.key, group: config.group})
121 end
122
123 describe "transform/1" do
124 test "string" do
125 binary = Config.transform("value as string")
126 assert binary == :erlang.term_to_binary("value as string")
127 assert Config.from_binary(binary) == "value as string"
128 end
129
130 test "boolean" do
131 binary = Config.transform(false)
132 assert binary == :erlang.term_to_binary(false)
133 assert Config.from_binary(binary) == false
134 end
135
136 test "nil" do
137 binary = Config.transform(nil)
138 assert binary == :erlang.term_to_binary(nil)
139 assert Config.from_binary(binary) == nil
140 end
141
142 test "integer" do
143 binary = Config.transform(150)
144 assert binary == :erlang.term_to_binary(150)
145 assert Config.from_binary(binary) == 150
146 end
147
148 test "atom" do
149 binary = Config.transform(":atom")
150 assert binary == :erlang.term_to_binary(:atom)
151 assert Config.from_binary(binary) == :atom
152 end
153
154 test "ssl options" do
155 binary = Config.transform([":tlsv1", ":tlsv1.1", ":tlsv1.2"])
156 assert binary == :erlang.term_to_binary([:tlsv1, :"tlsv1.1", :"tlsv1.2"])
157 assert Config.from_binary(binary) == [:tlsv1, :"tlsv1.1", :"tlsv1.2"]
158 end
159
160 test "pleroma module" do
161 binary = Config.transform("Pleroma.Bookmark")
162 assert binary == :erlang.term_to_binary(Pleroma.Bookmark)
163 assert Config.from_binary(binary) == Pleroma.Bookmark
164 end
165
166 test "pleroma string" do
167 binary = Config.transform("Pleroma")
168 assert binary == :erlang.term_to_binary("Pleroma")
169 assert Config.from_binary(binary) == "Pleroma"
170 end
171
172 test "phoenix module" do
173 binary = Config.transform("Phoenix.Socket.V1.JSONSerializer")
174 assert binary == :erlang.term_to_binary(Phoenix.Socket.V1.JSONSerializer)
175 assert Config.from_binary(binary) == Phoenix.Socket.V1.JSONSerializer
176 end
177
178 test "tesla module" do
179 binary = Config.transform("Tesla.Adapter.Hackney")
180 assert binary == :erlang.term_to_binary(Tesla.Adapter.Hackney)
181 assert Config.from_binary(binary) == Tesla.Adapter.Hackney
182 end
183
184 test "ExSyslogger module" do
185 binary = Config.transform("ExSyslogger")
186 assert binary == :erlang.term_to_binary(ExSyslogger)
187 assert Config.from_binary(binary) == ExSyslogger
188 end
189
190 test "Quack.Logger module" do
191 binary = Config.transform("Quack.Logger")
192 assert binary == :erlang.term_to_binary(Quack.Logger)
193 assert Config.from_binary(binary) == Quack.Logger
194 end
195
196 test "sigil" do
197 binary = Config.transform("~r[comp[lL][aA][iI][nN]er]")
198 assert binary == :erlang.term_to_binary(~r/comp[lL][aA][iI][nN]er/)
199 assert Config.from_binary(binary) == ~r/comp[lL][aA][iI][nN]er/
200 end
201
202 test "link sigil" do
203 binary = Config.transform("~r/https:\/\/example.com/")
204 assert binary == :erlang.term_to_binary(~r/https:\/\/example.com/)
205 assert Config.from_binary(binary) == ~r/https:\/\/example.com/
206 end
207
208 test "link sigil with um modifiers" do
209 binary = Config.transform("~r/https:\/\/example.com/um")
210 assert binary == :erlang.term_to_binary(~r/https:\/\/example.com/um)
211 assert Config.from_binary(binary) == ~r/https:\/\/example.com/um
212 end
213
214 test "link sigil with i modifier" do
215 binary = Config.transform("~r/https:\/\/example.com/i")
216 assert binary == :erlang.term_to_binary(~r/https:\/\/example.com/i)
217 assert Config.from_binary(binary) == ~r/https:\/\/example.com/i
218 end
219
220 test "link sigil with s modifier" do
221 binary = Config.transform("~r/https:\/\/example.com/s")
222 assert binary == :erlang.term_to_binary(~r/https:\/\/example.com/s)
223 assert Config.from_binary(binary) == ~r/https:\/\/example.com/s
224 end
225
226 test "raise if valid delimiter not found" do
227 assert_raise ArgumentError, "valid delimiter for Regex expression not found", fn ->
228 Config.transform("~r/https://[]{}<>\"'()|example.com/s")
229 end
230 end
231
232 test "2 child tuple" do
233 binary = Config.transform(%{"tuple" => ["v1", ":v2"]})
234 assert binary == :erlang.term_to_binary({"v1", :v2})
235 assert Config.from_binary(binary) == {"v1", :v2}
236 end
237
238 test "proxy tuple with localhost" do
239 binary =
240 Config.transform(%{
241 "tuple" => [":proxy_url", %{"tuple" => [":socks5", "localhost", 1234]}]
242 })
243
244 assert binary == :erlang.term_to_binary({:proxy_url, {:socks5, :localhost, 1234}})
245 assert Config.from_binary(binary) == {:proxy_url, {:socks5, :localhost, 1234}}
246 end
247
248 test "proxy tuple with domain" do
249 binary =
250 Config.transform(%{
251 "tuple" => [":proxy_url", %{"tuple" => [":socks5", "domain.com", 1234]}]
252 })
253
254 assert binary == :erlang.term_to_binary({:proxy_url, {:socks5, 'domain.com', 1234}})
255 assert Config.from_binary(binary) == {:proxy_url, {:socks5, 'domain.com', 1234}}
256 end
257
258 test "proxy tuple with ip" do
259 binary =
260 Config.transform(%{
261 "tuple" => [":proxy_url", %{"tuple" => [":socks5", "127.0.0.1", 1234]}]
262 })
263
264 assert binary == :erlang.term_to_binary({:proxy_url, {:socks5, {127, 0, 0, 1}, 1234}})
265 assert Config.from_binary(binary) == {:proxy_url, {:socks5, {127, 0, 0, 1}, 1234}}
266 end
267
268 test "tuple with n childs" do
269 binary =
270 Config.transform(%{
271 "tuple" => [
272 "v1",
273 ":v2",
274 "Pleroma.Bookmark",
275 150,
276 false,
277 "Phoenix.Socket.V1.JSONSerializer"
278 ]
279 })
280
281 assert binary ==
282 :erlang.term_to_binary(
283 {"v1", :v2, Pleroma.Bookmark, 150, false, Phoenix.Socket.V1.JSONSerializer}
284 )
285
286 assert Config.from_binary(binary) ==
287 {"v1", :v2, Pleroma.Bookmark, 150, false, Phoenix.Socket.V1.JSONSerializer}
288 end
289
290 test "tuple with dispatch key" do
291 binary = Config.transform(%{"tuple" => [":dispatch", ["{:_,
292 [
293 {\"/api/v1/streaming\", Pleroma.Web.MastodonAPI.WebsocketHandler, []},
294 {\"/websocket\", Phoenix.Endpoint.CowboyWebSocket,
295 {Phoenix.Transports.WebSocket,
296 {Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, [path: \"/websocket\"]}}},
297 {:_, Phoenix.Endpoint.Cowboy2Handler, {Pleroma.Web.Endpoint, []}}
298 ]}"]]})
299
300 assert binary ==
301 :erlang.term_to_binary(
302 {:dispatch,
303 [
304 {:_,
305 [
306 {"/api/v1/streaming", Pleroma.Web.MastodonAPI.WebsocketHandler, []},
307 {"/websocket", Phoenix.Endpoint.CowboyWebSocket,
308 {Phoenix.Transports.WebSocket,
309 {Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, [path: "/websocket"]}}},
310 {:_, Phoenix.Endpoint.Cowboy2Handler, {Pleroma.Web.Endpoint, []}}
311 ]}
312 ]}
313 )
314
315 assert Config.from_binary(binary) ==
316 {:dispatch,
317 [
318 {:_,
319 [
320 {"/api/v1/streaming", Pleroma.Web.MastodonAPI.WebsocketHandler, []},
321 {"/websocket", Phoenix.Endpoint.CowboyWebSocket,
322 {Phoenix.Transports.WebSocket,
323 {Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, [path: "/websocket"]}}},
324 {:_, Phoenix.Endpoint.Cowboy2Handler, {Pleroma.Web.Endpoint, []}}
325 ]}
326 ]}
327 end
328
329 test "map with string key" do
330 binary = Config.transform(%{"key" => "value"})
331 assert binary == :erlang.term_to_binary(%{"key" => "value"})
332 assert Config.from_binary(binary) == %{"key" => "value"}
333 end
334
335 test "map with atom key" do
336 binary = Config.transform(%{":key" => "value"})
337 assert binary == :erlang.term_to_binary(%{key: "value"})
338 assert Config.from_binary(binary) == %{key: "value"}
339 end
340
341 test "list of strings" do
342 binary = Config.transform(["v1", "v2", "v3"])
343 assert binary == :erlang.term_to_binary(["v1", "v2", "v3"])
344 assert Config.from_binary(binary) == ["v1", "v2", "v3"]
345 end
346
347 test "list of modules" do
348 binary = Config.transform(["Pleroma.Repo", "Pleroma.Activity"])
349 assert binary == :erlang.term_to_binary([Pleroma.Repo, Pleroma.Activity])
350 assert Config.from_binary(binary) == [Pleroma.Repo, Pleroma.Activity]
351 end
352
353 test "list of atoms" do
354 binary = Config.transform([":v1", ":v2", ":v3"])
355 assert binary == :erlang.term_to_binary([:v1, :v2, :v3])
356 assert Config.from_binary(binary) == [:v1, :v2, :v3]
357 end
358
359 test "list of mixed values" do
360 binary =
361 Config.transform([
362 "v1",
363 ":v2",
364 "Pleroma.Repo",
365 "Phoenix.Socket.V1.JSONSerializer",
366 15,
367 false
368 ])
369
370 assert binary ==
371 :erlang.term_to_binary([
372 "v1",
373 :v2,
374 Pleroma.Repo,
375 Phoenix.Socket.V1.JSONSerializer,
376 15,
377 false
378 ])
379
380 assert Config.from_binary(binary) == [
381 "v1",
382 :v2,
383 Pleroma.Repo,
384 Phoenix.Socket.V1.JSONSerializer,
385 15,
386 false
387 ]
388 end
389
390 test "simple keyword" do
391 binary = Config.transform([%{"tuple" => [":key", "value"]}])
392 assert binary == :erlang.term_to_binary([{:key, "value"}])
393 assert Config.from_binary(binary) == [{:key, "value"}]
394 assert Config.from_binary(binary) == [key: "value"]
395 end
396
397 test "keyword with partial_chain key" do
398 binary =
399 Config.transform([%{"tuple" => [":partial_chain", "&:hackney_connect.partial_chain/1"]}])
400
401 assert binary == :erlang.term_to_binary(partial_chain: &:hackney_connect.partial_chain/1)
402 assert Config.from_binary(binary) == [partial_chain: &:hackney_connect.partial_chain/1]
403 end
404
405 test "keyword" do
406 binary =
407 Config.transform([
408 %{"tuple" => [":types", "Pleroma.PostgresTypes"]},
409 %{"tuple" => [":telemetry_event", ["Pleroma.Repo.Instrumenter"]]},
410 %{"tuple" => [":migration_lock", nil]},
411 %{"tuple" => [":key1", 150]},
412 %{"tuple" => [":key2", "string"]}
413 ])
414
415 assert binary ==
416 :erlang.term_to_binary(
417 types: Pleroma.PostgresTypes,
418 telemetry_event: [Pleroma.Repo.Instrumenter],
419 migration_lock: nil,
420 key1: 150,
421 key2: "string"
422 )
423
424 assert Config.from_binary(binary) == [
425 types: Pleroma.PostgresTypes,
426 telemetry_event: [Pleroma.Repo.Instrumenter],
427 migration_lock: nil,
428 key1: 150,
429 key2: "string"
430 ]
431 end
432
433 test "complex keyword with nested mixed childs" do
434 binary =
435 Config.transform([
436 %{"tuple" => [":uploader", "Pleroma.Uploaders.Local"]},
437 %{"tuple" => [":filters", ["Pleroma.Upload.Filter.Dedupe"]]},
438 %{"tuple" => [":link_name", true]},
439 %{"tuple" => [":proxy_remote", false]},
440 %{"tuple" => [":common_map", %{":key" => "value"}]},
441 %{
442 "tuple" => [
443 ":proxy_opts",
444 [
445 %{"tuple" => [":redirect_on_failure", false]},
446 %{"tuple" => [":max_body_length", 1_048_576]},
447 %{
448 "tuple" => [
449 ":http",
450 [%{"tuple" => [":follow_redirect", true]}, %{"tuple" => [":pool", ":upload"]}]
451 ]
452 }
453 ]
454 ]
455 }
456 ])
457
458 assert binary ==
459 :erlang.term_to_binary(
460 uploader: Pleroma.Uploaders.Local,
461 filters: [Pleroma.Upload.Filter.Dedupe],
462 link_name: true,
463 proxy_remote: false,
464 common_map: %{key: "value"},
465 proxy_opts: [
466 redirect_on_failure: false,
467 max_body_length: 1_048_576,
468 http: [
469 follow_redirect: true,
470 pool: :upload
471 ]
472 ]
473 )
474
475 assert Config.from_binary(binary) ==
476 [
477 uploader: Pleroma.Uploaders.Local,
478 filters: [Pleroma.Upload.Filter.Dedupe],
479 link_name: true,
480 proxy_remote: false,
481 common_map: %{key: "value"},
482 proxy_opts: [
483 redirect_on_failure: false,
484 max_body_length: 1_048_576,
485 http: [
486 follow_redirect: true,
487 pool: :upload
488 ]
489 ]
490 ]
491 end
492
493 test "common keyword" do
494 binary =
495 Config.transform([
496 %{"tuple" => [":level", ":warn"]},
497 %{"tuple" => [":meta", [":all"]]},
498 %{"tuple" => [":path", ""]},
499 %{"tuple" => [":val", nil]},
500 %{"tuple" => [":webhook_url", "https://hooks.slack.com/services/YOUR-KEY-HERE"]}
501 ])
502
503 assert binary ==
504 :erlang.term_to_binary(
505 level: :warn,
506 meta: [:all],
507 path: "",
508 val: nil,
509 webhook_url: "https://hooks.slack.com/services/YOUR-KEY-HERE"
510 )
511
512 assert Config.from_binary(binary) == [
513 level: :warn,
514 meta: [:all],
515 path: "",
516 val: nil,
517 webhook_url: "https://hooks.slack.com/services/YOUR-KEY-HERE"
518 ]
519 end
520
521 test "complex keyword with sigil" do
522 binary =
523 Config.transform([
524 %{"tuple" => [":federated_timeline_removal", []]},
525 %{"tuple" => [":reject", ["~r/comp[lL][aA][iI][nN]er/"]]},
526 %{"tuple" => [":replace", []]}
527 ])
528
529 assert binary ==
530 :erlang.term_to_binary(
531 federated_timeline_removal: [],
532 reject: [~r/comp[lL][aA][iI][nN]er/],
533 replace: []
534 )
535
536 assert Config.from_binary(binary) ==
537 [federated_timeline_removal: [], reject: [~r/comp[lL][aA][iI][nN]er/], replace: []]
538 end
539
540 test "complex keyword with tuples with more than 2 values" do
541 binary =
542 Config.transform([
543 %{
544 "tuple" => [
545 ":http",
546 [
547 %{
548 "tuple" => [
549 ":key1",
550 [
551 %{
552 "tuple" => [
553 ":_",
554 [
555 %{
556 "tuple" => [
557 "/api/v1/streaming",
558 "Pleroma.Web.MastodonAPI.WebsocketHandler",
559 []
560 ]
561 },
562 %{
563 "tuple" => [
564 "/websocket",
565 "Phoenix.Endpoint.CowboyWebSocket",
566 %{
567 "tuple" => [
568 "Phoenix.Transports.WebSocket",
569 %{
570 "tuple" => [
571 "Pleroma.Web.Endpoint",
572 "Pleroma.Web.UserSocket",
573 []
574 ]
575 }
576 ]
577 }
578 ]
579 },
580 %{
581 "tuple" => [
582 ":_",
583 "Phoenix.Endpoint.Cowboy2Handler",
584 %{"tuple" => ["Pleroma.Web.Endpoint", []]}
585 ]
586 }
587 ]
588 ]
589 }
590 ]
591 ]
592 }
593 ]
594 ]
595 }
596 ])
597
598 assert binary ==
599 :erlang.term_to_binary(
600 http: [
601 key1: [
602 _: [
603 {"/api/v1/streaming", Pleroma.Web.MastodonAPI.WebsocketHandler, []},
604 {"/websocket", Phoenix.Endpoint.CowboyWebSocket,
605 {Phoenix.Transports.WebSocket,
606 {Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, []}}},
607 {:_, Phoenix.Endpoint.Cowboy2Handler, {Pleroma.Web.Endpoint, []}}
608 ]
609 ]
610 ]
611 )
612
613 assert Config.from_binary(binary) == [
614 http: [
615 key1: [
616 {:_,
617 [
618 {"/api/v1/streaming", Pleroma.Web.MastodonAPI.WebsocketHandler, []},
619 {"/websocket", Phoenix.Endpoint.CowboyWebSocket,
620 {Phoenix.Transports.WebSocket,
621 {Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, []}}},
622 {:_, Phoenix.Endpoint.Cowboy2Handler, {Pleroma.Web.Endpoint, []}}
623 ]}
624 ]
625 ]
626 ]
627 end
628 end
629 end