mastodon_api_controller_test.exs 55.1 KB
Newer Older
kaniini's avatar
kaniini committed
1
# Pleroma: A lightweight social networking server
minibikini's avatar
minibikini committed
2
# Copyright © 2017-2019 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
7
8
defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
  use Pleroma.Web.ConnCase

  alias Pleroma.Web.TwitterAPI.TwitterAPI
Haelwenn's avatar
Haelwenn committed
9
10
11
12
13
14
15
  alias Pleroma.Repo
  alias Pleroma.User
  alias Pleroma.Object
  alias Pleroma.Activity
  alias Pleroma.Notification
  alias Pleroma.Web.OStatus
  alias Pleroma.Web.CommonAPI
kaniini's avatar
kaniini committed
16
  alias Pleroma.Web.ActivityPub.ActivityPub
Maksim's avatar
Maksim committed
17
  alias Pleroma.Web.MastodonAPI.FilterView
18
  alias Ecto.Changeset
lain's avatar
lain committed
19
  import Pleroma.Factory
lain's avatar
lain committed
20
  import ExUnit.CaptureLog
Maksim's avatar
Maksim committed
21
22
23
24
25
26
  import Tesla.Mock

  setup do
    mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
    :ok
  end
lain's avatar
lain committed
27
28
29
30
31
32
33

  test "the home timeline", %{conn: conn} do
    user = insert(:user)
    following = insert(:user)

    {:ok, _activity} = TwitterAPI.create_status(following, %{"status" => "test"})

lain's avatar
lain committed
34
35
36
37
    conn =
      conn
      |> assign(:user, user)
      |> get("/api/v1/timelines/home")
lain's avatar
lain committed
38

39
    assert Enum.empty?(json_response(conn, 200))
lain's avatar
lain committed
40
41
42

    {:ok, user} = User.follow(user, following)

lain's avatar
lain committed
43
44
45
46
    conn =
      build_conn()
      |> assign(:user, user)
      |> get("/api/v1/timelines/home")
lain's avatar
lain committed
47
48
49
50
51
52
53

    assert [%{"content" => "test"}] = json_response(conn, 200)
  end

  test "the public timeline", %{conn: conn} do
    following = insert(:user)

lain's avatar
lain committed
54
    capture_log(fn ->
lain's avatar
lain committed
55
      {:ok, _activity} = TwitterAPI.create_status(following, %{"status" => "test"})
lain's avatar
lain committed
56

lain's avatar
lain committed
57
58
59
60
61
62
      {:ok, [_activity]} =
        OStatus.fetch_activity_from_url("https://shitposter.club/notice/2827873")

      conn =
        conn
        |> get("/api/v1/timelines/public", %{"local" => "False"})
lain's avatar
lain committed
63

lain's avatar
lain committed
64
      assert length(json_response(conn, 200)) == 2
lain's avatar
lain committed
65

lain's avatar
lain committed
66
67
68
      conn =
        build_conn()
        |> get("/api/v1/timelines/public", %{"local" => "True"})
lain's avatar
lain committed
69

lain's avatar
lain committed
70
      assert [%{"content" => "test"}] = json_response(conn, 200)
lain's avatar
lain committed
71

lain's avatar
lain committed
72
73
74
      conn =
        build_conn()
        |> get("/api/v1/timelines/public", %{"local" => "1"})
lain's avatar
lain committed
75

lain's avatar
lain committed
76
      assert [%{"content" => "test"}] = json_response(conn, 200)
lain's avatar
lain committed
77
    end)
lain's avatar
lain committed
78
79
80
81
82
  end

  test "posting a status", %{conn: conn} do
    user = insert(:user)

lain's avatar
lain committed
83
84
85
    idempotency_key = "Pikachu rocks!"

    conn_one =
lain's avatar
lain committed
86
87
      conn
      |> assign(:user, user)
lain's avatar
lain committed
88
      |> put_req_header("idempotency-key", idempotency_key)
lain's avatar
lain committed
89
90
91
92
93
94
      |> post("/api/v1/statuses", %{
        "status" => "cofe",
        "spoiler_text" => "2hu",
        "sensitive" => "false"
      })

95
96
97
    {:ok, ttl} = Cachex.ttl(:idempotency_cache, idempotency_key)
    # Six hours
    assert ttl > :timer.seconds(6 * 60 * 60 - 1)
98

lain's avatar
lain committed
99
    assert %{"content" => "cofe", "id" => id, "spoiler_text" => "2hu", "sensitive" => false} =
lain's avatar
lain committed
100
             json_response(conn_one, 200)
lain's avatar
lain committed
101
102

    assert Repo.get(Activity, id)
lain's avatar
lain committed
103
104
105
106
107
108
109
110
111
112
113
114
115
116

    conn_two =
      conn
      |> assign(:user, user)
      |> put_req_header("idempotency-key", idempotency_key)
      |> post("/api/v1/statuses", %{
        "status" => "cofe",
        "spoiler_text" => "2hu",
        "sensitive" => "false"
      })

    assert %{"id" => second_id} = json_response(conn_two, 200)

    assert id == second_id
117
118
119
120
121
122
123
124
125
126
127
128
129

    conn_three =
      conn
      |> assign(:user, user)
      |> post("/api/v1/statuses", %{
        "status" => "cofe",
        "spoiler_text" => "2hu",
        "sensitive" => "false"
      })

    assert %{"id" => third_id} = json_response(conn_three, 200)

    refute id == third_id
lain's avatar
lain committed
130
131
  end

132
133
134
  test "posting a sensitive status", %{conn: conn} do
    user = insert(:user)

lain's avatar
lain committed
135
136
137
138
    conn =
      conn
      |> assign(:user, user)
      |> post("/api/v1/statuses", %{"status" => "cofe", "sensitive" => true})
139
140
141
142
143

    assert %{"content" => "cofe", "id" => id, "sensitive" => true} = json_response(conn, 200)
    assert Repo.get(Activity, id)
  end

144
  test "posting a status with OGP link preview", %{conn: conn} do
lain's avatar
lain committed
145
    Pleroma.Config.put([:rich_media, :enabled], true)
146
147
148
149
150
151
152
153
154
155
156
    user = insert(:user)

    conn =
      conn
      |> assign(:user, user)
      |> post("/api/v1/statuses", %{
        "status" => "http://example.com/ogp"
      })

    assert %{"id" => id, "card" => %{"title" => "The Rock"}} = json_response(conn, 200)
    assert Repo.get(Activity, id)
lain's avatar
lain committed
157
    Pleroma.Config.put([:rich_media, :enabled], false)
158
159
  end

csaurus's avatar
csaurus committed
160
  test "posting a direct status", %{conn: conn} do
161
162
163
164
165
166
167
168
169
170
171
    user1 = insert(:user)
    user2 = insert(:user)
    content = "direct cofe @#{user2.nickname}"

    conn =
      conn
      |> assign(:user, user1)
      |> post("api/v1/statuses", %{"status" => content, "visibility" => "direct"})

    assert %{"id" => id, "visibility" => "direct"} = json_response(conn, 200)
    assert activity = Repo.get(Activity, id)
Maxim Filippov's avatar
Maxim Filippov committed
172
    assert activity.recipients == [user2.ap_id, user1.ap_id]
lain's avatar
lain committed
173
174
    assert activity.data["to"] == [user2.ap_id]
    assert activity.data["cc"] == []
175
176
177
  end

  test "direct timeline", %{conn: conn} do
lain's avatar
lain committed
178
179
    user_one = insert(:user)
    user_two = insert(:user)
180

lain's avatar
lain committed
181
    {:ok, user_two} = User.follow(user_two, user_one)
182

lain's avatar
lain committed
183
184
185
186
187
188
189
190
191
192
193
194
195
196
    {:ok, direct} =
      CommonAPI.post(user_one, %{
        "status" => "Hi @#{user_two.nickname}!",
        "visibility" => "direct"
      })

    {:ok, _follower_only} =
      CommonAPI.post(user_one, %{
        "status" => "Hi @#{user_two.nickname}!",
        "visibility" => "private"
      })

    # Only direct should be visible here
    res_conn =
197
      conn
lain's avatar
lain committed
198
      |> assign(:user, user_two)
199
200
      |> get("api/v1/timelines/direct")

lain's avatar
lain committed
201
202
203
204
205
    [status] = json_response(res_conn, 200)

    assert %{"visibility" => "direct"} = status
    assert status["url"] != direct.data["id"]

Maxim Filippov's avatar
Maxim Filippov committed
206
207
208
209
210
211
212
213
214
215
    # User should be able to see his own direct message
    res_conn =
      build_conn()
      |> assign(:user, user_one)
      |> get("api/v1/timelines/direct")

    [status] = json_response(res_conn, 200)

    assert %{"visibility" => "direct"} = status

lain's avatar
lain committed
216
217
218
219
220
    # Both should be visible here
    res_conn =
      conn
      |> assign(:user, user_two)
      |> get("api/v1/timelines/home")
221

lain's avatar
lain committed
222
    [_s1, _s2] = json_response(res_conn, 200)
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248

    # Test pagination
    Enum.each(1..20, fn _ ->
      {:ok, _} =
        CommonAPI.post(user_one, %{
          "status" => "Hi @#{user_two.nickname}!",
          "visibility" => "direct"
        })
    end)

    res_conn =
      conn
      |> assign(:user, user_two)
      |> get("api/v1/timelines/direct")

    statuses = json_response(res_conn, 200)
    assert length(statuses) == 20

    res_conn =
      conn
      |> assign(:user, user_two)
      |> get("api/v1/timelines/direct", %{max_id: List.last(statuses)["id"]})

    [status] = json_response(res_conn, 200)

    assert status["url"] != direct.data["id"]
csaurus's avatar
csaurus committed
249
250
  end

Eugenij's avatar
Eugenij committed
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
  test "doesn't include DMs from blocked users", %{conn: conn} do
    blocker = insert(:user)
    blocked = insert(:user)
    user = insert(:user)
    {:ok, blocker} = User.block(blocker, blocked)

    {:ok, _blocked_direct} =
      CommonAPI.post(blocked, %{
        "status" => "Hi @#{blocker.nickname}!",
        "visibility" => "direct"
      })

    {:ok, direct} =
      CommonAPI.post(user, %{
        "status" => "Hi @#{blocker.nickname}!",
        "visibility" => "direct"
      })

    res_conn =
      conn
      |> assign(:user, user)
      |> get("api/v1/timelines/direct")

    [status] = json_response(res_conn, 200)
    assert status["id"] == direct.id
  end

lain's avatar
lain committed
278
279
280
281
282
  test "replying to a status", %{conn: conn} do
    user = insert(:user)

    {:ok, replied_to} = TwitterAPI.create_status(user, %{"status" => "cofe"})

lain's avatar
lain committed
283
284
285
286
    conn =
      conn
      |> assign(:user, user)
      |> post("/api/v1/statuses", %{"status" => "xD", "in_reply_to_id" => replied_to.id})
lain's avatar
lain committed
287
288
289
290
291
292
293
294
295

    assert %{"content" => "xD", "id" => id} = json_response(conn, 200)

    activity = Repo.get(Activity, id)

    assert activity.data["context"] == replied_to.data["context"]
    assert activity.data["object"]["inReplyToStatusId"] == replied_to.id
  end

lain's avatar
lain committed
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
  test "posting a status with an invalid in_reply_to_id", %{conn: conn} do
    user = insert(:user)

    conn =
      conn
      |> assign(:user, user)
      |> post("/api/v1/statuses", %{"status" => "xD", "in_reply_to_id" => ""})

    assert %{"content" => "xD", "id" => id} = json_response(conn, 200)

    activity = Repo.get(Activity, id)

    assert activity
  end

lain's avatar
lain committed
311
312
313
  test "verify_credentials", %{conn: conn} do
    user = insert(:user)

lain's avatar
lain committed
314
315
316
317
    conn =
      conn
      |> assign(:user, user)
      |> get("/api/v1/accounts/verify_credentials")
lain's avatar
lain committed
318

319
320
321
322
323
    assert %{"id" => id, "source" => %{"privacy" => "public"}} = json_response(conn, 200)
    assert id == to_string(user.id)
  end

  test "verify_credentials default scope unlisted", %{conn: conn} do
lain's avatar
lain committed
324
    user = insert(:user, %{info: %Pleroma.User.Info{default_scope: "unlisted"}})
325
326
327
328
329
330
331

    conn =
      conn
      |> assign(:user, user)
      |> get("/api/v1/accounts/verify_credentials")

    assert %{"id" => id, "source" => %{"privacy" => "unlisted"}} = json_response(conn, 200)
lain's avatar
lain committed
332
    assert id == to_string(user.id)
lain's avatar
lain committed
333
334
335
336
337
  end

  test "get a status", %{conn: conn} do
    activity = insert(:note_activity)

lain's avatar
lain committed
338
339
340
    conn =
      conn
      |> get("/api/v1/statuses/#{activity.id}")
lain's avatar
lain committed
341
342

    assert %{"id" => id} = json_response(conn, 200)
lain's avatar
lain committed
343
    assert id == to_string(activity.id)
lain's avatar
lain committed
344
  end
lain's avatar
lain committed
345
346
347
348
349
350

  describe "deleting a status" do
    test "when you created it", %{conn: conn} do
      activity = insert(:note_activity)
      author = User.get_by_ap_id(activity.data["actor"])

lain's avatar
lain committed
351
352
353
354
      conn =
        conn
        |> assign(:user, author)
        |> delete("/api/v1/statuses/#{activity.id}")
lain's avatar
lain committed
355
356
357

      assert %{} = json_response(conn, 200)

358
      refute Repo.get(Activity, activity.id)
lain's avatar
lain committed
359
360
361
362
363
364
    end

    test "when you didn't create it", %{conn: conn} do
      activity = insert(:note_activity)
      user = insert(:user)

lain's avatar
lain committed
365
366
367
368
      conn =
        conn
        |> assign(:user, user)
        |> delete("/api/v1/statuses/#{activity.id}")
lain's avatar
lain committed
369
370
371
372
373

      assert %{"error" => _} = json_response(conn, 403)

      assert Repo.get(Activity, activity.id) == activity
    end
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397

    test "when you're an admin or moderator", %{conn: conn} do
      activity1 = insert(:note_activity)
      activity2 = insert(:note_activity)
      admin = insert(:user, info: %{is_admin: true})
      moderator = insert(:user, info: %{is_moderator: true})

      res_conn =
        conn
        |> assign(:user, admin)
        |> delete("/api/v1/statuses/#{activity1.id}")

      assert %{} = json_response(res_conn, 200)

      res_conn =
        conn
        |> assign(:user, moderator)
        |> delete("/api/v1/statuses/#{activity2.id}")

      assert %{} = json_response(res_conn, 200)

      refute Repo.get(Activity, activity1.id)
      refute Repo.get(Activity, activity2.id)
    end
lain's avatar
lain committed
398
  end
lain's avatar
lain committed
399

Haelwenn's avatar
Haelwenn committed
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
  describe "filters" do
    test "creating a filter", %{conn: conn} do
      user = insert(:user)

      filter = %Pleroma.Filter{
        phrase: "knights",
        context: ["home"]
      }

      conn =
        conn
        |> assign(:user, user)
        |> post("/api/v1/filters", %{"phrase" => filter.phrase, context: filter.context})

      assert response = json_response(conn, 200)
      assert response["phrase"] == filter.phrase
      assert response["context"] == filter.context
Lee Starnes's avatar
Lee Starnes committed
417
418
      assert response["id"] != nil
      assert response["id"] != ""
Haelwenn's avatar
Haelwenn committed
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
    end

    test "fetching a list of filters", %{conn: conn} do
      user = insert(:user)

      query_one = %Pleroma.Filter{
        user_id: user.id,
        filter_id: 1,
        phrase: "knights",
        context: ["home"]
      }

      query_two = %Pleroma.Filter{
        user_id: user.id,
        filter_id: 2,
        phrase: "who",
        context: ["home"]
      }

      {:ok, filter_one} = Pleroma.Filter.create(query_one)
      {:ok, filter_two} = Pleroma.Filter.create(query_two)

Maksim's avatar
Maksim committed
441
      response =
Haelwenn's avatar
Haelwenn committed
442
443
444
        conn
        |> assign(:user, user)
        |> get("/api/v1/filters")
Maksim's avatar
Maksim committed
445
446
447
448
449
450
451
452
        |> json_response(200)

      assert response ==
               render_json(
                 FilterView,
                 "filters.json",
                 filters: [filter_two, filter_one]
               )
Haelwenn's avatar
Haelwenn committed
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
    end

    test "get a filter", %{conn: conn} do
      user = insert(:user)

      query = %Pleroma.Filter{
        user_id: user.id,
        filter_id: 2,
        phrase: "knight",
        context: ["home"]
      }

      {:ok, filter} = Pleroma.Filter.create(query)

      conn =
        conn
        |> assign(:user, user)
        |> get("/api/v1/filters/#{filter.filter_id}")

kaniini's avatar
kaniini committed
472
      assert _response = json_response(conn, 200)
Haelwenn's avatar
Haelwenn committed
473
474
475
476
477
478
479
480
481
482
483
484
    end

    test "update a filter", %{conn: conn} do
      user = insert(:user)

      query = %Pleroma.Filter{
        user_id: user.id,
        filter_id: 2,
        phrase: "knight",
        context: ["home"]
      }

Maksim's avatar
Maksim committed
485
      {:ok, _filter} = Pleroma.Filter.create(query)
Haelwenn's avatar
Haelwenn committed
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526

      new = %Pleroma.Filter{
        phrase: "nii",
        context: ["home"]
      }

      conn =
        conn
        |> assign(:user, user)
        |> put("/api/v1/filters/#{query.filter_id}", %{
          phrase: new.phrase,
          context: new.context
        })

      assert response = json_response(conn, 200)
      assert response["phrase"] == new.phrase
      assert response["context"] == new.context
    end

    test "delete a filter", %{conn: conn} do
      user = insert(:user)

      query = %Pleroma.Filter{
        user_id: user.id,
        filter_id: 2,
        phrase: "knight",
        context: ["home"]
      }

      {:ok, filter} = Pleroma.Filter.create(query)

      conn =
        conn
        |> assign(:user, user)
        |> delete("/api/v1/filters/#{filter.filter_id}")

      assert response = json_response(conn, 200)
      assert response == %{}
    end
  end

eal's avatar
eal committed
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
  describe "lists" do
    test "creating a list", %{conn: conn} do
      user = insert(:user)

      conn =
        conn
        |> assign(:user, user)
        |> post("/api/v1/lists", %{"title" => "cuties"})

      assert %{"title" => title} = json_response(conn, 200)
      assert title == "cuties"
    end

    test "adding users to a list", %{conn: conn} do
      user = insert(:user)
      other_user = insert(:user)
      {:ok, list} = Pleroma.List.create("name", user)

      conn =
        conn
        |> assign(:user, user)
        |> post("/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]})

      assert %{} == json_response(conn, 200)
      %Pleroma.List{following: following} = Pleroma.List.get(list.id, user)
      assert following == [other_user.follower_address]
    end

    test "removing users from a list", %{conn: conn} do
      user = insert(:user)
      other_user = insert(:user)
      third_user = insert(:user)
      {:ok, list} = Pleroma.List.create("name", user)
      {:ok, list} = Pleroma.List.follow(list, other_user)
      {:ok, list} = Pleroma.List.follow(list, third_user)

      conn =
        conn
        |> assign(:user, user)
        |> delete("/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]})

      assert %{} == json_response(conn, 200)
      %Pleroma.List{following: following} = Pleroma.List.get(list.id, user)
      assert following == [third_user.follower_address]
    end

    test "listing users in a list", %{conn: conn} do
      user = insert(:user)
      other_user = insert(:user)
      {:ok, list} = Pleroma.List.create("name", user)
      {:ok, list} = Pleroma.List.follow(list, other_user)

      conn =
        conn
        |> assign(:user, user)
        |> get("/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]})

      assert [%{"id" => id}] = json_response(conn, 200)
      assert id == to_string(other_user.id)
    end

    test "retrieving a list", %{conn: conn} do
      user = insert(:user)
      {:ok, list} = Pleroma.List.create("name", user)

      conn =
        conn
        |> assign(:user, user)
        |> get("/api/v1/lists/#{list.id}")

      assert %{"id" => id} = json_response(conn, 200)
      assert id == to_string(list.id)
    end

    test "renaming a list", %{conn: conn} do
      user = insert(:user)
      {:ok, list} = Pleroma.List.create("name", user)

      conn =
        conn
        |> assign(:user, user)
        |> put("/api/v1/lists/#{list.id}", %{"title" => "newname"})

      assert %{"title" => name} = json_response(conn, 200)
      assert name == "newname"
    end

    test "deleting a list", %{conn: conn} do
      user = insert(:user)
      {:ok, list} = Pleroma.List.create("name", user)

      conn =
        conn
        |> assign(:user, user)
        |> delete("/api/v1/lists/#{list.id}")

      assert %{} = json_response(conn, 200)
      assert is_nil(Repo.get(Pleroma.List, list.id))
    end

    test "list timeline", %{conn: conn} do
      user = insert(:user)
      other_user = insert(:user)
lain's avatar
lain committed
630
      {:ok, _activity_one} = TwitterAPI.create_status(user, %{"status" => "Marisa is cute."})
eal's avatar
eal committed
631
632
633
634
635
636
637
638
639
640
641
642
643
      {:ok, activity_two} = TwitterAPI.create_status(other_user, %{"status" => "Marisa is cute."})
      {:ok, list} = Pleroma.List.create("name", user)
      {:ok, list} = Pleroma.List.follow(list, other_user)

      conn =
        conn
        |> assign(:user, user)
        |> get("/api/v1/timelines/list/#{list.id}")

      assert [%{"id" => id}] = json_response(conn, 200)

      assert id == to_string(activity_two.id)
    end
644
645
646
647
648
649

    test "list timeline does not leak non-public statuses for unfollowed users", %{conn: conn} do
      user = insert(:user)
      other_user = insert(:user)
      {:ok, activity_one} = TwitterAPI.create_status(other_user, %{"status" => "Marisa is cute."})

Maksim's avatar
Maksim committed
650
      {:ok, _activity_two} =
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
        TwitterAPI.create_status(other_user, %{
          "status" => "Marisa is cute.",
          "visibility" => "private"
        })

      {:ok, list} = Pleroma.List.create("name", user)
      {:ok, list} = Pleroma.List.follow(list, other_user)

      conn =
        conn
        |> assign(:user, user)
        |> get("/api/v1/timelines/list/#{list.id}")

      assert [%{"id" => id}] = json_response(conn, 200)

      assert id == to_string(activity_one.id)
    end
eal's avatar
eal committed
668
669
  end

670
671
672
673
674
  describe "notifications" do
    test "list of notifications", %{conn: conn} do
      user = insert(:user)
      other_user = insert(:user)

lain's avatar
lain committed
675
676
677
      {:ok, activity} =
        TwitterAPI.create_status(other_user, %{"status" => "hi @#{user.nickname}"})

lain's avatar
lain committed
678
      {:ok, [_notification]} = Notification.create_notifications(activity)
679

lain's avatar
lain committed
680
681
682
683
684
685
      conn =
        conn
        |> assign(:user, user)
        |> get("/api/v1/notifications")

      expected_response =
kaniini's avatar
kaniini committed
686
687
688
        "hi <span class=\"h-card\"><a data-user=\"#{user.id}\" class=\"u-url mention\" href=\"#{
          user.ap_id
        }\">@<span>#{user.nickname}</span></a></span>"
689
690
691
692
693
694
695
696
697

      assert [%{"status" => %{"content" => response}} | _rest] = json_response(conn, 200)
      assert response == expected_response
    end

    test "getting a single notification", %{conn: conn} do
      user = insert(:user)
      other_user = insert(:user)

lain's avatar
lain committed
698
699
700
      {:ok, activity} =
        TwitterAPI.create_status(other_user, %{"status" => "hi @#{user.nickname}"})

701
702
      {:ok, [notification]} = Notification.create_notifications(activity)

lain's avatar
lain committed
703
704
705
706
707
708
      conn =
        conn
        |> assign(:user, user)
        |> get("/api/v1/notifications/#{notification.id}")

      expected_response =
kaniini's avatar
kaniini committed
709
710
711
        "hi <span class=\"h-card\"><a data-user=\"#{user.id}\" class=\"u-url mention\" href=\"#{
          user.ap_id
        }\">@<span>#{user.nickname}</span></a></span>"
712
713
714
715
716
717
718
719
720

      assert %{"status" => %{"content" => response}} = json_response(conn, 200)
      assert response == expected_response
    end

    test "dismissing a single notification", %{conn: conn} do
      user = insert(:user)
      other_user = insert(:user)

lain's avatar
lain committed
721
722
723
      {:ok, activity} =
        TwitterAPI.create_status(other_user, %{"status" => "hi @#{user.nickname}"})

724
725
      {:ok, [notification]} = Notification.create_notifications(activity)

lain's avatar
lain committed
726
727
728
729
      conn =
        conn
        |> assign(:user, user)
        |> post("/api/v1/notifications/dismiss", %{"id" => notification.id})
730
731
732
733
734
735
736
737

      assert %{} = json_response(conn, 200)
    end

    test "clearing all notifications", %{conn: conn} do
      user = insert(:user)
      other_user = insert(:user)

lain's avatar
lain committed
738
739
740
      {:ok, activity} =
        TwitterAPI.create_status(other_user, %{"status" => "hi @#{user.nickname}"})

lain's avatar
lain committed
741
      {:ok, [_notification]} = Notification.create_notifications(activity)
742

lain's avatar
lain committed
743
744
745
746
      conn =
        conn
        |> assign(:user, user)
        |> post("/api/v1/notifications/clear")
747
748
749

      assert %{} = json_response(conn, 200)

lain's avatar
lain committed
750
751
752
753
      conn =
        build_conn()
        |> assign(:user, user)
        |> get("/api/v1/notifications")
754
755
756
757
758
759

      assert all = json_response(conn, 200)
      assert all == []
    end
  end

lain's avatar
lain committed
760
761
762
763
764
  describe "reblogging" do
    test "reblogs and returns the reblogged status", %{conn: conn} do
      activity = insert(:note_activity)
      user = insert(:user)

lain's avatar
lain committed
765
766
767
768
769
770
771
      conn =
        conn
        |> assign(:user, user)
        |> post("/api/v1/statuses/#{activity.id}/reblog")

      assert %{"reblog" => %{"id" => id, "reblogged" => true, "reblogs_count" => 1}} =
               json_response(conn, 200)
lain's avatar
lain committed
772

lain's avatar
lain committed
773
      assert to_string(activity.id) == id
lain's avatar
lain committed
774
775
    end
  end
lain's avatar
lain committed
776

normandy's avatar
normandy committed
777
778
779
780
781
782
783
784
785
786
787
788
  describe "unreblogging" do
    test "unreblogs and returns the unreblogged status", %{conn: conn} do
      activity = insert(:note_activity)
      user = insert(:user)

      {:ok, _, _} = CommonAPI.repeat(activity.id, user)

      conn =
        conn
        |> assign(:user, user)
        |> post("/api/v1/statuses/#{activity.id}/unreblog")

normandy's avatar
normandy committed
789
      assert %{"id" => id, "reblogged" => false, "reblogs_count" => 0} = json_response(conn, 200)
normandy's avatar
normandy committed
790
791
792
793
794

      assert to_string(activity.id) == id
    end
  end

lain's avatar
lain committed
795
796
797
798
799
  describe "favoriting" do
    test "favs a status and returns it", %{conn: conn} do
      activity = insert(:note_activity)
      user = insert(:user)

lain's avatar
lain committed
800
801
802
803
804
805
806
      conn =
        conn
        |> assign(:user, user)
        |> post("/api/v1/statuses/#{activity.id}/favourite")

      assert %{"id" => id, "favourites_count" => 1, "favourited" => true} =
               json_response(conn, 200)
lain's avatar
lain committed
807

lain's avatar
lain committed
808
      assert to_string(activity.id) == id
lain's avatar
lain committed
809
    end
810
811
812
813
814
815
816
817
818
819
820
821

    test "returns 500 for a wrong id", %{conn: conn} do
      user = insert(:user)

      resp =
        conn
        |> assign(:user, user)
        |> post("/api/v1/statuses/1/favourite")
        |> json_response(500)

      assert resp == "Something went wrong"
    end
lain's avatar
lain committed
822
  end
lain's avatar
lain committed
823
824
825
826
827
828
829
830

  describe "unfavoriting" do
    test "unfavorites a status and returns it", %{conn: conn} do
      activity = insert(:note_activity)
      user = insert(:user)

      {:ok, _, _} = CommonAPI.favorite(activity.id, user)

lain's avatar
lain committed
831
832
833
834
835
836
837
      conn =
        conn
        |> assign(:user, user)
        |> post("/api/v1/statuses/#{activity.id}/unfavourite")

      assert %{"id" => id, "favourites_count" => 0, "favourited" => false} =
               json_response(conn, 200)
lain's avatar
lain committed
838

lain's avatar
lain committed
839
      assert to_string(activity.id) == id
lain's avatar
lain committed
840
841
    end
  end
lain's avatar
lain committed
842
843
844

  describe "user timelines" do
    test "gets a users statuses", %{conn: conn} do
845
846
847
      user_one = insert(:user)
      user_two = insert(:user)
      user_three = insert(:user)
lain's avatar
lain committed
848

849
      {:ok, user_three} = User.follow(user_three, user_one)
lain's avatar
lain committed
850

851
852
853
854
855
856
857
858
859
860
861
862
      {:ok, activity} = CommonAPI.post(user_one, %{"status" => "HI!!!"})

      {:ok, direct_activity} =
        CommonAPI.post(user_one, %{
          "status" => "Hi, @#{user_two.nickname}.",
          "visibility" => "direct"
        })

      {:ok, private_activity} =
        CommonAPI.post(user_one, %{"status" => "private", "visibility" => "private"})

      resp =
lain's avatar
lain committed
863
        conn
864
        |> get("/api/v1/accounts/#{user_one.id}/statuses")
lain's avatar
lain committed
865

866
867
      assert [%{"id" => id}] = json_response(resp, 200)
      assert id == to_string(activity.id)
lain's avatar
lain committed
868

869
870
871
872
      resp =
        conn
        |> assign(:user, user_two)
        |> get("/api/v1/accounts/#{user_one.id}/statuses")
lain's avatar
lain committed
873

874
875
876
877
878
879
880
881
      assert [%{"id" => id_one}, %{"id" => id_two}] = json_response(resp, 200)
      assert id_one == to_string(direct_activity.id)
      assert id_two == to_string(activity.id)

      resp =
        conn
        |> assign(:user, user_three)
        |> get("/api/v1/accounts/#{user_one.id}/statuses")
lain's avatar
lain committed
882

883
884
885
      assert [%{"id" => id_one}, %{"id" => id_two}] = json_response(resp, 200)
      assert id_one == to_string(private_activity.id)
      assert id_two == to_string(activity.id)
lain's avatar
lain committed
886
    end
eal's avatar
eal committed
887

Gian Sass's avatar
Gian Sass committed
888
889
    test "unimplemented pinned statuses feature", %{conn: conn} do
      note = insert(:note_activity)
Gian Sass's avatar
Oops    
Gian Sass committed
890
      user = User.get_by_ap_id(note.data["actor"])
Gian Sass's avatar
Gian Sass committed
891
892
893
894
895
896
897
898

      conn =
        conn
        |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true")

      assert json_response(conn, 200) == []
    end

eal's avatar
eal committed
899
900
901
902
    test "gets an users media", %{conn: conn} do
      note = insert(:note_activity)
      user = User.get_by_ap_id(note.data["actor"])

lain's avatar
lain committed
903
904
905
906
907
      file = %Plug.Upload{
        content_type: "image/jpg",
        path: Path.absname("test/fixtures/image.jpg"),
        filename: "an_image.jpg"
      }
eal's avatar
eal committed
908

lain's avatar
lain committed
909
      media =
910
        TwitterAPI.upload(file, user, "json")
lain's avatar
lain committed
911
        |> Poison.decode!()
eal's avatar
eal committed
912

lain's avatar
lain committed
913
914
915
916
917
918
      {:ok, image_post} =
        TwitterAPI.create_status(user, %{"status" => "cofe", "media_ids" => [media["media_id"]]})

      conn =
        conn
        |> get("/api/v1/accounts/#{user.id}/statuses", %{"only_media" => "true"})
eal's avatar
eal committed
919
920
921
922

      assert [%{"id" => id}] = json_response(conn, 200)
      assert id == to_string(image_post.id)

lain's avatar
lain committed
923
924
925
      conn =
        build_conn()
        |> get("/api/v1/accounts/#{user.id}/statuses", %{"only_media" => "1"})
eal's avatar
eal committed
926
927
928
929

      assert [%{"id" => id}] = json_response(conn, 200)
      assert id == to_string(image_post.id)
    end
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949

    test "gets a user's statuses without reblogs", %{conn: conn} do
      user = insert(:user)
      {:ok, post} = CommonAPI.post(user, %{"status" => "HI!!!"})
      {:ok, _, _} = CommonAPI.repeat(post.id, user)

      conn =
        conn
        |> get("/api/v1/accounts/#{user.id}/statuses", %{"exclude_reblogs" => "true"})

      assert [%{"id" => id}] = json_response(conn, 200)
      assert id == to_string(post.id)

      conn =
        conn
        |> get("/api/v1/accounts/#{user.id}/statuses", %{"exclude_reblogs" => "1"})

      assert [%{"id" => id}] = json_response(conn, 200)
      assert id == to_string(post.id)
    end
lain's avatar
lain committed
950
  end
Roger Braun's avatar
Roger Braun committed
951
952
953
954
955
956
957

  describe "user relationships" do
    test "returns the relationships for the current user", %{conn: conn} do
      user = insert(:user)
      other_user = insert(:user)
      {:ok, user} = User.follow(user, other_user)

lain's avatar
lain committed
958
959
960
961
      conn =
        conn
        |> assign(:user, user)
        |> get("/api/v1/accounts/relationships", %{"id" => [other_user.id]})
Roger Braun's avatar
Roger Braun committed
962
963
964

      assert [relationship] = json_response(conn, 200)

lain's avatar
lain committed
965
      assert to_string(other_user.id) == relationship["id"]
Roger Braun's avatar
Roger Braun committed
966
967
    end
  end
Roger Braun's avatar
Roger Braun committed
968

kaniini's avatar
kaniini committed
969
970
  describe "locked accounts" do
    test "/api/v1/follow_requests works" do
lain's avatar
lain committed
971
      user = insert(:user, %{info: %Pleroma.User.Info{locked: true}})
kaniini's avatar
kaniini committed
972
973
      other_user = insert(:user)

Maksim's avatar
Maksim committed
974
      {:ok, _activity} = ActivityPub.follow(other_user, user)
kaniini's avatar
kaniini committed
975

976
977
978
979
980
      user = Repo.get(User, user.id)
      other_user = Repo.get(User, other_user.id)

      assert User.following?(other_user, user) == false

kaniini's avatar
kaniini committed
981
982
983
984
985
986
987
988
989
990
      conn =
        build_conn()
        |> assign(:user, user)
        |> get("/api/v1/follow_requests")

      assert [relationship] = json_response(conn, 200)
      assert to_string(other_user.id) == relationship["id"]
    end

    test "/api/v1/follow_requests/:id/authorize works" do
991
      user = insert(:user, %{info: %User.Info{locked: true}})
kaniini's avatar
kaniini committed
992
993
      other_user = insert(:user)

Maksim's avatar
Maksim committed
994
      {:ok, _activity} = ActivityPub.follow(other_user, user)
kaniini's avatar
kaniini committed
995

996
997
998
999
1000
      user = Repo.get(User, user.id)
      other_user = Repo.get(User, other_user.id)

      assert User.following?(other_user, user) == false

For faster browsing, not all history is shown. View entire blame