added User.NotificationSetting struct
authorMaksim Pechnikov <parallel588@gmail.com>
Mon, 28 Oct 2019 09:47:23 +0000 (12:47 +0300)
committerMaksim Pechnikov <parallel588@gmail.com>
Thu, 28 Nov 2019 19:08:30 +0000 (22:08 +0300)
lib/pleroma/notification.ex
lib/pleroma/user.ex
lib/pleroma/user/notification_setting.ex [new file with mode: 0644]
test/notification_test.exs
test/support/builders/user_builder.ex
test/support/factory.ex
test/user/notification_setting_test.exs [new file with mode: 0644]
test/user_search_test.exs
test/web/mastodon_api/views/account_view_test.exs
test/web/twitter_api/util_controller_test.exs

index b7ecf51e4681fc9a25b8d1cd9d596c928f930bba..acb635fdcda16f4342e9f80658cb971cb4a65392 100644 (file)
@@ -314,7 +314,7 @@ defmodule Pleroma.Notification do
   def skip?(
         :followers,
         activity,
-        %{notification_settings: %{"followers" => false}} = user
+        %{notification_settings: %{followers: false}} = user
       ) do
     actor = activity.data["actor"]
     follower = User.get_cached_by_ap_id(actor)
@@ -324,14 +324,14 @@ defmodule Pleroma.Notification do
   def skip?(
         :non_followers,
         activity,
-        %{notification_settings: %{"non_followers" => false}} = user
+        %{notification_settings: %{non_followers: false}} = user
       ) do
     actor = activity.data["actor"]
     follower = User.get_cached_by_ap_id(actor)
     !User.following?(follower, user)
   end
 
-  def skip?(:follows, activity, %{notification_settings: %{"follows" => false}} = user) do
+  def skip?(:follows, activity, %{notification_settings: %{follows: false}} = user) do
     actor = activity.data["actor"]
     followed = User.get_cached_by_ap_id(actor)
     User.following?(user, followed)
@@ -340,7 +340,7 @@ defmodule Pleroma.Notification do
   def skip?(
         :non_follows,
         activity,
-        %{notification_settings: %{"non_follows" => false}} = user
+        %{notification_settings: %{non_follows: false}} = user
       ) do
     actor = activity.data["actor"]
     followed = User.get_cached_by_ap_id(actor)
index b18a4c6a5099a4d381ec72e51d78033323eb474d..94fca2a9fcaf69b30af6db2c07a78282e21c680a 100644 (file)
@@ -105,13 +105,10 @@ defmodule Pleroma.User do
     field(:invisible, :boolean, default: false)
     field(:skip_thread_containment, :boolean, default: false)
 
-    field(:notification_settings, :map,
-      default: %{
-        "followers" => true,
-        "follows" => true,
-        "non_follows" => true,
-        "non_followers" => true
-      }
+    embeds_one(
+      :notification_settings,
+      Pleroma.User.NotificationSetting,
+      on_replace: :update
     )
 
     has_many(:notifications, Notification)
@@ -1095,20 +1092,9 @@ defmodule Pleroma.User do
   end
 
   def update_notification_settings(%User{} = user, settings) do
-    settings =
-      settings
-      |> Enum.map(fn {k, v} -> {k, v in [true, "true", "True", "1"]} end)
-      |> Map.new()
-
-    notification_settings =
-      user.notification_settings
-      |> Map.merge(settings)
-      |> Map.take(["followers", "follows", "non_follows", "non_followers"])
-
-    params = %{notification_settings: notification_settings}
-
     user
-    |> cast(params, [:notification_settings])
+    |> cast(%{notification_settings: settings}, [])
+    |> cast_embed(:notification_settings)
     |> validate_required([:notification_settings])
     |> update_and_set_cache()
   end
diff --git a/lib/pleroma/user/notification_setting.ex b/lib/pleroma/user/notification_setting.ex
new file mode 100644 (file)
index 0000000..64100c0
--- /dev/null
@@ -0,0 +1,49 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.User.NotificationSetting do
+  use Ecto.Schema
+  import Ecto.Changeset
+
+  @derive Jason.Encoder
+  @primary_key false
+
+  @privacy_options %{
+    name_and_message: "name_and_message",
+    name_only: "name_only",
+    no_name_or_message: "no_name_or_message"
+  }
+
+  embedded_schema do
+    field(:followers, :boolean, default: true)
+    field(:follows, :boolean, default: true)
+    field(:non_follows, :boolean, default: true)
+    field(:non_followers, :boolean, default: true)
+    field(:privacy_option, :string, default: @privacy_options.name_and_message)
+  end
+
+  def changeset(schema, params) do
+    schema
+    |> cast(prepare_attrs(params), [
+      :followers,
+      :follows,
+      :non_follows,
+      :non_followers,
+      :privacy_option
+    ])
+    |> validate_inclusion(:privacy_option, Map.values(@privacy_options))
+  end
+
+  defp prepare_attrs(params) do
+    Enum.reduce(params, %{}, fn
+      {k, v}, acc
+      when k in ["followers", "follows", "non_follows", "non_followers"] and
+             is_binary(v) ->
+        Map.put(acc, k, String.downcase(v))
+
+      {k, v}, acc ->
+        Map.put(acc, k, v)
+    end)
+  end
+end
index f8d42922322353a2d509dc8fc2c4c33313db186a..e7c031c8fa1c423c6c021814d13a800083f7b28c 100644 (file)
@@ -136,7 +136,10 @@ defmodule Pleroma.NotificationTest do
 
     test "it disables notifications from followers" do
       follower = insert(:user)
-      followed = insert(:user, notification_settings: %{"followers" => false})
+
+      followed =
+        insert(:user, notification_settings: %Pleroma.User.NotificationSetting{followers: false})
+
       User.follow(follower, followed)
       {:ok, activity} = CommonAPI.post(follower, %{"status" => "hey @#{followed.nickname}"})
       refute Notification.create_notification(activity, followed)
@@ -144,13 +147,20 @@ defmodule Pleroma.NotificationTest do
 
     test "it disables notifications from non-followers" do
       follower = insert(:user)
-      followed = insert(:user, notification_settings: %{"non_followers" => false})
+
+      followed =
+        insert(:user,
+          notification_settings: %Pleroma.User.NotificationSetting{non_followers: false}
+        )
+
       {:ok, activity} = CommonAPI.post(follower, %{"status" => "hey @#{followed.nickname}"})
       refute Notification.create_notification(activity, followed)
     end
 
     test "it disables notifications from people the user follows" do
-      follower = insert(:user, notification_settings: %{"follows" => false})
+      follower =
+        insert(:user, notification_settings: %Pleroma.User.NotificationSetting{follows: false})
+
       followed = insert(:user)
       User.follow(follower, followed)
       follower = Repo.get(User, follower.id)
@@ -159,7 +169,9 @@ defmodule Pleroma.NotificationTest do
     end
 
     test "it disables notifications from people the user does not follow" do
-      follower = insert(:user, notification_settings: %{"non_follows" => false})
+      follower =
+        insert(:user, notification_settings: %Pleroma.User.NotificationSetting{non_follows: false})
+
       followed = insert(:user)
       {:ok, activity} = CommonAPI.post(followed, %{"status" => "hey @#{follower.nickname}"})
       refute Notification.create_notification(activity, follower)
index 6da16f71a90df664f9467633cfef851502f4c132..fcfea666f1a2f517f2b8a698e632cc0f1c1a9728 100644 (file)
@@ -10,7 +10,8 @@ defmodule Pleroma.Builders.UserBuilder do
       password_hash: Comeonin.Pbkdf2.hashpwsalt("test"),
       bio: "A tester.",
       ap_id: "some id",
-      last_digest_emailed_at: NaiveDateTime.truncate(NaiveDateTime.utc_now(), :second)
+      last_digest_emailed_at: NaiveDateTime.truncate(NaiveDateTime.utc_now(), :second),
+      notification_settings: %Pleroma.User.NotificationSetting{}
     }
 
     Map.merge(user, data)
index e3f797f64c16b4abb0dcc8f05ada8cd8a811479f..4bd82ebd69dbd8119dec0bb5d771e350b2db4934 100644 (file)
@@ -32,7 +32,8 @@ defmodule Pleroma.Factory do
       password_hash: Comeonin.Pbkdf2.hashpwsalt("test"),
       bio: sequence(:bio, &"Tester Number #{&1}"),
       info: %{},
-      last_digest_emailed_at: NaiveDateTime.utc_now()
+      last_digest_emailed_at: NaiveDateTime.utc_now(),
+      notification_settings: %Pleroma.User.NotificationSetting{}
     }
 
     %{
diff --git a/test/user/notification_setting_test.exs b/test/user/notification_setting_test.exs
new file mode 100644 (file)
index 0000000..d1f766e
--- /dev/null
@@ -0,0 +1,40 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.User.NotificationSettingTest do
+  use Pleroma.DataCase
+
+  alias Pleroma.User.NotificationSetting
+
+  describe "changeset/2" do
+    test "sets valid privacy option" do
+      changeset =
+        NotificationSetting.changeset(
+          %NotificationSetting{},
+          %{"privacy_option" => "name_only"}
+        )
+
+      assert %Ecto.Changeset{valid?: true} = changeset
+    end
+
+    test "returns invalid changeset when privacy option is incorrect" do
+      changeset =
+        NotificationSetting.changeset(
+          %NotificationSetting{},
+          %{"privacy_option" => "full_content"}
+        )
+
+      assert %Ecto.Changeset{valid?: false} = changeset
+
+      assert [
+               privacy_option:
+                 {"is invalid",
+                  [
+                    validation: :inclusion,
+                    enum: ["name_and_message", "name_only", "no_name_or_message"]
+                  ]}
+             ] = changeset.errors
+    end
+  end
+end
index 98841dbbda2c231f586a3b17896ca08815f2b737..82185847672a6a2e5affa1be18339721fd78f0f6 100644 (file)
@@ -174,6 +174,7 @@ defmodule Pleroma.UserSearchTest do
         |> Map.put(:search_rank, nil)
         |> Map.put(:search_type, nil)
         |> Map.put(:last_digest_emailed_at, nil)
+        |> Map.put(:notification_settings, nil)
 
       assert user == expected
     end
index d147079ab603f3e2b2592c25dfaa2eda2feb045b..7feff560ccb9ac25100295623fad9c45b93e24ac 100644 (file)
@@ -92,13 +92,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
   test "Represent the user account for the account owner" do
     user = insert(:user)
 
-    notification_settings = %{
-      "followers" => true,
-      "follows" => true,
-      "non_follows" => true,
-      "non_followers" => true
-    }
-
+    notification_settings = %Pleroma.User.NotificationSetting{}
     privacy = user.default_scope
 
     assert %{
index f0211f59c64e4f5681ac7c4ed1cb3462b7386a9a..f1557c1931c5000f6e76c37529e92a852db74401 100644 (file)
@@ -159,11 +159,31 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
 
       user = Repo.get(User, user.id)
 
-      assert %{
-               "followers" => false,
-               "follows" => true,
-               "non_follows" => true,
-               "non_followers" => true
+      assert %Pleroma.User.NotificationSetting{
+               followers: false,
+               follows: true,
+               non_follows: true,
+               non_followers: true,
+               privacy_option: "name_and_message"
+             } == user.notification_settings
+    end
+
+    test "it update notificatin privacy option", %{conn: conn} do
+      user = insert(:user)
+
+      conn
+      |> assign(:user, user)
+      |> put("/api/pleroma/notification_settings", %{"privacy_option" => "name_only"})
+      |> json_response(:ok)
+
+      user = refresh_record(user)
+
+      assert %Pleroma.User.NotificationSetting{
+               followers: true,
+               follows: true,
+               non_follows: true,
+               non_followers: true,
+               privacy_option: "name_only"
              } == user.notification_settings
     end
   end