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

lain's avatar
lain committed
5
6
defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
  use Pleroma.DataCase
7

Roger Braun's avatar
Roger Braun committed
8
  alias Pleroma.User
9
  alias Pleroma.UserRelationship
10
  alias Pleroma.Web.CommonAPI
11
  alias Pleroma.Web.MastodonAPI.AccountView
lain's avatar
lain committed
12

13
14
15
16
17
18
19
20
  import Pleroma.Factory
  import Tesla.Mock

  setup do
    mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
    :ok
  end

lain's avatar
lain committed
21
  test "Represent a user account" do
eal's avatar
eal committed
22
23
24
25
26
27
28
29
30
31
    source_data = %{
      "tag" => [
        %{
          "type" => "Emoji",
          "icon" => %{"url" => "/file.png"},
          "name" => ":karjalanpiirakka:"
        }
      ]
    }

lain's avatar
lain committed
32
33
34
35
    background_image = %{
      "url" => [%{"href" => "https://example.com/images/asuka_hospital.png"}]
    }

lain's avatar
lain committed
36
37
    user =
      insert(:user, %{
38
39
40
41
        follower_count: 3,
        note_count: 5,
        source_data: source_data,
        background: background_image,
lain's avatar
lain committed
42
        nickname: "shp@shitposter.club",
eal's avatar
eal committed
43
        name: ":karjalanpiirakka: shp",
44
45
        bio:
          "<script src=\"invalid-html\"></script><span>valid html</span>. a<br>b<br/>c<br >d<br />f",
lain's avatar
lain committed
46
47
        inserted_at: ~N[2017-08-15 15:47:06.597036]
      })
lain's avatar
lain committed
48
49

    expected = %{
lain's avatar
lain committed
50
      id: to_string(user.id),
51
      username: "shp",
lain's avatar
lain committed
52
53
54
      acct: user.nickname,
      display_name: user.name,
      locked: false,
55
      created_at: "2017-08-15T15:47:06.000Z",
lain's avatar
lain committed
56
57
58
      followers_count: 3,
      following_count: 0,
      statuses_count: 5,
59
      note: "<span>valid html</span>. a<br/>b<br/>c<br/>d<br/>f",
lain's avatar
lain committed
60
      url: user.ap_id,
61
62
63
64
      avatar: "http://localhost:4001/images/avi.png",
      avatar_static: "http://localhost:4001/images/avi.png",
      header: "http://localhost:4001/images/banner.png",
      header_static: "http://localhost:4001/images/banner.png",
eal's avatar
eal committed
65
66
67
68
69
70
71
72
      emojis: [
        %{
          "static_url" => "/file.png",
          "url" => "/file.png",
          "shortcode" => "karjalanpiirakka",
          "visible_in_picker" => false
        }
      ],
Haelwenn's avatar
Haelwenn committed
73
      fields: [],
74
75
      bot: false,
      source: %{
76
        note: "valid html. a\nb\nc\nd\nf",
rinpatch's avatar
rinpatch committed
77
        sensitive: false,
78
        pleroma: %{
79
          actor_type: "Person",
80
81
          discoverable: false
        },
minibikini's avatar
minibikini committed
82
        fields: []
Ivan Tashkinov's avatar
Ivan Tashkinov committed
83
      },
84
      pleroma: %{
lain's avatar
lain committed
85
        background_image: "https://example.com/images/asuka_hospital.png",
86
        confirmation_pending: false,
87
88
        tags: [],
        is_admin: false,
89
        is_moderator: false,
90
91
92
        hide_favorites: true,
        hide_followers: false,
        hide_follows: false,
93
94
        hide_followers_count: false,
        hide_follows_count: false,
Maksim's avatar
Maksim committed
95
96
        relationship: %{},
        skip_thread_containment: false
97
      }
98
99
    }

minibikini's avatar
minibikini committed
100
    assert expected == AccountView.render("show.json", %{user: user})
101
102
  end

103
104
105
  test "Represent the user account for the account owner" do
    user = insert(:user)

Maksim's avatar
Maksim committed
106
    notification_settings = %Pleroma.User.NotificationSetting{}
107
    privacy = user.default_scope
108
109

    assert %{
110
             pleroma: %{notification_settings: ^notification_settings, allow_following_move: true},
111
             source: %{privacy: ^privacy}
minibikini's avatar
minibikini committed
112
           } = AccountView.render("show.json", %{user: user, for: user})
113
114
  end

115
116
117
  test "Represent a Service(bot) account" do
    user =
      insert(:user, %{
118
119
        follower_count: 3,
        note_count: 5,
120
121
        source_data: %{},
        actor_type: "Service",
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
        nickname: "shp@shitposter.club",
        inserted_at: ~N[2017-08-15 15:47:06.597036]
      })

    expected = %{
      id: to_string(user.id),
      username: "shp",
      acct: user.nickname,
      display_name: user.name,
      locked: false,
      created_at: "2017-08-15T15:47:06.000Z",
      followers_count: 3,
      following_count: 0,
      statuses_count: 5,
      note: user.bio,
      url: user.ap_id,
      avatar: "http://localhost:4001/images/avi.png",
      avatar_static: "http://localhost:4001/images/avi.png",
      header: "http://localhost:4001/images/banner.png",
      header_static: "http://localhost:4001/images/banner.png",
      emojis: [],
      fields: [],
      bot: true,
145
      source: %{
146
        note: user.bio,
rinpatch's avatar
rinpatch committed
147
        sensitive: false,
148
        pleroma: %{
149
          actor_type: "Service",
150
151
          discoverable: false
        },
minibikini's avatar
minibikini committed
152
        fields: []
Ivan Tashkinov's avatar
Ivan Tashkinov committed
153
      },
154
      pleroma: %{
lain's avatar
lain committed
155
        background_image: nil,
156
        confirmation_pending: false,
157
158
        tags: [],
        is_admin: false,
159
        is_moderator: false,
160
161
162
        hide_favorites: true,
        hide_followers: false,
        hide_follows: false,
163
164
        hide_followers_count: false,
        hide_follows_count: false,
Maksim's avatar
Maksim committed
165
166
        relationship: %{},
        skip_thread_containment: false
167
      }
lain's avatar
lain committed
168
169
    }

minibikini's avatar
minibikini committed
170
    assert expected == AccountView.render("show.json", %{user: user})
lain's avatar
lain committed
171
172
  end

173
174
175
176
177
178
179
180
  test "Represent a Funkwhale channel" do
    {:ok, user} =
      User.get_or_fetch_by_ap_id(
        "https://channels.tests.funkwhale.audio/federation/actors/compositions"
      )

    assert represented = AccountView.render("show.json", %{user: user})
    assert represented.acct == "compositions@channels.tests.funkwhale.audio"
181
    assert represented.url == "https://channels.tests.funkwhale.audio/channels/compositions"
182
183
  end

184
  test "Represent a deactivated user for an admin" do
185
186
    admin = insert(:user, is_admin: true)
    deactivated_user = insert(:user, deactivated: true)
minibikini's avatar
minibikini committed
187
    represented = AccountView.render("show.json", %{user: deactivated_user, for: admin})
188
189
190
    assert represented[:pleroma][:deactivated] == true
  end

lain's avatar
lain committed
191
192
193
194
  test "Represent a smaller mention" do
    user = insert(:user)

    expected = %{
lain's avatar
lain committed
195
      id: to_string(user.id),
lain's avatar
lain committed
196
197
198
199
200
201
202
      acct: user.nickname,
      username: user.nickname,
      url: user.ap_id
    }

    assert expected == AccountView.render("mention.json", %{user: user})
  end
Roger Braun's avatar
Roger Braun committed
203

204
  describe "relationship" do
205
    defp test_relationship_rendering(user, other_user, expected_result) do
206
      opts = %{user: user, target: other_user, relationships: nil}
207
208
209
210
211
      assert expected_result == AccountView.render("relationship.json", opts)

      relationships_opt = UserRelationship.view_relationships_option(user, [other_user])
      opts = Map.put(opts, :relationships, relationships_opt)
      assert expected_result == AccountView.render("relationship.json", opts)
212
213
214

      assert [expected_result] ==
               AccountView.render("relationships.json", %{user: user, targets: [other_user]})
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
    end

    @blank_response %{
      following: false,
      followed_by: false,
      blocking: false,
      blocked_by: false,
      muting: false,
      muting_notifications: false,
      subscribing: false,
      requested: false,
      domain_blocking: false,
      showing_reblogs: true,
      endorsed: false
    }

231
232
233
    test "represent a relationship for the following and followed user" do
      user = insert(:user)
      other_user = insert(:user)
Roger Braun's avatar
Roger Braun committed
234

235
236
      {:ok, user} = User.follow(user, other_user)
      {:ok, other_user} = User.follow(other_user, user)
237
      {:ok, _subscription} = User.subscribe(user, other_user)
238
239
      {:ok, _user_relationships} = User.mute(user, other_user, true)
      {:ok, _reblog_mute} = CommonAPI.hide_reblogs(user, other_user)
Roger Braun's avatar
Roger Braun committed
240

241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
      expected =
        Map.merge(
          @blank_response,
          %{
            following: true,
            followed_by: true,
            muting: true,
            muting_notifications: true,
            subscribing: true,
            showing_reblogs: false,
            id: to_string(other_user.id)
          }
        )

      test_relationship_rendering(user, other_user, expected)
256
257
258
259
260
261
262
    end

    test "represent a relationship for the blocking and blocked user" do
      user = insert(:user)
      other_user = insert(:user)

      {:ok, user} = User.follow(user, other_user)
263
      {:ok, _subscription} = User.subscribe(user, other_user)
264
265
      {:ok, _user_relationship} = User.block(user, other_user)
      {:ok, _user_relationship} = User.block(other_user, user)
266

267
268
269
270
271
      expected =
        Map.merge(
          @blank_response,
          %{following: false, blocking: true, blocked_by: true, id: to_string(other_user.id)}
        )
272

273
      test_relationship_rendering(user, other_user, expected)
274
275
    end

276
277
278
279
280
281
    test "represent a relationship for the user blocking a domain" do
      user = insert(:user)
      other_user = insert(:user, ap_id: "https://bad.site/users/other_user")

      {:ok, user} = User.block_domain(user, "bad.site")

282
283
284
285
286
287
288
      expected =
        Map.merge(
          @blank_response,
          %{domain_blocking: true, blocking: false, id: to_string(other_user.id)}
        )

      test_relationship_rendering(user, other_user, expected)
289
290
    end

291
292
    test "represent a relationship for the user with a pending follow request" do
      user = insert(:user)
293
      other_user = insert(:user, locked: true)
294
295
296
297
298

      {:ok, user, other_user, _} = CommonAPI.follow(user, other_user)
      user = User.get_cached_by_id(user.id)
      other_user = User.get_cached_by_id(other_user.id)

299
300
301
302
303
      expected =
        Map.merge(
          @blank_response,
          %{requested: true, following: false, id: to_string(other_user.id)}
        )
Roger Braun's avatar
Roger Braun committed
304

305
      test_relationship_rendering(user, other_user, expected)
306
    end
Roger Braun's avatar
Roger Braun committed
307
  end
308
309
310
311

  test "represent an embedded relationship" do
    user =
      insert(:user, %{
312
313
        follower_count: 0,
        note_count: 5,
314
315
        source_data: %{},
        actor_type: "Service",
316
317
318
319
320
321
        nickname: "shp@shitposter.club",
        inserted_at: ~N[2017-08-15 15:47:06.597036]
      })

    other_user = insert(:user)
    {:ok, other_user} = User.follow(other_user, user)
322
    {:ok, _user_relationship} = User.block(other_user, user)
minibikini's avatar
minibikini committed
323
    {:ok, _} = User.follow(insert(:user), user)
324
325
326
327
328
329
330
331

    expected = %{
      id: to_string(user.id),
      username: "shp",
      acct: user.nickname,
      display_name: user.name,
      locked: false,
      created_at: "2017-08-15T15:47:06.000Z",
minibikini's avatar
minibikini committed
332
      followers_count: 1,
333
334
335
336
337
338
339
340
341
342
343
344
      following_count: 0,
      statuses_count: 5,
      note: user.bio,
      url: user.ap_id,
      avatar: "http://localhost:4001/images/avi.png",
      avatar_static: "http://localhost:4001/images/avi.png",
      header: "http://localhost:4001/images/banner.png",
      header_static: "http://localhost:4001/images/banner.png",
      emojis: [],
      fields: [],
      bot: true,
      source: %{
345
        note: user.bio,
rinpatch's avatar
rinpatch committed
346
        sensitive: false,
347
        pleroma: %{
348
          actor_type: "Service",
349
350
          discoverable: false
        },
minibikini's avatar
minibikini committed
351
        fields: []
352
353
      },
      pleroma: %{
lain's avatar
lain committed
354
        background_image: nil,
355
356
357
358
        confirmation_pending: false,
        tags: [],
        is_admin: false,
        is_moderator: false,
359
360
361
        hide_favorites: true,
        hide_followers: false,
        hide_follows: false,
362
363
        hide_followers_count: false,
        hide_follows_count: false,
364
365
366
367
368
        relationship: %{
          id: to_string(user.id),
          following: false,
          followed_by: false,
          blocking: true,
369
          blocked_by: false,
370
          subscribing: false,
371
372
373
374
          muting: false,
          muting_notifications: false,
          requested: false,
          domain_blocking: false,
375
          showing_reblogs: true,
376
          endorsed: false
Maksim's avatar
Maksim committed
377
378
        },
        skip_thread_containment: false
379
380
381
      }
    }

minibikini's avatar
minibikini committed
382
383
    assert expected ==
             AccountView.render("show.json", %{user: refresh_record(user), for: other_user})
384
  end
385
386

  test "returns the settings store if the requesting user is the represented user and it's requested specifically" do
387
    user = insert(:user, pleroma_settings_store: %{fe: "test"})
388
389

    result =
minibikini's avatar
minibikini committed
390
      AccountView.render("show.json", %{user: user, for: user, with_pleroma_settings: true})
391

lain's avatar
lain committed
392
    assert result.pleroma.settings_store == %{:fe => "test"}
393

minibikini's avatar
minibikini committed
394
    result = AccountView.render("show.json", %{user: user, with_pleroma_settings: true})
lain's avatar
lain committed
395
    assert result.pleroma[:settings_store] == nil
396

minibikini's avatar
minibikini committed
397
    result = AccountView.render("show.json", %{user: user, for: user})
lain's avatar
lain committed
398
    assert result.pleroma[:settings_store] == nil
399
  end
400

401
  test "doesn't sanitize display names" do
402
    user = insert(:user, name: "<marquee> username </marquee>")
minibikini's avatar
minibikini committed
403
    result = AccountView.render("show.json", %{user: user})
404
    assert result.display_name == "<marquee> username </marquee>"
405
  end
406

407
408
409
410
411
412
413
414
  test "never display nil user follow counts" do
    user = insert(:user, following_count: 0, follower_count: 0)
    result = AccountView.render("show.json", %{user: user})

    assert result.following_count == 0
    assert result.followers_count == 0
  end

415
  describe "hiding follows/following" do
416
    test "shows when follows/followers stats are hidden and sets follow/follower count to 0" do
417
418
419
420
421
422
423
      user =
        insert(:user, %{
          hide_followers: true,
          hide_followers_count: true,
          hide_follows: true,
          hide_follows_count: true
        })
424

425
426
427
428
429
430
431
      other_user = insert(:user)
      {:ok, user, other_user, _activity} = CommonAPI.follow(user, other_user)
      {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)

      assert %{
               followers_count: 0,
               following_count: 0,
432
               pleroma: %{hide_follows_count: true, hide_followers_count: true}
minibikini's avatar
minibikini committed
433
             } = AccountView.render("show.json", %{user: user})
434
435
436
    end

    test "shows when follows/followers are hidden" do
437
      user = insert(:user, hide_followers: true, hide_follows: true)
438
439
440
441
442
443
444
      other_user = insert(:user)
      {:ok, user, other_user, _activity} = CommonAPI.follow(user, other_user)
      {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)

      assert %{
               followers_count: 1,
               following_count: 1,
445
               pleroma: %{hide_follows: true, hide_followers: true}
minibikini's avatar
minibikini committed
446
             } = AccountView.render("show.json", %{user: user})
447
448
449
    end

    test "shows actual follower/following count to the account owner" do
450
      user = insert(:user, hide_followers: true, hide_follows: true)
451
452
453
454
455
456
457
      other_user = insert(:user)
      {:ok, user, other_user, _activity} = CommonAPI.follow(user, other_user)
      {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)

      assert %{
               followers_count: 1,
               following_count: 1
minibikini's avatar
minibikini committed
458
             } = AccountView.render("show.json", %{user: user, for: user})
459
    end
460
461
462
463
464
465

    test "shows unread_conversation_count only to the account owner" do
      user = insert(:user)
      other_user = insert(:user)

      {:ok, _activity} =
466
467
        CommonAPI.post(other_user, %{
          "status" => "Hey @#{user.nickname}.",
468
469
470
471
472
473
474
475
476
477
478
479
480
          "visibility" => "direct"
        })

      user = User.get_cached_by_ap_id(user.ap_id)

      assert AccountView.render("show.json", %{user: user, for: other_user})[:pleroma][
               :unread_conversation_count
             ] == nil

      assert AccountView.render("show.json", %{user: user, for: user})[:pleroma][
               :unread_conversation_count
             ] == 1
    end
481
  end
482
483
484
485
486
487

  describe "follow requests counter" do
    test "shows zero when no follow requests are pending" do
      user = insert(:user)

      assert %{follow_requests_count: 0} =
minibikini's avatar
minibikini committed
488
               AccountView.render("show.json", %{user: user, for: user})
489
490
491
492
493

      other_user = insert(:user)
      {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)

      assert %{follow_requests_count: 0} =
minibikini's avatar
minibikini committed
494
               AccountView.render("show.json", %{user: user, for: user})
495
496
497
    end

    test "shows non-zero when follow requests are pending" do
498
      user = insert(:user, locked: true)
499

minibikini's avatar
minibikini committed
500
      assert %{locked: true} = AccountView.render("show.json", %{user: user, for: user})
501
502
503
504
505

      other_user = insert(:user)
      {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)

      assert %{locked: true, follow_requests_count: 1} =
minibikini's avatar
minibikini committed
506
               AccountView.render("show.json", %{user: user, for: user})
507
508
509
    end

    test "decreases when accepting a follow request" do
510
      user = insert(:user, locked: true)
511

minibikini's avatar
minibikini committed
512
      assert %{locked: true} = AccountView.render("show.json", %{user: user, for: user})
513
514
515
516
517

      other_user = insert(:user)
      {:ok, other_user, user, _activity} = CommonAPI.follow(other_user, user)

      assert %{locked: true, follow_requests_count: 1} =
minibikini's avatar
minibikini committed
518
               AccountView.render("show.json", %{user: user, for: user})
519
520
521
522

      {:ok, _other_user} = CommonAPI.accept_follow_request(other_user, user)

      assert %{locked: true, follow_requests_count: 0} =
minibikini's avatar
minibikini committed
523
               AccountView.render("show.json", %{user: user, for: user})
524
525
526
    end

    test "decreases when rejecting a follow request" do
527
      user = insert(:user, locked: true)
528

minibikini's avatar
minibikini committed
529
      assert %{locked: true} = AccountView.render("show.json", %{user: user, for: user})
530
531
532
533
534

      other_user = insert(:user)
      {:ok, other_user, user, _activity} = CommonAPI.follow(other_user, user)

      assert %{locked: true, follow_requests_count: 1} =
minibikini's avatar
minibikini committed
535
               AccountView.render("show.json", %{user: user, for: user})
536
537
538
539

      {:ok, _other_user} = CommonAPI.reject_follow_request(other_user, user)

      assert %{locked: true, follow_requests_count: 0} =
minibikini's avatar
minibikini committed
540
               AccountView.render("show.json", %{user: user, for: user})
541
542
543
    end

    test "shows non-zero when historical unapproved requests are present" do
544
      user = insert(:user, locked: true)
545

minibikini's avatar
minibikini committed
546
      assert %{locked: true} = AccountView.render("show.json", %{user: user, for: user})
547
548
549
550

      other_user = insert(:user)
      {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)

551
      {:ok, user} = User.update_and_set_cache(user, %{locked: false})
552
553

      assert %{locked: false, follow_requests_count: 1} =
minibikini's avatar
minibikini committed
554
               AccountView.render("show.json", %{user: user, for: user})
555
556
    end
  end
lain's avatar
lain committed
557
end