summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorerdgeist <erdgeist@erdgeist.org>2026-07-17 23:14:17 +0200
committererdgeist <erdgeist@erdgeist.org>2026-07-17 23:14:17 +0200
commit5dced8b4b624aabf4215ba21b13957080345c326 (patch)
tree70afdbd65f28309da76b60e084aad05776ec1881
parent2748dc23be86eeb1e4f5e155b8f2191245bb5f5c (diff)
Route and control trash, restore, and permanent deletion
-rw-r--r--app/controllers/nodes_controller.rb37
-rw-r--r--app/views/nodes/destroy.html.erb2
-rw-r--r--config/routes.rb2
-rw-r--r--test/controllers/nodes_controller_test.rb52
4 files changed, 89 insertions, 4 deletions
diff --git a/app/controllers/nodes_controller.rb b/app/controllers/nodes_controller.rb
index 9834a17..9ea66ad 100644
--- a/app/controllers/nodes_controller.rb
+++ b/app/controllers/nodes_controller.rb
@@ -13,7 +13,9 @@ class NodesController < ApplicationController
13 :publish, 13 :publish,
14 :unlock, 14 :unlock,
15 :autosave, 15 :autosave,
16 :revert 16 :revert,
17 :trash,
18 :restore_from_trash
17 ] 19 ]
18 20
19 around_action :pin_to_default_locale, :only => [:show, :edit, :update, :autosave] 21 around_action :pin_to_default_locale, :only => [:show, :edit, :update, :autosave]
@@ -139,8 +141,39 @@ class NodesController < ApplicationController
139 redirect_to node_path(@node) 141 redirect_to node_path(@node)
140 end 142 end
141 143
144 def trash
145 if @node.trash!(current_user)
146 flash[:notice] = "Page has been moved to the Trash"
147 redirect_to node_path(Node.trash)
148 else
149 flash[:notice] = "Page is already in the Trash"
150 redirect_to node_path(@node)
151 end
152 rescue ActiveRecord::RecordInvalid, LockedByAnotherUser => e
153 flash[:error] = e.message
154 redirect_to node_path(@node)
155 end
156
157 def restore_from_trash
158 parent = Node.find(params[:parent_id])
159 @node.restore_from_trash!(parent, current_user)
160 flash[:notice] = "Page has been restored from the Trash"
161 redirect_to node_path(@node)
162 rescue ActiveRecord::RecordNotFound
163 flash[:error] = "Restore target not found"
164 redirect_to node_path(@node)
165 rescue ActiveRecord::RecordInvalid => e
166 flash[:error] = e.message
167 redirect_to node_path(@node)
168 end
169
142 def destroy 170 def destroy
143 @node.destroy 171 @node.destroy_from_trash!(current_user)
172 flash[:notice] = "Page has been permanently deleted"
173 redirect_to node_path(Node.trash)
174 rescue ActiveRecord::RecordInvalid, ActiveRecord::RecordNotDestroyed => e
175 flash[:error] = e.message
176 redirect_to node_path(@node)
144 end 177 end
145 178
146 def publish 179 def publish
diff --git a/app/views/nodes/destroy.html.erb b/app/views/nodes/destroy.html.erb
deleted file mode 100644
index 065cf1d..0000000
--- a/app/views/nodes/destroy.html.erb
+++ /dev/null
@@ -1,2 +0,0 @@
1<h1>Nodes#destroy</h1>
2<p>Find me in app/views/nodes/destroy.html.erb</p>
diff --git a/config/routes.rb b/config/routes.rb
index c2b9590..16145c5 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -53,6 +53,8 @@ Cccms::Application.routes.draw do
53 put :revoke_shared_preview 53 put :revoke_shared_preview
54 put :autosave 54 put :autosave
55 put :revert 55 put :revert
56 put :trash
57 put :restore_from_trash
56 end 58 end
57 59
58 resources :translations, controller: 'page_translations', 60 resources :translations, controller: 'page_translations',
diff --git a/test/controllers/nodes_controller_test.rb b/test/controllers/nodes_controller_test.rb
index b0d7416..7e5a990 100644
--- a/test/controllers/nodes_controller_test.rb
+++ b/test/controllers/nodes_controller_test.rb
@@ -672,4 +672,56 @@ class NodesControllerTest < ActionController::TestCase
672 assert_equal "Brand New", action.metadata["title"] 672 assert_equal "Brand New", action.metadata["title"]
673 assert_equal Node.last.unique_name, action.metadata["path"] 673 assert_equal Node.last.unique_name, action.metadata["path"]
674 end 674 end
675
676 test "trash moves the node and redirects to the Trash" do
677 login_as :quentin
678 node = Node.root.children.create!(:slug => "trash_me")
679
680 put :trash, params: { :id => node.id }
681
682 assert_redirected_to node_path(Node.trash)
683 assert node.reload.in_trash?
684 end
685
686 test "trashing the Trash node itself is refused" do
687 login_as :quentin
688
689 put :trash, params: { :id => Node.trash.id }
690
691 assert_redirected_to node_path(Node.trash)
692 assert flash[:error].present?
693 end
694
695 test "restore_from_trash reparents to the given parent" do
696 login_as :quentin
697 node = Node.root.children.create!(:slug => "restore_me")
698 node.trash!(users(:quentin))
699 target = Node.root.children.create!(:slug => "restore_home")
700
701 put :restore_from_trash, params: { :id => node.id, :parent_id => target.id }
702
703 assert_redirected_to node_path(node)
704 assert_equal target, node.reload.parent
705 end
706
707 test "destroy refuses a node outside the Trash" do
708 login_as :quentin
709 node = Node.root.children.create!(:slug => "not_deletable_here")
710
711 delete :destroy, params: { :id => node.id }
712
713 assert Node.exists?(node.id)
714 assert flash[:error].present?
715 end
716
717 test "destroy deletes a trashed node and redirects to the Trash" do
718 login_as :quentin
719 node = Node.root.children.create!(:slug => "deletable")
720 node.trash!(users(:quentin))
721
722 delete :destroy, params: { :id => node.id }
723
724 assert_not Node.exists?(node.id)
725 assert_redirected_to node_path(Node.trash)
726 end
675end 727end