summaryrefslogtreecommitdiff
path: root/test/models
diff options
context:
space:
mode:
authorerdgeist <erdgeist@erdgeist.org>2026-07-10 23:54:38 +0200
committererdgeist <erdgeist@erdgeist.org>2026-07-10 23:54:38 +0200
commitab392d472c15eee3618cb7c02b2b4707151598b6 (patch)
tree70743f8fa0df9b75b0debb8f2724ea947ad99175 /test/models
parent7d6a665b896252537b8b8df2f15e204d04417231 (diff)
Prevent a staged parent move from crashing on its own descendant
publish_draft! called move_to_child_of before validating the new parent at all. Staging a node under one of its own descendants created a real, if transient, cycle in parent_id the instant that save landed -- and update_unique_names_of_children's after_save callback, which recurses down through parent_id with no cycle check and no depth limit, bounced between the two nodes forever, crashing the whole process with a SystemStackError rather than just producing bad data. Now rejected up front with a normal ActiveRecord::RecordInvalid.
Diffstat (limited to 'test/models')
-rw-r--r--test/models/node_test.rb12
1 files changed, 12 insertions, 0 deletions
diff --git a/test/models/node_test.rb b/test/models/node_test.rb
index 280614e..5626384 100644
--- a/test/models/node_test.rb
+++ b/test/models/node_test.rb
@@ -499,4 +499,16 @@ class NodeTest < ActiveSupport::TestCase
499 node.autosave!({title: "v3"}, user) 499 node.autosave!({title: "v3"}, user)
500 assert_equal [[:head, :draft], [:draft, :autosave]], node.available_layer_pairs # state D 500 assert_equal [[:head, :draft], [:draft, :autosave]], node.available_layer_pairs # state D
501 end 501 end
502
503 test "publishing a staged move under one's own descendant is rejected, not allowed to crash" do
504 a = Node.root.children.create!(:slug => "cycle_guard_a")
505 b = a.children.create!(:slug => "cycle_guard_b")
506
507 a.staged_parent_id = b.id
508
509 assert_raises(ActiveRecord::RecordInvalid) { a.publish_draft! }
510
511 a.reload
512 assert_equal Node.root.id, a.parent_id
513 end
502end 514end