admin_api_controller_test.exs 81.4 KB
Newer Older
kaniini's avatar
kaniini committed
1
# Pleroma: A lightweight social networking server
2
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
kaniini's avatar
kaniini committed
3 4
# SPDX-License-Identifier: AGPL-3.0-only

5 6
defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
  use Pleroma.Web.ConnCase
7
  use Oban.Testing, repo: Pleroma.Repo
8

Sergey Suprunenko's avatar
Sergey Suprunenko committed
9
  alias Pleroma.Activity
Maxim Filippov's avatar
Maxim Filippov committed
10
  alias Pleroma.HTML
Maxim Filippov's avatar
Maxim Filippov committed
11 12
  alias Pleroma.ModerationLog
  alias Pleroma.Repo
13
  alias Pleroma.Tests.ObanHelpers
Haelwenn's avatar
Haelwenn committed
14
  alias Pleroma.User
15
  alias Pleroma.UserInviteToken
Sergey Suprunenko's avatar
Sergey Suprunenko committed
16
  alias Pleroma.Web.CommonAPI
17
  alias Pleroma.Web.MediaProxy
18 19
  import Pleroma.Factory

20 21 22 23 24 25
  setup_all do
    Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)

    :ok
  end

26 27
  describe "DELETE /api/pleroma/admin/users" do
    test "single user" do
28
      admin = insert(:user, is_admin: true)
29 30 31 32 33 34
      user = insert(:user)

      conn =
        build_conn()
        |> assign(:user, admin)
        |> put_req_header("accept", "application/json")
Sachin Joshi's avatar
Sachin Joshi committed
35
        |> delete("/api/pleroma/admin/users?nickname=#{user.nickname}")
36

Maxim Filippov's avatar
Maxim Filippov committed
37 38 39
      log_entry = Repo.one(ModerationLog)

      assert ModerationLog.get_log_entry_message(log_entry) ==
40
               "@#{admin.nickname} deleted users: @#{user.nickname}"
Maxim Filippov's avatar
Maxim Filippov committed
41

42 43 44
      assert json_response(conn, 200) == user.nickname
    end

45
    test "multiple users" do
46
      admin = insert(:user, is_admin: true)
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
      user_one = insert(:user)
      user_two = insert(:user)

      conn =
        build_conn()
        |> assign(:user, admin)
        |> put_req_header("accept", "application/json")
        |> delete("/api/pleroma/admin/users", %{
          nicknames: [user_one.nickname, user_two.nickname]
        })

      log_entry = Repo.one(ModerationLog)

      assert ModerationLog.get_log_entry_message(log_entry) ==
               "@#{admin.nickname} deleted users: @#{user_one.nickname}, @#{user_two.nickname}"

      response = json_response(conn, 200)
      assert response -- [user_one.nickname, user_two.nickname] == []
    end
  end

  describe "/api/pleroma/admin/users" do
69
    test "Create" do
70
      admin = insert(:user, is_admin: true)
71 72 73 74 75

      conn =
        build_conn()
        |> assign(:user, admin)
        |> put_req_header("accept", "application/json")
Sachin Joshi's avatar
Sachin Joshi committed
76
        |> post("/api/pleroma/admin/users", %{
77 78 79 80 81
          "users" => [
            %{
              "nickname" => "lain",
              "email" => "lain@example.org",
              "password" => "test"
82 83 84 85 86
            },
            %{
              "nickname" => "lain2",
              "email" => "lain2@example.org",
              "password" => "test"
87 88
            }
          ]
89 90
        })

91 92
      response = json_response(conn, 200) |> Enum.map(&Map.get(&1, "type"))
      assert response == ["success", "success"]
Maxim Filippov's avatar
Maxim Filippov committed
93 94 95

      log_entry = Repo.one(ModerationLog)

Maxim Filippov's avatar
Maxim Filippov committed
96
      assert ["lain", "lain2"] -- Enum.map(log_entry.data["subjects"], & &1["nickname"]) == []
97 98 99
    end

    test "Cannot create user with exisiting email" do
100
      admin = insert(:user, is_admin: true)
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
      user = insert(:user)

      conn =
        build_conn()
        |> assign(:user, admin)
        |> put_req_header("accept", "application/json")
        |> post("/api/pleroma/admin/users", %{
          "users" => [
            %{
              "nickname" => "lain",
              "email" => user.email,
              "password" => "test"
            }
          ]
        })

117
      assert json_response(conn, 409) == [
118 119 120 121 122 123 124 125 126 127 128 129 130
               %{
                 "code" => 409,
                 "data" => %{
                   "email" => user.email,
                   "nickname" => "lain"
                 },
                 "error" => "email has already been taken",
                 "type" => "error"
               }
             ]
    end

    test "Cannot create user with exisiting nickname" do
131
      admin = insert(:user, is_admin: true)
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
      user = insert(:user)

      conn =
        build_conn()
        |> assign(:user, admin)
        |> put_req_header("accept", "application/json")
        |> post("/api/pleroma/admin/users", %{
          "users" => [
            %{
              "nickname" => user.nickname,
              "email" => "someuser@plerama.social",
              "password" => "test"
            }
          ]
        })

148
      assert json_response(conn, 409) == [
149 150 151 152 153 154 155 156 157 158
               %{
                 "code" => 409,
                 "data" => %{
                   "email" => "someuser@plerama.social",
                   "nickname" => user.nickname
                 },
                 "error" => "nickname has already been taken",
                 "type" => "error"
               }
             ]
159
    end
160 161

    test "Multiple user creation works in transaction" do
162
      admin = insert(:user, is_admin: true)
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
      user = insert(:user)

      conn =
        build_conn()
        |> assign(:user, admin)
        |> put_req_header("accept", "application/json")
        |> post("/api/pleroma/admin/users", %{
          "users" => [
            %{
              "nickname" => "newuser",
              "email" => "newuser@pleroma.social",
              "password" => "test"
            },
            %{
              "nickname" => "lain",
              "email" => user.email,
              "password" => "test"
            }
          ]
        })

      assert json_response(conn, 409) == [
               %{
                 "code" => 409,
                 "data" => %{
                   "email" => user.email,
                   "nickname" => "lain"
                 },
                 "error" => "email has already been taken",
                 "type" => "error"
               },
               %{
                 "code" => 409,
                 "data" => %{
                   "email" => "newuser@pleroma.social",
                   "nickname" => "newuser"
                 },
                 "error" => "",
                 "type" => "error"
               }
             ]

      assert User.get_by_nickname("newuser") === nil
206 207 208
    end
  end

209 210
  describe "/api/pleroma/admin/users/:nickname" do
    test "Show", %{conn: conn} do
211
      admin = insert(:user, is_admin: true)
212 213 214 215 216 217 218 219 220 221 222 223 224
      user = insert(:user)

      conn =
        conn
        |> assign(:user, admin)
        |> get("/api/pleroma/admin/users/#{user.nickname}")

      expected = %{
        "deactivated" => false,
        "id" => to_string(user.id),
        "local" => true,
        "nickname" => user.nickname,
        "roles" => %{"admin" => false, "moderator" => false},
225 226 227
        "tags" => [],
        "avatar" => User.avatar_url(user) |> MediaProxy.url(),
        "display_name" => HTML.strip_tags(user.name || user.nickname)
228 229 230 231 232 233
      }

      assert expected == json_response(conn, 200)
    end

    test "when the user doesn't exist", %{conn: conn} do
234
      admin = insert(:user, is_admin: true)
235 236 237 238 239 240 241 242 243 244 245
      user = build(:user)

      conn =
        conn
        |> assign(:user, admin)
        |> get("/api/pleroma/admin/users/#{user.nickname}")

      assert "Not found" == json_response(conn, 404)
    end
  end

Sachin Joshi's avatar
Sachin Joshi committed
246
  describe "/api/pleroma/admin/users/follow" do
247
    test "allows to force-follow another user" do
248
      admin = insert(:user, is_admin: true)
249 250 251
      user = insert(:user)
      follower = insert(:user)

252 253 254
      build_conn()
      |> assign(:user, admin)
      |> put_req_header("accept", "application/json")
Sachin Joshi's avatar
Sachin Joshi committed
255
      |> post("/api/pleroma/admin/users/follow", %{
256 257 258
        "follower" => follower.nickname,
        "followed" => user.nickname
      })
259

minibikini's avatar
minibikini committed
260 261
      user = User.get_cached_by_id(user.id)
      follower = User.get_cached_by_id(follower.id)
262 263

      assert User.following?(follower, user)
Maxim Filippov's avatar
Maxim Filippov committed
264 265 266 267 268

      log_entry = Repo.one(ModerationLog)

      assert ModerationLog.get_log_entry_message(log_entry) ==
               "@#{admin.nickname} made @#{follower.nickname} follow @#{user.nickname}"
269 270 271
    end
  end

Sachin Joshi's avatar
Sachin Joshi committed
272
  describe "/api/pleroma/admin/users/unfollow" do
273
    test "allows to force-unfollow another user" do
274
      admin = insert(:user, is_admin: true)
275 276 277 278 279
      user = insert(:user)
      follower = insert(:user)

      User.follow(follower, user)

280 281 282
      build_conn()
      |> assign(:user, admin)
      |> put_req_header("accept", "application/json")
Sachin Joshi's avatar
Sachin Joshi committed
283
      |> post("/api/pleroma/admin/users/unfollow", %{
284 285 286
        "follower" => follower.nickname,
        "followed" => user.nickname
      })
287

minibikini's avatar
minibikini committed
288 289
      user = User.get_cached_by_id(user.id)
      follower = User.get_cached_by_id(follower.id)
290 291

      refute User.following?(follower, user)
Maxim Filippov's avatar
Maxim Filippov committed
292 293 294 295 296

      log_entry = Repo.one(ModerationLog)

      assert ModerationLog.get_log_entry_message(log_entry) ==
               "@#{admin.nickname} made @#{follower.nickname} unfollow @#{user.nickname}"
297 298 299
    end
  end

300
  describe "PUT /api/pleroma/admin/users/tag" do
301
    setup do
302
      admin = insert(:user, is_admin: true)
303 304 305 306 307 308 309 310
      user1 = insert(:user, %{tags: ["x"]})
      user2 = insert(:user, %{tags: ["y"]})
      user3 = insert(:user, %{tags: ["unchanged"]})

      conn =
        build_conn()
        |> assign(:user, admin)
        |> put_req_header("accept", "application/json")
Ivan Tashkinov's avatar
Ivan Tashkinov committed
311 312 313 314 315
        |> put(
          "/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=#{
            user2.nickname
          }&tags[]=foo&tags[]=bar"
        )
316

Maxim Filippov's avatar
Maxim Filippov committed
317
      %{conn: conn, admin: admin, user1: user1, user2: user2, user3: user3}
318 319
    end

Ivan Tashkinov's avatar
Ivan Tashkinov committed
320 321
    test "it appends specified tags to users with specified nicknames", %{
      conn: conn,
Maxim Filippov's avatar
Maxim Filippov committed
322
      admin: admin,
Ivan Tashkinov's avatar
Ivan Tashkinov committed
323 324 325
      user1: user1,
      user2: user2
    } do
326
      assert json_response(conn, :no_content)
minibikini's avatar
minibikini committed
327 328
      assert User.get_cached_by_id(user1.id).tags == ["x", "foo", "bar"]
      assert User.get_cached_by_id(user2.id).tags == ["y", "foo", "bar"]
Maxim Filippov's avatar
Maxim Filippov committed
329 330 331 332 333 334 335 336 337 338 339 340

      log_entry = Repo.one(ModerationLog)

      users =
        [user1.nickname, user2.nickname]
        |> Enum.map(&"@#{&1}")
        |> Enum.join(", ")

      tags = ["foo", "bar"] |> Enum.join(", ")

      assert ModerationLog.get_log_entry_message(log_entry) ==
               "@#{admin.nickname} added tags: #{tags} to users: #{users}"
341 342 343 344
    end

    test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do
      assert json_response(conn, :no_content)
minibikini's avatar
minibikini committed
345
      assert User.get_cached_by_id(user3.id).tags == ["unchanged"]
346 347 348
    end
  end

349
  describe "DELETE /api/pleroma/admin/users/tag" do
350
    setup do
351
      admin = insert(:user, is_admin: true)
352 353 354 355 356 357 358 359
      user1 = insert(:user, %{tags: ["x"]})
      user2 = insert(:user, %{tags: ["y", "z"]})
      user3 = insert(:user, %{tags: ["unchanged"]})

      conn =
        build_conn()
        |> assign(:user, admin)
        |> put_req_header("accept", "application/json")
360 361
        |> delete(
          "/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=#{
Ivan Tashkinov's avatar
Ivan Tashkinov committed
362 363 364
            user2.nickname
          }&tags[]=x&tags[]=z"
        )
365

Maxim Filippov's avatar
Maxim Filippov committed
366
      %{conn: conn, admin: admin, user1: user1, user2: user2, user3: user3}
367 368
    end

Ivan Tashkinov's avatar
Ivan Tashkinov committed
369 370
    test "it removes specified tags from users with specified nicknames", %{
      conn: conn,
Maxim Filippov's avatar
Maxim Filippov committed
371
      admin: admin,
Ivan Tashkinov's avatar
Ivan Tashkinov committed
372 373 374
      user1: user1,
      user2: user2
    } do
375
      assert json_response(conn, :no_content)
minibikini's avatar
minibikini committed
376 377
      assert User.get_cached_by_id(user1.id).tags == []
      assert User.get_cached_by_id(user2.id).tags == ["y"]
Maxim Filippov's avatar
Maxim Filippov committed
378 379 380 381 382 383 384 385 386 387 388 389

      log_entry = Repo.one(ModerationLog)

      users =
        [user1.nickname, user2.nickname]
        |> Enum.map(&"@#{&1}")
        |> Enum.join(", ")

      tags = ["x", "z"] |> Enum.join(", ")

      assert ModerationLog.get_log_entry_message(log_entry) ==
               "@#{admin.nickname} removed tags: #{tags} from users: #{users}"
390 391 392 393
    end

    test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do
      assert json_response(conn, :no_content)
minibikini's avatar
minibikini committed
394
      assert User.get_cached_by_id(user3.id).tags == ["unchanged"]
395 396 397
    end
  end

Sachin Joshi's avatar
Sachin Joshi committed
398
  describe "/api/pleroma/admin/users/:nickname/permission_group" do
399
    test "GET is giving user_info" do
400
      admin = insert(:user, is_admin: true)
401 402 403 404 405

      conn =
        build_conn()
        |> assign(:user, admin)
        |> put_req_header("accept", "application/json")
Sachin Joshi's avatar
Sachin Joshi committed
406
        |> get("/api/pleroma/admin/users/#{admin.nickname}/permission_group/")
407

lain's avatar
lain committed
408 409 410 411
      assert json_response(conn, 200) == %{
               "is_admin" => true,
               "is_moderator" => false
             }
412 413 414
    end

    test "/:right POST, can add to a permission group" do
415
      admin = insert(:user, is_admin: true)
416 417 418 419 420 421
      user = insert(:user)

      conn =
        build_conn()
        |> assign(:user, admin)
        |> put_req_header("accept", "application/json")
Sachin Joshi's avatar
Sachin Joshi committed
422
        |> post("/api/pleroma/admin/users/#{user.nickname}/permission_group/admin")
423

lain's avatar
lain committed
424 425 426
      assert json_response(conn, 200) == %{
               "is_admin" => true
             }
Maxim Filippov's avatar
Maxim Filippov committed
427 428 429 430 431

      log_entry = Repo.one(ModerationLog)

      assert ModerationLog.get_log_entry_message(log_entry) ==
               "@#{admin.nickname} made @#{user.nickname} admin"
432 433
    end

Maxim Filippov's avatar
Maxim Filippov committed
434
    test "/:right POST, can add to a permission group (multiple)" do
435
      admin = insert(:user, is_admin: true)
436 437
      user_one = insert(:user)
      user_two = insert(:user)
438 439 440 441 442

      conn =
        build_conn()
        |> assign(:user, admin)
        |> put_req_header("accept", "application/json")
443 444 445
        |> post("/api/pleroma/admin/users/permission_group/admin", %{
          nicknames: [user_one.nickname, user_two.nickname]
        })
446

lain's avatar
lain committed
447 448 449
      assert json_response(conn, 200) == %{
               "is_admin" => true
             }
Maxim Filippov's avatar
Maxim Filippov committed
450 451 452 453

      log_entry = Repo.one(ModerationLog)

      assert ModerationLog.get_log_entry_message(log_entry) ==
454
               "@#{admin.nickname} made @#{user_one.nickname}, @#{user_two.nickname} admin"
455 456 457
    end

    test "/:right DELETE, can remove from a permission group" do
458
      admin = insert(:user, is_admin: true)
459
      user = insert(:user, is_admin: true)
460 461

      conn =
Maxim Filippov's avatar
Maxim Filippov committed
462
        build_conn()
463 464
        |> assign(:user, admin)
        |> put_req_header("accept", "application/json")
Maxim Filippov's avatar
Maxim Filippov committed
465
        |> delete("/api/pleroma/admin/users/#{user.nickname}/permission_group/admin")
466

Maxim Filippov's avatar
Maxim Filippov committed
467 468 469
      assert json_response(conn, 200) == %{
               "is_admin" => false
             }
Maxim Filippov's avatar
Maxim Filippov committed
470 471 472 473

      log_entry = Repo.one(ModerationLog)

      assert ModerationLog.get_log_entry_message(log_entry) ==
Maxim Filippov's avatar
Maxim Filippov committed
474
               "@#{admin.nickname} revoked admin role from @#{user.nickname}"
475 476
    end

Maxim Filippov's avatar
Maxim Filippov committed
477
    test "/:right DELETE, can remove from a permission group (multiple)" do
478 479 480
      admin = insert(:user, is_admin: true)
      user_one = insert(:user, is_admin: true)
      user_two = insert(:user, is_admin: true)
481 482

      conn =
483 484 485
        build_conn()
        |> assign(:user, admin)
        |> put_req_header("accept", "application/json")
486 487 488
        |> delete("/api/pleroma/admin/users/permission_group/admin", %{
          nicknames: [user_one.nickname, user_two.nickname]
        })
489

lain's avatar
lain committed
490 491 492
      assert json_response(conn, 200) == %{
               "is_admin" => false
             }
Maxim Filippov's avatar
Maxim Filippov committed
493 494 495 496

      log_entry = Repo.one(ModerationLog)

      assert ModerationLog.get_log_entry_message(log_entry) ==
497 498 499
               "@#{admin.nickname} revoked admin role from @#{user_one.nickname}, @#{
                 user_two.nickname
               }"
500 501 502
    end
  end

Ivan Tashkinov's avatar
Ivan Tashkinov committed
503
  describe "POST /api/pleroma/admin/email_invite, with valid config" do
504
    setup do
505
      [user: insert(:user, is_admin: true)]
506
    end
507

508 509 510
    clear_config([:instance, :registrations_open]) do
      Pleroma.Config.put([:instance, :registrations_open], false)
    end
511

512 513
    clear_config([:instance, :invites_enabled]) do
      Pleroma.Config.put([:instance, :invites_enabled], true)
514 515 516 517 518 519 520 521 522
    end

    test "sends invitation and returns 204", %{conn: conn, user: user} do
      recipient_email = "foo@bar.com"
      recipient_name = "J. D."

      conn =
        conn
        |> assign(:user, user)
Sachin Joshi's avatar
Sachin Joshi committed
523 524 525
        |> post(
          "/api/pleroma/admin/users/email_invite?email=#{recipient_email}&name=#{recipient_name}"
        )
526 527 528

      assert json_response(conn, :no_content)

Ivan Tashkinov's avatar
Ivan Tashkinov committed
529 530 531 532
      token_record = List.last(Pleroma.Repo.all(Pleroma.UserInviteToken))
      assert token_record
      refute token_record.used

533 534 535 536
      notify_email = Pleroma.Config.get([:instance, :notify_email])
      instance_name = Pleroma.Config.get([:instance, :name])

      email =
Alexander Strizhakov's avatar
Alexander Strizhakov committed
537
        Pleroma.Emails.UserEmail.user_invitation_email(
Ivan Tashkinov's avatar
Ivan Tashkinov committed
538 539 540 541 542
          user,
          token_record,
          recipient_email,
          recipient_name
        )
543 544 545 546 547

      Swoosh.TestAssertions.assert_email_sent(
        from: {instance_name, notify_email},
        to: {recipient_name, recipient_email},
        html_body: email.html_body
Ivan Tashkinov's avatar
Ivan Tashkinov committed
548 549 550 551 552 553 554 555 556
      )
    end

    test "it returns 403 if requested by a non-admin", %{conn: conn} do
      non_admin_user = insert(:user)

      conn =
        conn
        |> assign(:user, non_admin_user)
Sachin Joshi's avatar
Sachin Joshi committed
557
        |> post("/api/pleroma/admin/users/email_invite?email=foo@bar.com&name=JD")
Ivan Tashkinov's avatar
Ivan Tashkinov committed
558 559 560 561 562

      assert json_response(conn, :forbidden)
    end
  end

Sachin Joshi's avatar
Sachin Joshi committed
563
  describe "POST /api/pleroma/admin/users/email_invite, with invalid config" do
Ivan Tashkinov's avatar
Ivan Tashkinov committed
564
    setup do
565
      [user: insert(:user, is_admin: true)]
Ivan Tashkinov's avatar
Ivan Tashkinov committed
566 567
    end

568 569 570
    clear_config([:instance, :registrations_open])
    clear_config([:instance, :invites_enabled])

Ivan Tashkinov's avatar
Ivan Tashkinov committed
571 572 573 574 575 576 577
    test "it returns 500 if `invites_enabled` is not enabled", %{conn: conn, user: user} do
      Pleroma.Config.put([:instance, :registrations_open], false)
      Pleroma.Config.put([:instance, :invites_enabled], false)

      conn =
        conn
        |> assign(:user, user)
Sachin Joshi's avatar
Sachin Joshi committed
578
        |> post("/api/pleroma/admin/users/email_invite?email=foo@bar.com&name=JD")
Ivan Tashkinov's avatar
Ivan Tashkinov committed
579 580 581 582 583 584 585 586 587 588 589

      assert json_response(conn, :internal_server_error)
    end

    test "it returns 500 if `registrations_open` is enabled", %{conn: conn, user: user} do
      Pleroma.Config.put([:instance, :registrations_open], true)
      Pleroma.Config.put([:instance, :invites_enabled], true)

      conn =
        conn
        |> assign(:user, user)
Sachin Joshi's avatar
Sachin Joshi committed
590
        |> post("/api/pleroma/admin/users/email_invite?email=foo@bar.com&name=JD")
Ivan Tashkinov's avatar
Ivan Tashkinov committed
591 592

      assert json_response(conn, :internal_server_error)
593 594 595
    end
  end

Sachin Joshi's avatar
Sachin Joshi committed
596
  test "/api/pleroma/admin/users/:nickname/password_reset" do
597
    admin = insert(:user, is_admin: true)
lain's avatar
lain committed
598
    user = insert(:user)
599 600 601 602 603

    conn =
      build_conn()
      |> assign(:user, admin)
      |> put_req_header("accept", "application/json")
Sachin Joshi's avatar
Sachin Joshi committed
604
      |> get("/api/pleroma/admin/users/#{user.nickname}/password_reset")
605

606 607 608
    resp = json_response(conn, 200)

    assert Regex.match?(~r/(http:\/\/|https:\/\/)/, resp["link"])
609
  end
Maxim Filippov's avatar
Maxim Filippov committed
610

Maxim Filippov's avatar
Maxim Filippov committed
611
  describe "GET /api/pleroma/admin/users" do
Alexander Strizhakov's avatar
Alexander Strizhakov committed
612
    setup do
613
      admin = insert(:user, is_admin: true)
Maxim Filippov's avatar
Maxim Filippov committed
614

Maxim Filippov's avatar
Maxim Filippov committed
615 616 617
      conn =
        build_conn()
        |> assign(:user, admin)
Alexander Strizhakov's avatar
Alexander Strizhakov committed
618 619 620 621 622 623 624

      {:ok, conn: conn, admin: admin}
    end

    test "renders users array for the first page", %{conn: conn, admin: admin} do
      user = insert(:user, local: false, tags: ["foo", "bar"])
      conn = get(conn, "/api/pleroma/admin/users?page=1")
Maxim Filippov's avatar
Maxim Filippov committed
625

Maksim's avatar
Maksim committed
626 627 628
      users =
        [
          %{
629
            "deactivated" => admin.deactivated,
Maksim's avatar
Maksim committed
630 631 632 633
            "id" => admin.id,
            "nickname" => admin.nickname,
            "roles" => %{"admin" => true, "moderator" => false},
            "local" => true,
634 635 636
            "tags" => [],
            "avatar" => User.avatar_url(admin) |> MediaProxy.url(),
            "display_name" => HTML.strip_tags(admin.name || admin.nickname)
Maksim's avatar
Maksim committed
637 638
          },
          %{
639
            "deactivated" => user.deactivated,
Maksim's avatar
Maksim committed
640 641 642 643
            "id" => user.id,
            "nickname" => user.nickname,
            "roles" => %{"admin" => false, "moderator" => false},
            "local" => false,
644 645 646
            "tags" => ["foo", "bar"],
            "avatar" => User.avatar_url(user) |> MediaProxy.url(),
            "display_name" => HTML.strip_tags(user.name || user.nickname)
Maksim's avatar
Maksim committed
647 648 649 650
          }
        ]
        |> Enum.sort_by(& &1["nickname"])

Maxim Filippov's avatar
Maxim Filippov committed
651
      assert json_response(conn, 200) == %{
Maxim Filippov's avatar
Maxim Filippov committed
652
               "count" => 2,
Maxim Filippov's avatar
Maxim Filippov committed
653
               "page_size" => 50,
Maksim's avatar
Maksim committed
654
               "users" => users
Maxim Filippov's avatar
Maxim Filippov committed
655 656 657
             }
    end

Alexander Strizhakov's avatar
Alexander Strizhakov committed
658
    test "renders empty array for the second page", %{conn: conn} do
Maxim Filippov's avatar
Maxim Filippov committed
659
      insert(:user)
Maxim Filippov's avatar
Maxim Filippov committed
660

Alexander Strizhakov's avatar
Alexander Strizhakov committed
661
      conn = get(conn, "/api/pleroma/admin/users?page=2")
Maxim Filippov's avatar
Maxim Filippov committed
662 663

      assert json_response(conn, 200) == %{
Maxim Filippov's avatar
Maxim Filippov committed
664
               "count" => 2,
Maxim Filippov's avatar
Maxim Filippov committed
665 666 667 668
               "page_size" => 50,
               "users" => []
             }
    end
Maxim Filippov's avatar
Maxim Filippov committed
669

Alexander Strizhakov's avatar
Alexander Strizhakov committed
670
    test "regular search", %{conn: conn} do
671
      user = insert(:user, nickname: "bob")
Maxim Filippov's avatar
Maxim Filippov committed
672

Alexander Strizhakov's avatar
Alexander Strizhakov committed
673
      conn = get(conn, "/api/pleroma/admin/users?query=bo")
674 675

      assert json_response(conn, 200) == %{
676 677 678 679
               "count" => 1,
               "page_size" => 50,
               "users" => [
                 %{
680
                   "deactivated" => user.deactivated,
681
                   "id" => user.id,
682
                   "nickname" => user.nickname,
683
                   "roles" => %{"admin" => false, "moderator" => false},
Maxim Filippov's avatar
Maxim Filippov committed
684
                   "local" => true,
685 686 687
                   "tags" => [],
                   "avatar" => User.avatar_url(user) |> MediaProxy.url(),
                   "display_name" => HTML.strip_tags(user.name || user.nickname)
688 689 690
                 }
               ]
             }
691 692
    end

Alexander Strizhakov's avatar
Alexander Strizhakov committed
693 694 695 696 697 698 699 700 701 702 703
    test "search by domain", %{conn: conn} do
      user = insert(:user, nickname: "nickname@domain.com")
      insert(:user)

      conn = get(conn, "/api/pleroma/admin/users?query=domain.com")

      assert json_response(conn, 200) == %{
               "count" => 1,
               "page_size" => 50,
               "users" => [
                 %{
704
                   "deactivated" => user.deactivated,
Alexander Strizhakov's avatar
Alexander Strizhakov committed
705 706 707 708
                   "id" => user.id,
                   "nickname" => user.nickname,
                   "roles" => %{"admin" => false, "moderator" => false},
                   "local" => true,
709 710 711
                   "tags" => [],
                   "avatar" => User.avatar_url(user) |> MediaProxy.url(),
                   "display_name" => HTML.strip_tags(user.name || user.nickname)
Alexander Strizhakov's avatar
Alexander Strizhakov committed
712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727
                 }
               ]
             }
    end

    test "search by full nickname", %{conn: conn} do
      user = insert(:user, nickname: "nickname@domain.com")
      insert(:user)

      conn = get(conn, "/api/pleroma/admin/users?query=nickname@domain.com")

      assert json_response(conn, 200) == %{
               "count" => 1,
               "page_size" => 50,
               "users" => [
                 %{
728
                   "deactivated" => user.deactivated,
Alexander Strizhakov's avatar
Alexander Strizhakov committed
729 730 731 732
                   "id" => user.id,
                   "nickname" => user.nickname,
                   "roles" => %{"admin" => false, "moderator" => false},
                   "local" => true,
733 734 735
                   "tags" => [],
                   "avatar" => User.avatar_url(user) |> MediaProxy.url(),
                   "display_name" => HTML.strip_tags(user.name || user.nickname)
Alexander Strizhakov's avatar
Alexander Strizhakov committed
736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751
                 }
               ]
             }
    end

    test "search by display name", %{conn: conn} do
      user = insert(:user, name: "Display name")
      insert(:user)

      conn = get(conn, "/api/pleroma/admin/users?name=display")

      assert json_response(conn, 200) == %{
               "count" => 1,
               "page_size" => 50,
               "users" => [
                 %{
752
                   "deactivated" => user.deactivated,
Alexander Strizhakov's avatar
Alexander Strizhakov committed
753 754 755 756
                   "id" => user.id,
                   "nickname" => user.nickname,
                   "roles" => %{"admin" => false, "moderator" => false},
                   "local" => true,
757 758 759
                   "tags" => [],
                   "avatar" => User.avatar_url(user) |> MediaProxy.url(),
                   "display_name" => HTML.strip_tags(user.name || user.nickname)
Alexander Strizhakov's avatar
Alexander Strizhakov committed
760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775
                 }
               ]
             }
    end

    test "search by email", %{conn: conn} do
      user = insert(:user, email: "email@example.com")
      insert(:user)

      conn = get(conn, "/api/pleroma/admin/users?email=email@example.com")

      assert json_response(conn, 200) == %{
               "count" => 1,
               "page_size" => 50,
               "users" => [
                 %{
776
                   "deactivated" => user.deactivated,
Alexander Strizhakov's avatar
Alexander Strizhakov committed
777 778 779 780
                   "id" => user.id,
                   "nickname" => user.nickname,
                   "roles" => %{"admin" => false, "moderator" => false},
                   "local" => true,
781 782 783
                   "tags" => [],
                   "avatar" => User.avatar_url(user) |> MediaProxy.url(),
                   "display_name" => HTML.strip_tags(user.name || user.nickname)
Alexander Strizhakov's avatar
Alexander Strizhakov committed
784 785 786 787 788 789
                 }
               ]
             }
    end

    test "regular search with page size", %{conn: conn} do
790 791
      user = insert(:user, nickname: "aalice")
      user2 = insert(:user, nickname: "alice")
Maxim Filippov's avatar
Maxim Filippov committed
792

Alexander Strizhakov's avatar
Alexander Strizhakov committed
793
      conn1 = get(conn, "/api/pleroma/admin/users?query=a&page_size=1&page=1")
Maxim Filippov's avatar
Maxim Filippov committed
794

Alexander Strizhakov's avatar
Alexander Strizhakov committed
795
      assert json_response(conn1, 200) == %{
Maxim Filippov's avatar
Maxim Filippov committed
796 797 798 799
               "count" => 2,
               "page_size" => 1,
               "users" => [
                 %{
800
                   "deactivated" => user.deactivated,
Maxim Filippov's avatar
Maxim Filippov committed
801
                   "id" => user.id,
802
                   "nickname" => user.nickname,
803
                   "roles" => %{"admin" => false, "moderator" => false},
Maxim Filippov's avatar
Maxim Filippov committed
804
                   "local" => true,
805 806 807
                   "tags" => [],
                   "avatar" => User.avatar_url(user) |> MediaProxy.url(),
                   "display_name" => HTML.strip_tags(user.name || user.nickname)
Maxim Filippov's avatar
Maxim Filippov committed
808 809 810 811
                 }
               ]
             }

Alexander Strizhakov's avatar
Alexander Strizhakov committed
812
      conn2 = get(conn, "/api/pleroma/admin/users?query=a&page_size=1&page=2")
Maxim Filippov's avatar
Maxim Filippov committed
813

Alexander Strizhakov's avatar
Alexander Strizhakov committed
814
      assert json_response(conn2, 200) == %{
Maxim Filippov's avatar
Maxim Filippov committed
815 816 817 818
               "count" => 2,
               "page_size" => 1,
               "users" => [
                 %{
819
                   "deactivated" => user2.deactivated,
Maxim Filippov's avatar
Maxim Filippov committed
820
                   "id" => user2.id,
821
                   "nickname" => user2.nickname,
822
                   "roles" => %{"admin" => false, "moderator" => false},
Maxim Filippov's avatar
Maxim Filippov committed
823
                   "local" => true,
824 825 826
                   "tags" => [],
                   "avatar" => User.avatar_url(user2) |> MediaProxy.url(),
                   "display_name" => HTML.strip_tags(user2.name || user2.nickname)
Maxim Filippov's avatar
Maxim Filippov committed
827 828 829 830 831 832
                 }
               ]
             }
    end

    test "only local users" do
833
      admin = insert(:user, is_admin: true, nickname: "john")
Maxim Filippov's avatar
Maxim Filippov committed
834
      user = insert(:user, nickname: "bob")
835 836 837 838 839 840

      insert(:user, nickname: "bobb", local: false)

      conn =
        build_conn()
        |> assign(:user, admin)
841
        |> get("/api/pleroma/admin/users?query=bo&filters=local")
842 843

      assert json_response(conn, 200) == %{
844 845 846 847
               "count" => 1,
               "page_size" => 50,
               "users" => [
                 %{
848
                   "deactivated" => user.deactivated,
849
                   "id" => user.id,
850
                   "nickname" => user.nickname,
851
                   "roles" => %{"admin" => false, "moderator" => false},
Maxim Filippov's avatar
Maxim Filippov committed
852
                   "local" => true,
853 854 855
                   "tags" => [],
                   "avatar" => User.avatar_url(user) |> MediaProxy.url(),
                   "display_name" => HTML.strip_tags(user.name || user.nickname)
856 857 858
                 }
               ]
             }
859
    end
860

Alexander Strizhakov's avatar
Alexander Strizhakov committed
861
    test "only local users with no query", %{admin: old_admin} do
862
      admin = insert(:user, is_admin: true, nickname: "john")
863 864 865 866 867 868 869
      user = insert(:user, nickname: "bob")

      insert(:user, nickname: "bobb", local: false)

      conn =
        build_conn()
        |> assign(:user, admin)
870
        |> get("/api/pleroma/admin/users?filters=local")
871

Maksim's avatar
Maksim committed
872 873 874
      users =
        [
          %{
875
            "deactivated" => user.deactivated,
Maksim's avatar
Maksim committed
876 877 878 879
            "id" => user.id,
            "nickname" => user.nickname,
            "roles" => %{"admin" => false, "moderator" => false},
            "local" => true,
880 881 882
            "tags" => [],
            "avatar" => User.avatar_url(user) |> MediaProxy.url(),
            "display_name" => HTML.strip_tags(user.name || user.nickname)
Maksim's avatar
Maksim committed
883 884
          },
          %{
885
            "deactivated" => admin.deactivated,
Maksim's avatar
Maksim committed
886 887 888 889
            "id" => admin.id,
            "nickname" => admin.nickname,
            "roles" => %{"admin" => true, "moderator" => false},
            "local" => true,
890 891 892
            "tags" => [],
            "avatar" => User.avatar_url(admin) |> MediaProxy.url(),
            "display_name" => HTML.strip_tags(admin.name || admin.nickname)
Maksim's avatar
Maksim committed
893 894 895 896 897 898 899
          },
          %{
            "deactivated" => false,
            "id" => old_admin.id,
            "local" => true,
            "nickname" => old_admin.nickname,
            "roles" => %{"admin" => true, "moderator" => false},
900 901 902
            "tags" => [],
            "avatar" => User.avatar_url(old_admin) |> MediaProxy.url(),
            "display_name" => HTML.strip_tags(old_admin.name || old_admin.nickname)
Maksim's avatar
Maksim committed
903 904 905 906
          }
        ]
        |> Enum.sort_by(& &1["nickname"])

907
      assert json_response(conn, 200) == %{
Alexander Strizhakov's avatar
Alexander Strizhakov committed
908
               "count" => 3,
909
               "page_size" => 50,
Maksim's avatar
Maksim committed
910
               "users" => users
Alexander Strizhakov's avatar
Alexander Strizhakov committed
911 912 913 914
             }
    end

    test "load only admins", %{conn: conn, admin: admin} do
915
      second_admin = insert(:user, is_admin: true)
Alexander Strizhakov's avatar
Alexander Strizhakov committed
916 917 918 919 920
      insert(:user)
      insert(:user)

      conn = get(conn, "/api/pleroma/admin/users?filters=is_admin")

Maksim's avatar
Maksim committed
921 922 923 924 925 926 927 928
      users =
        [
          %{
            "deactivated" => false,
            "id" => admin.id,
            "nickname" => admin.nickname,
            "roles" => %{"admin" => true, "moderator" => false},
            "local" => admin.local,
929 930 931
            "tags" => [],
            "avatar" => User.avatar_url(admin) |> MediaProxy.url(),
            "display_name" => HTML.strip_tags(admin.name || admin.nickname)
Maksim's avatar
Maksim committed
932 933 934 935 936 937 938
          },
          %{
            "deactivated" => false,
            "id" => second_admin.id,
            "nickname" => second_admin.nickname,
            "roles" => %{"admin" => true, "moderator" => false},
            "local" => second_admin.local,
939 940 941
            "tags" => [],
            "avatar" => User.avatar_url(second_admin) |> MediaProxy.url(),
            "display_name" => HTML.strip_tags(second_admin.name || second_admin.nickname)
Maksim's avatar
Maksim committed
942 943 944 945
          }
        ]
        |> Enum.sort_by(& &1["nickname"])

Alexander Strizhakov's avatar
Alexander Strizhakov committed
946 947 948
      assert json_response(conn, 200) == %{
               "count" => 2,
               "page_size" => 50,
Maksim's avatar
Maksim committed
949
               "users" => users
Alexander Strizhakov's avatar
Alexander Strizhakov committed
950 951 952 953
             }
    end

    test "load only moderators", %{conn: conn} do
954
      moderator = insert(:user, is_moderator: true)
Alexander Strizhakov's avatar
Alexander Strizhakov committed
955 956 957 958 959 960 961 962 963 964 965 966 967 968 969
      insert(:user)
      insert(:user)

      conn = get(conn, "/api/pleroma/admin/users?filters=is_moderator")

      assert json_response(conn, 200) == %{
               "count" => 1,
               "page_size" => 50,
               "users" => [
                 %{
                   "deactivated" => false,
                   "id" => moderator.id,
                   "nickname" => moderator.nickname,
                   "roles" => %{"admin" => false, "moderator" => true},
                   "local" => moderator.local,
970 971 972
                   "tags" => [],
                   "avatar" => User.avatar_url(moderator) |> MediaProxy.url(),
                   "display_name" => HTML.strip_tags(moderator.name || moderator.nickname)
Alexander Strizhakov's avatar
Alexander Strizhakov committed
973 974 975 976 977 978 979 980 981 982 983 984 985
                 }
               ]
             }
    end

    test "load users with tags list", %{conn: conn} do
      user1 = insert(:user, tags: ["first"])
      user2 = insert(:user, tags: ["second"])
      insert(:user)
      insert(:user)

      conn = get(conn, "/api/pleroma/admin/users?tags[]=first&tags[]=second")

Maksim's avatar
Maksim committed
986 987 988 989 990 991 992 993
      users =
        [
          %{
            "deactivated" => false,
            "id" => user1.id,
            "nickname" => user1.nickname,
            "roles" => %{"admin" => false, "moderator" => false},
            "local" => user1.local,
994 995 996
            "tags" => ["first"],
            "avatar" => User.avatar_url(user1) |> MediaProxy.url(),
            "display_name" => HTML.strip_tags(user1.name || user1.nickname)
Maksim's avatar
Maksim committed
997 998 999 1000 1001 1002 1003
          },
          %{
            "deactivated" => false,
            "id" => user2.id,
            "nickname" => user2.nickname,
            "roles" => %{"admin" => false, "moderator" => false},
            "local" => user2.local,
1004 1005 1006
            "tags" => ["second"],
            "avatar" => User.avatar_url(user2) |> MediaProxy.url(),
            "display_name" => HTML.strip_tags(user2.name || user2.nickname)
Maksim's avatar
Maksim committed
1007 1008 1009 1010
          }
        ]
        |> Enum.sort_by(& &1["nickname"])

Alexander Strizhakov's avatar
Alexander Strizhakov committed
1011 1012 1013
      assert json_response(conn, 200) == %{
               "count" => 2,
               "page_size" => 50,
Maksim's avatar
Maksim committed
1014
               "users" => users
1015 1016
             }
    end
1017 1018

    test "it works with multiple filters" do
1019 1020
      admin = insert(:user, nickname: "john", is_admin: true)
      user = insert(:user, nickname: "bob", local: false, deactivated: true)
1021

1022 1023
      insert(:user, nickname: "ken", local: true, deactivated: true)
      insert(:user, nickname: "bobb", local: false, deactivated: false)
1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034

      conn =
        build_conn()
        |> assign(:user, admin)
        |> get("/api/pleroma/admin/users?filters=deactivated,external")

      assert json_response(conn, 200) == %{
               "count" => 1,
               "page_size" => 50,
               "users" => [
                 %{
1035
                   "deactivated" => user.deactivated,
1036 1037 1038 1039
                   "id" => user.id,
                   "nickname" => user.nickname,
                   "roles" => %{"admin" => false, "moderator" => false},
                   "local" => user.local,