summaryrefslogtreecommitdiff
path: root/test/models
diff options
context:
space:
mode:
authorerdgeist <erdgeist@erdgeist.org>2026-07-18 02:15:29 +0200
committererdgeist <erdgeist@erdgeist.org>2026-07-18 02:15:29 +0200
commitd41ee504caedbe858e24ab2a23c7a804454c64c8 (patch)
treeeb3ec7c8f44d15fea40292d0a9e7358e41640edc /test/models
parent5dced8b4b624aabf4215ba21b13957080345c326 (diff)
Add Trash affordances: cockpit, listing, dashboard entry
nodes#show gains a Trash section on trashed nodes: provenance from the trash entry, a restore form whose parent picker pre-fills the old parent while it still lives, and permanent deletion. A Move-to-Trash button joins the status actions on living nodes. nodes#trashed lists trashed subtree roots with weight, provenance, and deletion; the dashboard housekeeping row links to it, and trash/destroy redirect there. Deletion from Trash now removes the whole subtree, deepest first, each node through a real destroy! so every per-node cascade runs -- amending the never-recursive rule for this one sanctioned path (both confirms state the count; the root entry carries destroyed_descendants). Bare Node#destroy still refuses children.
Diffstat (limited to 'test/models')
-rw-r--r--test/models/node_trash_test.rb41
1 files changed, 36 insertions, 5 deletions
diff --git a/test/models/node_trash_test.rb b/test/models/node_trash_test.rb
index b72770b..07e5bc6 100644
--- a/test/models/node_trash_test.rb
+++ b/test/models/node_trash_test.rb
@@ -102,12 +102,25 @@ class NodeTrashTest < ActiveSupport::TestCase
102 assert Node.exists?(node.id) 102 assert Node.exists?(node.id)
103 end 103 end
104 104
105 test "destroy_from_trash! refuses nodes with children" do 105 test "destroy_from_trash! removes the whole subtree bottom-up with one entry" do
106 node = create_node_with_published_page 106 parent = create_node_with_published_page
107 node.children.create!(:slug => "still_here") 107 child = parent.children.create!(:slug => "doomed_child")
108 node.trash!(@user1) 108 grandchild = child.children.create!(:slug => "doomed_grandchild")
109 page_ids = [parent, child, grandchild].flat_map { |n| n.pages.pluck(:id) }
110 parent.trash!(@user1)
111
112 assert_difference "NodeAction.count", 1 do
113 parent.reload.destroy_from_trash!(@user1)
114 end
115
116 assert_not Node.exists?(parent.id)
117 assert_not Node.exists?(child.id)
118 assert_not Node.exists?(grandchild.id)
119 assert_equal 0, Page.where(:id => page_ids).count
109 120
110 assert_raises(ActiveRecord::RecordNotDestroyed) { node.reload.destroy_from_trash!(@user1) } 121 action = NodeAction.where(:action => "destroy").last
122 assert_equal 2, action.metadata["destroyed_descendants"]
123 assert_nil action.node_id
111 end 124 end
112 125
113 test "destroy_from_trash! logs an entry that survives the node" do 126 test "destroy_from_trash! logs an entry that survives the node" do
@@ -124,4 +137,22 @@ class NodeTrashTest < ActiveSupport::TestCase
124 assert_equal "Doomed", action.subject_name 137 assert_equal "Doomed", action.subject_name
125 assert_equal @user1, action.user 138 assert_equal @user1, action.user
126 end 139 end
140
141 test "suggested_restore_parent finds the old parent while it lives" do
142 parent = Node.root.children.create!(:slug => "old_home")
143 node = parent.children.create!(:slug => "comes_back")
144 node.trash!(@user1)
145
146 assert_equal parent, node.reload.suggested_restore_parent
147
148 parent.trash!(@user1)
149 assert_nil node.reload.suggested_restore_parent
150 end
151
152 test "suggested_restore_parent is root for trashed top-level nodes" do
153 node = Node.root.children.create!(:slug => "was_top_level")
154 node.trash!(@user1)
155
156 assert_equal Node.root, node.reload.suggested_restore_parent
157 end
127end 158end