From 1b572c592cc241504f37cf4ef133ae6d062baff7 Mon Sep 17 00:00:00 2001 From: evazion Date: Sat, 8 Apr 2017 02:23:42 -0500 Subject: [PATCH] wikis: disallow renaming unless tag is empty (fix #2964). --- app/models/tag_alias.rb | 4 +--- app/models/wiki_page.rb | 17 +++++++++++++++- app/views/wiki_pages/_form.html.erb | 20 +++++++++---------- test/functional/wiki_pages_controller_test.rb | 15 +++++++++++++- 4 files changed, 40 insertions(+), 16 deletions(-) diff --git a/app/models/tag_alias.rb b/app/models/tag_alias.rb index 0c06ad9dd..7900894db 100644 --- a/app/models/tag_alias.rb +++ b/app/models/tag_alias.rb @@ -254,9 +254,7 @@ class TagAlias < ActiveRecord::Base if antecedent_wiki.present? if WikiPage.titled(consequent_name).blank? CurrentUser.scoped(creator, creator_ip_addr) do - antecedent_wiki.update_attributes( - :title => consequent_name - ) + antecedent_wiki.update(title: consequent_name, skip_secondary_validations: true) end else message = "The tag alias [[#{antecedent_name}]] -> [[#{consequent_name}]] (alias ##{id}) has conflicting wiki pages. [[#{consequent_name}]] should be updated to include information from [[#{antecedent_name}]] if necessary." diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index d31b7fb20..ec8052ffb 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -10,9 +10,11 @@ class WikiPage < ActiveRecord::Base belongs_to :updater, :class_name => "User" validates_uniqueness_of :title, :case_sensitive => false validates_presence_of :title + validate :validate_rename validate :validate_locker_is_builder validate :validate_not_locked - attr_accessible :title, :body, :is_locked, :is_deleted, :other_names + attr_accessor :skip_secondary_validations + attr_accessible :title, :body, :is_locked, :is_deleted, :other_names, :skip_secondary_validations has_one :tag, :foreign_key => "name", :primary_key => "title" has_one :artist, lambda {where(:is_active => true)}, :foreign_key => "name", :primary_key => "title" has_many :versions, lambda {order("wiki_page_versions.id ASC")}, :class_name => "WikiPageVersion", :dependent => :destroy @@ -120,6 +122,15 @@ class WikiPage < ActiveRecord::Base end end + def validate_rename + return if !title_changed? || skip_secondary_validations + + tag_was = Tag.find_by_name(Tag.normalize_name(title_was)) + if tag_was.present? && tag_was.post_count > 0 + errors.add(:title, "cannot be changed: '#{tag_was.name}' still has #{tag_was.post_count} posts. Move the posts and update any wikis linking to this page first.") + end + end + def revert_to(version) if id != version.wiki_page_id raise RevertError.new("You cannot revert to a previous version of another wiki page.") @@ -145,6 +156,10 @@ class WikiPage < ActiveRecord::Base self.other_names = normalized_other_names.uniq.join(" ") end + def skip_secondary_validations=(value) + @skip_secondary_validations = (value == true || value == "1") + end + def creator_name User.id_to_name(creator_id).tr("_", " ") end diff --git a/app/views/wiki_pages/_form.html.erb b/app/views/wiki_pages/_form.html.erb index 2191441d7..79cd3f3d5 100644 --- a/app/views/wiki_pages/_form.html.erb +++ b/app/views/wiki_pages/_form.html.erb @@ -2,17 +2,11 @@ <%= error_messages_for("wiki_page") %> <%= simple_form_for(@wiki_page) do |f| %> -
- - <% if @wiki_page.new_record? %> - <%= text_field "wiki_page", "title" %> - <% elsif CurrentUser.user.is_builder? %> - <%= text_field "wiki_page", "title" %> - Change to rename this wiki page - <% else %> -

<%= @wiki_page.title %>

- <% end %> -
+ <% if @wiki_page.new_record? %> + <%= f.input :title, error: false %> + <% else %> + <%= f.input :title, error: false, hint: "Change to rename this wiki page. Move the tag and update any wikis linking to this page first." %> + <% end %> <%= f.input :other_names, :as => :text, :label => "Other names (view help)".html_safe, :hint => "Names used for this tag on other sites such as Pixiv. Separate with spaces." %> @@ -26,6 +20,10 @@ <%= f.input :is_locked, :label => "Locked" %> <% end %> + <% if @wiki_page.errors[:title].present? %> + <%= f.input :skip_secondary_validations, as: :boolean, label: "Force rename", hint: "Ignore the renaming requirements" %> + <% end %> + <%= f.button :submit, "Submit", :data => { :disable_with => "Submitting..." } %> <%= dtext_preview_button "wiki_page", "body" %> <% end %> diff --git a/test/functional/wiki_pages_controller_test.rb b/test/functional/wiki_pages_controller_test.rb index 782508aa9..2c9496aa1 100644 --- a/test/functional/wiki_pages_controller_test.rb +++ b/test/functional/wiki_pages_controller_test.rb @@ -99,7 +99,8 @@ class WikiPagesControllerTest < ActionController::TestCase context "update action" do setup do - @wiki_page = FactoryGirl.create(:wiki_page) + @tag = FactoryGirl.create(:tag, name: "foo", post_count: 42) + @wiki_page = FactoryGirl.create(:wiki_page, title: "foo") end should "update a wiki_page" do @@ -107,6 +108,18 @@ class WikiPagesControllerTest < ActionController::TestCase @wiki_page.reload assert_equal("xyz", @wiki_page.body) end + + should "not rename a wiki page with a non-empty tag" do + post :update, {:id => @wiki_page.id, :wiki_page => {:title => "bar"}}, {:user_id => @user.id} + + assert_equal("foo", @wiki_page.reload.title) + end + + should "rename a wiki page with a non-empty tag if secondary validations are skipped" do + post :update, {:id => @wiki_page.id, :wiki_page => {:title => "bar", :skip_secondary_validations => "1"}}, {:user_id => @user.id} + + assert_equal("bar", @wiki_page.reload.title) + end end context "destroy action" do