diff --git a/Gemfile b/Gemfile index 6f613a1f8..b93d6a5d1 100644 --- a/Gemfile +++ b/Gemfile @@ -3,7 +3,7 @@ source 'http://gemcutter.org' group :test do gem "shoulda" gem "factory_girl" - gem "mocha" + gem "mocha", :require => "mocha/setup" gem "ffaker", :git => "http://github.com/EmmanuelOga/ffaker.git" gem "simplecov", :require => false end diff --git a/app/controllers/moderator/post/posts_controller.rb b/app/controllers/moderator/post/posts_controller.rb index 0deddf3f8..def840222 100644 --- a/app/controllers/moderator/post/posts_controller.rb +++ b/app/controllers/moderator/post/posts_controller.rb @@ -2,7 +2,7 @@ module Moderator module Post class PostsController < ApplicationController before_filter :janitor_only, :only => [:delete, :undelete] - before_filter :admin_only, :only => [:annihilate] + before_filter :admin_only, :only => [:expunge] rescue_from ::PostFlag::Error, :with => :rescue_exception def confirm_delete @@ -23,9 +23,9 @@ module Moderator @post.undelete! end - def annihilate + def expunge @post = ::Post.find(params[:id]) - @post.annihilate! + @post.expunge! end end end diff --git a/app/models/post.rb b/app/models/post.rb index 6139a4b02..6934b5cc7 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -31,7 +31,6 @@ class Post < ActiveRecord::Base has_many :disapprovals, :class_name => "PostDisapproval" validates_uniqueness_of :md5 validates_presence_of :parent, :if => lambda {|rec| !rec.parent_id.nil?} - # validate :validate_parent_does_not_have_a_parent attr_accessible :source, :rating, :tag_string, :old_tag_string, :last_noted_at, :parent_id, :as => [:member, :builder, :privileged, :platinum, :contributor, :janitor, :moderator, :admin, :default] attr_accessible :is_rating_locked, :is_note_locked, :as => [:builder, :contributor, :janitor, :moderator, :admin] attr_accessible :is_status_locked, :as => [:admin] @@ -251,7 +250,6 @@ class Post < ActiveRecord::Base self.is_deleted = false self.approver_id = CurrentUser.id save! - # ModAction.create(:description => "approved post ##{id}") end def disapproved_by?(user) @@ -678,13 +676,13 @@ class Post < ActiveRecord::Base # A parent has many children. A child belongs to a parent. # A parent cannot have a parent. # - # After deleting a child: + # After expunging a child: # - Move favorites to parent. # - Does the parent have any active children? # - Yes: Done. # - No: Update parent's has_children flag to false. # - # After deleting a parent: + # After expunging a parent: # - Move favorites to the first child. # - Reparent all active children to the first active child. @@ -756,15 +754,18 @@ class Post < ActiveRecord::Base end module DeletionMethods - def annihilate! + def expunge! if is_status_locked? self.errors.add(:is_status_locked, "; cannot delete post") return false end ModAction.create(:description => "permanently deleted post ##{id}") - decrement_tag_post_counts delete!(:without_mod_action => true) + give_favorites_to_parent + update_children_on_destroy + update_parent_on_destroy + decrement_tag_post_counts destroy end @@ -779,11 +780,6 @@ class Post < ActiveRecord::Base update_column(:is_pending, false) update_column(:is_flagged, false) update_column(:is_banned, true) if options[:ban] - give_favorites_to_parent - update_children_on_destroy - update_parent_on_destroy - # decrement_tag_post_counts - update_column(:parent_id, nil) unless options[:without_mod_action] ModAction.create(:description => "deleted post ##{id}") @@ -801,7 +797,6 @@ class Post < ActiveRecord::Base self.approver_id = CurrentUser.id save Post.expire_cache_for_all(tag_array) - update_parent_on_save ModAction.create(:description => "undeleted post ##{id}") end end diff --git a/app/views/moderator/post/posts/annihilate.js.erb b/app/views/moderator/post/posts/annihilate.js.erb deleted file mode 100644 index 85bb8da47..000000000 --- a/app/views/moderator/post/posts/annihilate.js.erb +++ /dev/null @@ -1 +0,0 @@ -Danbooru.notice("Post was annihilated"); \ No newline at end of file diff --git a/app/views/moderator/post/posts/expunge.js.erb b/app/views/moderator/post/posts/expunge.js.erb new file mode 100644 index 000000000..bb1a66f85 --- /dev/null +++ b/app/views/moderator/post/posts/expunge.js.erb @@ -0,0 +1 @@ +Danbooru.notice("Post was permanently deleted"); \ No newline at end of file diff --git a/app/views/posts/partials/show/_options.html.erb b/app/views/posts/partials/show/_options.html.erb index 8b89a453d..26a0bb9fb 100644 --- a/app/views/posts/partials/show/_options.html.erb +++ b/app/views/posts/partials/show/_options.html.erb @@ -35,6 +35,6 @@ <% end %> <% if CurrentUser.is_admin? %> -
  • <%= link_to "Expunge", annihilate_moderator_post_post_path(:post_id => post.id), :remote => true, :method => :post, :id => "annihilate", :confirm => "This will permanently delete this post (meaning the file will be deleted). Are you sure you want to delete this post?" %>
  • +
  • <%= link_to "Expunge", expunge_moderator_post_post_path(:post_id => post.id), :remote => true, :method => :post, :id => "expunge", :confirm => "This will permanently delete this post (meaning the file will be deleted). Are you sure you want to delete this post?" %>
  • <% end %> \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 559f1e9d9..c61cf80d7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -16,10 +16,10 @@ Danbooru::Application.routes.draw do resource :queue, :only => [:show] resource :approval, :only => [:create] resource :disapproval, :only => [:create] - resources :posts, :only => [:delete, :undelete, :annihilate, :confirm_delete] do + resources :posts, :only => [:delete, :undelete, :expunge, :confirm_delete] do member do get :confirm_delete - post :annihilate + post :expunge post :delete post :undelete end diff --git a/script/fixes/006.rb b/script/fixes/006.rb index 190b663ff..5e0100e89 100644 --- a/script/fixes/006.rb +++ b/script/fixes/006.rb @@ -15,7 +15,7 @@ Post.where("created_at > '2013-02-01'").find_each do |post| post.update_column(:tag_count_character, post.tag_count_character) end -PoolVersion.where("post_ids like '% 4 %' and post_ids like '% 8 %' and post_ids like '% 9 %' and post_ids like '% 11 %'").find_each do |pool_version| +PoolVersion.where("post_ids like '% 10 %' and post_ids like '% 12 %' and post_ids like '% 13 %' and post_ids like '% 14 %'").find_each do |pool_version| cleaned_post_ids = pool_version.post_ids.scan(/(\d+) \d+/).join(" ") pool_version.update_column(:post_ids, cleaned_post_ids) end; true diff --git a/test/unit/post_test.rb b/test/unit/post_test.rb index 4b81a3619..07ddce06b 100644 --- a/test/unit/post_test.rb +++ b/test/unit/post_test.rb @@ -15,7 +15,7 @@ class PostTest < ActiveSupport::TestCase end context "Deletion:" do - context "Annihilating a post" do + context "Expunging a post" do setup do @post = FactoryGirl.create(:post) end @@ -26,13 +26,13 @@ class PostTest < ActiveSupport::TestCase end should "not destroy the record" do - @post.annihilate! + @post.expunge! assert_equal(1, Post.where("id = ?", @post.id).count) end end should "destroy the record" do - @post.annihilate! + @post.expunge! assert_equal([], @post.errors.full_messages) assert_equal(0, Post.where("id = ?", @post.id).count) end @@ -108,22 +108,14 @@ class PostTest < ActiveSupport::TestCase post.save assert(post.errors[:parent].any?, "Parent should be invalid") end - - # should "fail if the parent has a parent" do - # p1 = FactoryGirl.create(:post) - # c1 = FactoryGirl.create(:post, :parent_id => p1.id) - # c2 = FactoryGirl.build(:post, :parent_id => c1.id) - # c2.save - # assert(c2.errors[:parent].any?, "Parent should be invalid") - # end end - context "Destroying a post with" do + context "Expunging a post with" do context "a parent" do should "reset the has_children flag of the parent" do p1 = FactoryGirl.create(:post) c1 = FactoryGirl.create(:post, :parent_id => p1.id) - c1.delete! + c1.expunge! p1.reload assert_equal(false, p1.has_children?) end @@ -133,7 +125,7 @@ class PostTest < ActiveSupport::TestCase c1 = FactoryGirl.create(:post, :parent_id => p1.id) user = FactoryGirl.create(:user) c1.add_favorite!(user) - c1.delete! + c1.expunge! p1.reload assert(!Favorite.exists?(:post_id => c1.id, :user_id => user.id)) assert(Favorite.exists?(:post_id => p1.id, :user_id => user.id)) @@ -143,24 +135,17 @@ class PostTest < ActiveSupport::TestCase should "update the parent's has_children flag" do p1 = FactoryGirl.create(:post) c1 = FactoryGirl.create(:post, :parent_id => p1.id) - c1.delete! + c1.expunge! p1.reload assert(!p1.has_children?, "Parent should not have children") end end context "one child" do - should "remove the has_children flag" do - p1 = FactoryGirl.create(:post) - c1 = FactoryGirl.create(:post, :parent_id => p1.id) - p1.delete! - assert_equal(false, p1.has_children?) - end - should "remove the parent of that child" do p1 = FactoryGirl.create(:post) c1 = FactoryGirl.create(:post, :parent_id => p1.id) - p1.delete! + p1.expunge! c1.reload assert_nil(c1.parent) end @@ -172,19 +157,85 @@ class PostTest < ActiveSupport::TestCase c1 = FactoryGirl.create(:post, :parent_id => p1.id) c2 = FactoryGirl.create(:post, :parent_id => p1.id) c3 = FactoryGirl.create(:post, :parent_id => p1.id) - p1.delete! + p1.expunge! c1.reload c2.reload c3.reload - assert_nil(c1.parent) + assert_nil(c1.parent_id) assert_equal(c1.id, c2.parent_id) assert_equal(c1.id, c3.parent_id) end end end + + context "Deleting a post with" do + context "a parent" do + should "not reset the has_children flag of the parent" do + p1 = FactoryGirl.create(:post) + c1 = FactoryGirl.create(:post, :parent_id => p1.id) + c1.delete! + p1.reload + assert_equal(true, p1.has_children?) + end - context "Undestroying a post with a parent" do - should "create a new approver" do + should "not reassign favorites to the parent" do + p1 = FactoryGirl.create(:post) + c1 = FactoryGirl.create(:post, :parent_id => p1.id) + user = FactoryGirl.create(:user) + c1.add_favorite!(user) + c1.delete! + p1.reload + assert(Favorite.exists?(:post_id => c1.id, :user_id => user.id)) + assert(!Favorite.exists?(:post_id => p1.id, :user_id => user.id)) + assert_equal(0, c1.score) + end + + should "not update the parent's has_children flag" do + p1 = FactoryGirl.create(:post) + c1 = FactoryGirl.create(:post, :parent_id => p1.id) + c1.delete! + p1.reload + assert(p1.has_children?, "Parent should have children") + end + end + + context "one child" do + should "not remove the has_children flag" do + p1 = FactoryGirl.create(:post) + c1 = FactoryGirl.create(:post, :parent_id => p1.id) + p1.delete! + p1.reload + assert_equal(true, p1.has_children?) + end + + should "not remove the parent of that child" do + p1 = FactoryGirl.create(:post) + c1 = FactoryGirl.create(:post, :parent_id => p1.id) + p1.delete! + c1.reload + assert_not_nil(c1.parent) + end + end + + context "two or more children" do + should "not reparent all children to the first child" do + p1 = FactoryGirl.create(:post) + c1 = FactoryGirl.create(:post, :parent_id => p1.id) + c2 = FactoryGirl.create(:post, :parent_id => p1.id) + c3 = FactoryGirl.create(:post, :parent_id => p1.id) + p1.delete! + c1.reload + c2.reload + c3.reload + assert_equal(p1.id, c1.parent_id) + assert_equal(p1.id, c2.parent_id) + assert_equal(p1.id, c3.parent_id) + end + end + end + + context "Undeleting a post with a parent" do + should "update with a new approver" do new_user = FactoryGirl.create(:moderator_user) p1 = FactoryGirl.create(:post) c1 = FactoryGirl.create(:post, :parent_id => p1.id) @@ -196,14 +247,14 @@ class PostTest < ActiveSupport::TestCase assert_equal(new_user.id, c1.approver_id) end - should "not preserve the parent's has_children flag" do + should "preserve the parent's has_children flag" do p1 = FactoryGirl.create(:post) c1 = FactoryGirl.create(:post, :parent_id => p1.id) c1.delete! c1.undelete! p1.reload - assert_nil(p1.parent_id) - assert(!p1.has_children?, "Parent should not have children") + assert_not_nil(c1.parent_id) + assert(p1.has_children?, "Parent should have children") end end end diff --git a/test/unit/user_test.rb b/test/unit/user_test.rb index 27a116a45..037fc062e 100644 --- a/test/unit/user_test.rb +++ b/test/unit/user_test.rb @@ -203,7 +203,7 @@ class UserTest < ActiveSupport::TestCase assert(User.authenticate(@user.name, "zugzug5"), "Authentication should have succeeded") end - should "match the confirmation" do + should "fail if the confirmation does not match" do @user = FactoryGirl.create(:user) @user.password = "zugzug6" @user.password_confirmation = "zugzug5"