Add `account_activation_required` to /api/v1/instance
[akkoma] / test / web / mastodon_api / views / account_view_test.exs
index ad209b4a34d8d20e1e24fa502d9ba2a67a4f55e0..f91333e5c3a3033a860410d76ee3abead9a07c8e 100644 (file)
@@ -1,41 +1,39 @@
 # Pleroma: A lightweight social networking server
 # Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
   use Pleroma.DataCase
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
   use Pleroma.DataCase
-  import Pleroma.Factory
+
   alias Pleroma.User
   alias Pleroma.User
+  alias Pleroma.UserRelationship
   alias Pleroma.Web.CommonAPI
   alias Pleroma.Web.MastodonAPI.AccountView
 
   alias Pleroma.Web.CommonAPI
   alias Pleroma.Web.MastodonAPI.AccountView
 
-  test "Represent a user account" do
-    source_data = %{
-      "tag" => [
-        %{
-          "type" => "Emoji",
-          "icon" => %{"url" => "/file.png"},
-          "name" => ":karjalanpiirakka:"
-        }
-      ]
-    }
+  import Pleroma.Factory
+  import Tesla.Mock
 
 
+  setup do
+    mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
+    :ok
+  end
+
+  test "Represent a user account" do
     background_image = %{
       "url" => [%{"href" => "https://example.com/images/asuka_hospital.png"}]
     }
 
     user =
       insert(:user, %{
     background_image = %{
       "url" => [%{"href" => "https://example.com/images/asuka_hospital.png"}]
     }
 
     user =
       insert(:user, %{
-        info: %{
-          note_count: 5,
-          follower_count: 3,
-          source_data: source_data,
-          background: background_image
-        },
+        follower_count: 3,
+        note_count: 5,
+        background: background_image,
         nickname: "shp@shitposter.club",
         name: ":karjalanpiirakka: shp",
         nickname: "shp@shitposter.club",
         name: ":karjalanpiirakka: shp",
-        bio: "<script src=\"invalid-html\"></script><span>valid html</span>",
-        inserted_at: ~N[2017-08-15 15:47:06.597036]
+        bio:
+          "<script src=\"invalid-html\"></script><span>valid html</span>. a<br>b<br/>c<br >d<br />f '&<>\"",
+        inserted_at: ~N[2017-08-15 15:47:06.597036],
+        emoji: %{"karjalanpiirakka" => "/file.png"}
       })
 
     expected = %{
       })
 
     expected = %{
@@ -48,7 +46,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
       followers_count: 3,
       following_count: 0,
       statuses_count: 5,
       followers_count: 3,
       following_count: 0,
       statuses_count: 5,
-      note: "<span>valid html</span>",
+      note: "<span>valid html</span>. a<br/>b<br/>c<br/>d<br/>f &#39;&amp;&lt;&gt;&quot;",
       url: user.ap_id,
       avatar: "http://localhost:4001/images/avi.png",
       avatar_static: "http://localhost:4001/images/avi.png",
       url: user.ap_id,
       avatar: "http://localhost:4001/images/avi.png",
       avatar_static: "http://localhost:4001/images/avi.png",
@@ -56,18 +54,19 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
       header_static: "http://localhost:4001/images/banner.png",
       emojis: [
         %{
       header_static: "http://localhost:4001/images/banner.png",
       emojis: [
         %{
-          "static_url" => "/file.png",
-          "url" => "/file.png",
-          "shortcode" => "karjalanpiirakka",
-          "visible_in_picker" => false
+          static_url: "/file.png",
+          url: "/file.png",
+          shortcode: "karjalanpiirakka",
+          visible_in_picker: false
         }
       ],
       fields: [],
       bot: false,
       source: %{
         }
       ],
       fields: [],
       bot: false,
       source: %{
-        note: "valid html",
+        note: "valid html. a\nb\nc\nd\nf '&<>\"",
         sensitive: false,
         pleroma: %{
         sensitive: false,
         pleroma: %{
+          actor_type: "Person",
           discoverable: false
         },
         fields: []
           discoverable: false
         },
         fields: []
@@ -95,16 +94,17 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
     user = insert(:user)
 
     notification_settings = %{
     user = insert(:user)
 
     notification_settings = %{
-      "followers" => true,
-      "follows" => true,
-      "non_follows" => true,
-      "non_followers" => true
+      followers: true,
+      follows: true,
+      non_followers: true,
+      non_follows: true,
+      privacy_option: false
     }
 
     }
 
-    privacy = user.info.default_scope
+    privacy = user.default_scope
 
     assert %{
 
     assert %{
-             pleroma: %{notification_settings: ^notification_settings},
+             pleroma: %{notification_settings: ^notification_settings, allow_following_move: true},
              source: %{privacy: ^privacy}
            } = AccountView.render("show.json", %{user: user, for: user})
   end
              source: %{privacy: ^privacy}
            } = AccountView.render("show.json", %{user: user, for: user})
   end
@@ -112,7 +112,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
   test "Represent a Service(bot) account" do
     user =
       insert(:user, %{
   test "Represent a Service(bot) account" do
     user =
       insert(:user, %{
-        info: %{note_count: 5, follower_count: 3, source_data: %{"type" => "Service"}},
+        follower_count: 3,
+        note_count: 5,
+        actor_type: "Service",
         nickname: "shp@shitposter.club",
         inserted_at: ~N[2017-08-15 15:47:06.597036]
       })
         nickname: "shp@shitposter.club",
         inserted_at: ~N[2017-08-15 15:47:06.597036]
       })
@@ -140,6 +142,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
         note: user.bio,
         sensitive: false,
         pleroma: %{
         note: user.bio,
         sensitive: false,
         pleroma: %{
+          actor_type: "Service",
           discoverable: false
         },
         fields: []
           discoverable: false
         },
         fields: []
@@ -163,9 +166,20 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
     assert expected == AccountView.render("show.json", %{user: user})
   end
 
     assert expected == AccountView.render("show.json", %{user: user})
   end
 
+  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"
+    assert represented.url == "https://channels.tests.funkwhale.audio/channels/compositions"
+  end
+
   test "Represent a deactivated user for an admin" do
   test "Represent a deactivated user for an admin" do
-    admin = insert(:user, %{info: %{is_admin: true}})
-    deactivated_user = insert(:user, %{info: %{deactivated: true}})
+    admin = insert(:user, is_admin: true)
+    deactivated_user = insert(:user, deactivated: true)
     represented = AccountView.render("show.json", %{user: deactivated_user, for: admin})
     assert represented[:pleroma][:deactivated] == true
   end
     represented = AccountView.render("show.json", %{user: deactivated_user, for: admin})
     assert represented[:pleroma][:deactivated] == true
   end
@@ -184,33 +198,57 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
   end
 
   describe "relationship" do
   end
 
   describe "relationship" do
+    defp test_relationship_rendering(user, other_user, expected_result) do
+      opts = %{user: user, target: other_user, relationships: nil}
+      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)
+
+      assert [expected_result] ==
+               AccountView.render("relationships.json", %{user: user, targets: [other_user]})
+    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
+    }
+
     test "represent a relationship for the following and followed user" do
       user = insert(:user)
       other_user = insert(:user)
 
       {:ok, user} = User.follow(user, other_user)
       {:ok, other_user} = User.follow(other_user, user)
     test "represent a relationship for the following and followed user" do
       user = insert(:user)
       other_user = insert(:user)
 
       {:ok, user} = User.follow(user, other_user)
       {:ok, other_user} = User.follow(other_user, user)
-      {:ok, other_user} = User.subscribe(user, other_user)
-      {:ok, user} = User.mute(user, other_user, true)
-      {:ok, user} = CommonAPI.hide_reblogs(user, other_user)
-
-      expected = %{
-        id: to_string(other_user.id),
-        following: true,
-        followed_by: true,
-        blocking: false,
-        blocked_by: false,
-        muting: true,
-        muting_notifications: true,
-        subscribing: true,
-        requested: false,
-        domain_blocking: false,
-        showing_reblogs: false,
-        endorsed: false
-      }
-
-      assert expected ==
-               AccountView.render("relationship.json", %{user: user, target: other_user})
+      {:ok, _subscription} = User.subscribe(user, other_user)
+      {:ok, _user_relationships} = User.mute(user, other_user, true)
+      {:ok, _reblog_mute} = CommonAPI.hide_reblogs(user, other_user)
+
+      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)
     end
 
     test "represent a relationship for the blocking and blocked user" do
     end
 
     test "represent a relationship for the blocking and blocked user" do
@@ -218,27 +256,17 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
       other_user = insert(:user)
 
       {:ok, user} = User.follow(user, other_user)
       other_user = insert(:user)
 
       {:ok, user} = User.follow(user, other_user)
-      {:ok, other_user} = User.subscribe(user, other_user)
-      {:ok, user} = User.block(user, other_user)
-      {:ok, other_user} = User.block(other_user, user)
-
-      expected = %{
-        id: to_string(other_user.id),
-        following: false,
-        followed_by: false,
-        blocking: true,
-        blocked_by: true,
-        muting: false,
-        muting_notifications: false,
-        subscribing: false,
-        requested: false,
-        domain_blocking: false,
-        showing_reblogs: true,
-        endorsed: false
-      }
+      {:ok, _subscription} = User.subscribe(user, other_user)
+      {:ok, _user_relationship} = User.block(user, other_user)
+      {:ok, _user_relationship} = User.block(other_user, user)
+
+      expected =
+        Map.merge(
+          @blank_response,
+          %{following: false, blocking: true, blocked_by: true, id: to_string(other_user.id)}
+        )
 
 
-      assert expected ==
-               AccountView.render("relationship.json", %{user: user, target: other_user})
+      test_relationship_rendering(user, other_user, expected)
     end
 
     test "represent a relationship for the user blocking a domain" do
     end
 
     test "represent a relationship for the user blocking a domain" do
@@ -247,112 +275,35 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
 
       {:ok, user} = User.block_domain(user, "bad.site")
 
 
       {:ok, user} = User.block_domain(user, "bad.site")
 
-      assert %{domain_blocking: true, blocking: false} =
-               AccountView.render("relationship.json", %{user: user, target: other_user})
+      expected =
+        Map.merge(
+          @blank_response,
+          %{domain_blocking: true, blocking: false, id: to_string(other_user.id)}
+        )
+
+      test_relationship_rendering(user, other_user, expected)
     end
 
     test "represent a relationship for the user with a pending follow request" do
       user = insert(:user)
     end
 
     test "represent a relationship for the user with a pending follow request" do
       user = insert(:user)
-      other_user = insert(:user, %{info: %User.Info{locked: true}})
+      other_user = insert(:user, locked: true)
 
       {: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)
 
 
       {: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)
 
-      expected = %{
-        id: to_string(other_user.id),
-        following: false,
-        followed_by: false,
-        blocking: false,
-        blocked_by: false,
-        muting: false,
-        muting_notifications: false,
-        subscribing: false,
-        requested: true,
-        domain_blocking: false,
-        showing_reblogs: true,
-        endorsed: false
-      }
+      expected =
+        Map.merge(
+          @blank_response,
+          %{requested: true, following: false, id: to_string(other_user.id)}
+        )
 
 
-      assert expected ==
-               AccountView.render("relationship.json", %{user: user, target: other_user})
+      test_relationship_rendering(user, other_user, expected)
     end
   end
 
     end
   end
 
-  test "represent an embedded relationship" do
-    user =
-      insert(:user, %{
-        info: %{note_count: 5, follower_count: 0, source_data: %{"type" => "Service"}},
-        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)
-    {:ok, other_user} = User.block(other_user, user)
-    {:ok, _} = User.follow(insert(:user), user)
-
-    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: 1,
-      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: %{
-        note: user.bio,
-        sensitive: false,
-        pleroma: %{
-          discoverable: false
-        },
-        fields: []
-      },
-      pleroma: %{
-        background_image: nil,
-        confirmation_pending: false,
-        tags: [],
-        is_admin: false,
-        is_moderator: false,
-        hide_favorites: true,
-        hide_followers: false,
-        hide_follows: false,
-        hide_followers_count: false,
-        hide_follows_count: false,
-        relationship: %{
-          id: to_string(user.id),
-          following: false,
-          followed_by: false,
-          blocking: true,
-          blocked_by: false,
-          subscribing: false,
-          muting: false,
-          muting_notifications: false,
-          requested: false,
-          domain_blocking: false,
-          showing_reblogs: true,
-          endorsed: false
-        },
-        skip_thread_containment: false
-      }
-    }
-
-    assert expected == AccountView.render("show.json", %{user: user, for: other_user})
-  end
-
   test "returns the settings store if the requesting user is the represented user and it's requested specifically" do
   test "returns the settings store if the requesting user is the represented user and it's requested specifically" do
-    user = insert(:user, %{info: %User.Info{pleroma_settings_store: %{fe: "test"}}})
+    user = insert(:user, pleroma_settings_store: %{fe: "test"})
 
     result =
       AccountView.render("show.json", %{user: user, for: user, with_pleroma_settings: true})
 
     result =
       AccountView.render("show.json", %{user: user, for: user, with_pleroma_settings: true})
@@ -366,22 +317,29 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
     assert result.pleroma[:settings_store] == nil
   end
 
     assert result.pleroma[:settings_store] == nil
   end
 
-  test "sanitizes display names" do
+  test "doesn't sanitize display names" do
     user = insert(:user, name: "<marquee> username </marquee>")
     result = AccountView.render("show.json", %{user: user})
     user = insert(:user, name: "<marquee> username </marquee>")
     result = AccountView.render("show.json", %{user: user})
-    refute result.display_name == "<marquee> username </marquee>"
+    assert result.display_name == "<marquee> username </marquee>"
+  end
+
+  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
 
   describe "hiding follows/following" do
     test "shows when follows/followers stats are hidden and sets follow/follower count to 0" do
   end
 
   describe "hiding follows/following" do
     test "shows when follows/followers stats are hidden and sets follow/follower count to 0" do
-      info = %{
-        hide_followers: true,
-        hide_followers_count: true,
-        hide_follows: true,
-        hide_follows_count: true
-      }
-
-      user = insert(:user, info: info)
+      user =
+        insert(:user, %{
+          hide_followers: true,
+          hide_followers_count: true,
+          hide_follows: true,
+          hide_follows_count: true
+        })
 
       other_user = insert(:user)
       {:ok, user, other_user, _activity} = CommonAPI.follow(user, other_user)
 
       other_user = insert(:user)
       {:ok, user, other_user, _activity} = CommonAPI.follow(user, other_user)
@@ -395,7 +353,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
     end
 
     test "shows when follows/followers are hidden" do
     end
 
     test "shows when follows/followers are hidden" do
-      user = insert(:user, info: %{hide_followers: true, hide_follows: true})
+      user = insert(:user, hide_followers: true, hide_follows: true)
       other_user = insert(:user)
       {:ok, user, other_user, _activity} = CommonAPI.follow(user, other_user)
       {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
       other_user = insert(:user)
       {:ok, user, other_user, _activity} = CommonAPI.follow(user, other_user)
       {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
@@ -408,7 +366,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
     end
 
     test "shows actual follower/following count to the account owner" do
     end
 
     test "shows actual follower/following count to the account owner" do
-      user = insert(:user, info: %{hide_followers: true, hide_follows: true})
+      user = insert(:user, hide_followers: true, hide_follows: true)
       other_user = insert(:user)
       {:ok, user, other_user, _activity} = CommonAPI.follow(user, other_user)
       {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
       other_user = insert(:user)
       {:ok, user, other_user, _activity} = CommonAPI.follow(user, other_user)
       {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
@@ -425,8 +383,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
 
       {:ok, _activity} =
         CommonAPI.post(other_user, %{
 
       {:ok, _activity} =
         CommonAPI.post(other_user, %{
-          "status" => "Hey @#{user.nickname}.",
-          "visibility" => "direct"
+          status: "Hey @#{user.nickname}.",
+          visibility: "direct"
         })
 
       user = User.get_cached_by_ap_id(user.ap_id)
         })
 
       user = User.get_cached_by_ap_id(user.ap_id)
@@ -439,6 +397,24 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
                :unread_conversation_count
              ] == 1
     end
                :unread_conversation_count
              ] == 1
     end
+
+    test "shows unread_count only to the account owner" do
+      user = insert(:user)
+      insert_list(7, :notification, user: user)
+      other_user = insert(:user)
+
+      user = User.get_cached_by_ap_id(user.ap_id)
+
+      assert AccountView.render(
+               "show.json",
+               %{user: user, for: other_user}
+             )[:pleroma][:unread_notifications_count] == nil
+
+      assert AccountView.render(
+               "show.json",
+               %{user: user, for: user}
+             )[:pleroma][:unread_notifications_count] == 7
+    end
   end
 
   describe "follow requests counter" do
   end
 
   describe "follow requests counter" do
@@ -456,7 +432,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
     end
 
     test "shows non-zero when follow requests are pending" do
     end
 
     test "shows non-zero when follow requests are pending" do
-      user = insert(:user, %{info: %{locked: true}})
+      user = insert(:user, locked: true)
 
       assert %{locked: true} = AccountView.render("show.json", %{user: user, for: user})
 
 
       assert %{locked: true} = AccountView.render("show.json", %{user: user, for: user})
 
@@ -468,7 +444,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
     end
 
     test "decreases when accepting a follow request" do
     end
 
     test "decreases when accepting a follow request" do
-      user = insert(:user, %{info: %{locked: true}})
+      user = insert(:user, locked: true)
 
       assert %{locked: true} = AccountView.render("show.json", %{user: user, for: user})
 
 
       assert %{locked: true} = AccountView.render("show.json", %{user: user, for: user})
 
@@ -485,7 +461,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
     end
 
     test "decreases when rejecting a follow request" do
     end
 
     test "decreases when rejecting a follow request" do
-      user = insert(:user, %{info: %{locked: true}})
+      user = insert(:user, locked: true)
 
       assert %{locked: true} = AccountView.render("show.json", %{user: user, for: user})
 
 
       assert %{locked: true} = AccountView.render("show.json", %{user: user, for: user})
 
@@ -502,17 +478,44 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
     end
 
     test "shows non-zero when historical unapproved requests are present" do
     end
 
     test "shows non-zero when historical unapproved requests are present" do
-      user = insert(:user, %{info: %{locked: true}})
+      user = insert(:user, locked: true)
 
       assert %{locked: true} = AccountView.render("show.json", %{user: user, for: user})
 
       other_user = insert(:user)
       {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
 
 
       assert %{locked: true} = AccountView.render("show.json", %{user: user, for: user})
 
       other_user = insert(:user)
       {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
 
-      {:ok, user} = User.update_info(user, &User.Info.user_upgrade(&1, %{locked: false}))
+      {:ok, user} = User.update_and_set_cache(user, %{locked: false})
 
       assert %{locked: false, follow_requests_count: 1} =
                AccountView.render("show.json", %{user: user, for: user})
     end
   end
 
       assert %{locked: false, follow_requests_count: 1} =
                AccountView.render("show.json", %{user: user, for: user})
     end
   end
+
+  test "uses mediaproxy urls when it's enabled" do
+    clear_config([:media_proxy, :enabled], true)
+
+    user =
+      insert(:user,
+        avatar: %{"url" => [%{"href" => "https://evil.website/avatar.png"}]},
+        banner: %{"url" => [%{"href" => "https://evil.website/banner.png"}]},
+        emoji: %{"joker_smile" => "https://evil.website/society.png"}
+      )
+
+    AccountView.render("show.json", %{user: user})
+    |> Enum.all?(fn
+      {key, url} when key in [:avatar, :avatar_static, :header, :header_static] ->
+        String.starts_with?(url, Pleroma.Web.base_url())
+
+      {:emojis, emojis} ->
+        Enum.all?(emojis, fn %{url: url, static_url: static_url} ->
+          String.starts_with?(url, Pleroma.Web.base_url()) &&
+            String.starts_with?(static_url, Pleroma.Web.base_url())
+        end)
+
+      _ ->
+        true
+    end)
+    |> assert()
+  end
 end
 end