From a9997d0d2ba01f386579f7d8b4c7d9b471c5ee43 Mon Sep 17 00:00:00 2001 From: evazion Date: Wed, 17 Nov 2021 20:11:06 -0600 Subject: [PATCH] favgroups: make private favgroups a Gold-only option. Make private favgroups a Gold-only option. This is for consistency with private favorites and upvotes being Gold-only options. Existing Members with private favgroups are allowed to keep them, as long as they don't disable privacy. If they disable it, then they can't re-enable it again without upgrading to Gold first. --- app/controllers/favorite_groups_controller.rb | 2 +- app/models/favorite_group.rb | 21 ++++++++++++++++++- app/policies/favorite_group_policy.rb | 6 +++++- app/views/favorite_groups/_form.html.erb | 12 +++++++++++ app/views/favorite_groups/edit.html.erb | 7 +------ app/views/favorite_groups/new.html.erb | 7 +------ test/factories/favorite_group.rb | 5 +++++ .../favorite_groups_controller_test.rb | 15 +++++++++---- 8 files changed, 56 insertions(+), 19 deletions(-) create mode 100644 app/views/favorite_groups/_form.html.erb diff --git a/app/controllers/favorite_groups_controller.rb b/app/controllers/favorite_groups_controller.rb index 3f3b02f9e..f221e97e5 100644 --- a/app/controllers/favorite_groups_controller.rb +++ b/app/controllers/favorite_groups_controller.rb @@ -19,7 +19,7 @@ class FavoriteGroupsController < ApplicationController end def new - @favorite_group = authorize FavoriteGroup.new + @favorite_group = authorize FavoriteGroup.new(creator: CurrentUser.user) respond_with(@favorite_group) end diff --git a/app/models/favorite_group.rb b/app/models/favorite_group.rb index 2cbaacc05..eedde972d 100644 --- a/app/models/favorite_group.rb +++ b/app/models/favorite_group.rb @@ -10,6 +10,7 @@ class FavoriteGroup < ApplicationRecord validate :creator_can_create_favorite_groups, :on => :create validate :validate_number_of_posts validate :validate_posts + validate :validate_can_enable_privacy array_attribute :post_ids, parse: /\d+/, cast: :to_i @@ -83,6 +84,12 @@ class FavoriteGroup < ApplicationRecord end end + def validate_can_enable_privacy + if is_public_change == [true, false] && !Pundit.policy!(creator, self).can_enable_privacy? + errors.add(:base, "Can't enable privacy without a Gold account") + end + end + def self.normalize_name(name) name.gsub(/[[:space:]]+/, "_") end @@ -112,7 +119,7 @@ class FavoriteGroup < ApplicationRecord end def pretty_name - name.tr("_", " ") + name&.tr("_", " ") end def posts @@ -166,6 +173,18 @@ class FavoriteGroup < ApplicationRecord post_ids.include?(post_id) end + def is_private=(value) + self.is_public = !ActiveModel::Type::Boolean.new.cast(value) + end + + def is_private + !is_public? + end + + def is_private? + !is_public? + end + def self.available_includes [:creator] end diff --git a/app/policies/favorite_group_policy.rb b/app/policies/favorite_group_policy.rb index 05cefc298..8926a1f8b 100644 --- a/app/policies/favorite_group_policy.rb +++ b/app/policies/favorite_group_policy.rb @@ -15,7 +15,11 @@ class FavoriteGroupPolicy < ApplicationPolicy update? end + def can_enable_privacy? + record.creator.is_gold? + end + def permitted_attributes - [:name, :post_ids_string, :is_public, :post_ids, { post_ids: [] }] + [:name, :post_ids_string, :is_public, :is_private, :post_ids, { post_ids: [] }] end end diff --git a/app/views/favorite_groups/_form.html.erb b/app/views/favorite_groups/_form.html.erb new file mode 100644 index 000000000..ae4069218 --- /dev/null +++ b/app/views/favorite_groups/_form.html.erb @@ -0,0 +1,12 @@ +<%= edit_form_for(@favorite_group) do |f| %> + <%= f.input :name, as: :string, required: true, input_html: { value: @favorite_group.pretty_name } %> + <%= f.input :post_ids_string, label: "Posts", as: :text %> + <% if policy(@favorite_group).can_enable_privacy? %> + <%= f.input :is_private, label: "Private", as: :boolean, hint: "Don't allow others to view this favgroup." %> + <% elsif @favorite_group.is_private? %> + <%= f.input :is_private, label: "Private", as: :boolean, hint: "Don't allow others to view this favgroup. Warning: if you disable this, you can't re-enable it without ".html_safe + link_to("upgrading to Danbooru Gold", new_user_upgrade_path) + ". (".html_safe + link_to_wiki("learn more", "help:privacy_mode") + ")".html_safe %> + <% else %> + <%= f.input :is_private, label: "Private", as: :boolean, hint: link_to("Upgrade to Danbooru Gold to enable private favgroups", new_user_upgrade_path), input_html: { disabled: true } %> + <% end %> + <%= f.submit "Submit" %> +<% end %> diff --git a/app/views/favorite_groups/edit.html.erb b/app/views/favorite_groups/edit.html.erb index 29d7369eb..c74ea5149 100644 --- a/app/views/favorite_groups/edit.html.erb +++ b/app/views/favorite_groups/edit.html.erb @@ -2,12 +2,7 @@

Edit Favorite Group: <%= @favorite_group.pretty_name %>

- <%= edit_form_for(@favorite_group) do |f| %> - <%= f.input :name, :as => :string, :input_html => { :value => @favorite_group.pretty_name } %> - <%= f.input :post_ids_string, label: "Posts", as: :text %> - <%= f.input :is_public %> - <%= f.button :submit, "Submit" %> - <% end %> + <%= render "form" %>
diff --git a/app/views/favorite_groups/new.html.erb b/app/views/favorite_groups/new.html.erb index b3245edaa..f0ca86e04 100644 --- a/app/views/favorite_groups/new.html.erb +++ b/app/views/favorite_groups/new.html.erb @@ -2,12 +2,7 @@

New Favorite Group

- <%= edit_form_for(@favorite_group) do |f| %> - <%= f.input :name, as: :string, required: true %> - <%= f.input :post_ids_string, label: "Posts", as: :text %> - <%= f.input :is_public, label: "Public" %> - <%= f.submit "Submit" %> - <% end %> + <%= render "form" %>
diff --git a/test/factories/favorite_group.rb b/test/factories/favorite_group.rb index 73104b22a..f03473a07 100644 --- a/test/factories/favorite_group.rb +++ b/test/factories/favorite_group.rb @@ -2,5 +2,10 @@ FactoryBot.define do factory :favorite_group do creator name { SecureRandom.uuid } + + factory :private_favorite_group do + creator factory: :gold_user + is_public { false } + end end end diff --git a/test/functional/favorite_groups_controller_test.rb b/test/functional/favorite_groups_controller_test.rb index f9d0d32bb..bba7a91ce 100644 --- a/test/functional/favorite_groups_controller_test.rb +++ b/test/functional/favorite_groups_controller_test.rb @@ -10,7 +10,7 @@ class FavoriteGroupsControllerTest < ActionDispatch::IntegrationTest context "index action" do setup do @mod_favgroup = create(:favorite_group, name: "monochrome", creator: build(:moderator_user, name: "fumimi")) - @private_favgroup = create(:favorite_group, creator: @user, is_public: false) + @private_favgroup = create(:private_favorite_group) end should "render" do @@ -28,7 +28,7 @@ class FavoriteGroupsControllerTest < ActionDispatch::IntegrationTest context "for private favorite groups as the creator" do setup do - CurrentUser.user = @user + CurrentUser.user = @private_favgroup.creator end should respond_to_search(is_public: "false").with { @private_favgroup } @@ -42,13 +42,13 @@ class FavoriteGroupsControllerTest < ActionDispatch::IntegrationTest end should "show private favgroups to the creator" do - @favgroup.update!(is_public: false) + @favgroup.update_columns(is_public: false) get_auth favorite_group_path(@favgroup), @user assert_response :success end should "not show private favgroups to other users" do - @favgroup = create(:favorite_group, is_public: false) + @favgroup = create(:private_favorite_group) get_auth favorite_group_path(@favgroup), create(:user) assert_response 403 end @@ -91,6 +91,13 @@ class FavoriteGroupsControllerTest < ActionDispatch::IntegrationTest assert_response 403 assert_not_equal("foo", @favgroup.reload.name) end + + should "not allow non-Gold users to enable private favgroups" do + put_auth favorite_group_path(@favgroup), @user, params: { favorite_group: { is_private: true } } + + assert_response :success + assert_equal(false, @favgroup.is_private?) + end end context "destroy action" do