From a0f2cba0d872c997cb526f8beefe6e2fa222439c Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sat, 12 Jun 2021 15:44:24 -0500 Subject: [PATCH] Add `accepts_newsletter` field to User, set during registration or account updates --- lib/pleroma/user.ex | 13 +++++++++---- .../web/api_spec/operations/account_operation.ex | 12 +++++++++++- .../mastodon_api/controllers/account_controller.ex | 3 ++- lib/pleroma/web/twitter_api/twitter_api.ex | 2 +- ...20210612185407_add_newsletter_field_to_users.exs | 9 +++++++++ test/pleroma/user_test.exs | 21 +++++++++++++++++++++ .../controllers/account_controller_test.exs | 15 +++++++++++++++ .../web/mastodon_api/update_credentials_test.exs | 7 +++++++ test/pleroma/web/twitter_api/twitter_api_test.exs | 14 ++++++++++++++ 9 files changed, 89 insertions(+), 7 deletions(-) create mode 100644 priv/repo/migrations/20210612185407_add_newsletter_field_to_users.exs diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 9942617d8..35910aaff 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -148,6 +148,7 @@ defmodule Pleroma.User do field(:accepts_chat_messages, :boolean, default: nil) field(:last_active_at, :naive_datetime) field(:disclose_client, :boolean, default: true) + field(:accepts_newsletter, :boolean, default: false) embeds_one( :notification_settings, @@ -515,7 +516,8 @@ defmodule Pleroma.User do :is_discoverable, :actor_type, :accepts_chat_messages, - :disclose_client + :disclose_client, + :accepts_newsletter ] ) |> unique_constraint(:nickname) @@ -678,7 +680,8 @@ defmodule Pleroma.User do :name, :nickname, :email, - :accepts_chat_messages + :accepts_chat_messages, + :accepts_newsletter ]) |> validate_required([:name, :nickname]) |> unique_constraint(:nickname) @@ -722,7 +725,8 @@ defmodule Pleroma.User do :password_confirmation, :emoji, :accepts_chat_messages, - :registration_reason + :registration_reason, + :accepts_newsletter ]) |> validate_required([:name, :nickname, :password, :password_confirmation]) |> validate_confirmation(:password) @@ -1709,7 +1713,8 @@ defmodule Pleroma.User do fields: [], raw_fields: [], is_discoverable: false, - also_known_as: [] + also_known_as: [], + accepts_newsletter: false }) end diff --git a/lib/pleroma/web/api_spec/operations/account_operation.ex b/lib/pleroma/web/api_spec/operations/account_operation.ex index 54e5ebc76..0dec46139 100644 --- a/lib/pleroma/web/api_spec/operations/account_operation.ex +++ b/lib/pleroma/web/api_spec/operations/account_operation.ex @@ -458,6 +458,11 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do type: :string, nullable: true, description: "Invite token required when the registrations aren't public" + }, + accepts_newsletter: %Schema{ + allOf: [BooleanLike], + description: + "Whether the user opts-in to receiving news and marketing updates from site admins. These should be presented to the user in order to allow them to consent before setting this parameter to TRUE." } }, example: %{ @@ -635,7 +640,12 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do description: "Discovery (listing, indexing) of this account by external services (search bots etc.) is allowed." }, - actor_type: ActorType + actor_type: ActorType, + accepts_newsletter: %Schema{ + allOf: [BooleanLike], + description: + "Whether the user opts-in to receiving news and marketing updates from site admins." + } }, example: %{ bot: false, diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex index 7a1e99044..c7e21a0d2 100644 --- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex @@ -185,7 +185,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do :skip_thread_containment, :allow_following_move, :also_known_as, - :accepts_chat_messages + :accepts_chat_messages, + :accepts_newsletter ] |> Enum.reduce(%{}, fn key, acc -> Maps.put_if_present(acc, key, params[key], &{:ok, truthy_param?(&1)}) diff --git a/lib/pleroma/web/twitter_api/twitter_api.ex b/lib/pleroma/web/twitter_api/twitter_api.ex index 76ca82d20..f6250a313 100644 --- a/lib/pleroma/web/twitter_api/twitter_api.ex +++ b/lib/pleroma/web/twitter_api/twitter_api.ex @@ -14,7 +14,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do def register_user(params, opts \\ []) do params = params - |> Map.take([:email, :token, :password]) + |> Map.take([:email, :token, :password, :accepts_newsletter]) |> Map.put(:bio, params |> Map.get(:bio, "") |> User.parse_bio()) |> Map.put(:nickname, params[:username]) |> Map.put(:name, Map.get(params, :fullname, params[:username])) diff --git a/priv/repo/migrations/20210612185407_add_newsletter_field_to_users.exs b/priv/repo/migrations/20210612185407_add_newsletter_field_to_users.exs new file mode 100644 index 000000000..ee46a6076 --- /dev/null +++ b/priv/repo/migrations/20210612185407_add_newsletter_field_to_users.exs @@ -0,0 +1,9 @@ +defmodule Pleroma.Repo.Migrations.AddNewsletterFieldToUsers do + use Ecto.Migration + + def change do + alter table(:users) do + add(:accepts_newsletter, :boolean, default: false) + end + end +end diff --git a/test/pleroma/user_test.exs b/test/pleroma/user_test.exs index 6f5bcab57..2cfd54d52 100644 --- a/test/pleroma/user_test.exs +++ b/test/pleroma/user_test.exs @@ -663,6 +663,16 @@ defmodule Pleroma.UserTest do assert user.is_confirmed end + + test "it sets 'accepts_newsletter'" do + params = Map.put_new(@full_user_data, :accepts_newsletter, true) + changeset = User.register_changeset(%User{}, params) + assert changeset.valid? + + {:ok, user} = Repo.insert(changeset) + + assert user.accepts_newsletter + end end describe "user registration, with :account_activation_required" do @@ -737,6 +747,17 @@ defmodule Pleroma.UserTest do end end + describe "update_changeset/2" do + test "it sets :accepts_newsletter" do + changeset = + %User{accepts_newsletter: false} + |> User.update_changeset(%{accepts_newsletter: true}) + + assert changeset.valid? + assert %User{accepts_newsletter: true} = Ecto.Changeset.apply_changes(changeset) + end + end + describe "get_or_fetch/1" do test "gets an existing user by nickname" do user = insert(:user) diff --git a/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs index a327c0d1d..3558394fd 100644 --- a/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs @@ -1125,6 +1125,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do assert user assert user.is_confirmed assert user.is_approved + refute user.accepts_newsletter end test "registers but does not log in with :account_activation_required", %{conn: conn} do @@ -1356,6 +1357,20 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do assert json_response_and_validate_schema(res, 200) end + test "registration with accepts_newsletter", %{conn: conn, valid_params: valid_params} do + app_token = insert(:oauth_token, user: nil) + conn = put_req_header(conn, "authorization", "Bearer " <> app_token.token) + + res = + conn + |> put_req_header("content-type", "application/json") + |> Map.put(:remote_ip, {127, 0, 0, 9}) + |> post("/api/v1/accounts", Map.put(valid_params, :accepts_newsletter, true)) + + assert json_response_and_validate_schema(res, 200) + assert %User{accepts_newsletter: true} = Repo.get_by(User, email: "lain@example.org") + end + test "returns forbidden if token is invalid", %{conn: conn, valid_params: valid_params} do res = conn diff --git a/test/pleroma/web/mastodon_api/update_credentials_test.exs b/test/pleroma/web/mastodon_api/update_credentials_test.exs index cfbe6cf0e..21917e282 100644 --- a/test/pleroma/web/mastodon_api/update_credentials_test.exs +++ b/test/pleroma/web/mastodon_api/update_credentials_test.exs @@ -113,6 +113,13 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do assert user_data["pleroma"]["accepts_chat_messages"] == false end + test "updates the user's newsletter preference", %{user: user, conn: conn} do + conn = patch(conn, "/api/v1/accounts/update_credentials", %{accepts_newsletter: "true"}) + + assert json_response_and_validate_schema(conn, 200) + assert %User{accepts_newsletter: true} = User.get_by_id(user.id) + end + test "updates the user's allow_following_move", %{user: user, conn: conn} do assert user.allow_following_move == true diff --git a/test/pleroma/web/twitter_api/twitter_api_test.exs b/test/pleroma/web/twitter_api/twitter_api_test.exs index 85629be04..295a57d71 100644 --- a/test/pleroma/web/twitter_api/twitter_api_test.exs +++ b/test/pleroma/web/twitter_api/twitter_api_test.exs @@ -146,6 +146,20 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do assert user2.bio == expected_text end + test "it registers a new user with accepts_newsletter." do + data = %{ + :username => "lain", + :email => "lain@wired.jp", + :fullname => "lain iwakura", + :password => "bear", + :confirm => "bear", + :accepts_newsletter => true + } + + {:ok, user} = TwitterAPI.register_user(data) + assert user.accepts_newsletter + end + describe "register with one time token" do setup do: clear_config([:instance, :registrations_open], false)