added User.NotificationSetting struct

This commit is contained in:
Maksim Pechnikov 2019-10-28 12:47:23 +03:00
parent ca1acfa314
commit a52da55eb9
10 changed files with 146 additions and 42 deletions

View File

@ -314,7 +314,7 @@ defmodule Pleroma.Notification do
def skip?( def skip?(
:followers, :followers,
activity, activity,
%{notification_settings: %{"followers" => false}} = user %{notification_settings: %{followers: false}} = user
) do ) do
actor = activity.data["actor"] actor = activity.data["actor"]
follower = User.get_cached_by_ap_id(actor) follower = User.get_cached_by_ap_id(actor)
@ -324,14 +324,14 @@ defmodule Pleroma.Notification do
def skip?( def skip?(
:non_followers, :non_followers,
activity, activity,
%{notification_settings: %{"non_followers" => false}} = user %{notification_settings: %{non_followers: false}} = user
) do ) do
actor = activity.data["actor"] actor = activity.data["actor"]
follower = User.get_cached_by_ap_id(actor) follower = User.get_cached_by_ap_id(actor)
!User.following?(follower, user) !User.following?(follower, user)
end 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"] actor = activity.data["actor"]
followed = User.get_cached_by_ap_id(actor) followed = User.get_cached_by_ap_id(actor)
User.following?(user, followed) User.following?(user, followed)
@ -340,7 +340,7 @@ defmodule Pleroma.Notification do
def skip?( def skip?(
:non_follows, :non_follows,
activity, activity,
%{notification_settings: %{"non_follows" => false}} = user %{notification_settings: %{non_follows: false}} = user
) do ) do
actor = activity.data["actor"] actor = activity.data["actor"]
followed = User.get_cached_by_ap_id(actor) followed = User.get_cached_by_ap_id(actor)

View File

@ -105,13 +105,10 @@ defmodule Pleroma.User do
field(:invisible, :boolean, default: false) field(:invisible, :boolean, default: false)
field(:skip_thread_containment, :boolean, default: false) field(:skip_thread_containment, :boolean, default: false)
field(:notification_settings, :map, embeds_one(
default: %{ :notification_settings,
"followers" => true, Pleroma.User.NotificationSetting,
"follows" => true, on_replace: :update
"non_follows" => true,
"non_followers" => true
}
) )
has_many(:notifications, Notification) has_many(:notifications, Notification)
@ -1095,20 +1092,9 @@ defmodule Pleroma.User do
end end
def update_notification_settings(%User{} = user, settings) do 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 user
|> cast(params, [:notification_settings]) |> cast(%{notification_settings: settings}, [])
|> cast_embed(:notification_settings)
|> validate_required([:notification_settings]) |> validate_required([:notification_settings])
|> update_and_set_cache() |> update_and_set_cache()
end end

View File

@ -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

View File

@ -136,7 +136,10 @@ defmodule Pleroma.NotificationTest do
test "it disables notifications from followers" do test "it disables notifications from followers" do
follower = insert(:user) follower = insert(:user)
followed = insert(:user, notification_settings: %{"followers" => false})
followed =
insert(:user, notification_settings: %Pleroma.User.NotificationSetting{followers: false})
User.follow(follower, followed) User.follow(follower, followed)
{:ok, activity} = CommonAPI.post(follower, %{"status" => "hey @#{followed.nickname}"}) {:ok, activity} = CommonAPI.post(follower, %{"status" => "hey @#{followed.nickname}"})
refute Notification.create_notification(activity, followed) refute Notification.create_notification(activity, followed)
@ -144,13 +147,20 @@ defmodule Pleroma.NotificationTest do
test "it disables notifications from non-followers" do test "it disables notifications from non-followers" do
follower = insert(:user) 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}"}) {:ok, activity} = CommonAPI.post(follower, %{"status" => "hey @#{followed.nickname}"})
refute Notification.create_notification(activity, followed) refute Notification.create_notification(activity, followed)
end end
test "it disables notifications from people the user follows" do 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) followed = insert(:user)
User.follow(follower, followed) User.follow(follower, followed)
follower = Repo.get(User, follower.id) follower = Repo.get(User, follower.id)
@ -159,7 +169,9 @@ defmodule Pleroma.NotificationTest do
end end
test "it disables notifications from people the user does not follow" do 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) followed = insert(:user)
{:ok, activity} = CommonAPI.post(followed, %{"status" => "hey @#{follower.nickname}"}) {:ok, activity} = CommonAPI.post(followed, %{"status" => "hey @#{follower.nickname}"})
refute Notification.create_notification(activity, follower) refute Notification.create_notification(activity, follower)

View File

@ -10,7 +10,8 @@ defmodule Pleroma.Builders.UserBuilder do
password_hash: Comeonin.Pbkdf2.hashpwsalt("test"), password_hash: Comeonin.Pbkdf2.hashpwsalt("test"),
bio: "A tester.", bio: "A tester.",
ap_id: "some id", 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) Map.merge(user, data)

View File

@ -32,7 +32,8 @@ defmodule Pleroma.Factory do
password_hash: Comeonin.Pbkdf2.hashpwsalt("test"), password_hash: Comeonin.Pbkdf2.hashpwsalt("test"),
bio: sequence(:bio, &"Tester Number #{&1}"), bio: sequence(:bio, &"Tester Number #{&1}"),
info: %{}, info: %{},
last_digest_emailed_at: NaiveDateTime.utc_now() last_digest_emailed_at: NaiveDateTime.utc_now(),
notification_settings: %Pleroma.User.NotificationSetting{}
} }
%{ %{

View File

@ -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

View File

@ -174,6 +174,7 @@ defmodule Pleroma.UserSearchTest do
|> Map.put(:search_rank, nil) |> Map.put(:search_rank, nil)
|> Map.put(:search_type, nil) |> Map.put(:search_type, nil)
|> Map.put(:last_digest_emailed_at, nil) |> Map.put(:last_digest_emailed_at, nil)
|> Map.put(:notification_settings, nil)
assert user == expected assert user == expected
end end

View File

@ -92,13 +92,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
test "Represent the user account for the account owner" do test "Represent the user account for the account owner" do
user = insert(:user) user = insert(:user)
notification_settings = %{ notification_settings = %Pleroma.User.NotificationSetting{}
"followers" => true,
"follows" => true,
"non_follows" => true,
"non_followers" => true
}
privacy = user.default_scope privacy = user.default_scope
assert %{ assert %{

View File

@ -159,11 +159,31 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
user = Repo.get(User, user.id) user = Repo.get(User, user.id)
assert %{ assert %Pleroma.User.NotificationSetting{
"followers" => false, followers: false,
"follows" => true, follows: true,
"non_follows" => true, non_follows: true,
"non_followers" => 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 } == user.notification_settings
end end
end end