diff options
| author | erdgeist <erdgeist@erdgeist.org> | 2026-07-17 23:14:17 +0200 |
|---|---|---|
| committer | erdgeist <erdgeist@erdgeist.org> | 2026-07-17 23:14:17 +0200 |
| commit | 5dced8b4b624aabf4215ba21b13957080345c326 (patch) | |
| tree | 70afdbd65f28309da76b60e084aad05776ec1881 | |
| parent | 2748dc23be86eeb1e4f5e155b8f2191245bb5f5c (diff) | |
Route and control trash, restore, and permanent deletion
| -rw-r--r-- | app/controllers/nodes_controller.rb | 37 | ||||
| -rw-r--r-- | app/views/nodes/destroy.html.erb | 2 | ||||
| -rw-r--r-- | config/routes.rb | 2 | ||||
| -rw-r--r-- | test/controllers/nodes_controller_test.rb | 52 |
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 | ||
| 675 | end | 727 | end |
