diff options
| author | erdgeist <erdgeist@erdgeist.org> | 2026-08-07 06:15:14 +0200 |
|---|---|---|
| committer | erdgeist <erdgeist@erdgeist.org> | 2026-08-07 06:15:14 +0200 |
| commit | f4ddfff03ca9f25d50f39a1971877362d85eb9cb (patch) | |
| tree | 31e6774fd4cf2b579a9622277be150417a2fa48e /test | |
| parent | 02a4ea750428aa1a9c9e7f2680553c0ce4ef1fec (diff) | |
Move the pending address from the node onto the draft
Diffstat (limited to 'test')
| -rw-r--r-- | test/controllers/nodes_controller_test.rb | 51 | ||||
| -rw-r--r-- | test/models/node_test.rb | 96 | ||||
| -rw-r--r-- | test/models/node_trash_test.rb | 10 |
3 files changed, 117 insertions, 40 deletions
diff --git a/test/controllers/nodes_controller_test.rb b/test/controllers/nodes_controller_test.rb index 745ae4e0..c7caeed1 100644 --- a/test/controllers/nodes_controller_test.rb +++ b/test/controllers/nodes_controller_test.rb | |||
| @@ -193,7 +193,8 @@ class NodesControllerTest < ActionController::TestCase | |||
| 193 | test "publish draft with staged_slug unqueal slug" do | 193 | test "publish draft with staged_slug unqueal slug" do |
| 194 | login_as :quentin | 194 | login_as :quentin |
| 195 | 195 | ||
| 196 | test_node = Node.root.children.create! :slug => "test_node", :staged_slug => "peter_pan" | 196 | test_node = Node.root.children.create!(:slug => "test_node") |
| 197 | test_node.draft.update!(:slug => "peter_pan") | ||
| 197 | 198 | ||
| 198 | put :publish, params: { :id => test_node.id } | 199 | put :publish, params: { :id => test_node.id } |
| 199 | 200 | ||
| @@ -205,7 +206,8 @@ class NodesControllerTest < ActionController::TestCase | |||
| 205 | test "publish draft with staged_slug with more levels of nodes" do | 206 | test "publish draft with staged_slug with more levels of nodes" do |
| 206 | login_as :quentin | 207 | login_as :quentin |
| 207 | 208 | ||
| 208 | test_node = Node.root.children.create! :slug => "test_node", :staged_slug => "peter_pan" | 209 | test_node = Node.root.children.create!(:slug => "test_node") |
| 210 | test_node.draft.update!(:slug => "peter_pan") | ||
| 209 | test_node2 = test_node.children.create! :slug => "test_node2" | 211 | test_node2 = test_node.children.create! :slug => "test_node2" |
| 210 | 212 | ||
| 211 | put :publish, params: { :id => test_node.id } | 213 | put :publish, params: { :id => test_node.id } |
| @@ -215,12 +217,13 @@ class NodesControllerTest < ActionController::TestCase | |||
| 215 | assert_equal "peter_pan", test_node.unique_name | 217 | assert_equal "peter_pan", test_node.unique_name |
| 216 | end | 218 | end |
| 217 | 219 | ||
| 218 | test "publish draft with staged_parent_id" do | 220 | test "publish draft with a moved parent" do |
| 219 | login_as :quentin | 221 | login_as :quentin |
| 220 | 222 | ||
| 221 | parent = Node.root.children.create! :slug => "parent" | 223 | parent = Node.root.children.create!(:slug => "parent") |
| 222 | test_node = Node.root.children.create! :slug => "test_node", :staged_parent_id => parent.id | 224 | test_node = Node.root.children.create!(:slug => "test_node") |
| 223 | test_node2 = test_node.children.create! :slug => "test_node2" | 225 | test_node.draft.update!(:parent_node_id => parent.id) |
| 226 | test_node2 = test_node.children.create!(:slug => "test_node2") | ||
| 224 | 227 | ||
| 225 | put :publish, params: { :id => test_node.id } | 228 | put :publish, params: { :id => test_node.id } |
| 226 | 229 | ||
| @@ -229,18 +232,13 @@ class NodesControllerTest < ActionController::TestCase | |||
| 229 | assert_equal "parent/test_node/test_node2", test_node2.unique_name | 232 | assert_equal "parent/test_node/test_node2", test_node2.unique_name |
| 230 | end | 233 | end |
| 231 | 234 | ||
| 232 | test "publish draft with staged_parent_id and staged_slug" do | 235 | test "publish draft with a moved parent and a renamed slug" do |
| 233 | login_as :quentin | 236 | login_as :quentin |
| 234 | 237 | ||
| 235 | parent = Node.root.children.create! :slug => "parent" | 238 | parent = Node.root.children.create!(:slug => "parent") |
| 236 | 239 | test_node = Node.root.children.create!(:slug => "test_node") | |
| 237 | test_node = Node.root.children.create!( | 240 | test_node.draft.update!(:parent_node_id => parent.id, :slug => "peter_pan") |
| 238 | :slug => "test_node", | 241 | test_node2 = test_node.children.create!(:slug => "test_node2") |
| 239 | :staged_parent_id => parent.id, | ||
| 240 | :staged_slug => "peter_pan" | ||
| 241 | ) | ||
| 242 | |||
| 243 | test_node2 = test_node.children.create! :slug => "test_node2" | ||
| 244 | 242 | ||
| 245 | put :publish, params: { :id => test_node.id } | 243 | put :publish, params: { :id => test_node.id } |
| 246 | 244 | ||
| @@ -293,7 +291,7 @@ class NodesControllerTest < ActionController::TestCase | |||
| 293 | 291 | ||
| 294 | other_node = Node.root.children.create( :slug => "other" ) | 292 | other_node = Node.root.children.create( :slug => "other" ) |
| 295 | 293 | ||
| 296 | node.staged_parent_id = other_node.id | 294 | node.draft.update!(:parent_node_id => other_node.id) |
| 297 | node.publish_draft! | 295 | node.publish_draft! |
| 298 | 296 | ||
| 299 | assert Node.valid? | 297 | assert Node.valid? |
| @@ -711,18 +709,33 @@ class NodesControllerTest < ActionController::TestCase | |||
| 711 | assert flash[:error].present? | 709 | assert flash[:error].present? |
| 712 | end | 710 | end |
| 713 | 711 | ||
| 714 | test "restore_from_trash reparents to the given parent" do | 712 | test "restore_from_trash reparents to the 'old' parent" do |
| 715 | login_as :quentin | 713 | login_as :quentin |
| 716 | node = Node.root.children.create!(:slug => "restore_me") | 714 | node = Node.root.children.create!(:slug => "restore_me") |
| 717 | node.trash!(users(:quentin)) | 715 | node.trash!(users(:quentin)) |
| 718 | target = Node.root.children.create!(:slug => "restore_home") | 716 | target = Node.root.children.create!(:slug => "restore_home") |
| 719 | 717 | ||
| 720 | put :restore_from_trash, params: { :id => node.id, :parent_id => target.id } | 718 | node.reload.draft.update!(:parent_node_id => target.id) |
| 719 | put :restore_from_trash, params: { :locale => "de", :id => node.id } | ||
| 721 | 720 | ||
| 722 | assert_redirected_to node_path(node) | 721 | assert_redirected_to node_path(node) |
| 723 | assert_equal target, node.reload.parent | 722 | assert_equal target, node.reload.parent |
| 724 | end | 723 | end |
| 725 | 724 | ||
| 725 | test "restore_from_trash follows an explicitly chosen parent" do | ||
| 726 | login_as :quentin | ||
| 727 | node = Node.root.children.create!(:slug => "restore_pick") | ||
| 728 | node.trash!(users(:quentin)) | ||
| 729 | chosen = Node.root.children.create!(:slug => "chosen_home") | ||
| 730 | |||
| 731 | put :restore_from_trash, params: { :locale => "de", :id => node.id, | ||
| 732 | :parent_id => chosen.id } | ||
| 733 | |||
| 734 | assert_equal chosen, node.reload.parent | ||
| 735 | assert_equal chosen.id, node.draft.parent_node_id, | ||
| 736 | "the choice is recorded on the draft, not applied behind its back" | ||
| 737 | end | ||
| 738 | |||
| 726 | test "destroy refuses a node outside the Trash" do | 739 | test "destroy refuses a node outside the Trash" do |
| 727 | login_as :quentin | 740 | login_as :quentin |
| 728 | node = Node.root.children.create!(:slug => "not_deletable_here") | 741 | node = Node.root.children.create!(:slug => "not_deletable_here") |
diff --git a/test/models/node_test.rb b/test/models/node_test.rb index c7fee58e..df1e96cb 100644 --- a/test/models/node_test.rb +++ b/test/models/node_test.rb | |||
| @@ -488,7 +488,7 @@ class NodeTest < ActiveSupport::TestCase | |||
| 488 | a = Node.root.children.create!(:slug => "cycle_guard_a") | 488 | a = Node.root.children.create!(:slug => "cycle_guard_a") |
| 489 | b = a.children.create!(:slug => "cycle_guard_b") | 489 | b = a.children.create!(:slug => "cycle_guard_b") |
| 490 | 490 | ||
| 491 | a.staged_parent_id = b.id | 491 | a.draft.update!(:parent_node_id => b.id) |
| 492 | 492 | ||
| 493 | assert_raises(ActiveRecord::RecordInvalid) { a.publish_draft! } | 493 | assert_raises(ActiveRecord::RecordInvalid) { a.publish_draft! } |
| 494 | 494 | ||
| @@ -702,16 +702,15 @@ class NodeTest < ActiveSupport::TestCase | |||
| 702 | assert_equal "New Title", action.metadata.dig("title", "to") | 702 | assert_equal "New Title", action.metadata.dig("title", "to") |
| 703 | end | 703 | end |
| 704 | 704 | ||
| 705 | test "publishing a staged slug change logs a move with the path pair" do | 705 | test "publishing a slug change logs a move with the path pair" do |
| 706 | node = create_node_with_published_page | 706 | node = create_node_with_published_page |
| 707 | path_before = node.unique_name | 707 | path_before = node.unique_name |
| 708 | node.staged_slug = "moved-#{node.slug}" | 708 | find_or_create_draft(node, @user1) |
| 709 | node.save! | 709 | node.draft.update!(:slug => "moved-#{node.slug}") |
| 710 | publish_count_before = NodeAction.where(:action => "publish").count | ||
| 711 | 710 | ||
| 712 | node.publish_draft!(@user1) | 711 | node.publish_draft!(@user1) |
| 713 | |||
| 714 | node.reload | 712 | node.reload |
| 713 | |||
| 715 | assert_not_equal path_before, node.unique_name | 714 | assert_not_equal path_before, node.unique_name |
| 716 | 715 | ||
| 717 | action = NodeAction.where(:action => "move").last | 716 | action = NodeAction.where(:action => "move").last |
| @@ -719,16 +718,12 @@ class NodeTest < ActiveSupport::TestCase | |||
| 719 | assert_equal @user1, action.user | 718 | assert_equal @user1, action.user |
| 720 | assert_equal path_before, action.metadata.dig("path", "from") | 719 | assert_equal path_before, action.metadata.dig("path", "from") |
| 721 | assert_equal node.unique_name, action.metadata.dig("path", "to") | 720 | assert_equal node.unique_name, action.metadata.dig("path", "to") |
| 722 | |||
| 723 | # No draft was pending: path change alone must not fabricate a publish. | ||
| 724 | assert_equal publish_count_before, NodeAction.where(:action => "publish").count | ||
| 725 | end | 721 | end |
| 726 | 722 | ||
| 727 | test "publishing a draft together with a staged move logs two entries" do | 723 | test "publishing a draft together with a move logs two entries" do |
| 728 | node = create_node_with_published_page | 724 | node = create_node_with_published_page |
| 729 | find_or_create_draft(node, @user1) | 725 | find_or_create_draft(node, @user1) |
| 730 | node.staged_slug = "relocated-#{node.slug}" | 726 | node.draft.update!(:slug => "relocated-#{node.slug}") |
| 731 | node.save! | ||
| 732 | 727 | ||
| 733 | assert_difference "NodeAction.count", 2 do | 728 | assert_difference "NodeAction.count", 2 do |
| 734 | node.publish_draft!(@user1) | 729 | node.publish_draft!(@user1) |
| @@ -890,7 +885,8 @@ class NodeTest < ActiveSupport::TestCase | |||
| 890 | Node.trash | 885 | Node.trash |
| 891 | 886 | ||
| 892 | assert_not Node.root.children.build(:slug => CccConventions::TRASH_SLUG).valid? | 887 | assert_not Node.root.children.build(:slug => CccConventions::TRASH_SLUG).valid? |
| 893 | assert_not Node.root.children.build(:slug => "fine", :staged_slug => CccConventions::TRASH_SLUG).valid? | 888 | page = Page.new(:slug => CccConventions::TRASH_SLUG, :parent_node_id => Node.root.id) |
| 889 | assert_not page.valid? | ||
| 894 | assert Node.trash.children.create!(:slug => "sub").children.build(:slug => CccConventions::TRASH_SLUG).valid? | 890 | assert Node.trash.children.create!(:slug => "sub").children.build(:slug => CccConventions::TRASH_SLUG).valid? |
| 895 | end | 891 | end |
| 896 | 892 | ||
| @@ -1012,7 +1008,7 @@ class NodeTest < ActiveSupport::TestCase | |||
| 1012 | year = updates.children.create!(:slug => "2026") | 1008 | year = updates.children.create!(:slug => "2026") |
| 1013 | node = Node.root.children.create!(:slug => "outside-post") | 1009 | node = Node.root.children.create!(:slug => "outside-post") |
| 1014 | node.reload.draft.update!(:title => "Entwurf") | 1010 | node.reload.draft.update!(:title => "Entwurf") |
| 1015 | node.update!(:staged_parent_id => year.id) | 1011 | node.draft.update!(:parent_node_id => year.id) |
| 1016 | 1012 | ||
| 1017 | assert_raises(ActiveRecord::RecordInvalid) { node.publish_draft!(editor) } | 1013 | assert_raises(ActiveRecord::RecordInvalid) { node.publish_draft!(editor) } |
| 1018 | assert_nil node.reload.head | 1014 | assert_nil node.reload.head |
| @@ -1025,7 +1021,7 @@ class NodeTest < ActiveSupport::TestCase | |||
| 1025 | club = Node.root.children.create!(:slug => "club") | 1021 | club = Node.root.children.create!(:slug => "club") |
| 1026 | node = Node.root.children.create!(:slug => "movable-post") | 1022 | node = Node.root.children.create!(:slug => "movable-post") |
| 1027 | node.reload.draft.update!(:title => "Entwurf") | 1023 | node.reload.draft.update!(:title => "Entwurf") |
| 1028 | node.update!(:staged_parent_id => club.id) | 1024 | node.draft.update!(:parent_node_id => club.id) |
| 1029 | 1025 | ||
| 1030 | node.publish_draft!(editor) | 1026 | node.publish_draft!(editor) |
| 1031 | assert_equal club.id, node.reload.parent_id | 1027 | assert_equal club.id, node.reload.parent_id |
| @@ -1036,7 +1032,7 @@ class NodeTest < ActiveSupport::TestCase | |||
| 1036 | :password => "secret", :password_confirmation => "secret") | 1032 | :password => "secret", :password_confirmation => "secret") |
| 1037 | node = Node.root.children.create!(:slug => "harmless") | 1033 | node = Node.root.children.create!(:slug => "harmless") |
| 1038 | node.reload.draft.update!(:title => "Entwurf") | 1034 | node.reload.draft.update!(:title => "Entwurf") |
| 1039 | node.update!(:staged_slug => "updates") | 1035 | node.draft.update!(:slug => "updates") |
| 1040 | 1036 | ||
| 1041 | assert_raises(ActiveRecord::RecordInvalid) { node.publish_draft!(editor) } | 1037 | assert_raises(ActiveRecord::RecordInvalid) { node.publish_draft!(editor) } |
| 1042 | assert_nil node.reload.head | 1038 | assert_nil node.reload.head |
| @@ -1057,7 +1053,9 @@ class NodeTest < ActiveSupport::TestCase | |||
| 1057 | node = Node.root.children.create!(:slug => "restorable") | 1053 | node = Node.root.children.create!(:slug => "restorable") |
| 1058 | node.reload.trash! | 1054 | node.reload.trash! |
| 1059 | 1055 | ||
| 1060 | assert_raises(ActiveRecord::RecordInvalid) { node.restore_from_trash!(updates, editor) } | 1056 | node.reload.draft.update!(:parent_node_id => updates.id) |
| 1057 | |||
| 1058 | assert_raises(ActiveRecord::RecordInvalid) { node.restore_from_trash!(editor) } | ||
| 1061 | assert node.reload.in_trash? | 1059 | assert node.reload.in_trash? |
| 1062 | end | 1060 | end |
| 1063 | 1061 | ||
| @@ -1068,7 +1066,8 @@ class NodeTest < ActiveSupport::TestCase | |||
| 1068 | node = Node.root.children.create!(:slug => "restorable_free") | 1066 | node = Node.root.children.create!(:slug => "restorable_free") |
| 1069 | node.reload.trash! | 1067 | node.reload.trash! |
| 1070 | 1068 | ||
| 1071 | node.restore_from_trash!(club, editor) | 1069 | node.reload.draft.update!(:parent_node_id => club.id) |
| 1070 | node.restore_from_trash!(editor) | ||
| 1072 | assert_not node.reload.in_trash? | 1071 | assert_not node.reload.in_trash? |
| 1073 | assert_equal club.id, node.parent_id | 1072 | assert_equal club.id, node.parent_id |
| 1074 | end | 1073 | end |
| @@ -1101,4 +1100,65 @@ class NodeTest < ActiveSupport::TestCase | |||
| 1101 | node.update_external_url!("https://example.org", users(:quentin)) | 1100 | node.update_external_url!("https://example.org", users(:quentin)) |
| 1102 | end | 1101 | end |
| 1103 | end | 1102 | end |
| 1103 | |||
| 1104 | test "a new node's draft carries the node's address" do | ||
| 1105 | parent = Node.root.children.create!(:slug => "addr_parent") | ||
| 1106 | node = parent.children.create!(:slug => "addr_child") | ||
| 1107 | |||
| 1108 | assert_equal "addr_child", node.draft.slug | ||
| 1109 | assert_equal parent.id, node.draft.parent_node_id | ||
| 1110 | end | ||
| 1111 | |||
| 1112 | test "an autosave inherits the draft's address" do | ||
| 1113 | node = Node.root.children.create!(:slug => "addr_autosave") | ||
| 1114 | node.draft.update!(:slug => "renamed") | ||
| 1115 | node.lock_for_editing!(users(:quentin)) | ||
| 1116 | node.autosave!({ :title => "x" }, users(:quentin)) | ||
| 1117 | |||
| 1118 | assert_equal "renamed", node.autosave.slug | ||
| 1119 | end | ||
| 1120 | |||
| 1121 | test "a blank slug in an autosave leaves the address unchanged" do | ||
| 1122 | node = Node.root.children.create!(:slug => "addr_blank") | ||
| 1123 | node.lock_for_editing!(users(:quentin)) | ||
| 1124 | node.autosave!({ :slug => "", :title => "x" }, users(:quentin)) | ||
| 1125 | |||
| 1126 | assert_equal "addr_blank", node.autosave.slug | ||
| 1127 | end | ||
| 1128 | |||
| 1129 | test "a node with no draft has nothing to publish" do | ||
| 1130 | node = create_node_with_published_page | ||
| 1131 | assert_nil node.draft | ||
| 1132 | |||
| 1133 | assert_nil node.publish_draft!(@user1) | ||
| 1134 | end | ||
| 1135 | |||
| 1136 | test "prospective_unique_name reports the draft's intended address" do | ||
| 1137 | parent = Node.root.children.create!(:slug => "prospective_parent") | ||
| 1138 | node = Node.root.children.create!(:slug => "prospective_child") | ||
| 1139 | node.draft.update!(:parent_node_id => parent.id) | ||
| 1140 | |||
| 1141 | assert_equal "prospective_parent/prospective_child", | ||
| 1142 | node.prospective_unique_name | ||
| 1143 | end | ||
| 1144 | |||
| 1145 | test "prospective_unique_name falls back to the live address when the parent is gone" do | ||
| 1146 | parent = Node.root.children.create!(:slug => "doomed_parent") | ||
| 1147 | node = Node.root.children.create!(:slug => "orphan_child") | ||
| 1148 | node.draft.update!(:parent_node_id => parent.id) | ||
| 1149 | parent.destroy! | ||
| 1150 | |||
| 1151 | assert node.reload.draft.parent_node_missing? | ||
| 1152 | assert_equal "orphan_child", node.prospective_unique_name | ||
| 1153 | end | ||
| 1154 | |||
| 1155 | test "publishing a draft whose parent is gone is refused" do | ||
| 1156 | parent = Node.root.children.create!(:slug => "doomed_parent_two") | ||
| 1157 | node = Node.root.children.create!(:slug => "orphan_child_two") | ||
| 1158 | node.draft.update!(:parent_node_id => parent.id) | ||
| 1159 | parent.destroy! | ||
| 1160 | |||
| 1161 | assert_raises(ActiveRecord::RecordInvalid) { node.reload.publish_draft! } | ||
| 1162 | assert_nil node.reload.head | ||
| 1163 | end | ||
| 1104 | end | 1164 | end |
diff --git a/test/models/node_trash_test.rb b/test/models/node_trash_test.rb index 3947f20e..a4774c58 100644 --- a/test/models/node_trash_test.rb +++ b/test/models/node_trash_test.rb | |||
| @@ -76,7 +76,8 @@ class NodeTrashTest < ActiveSupport::TestCase | |||
| 76 | node.trash!(@user1) | 76 | node.trash!(@user1) |
| 77 | target = Node.root.children.create!(:slug => "restore_target") | 77 | target = Node.root.children.create!(:slug => "restore_target") |
| 78 | 78 | ||
| 79 | node.reload.restore_from_trash!(target, @user1) | 79 | node.reload.draft.update!(:parent_node_id => target.id) |
| 80 | node.reload.restore_from_trash!(@user1) | ||
| 80 | node.reload | 81 | node.reload |
| 81 | 82 | ||
| 82 | assert_equal target, node.parent | 83 | assert_equal target, node.parent |
| @@ -91,8 +92,11 @@ class NodeTrashTest < ActiveSupport::TestCase | |||
| 91 | node.trash!(@user1) | 92 | node.trash!(@user1) |
| 92 | other_trashed = Node.trash.children.create!(:slug => "also_trashed") | 93 | other_trashed = Node.trash.children.create!(:slug => "also_trashed") |
| 93 | 94 | ||
| 94 | assert_raises(ActiveRecord::RecordInvalid) { node.reload.restore_from_trash!(Node.trash, @user1) } | 95 | node.reload.draft.update!(:parent_node_id => Node.trash.id) |
| 95 | assert_raises(ActiveRecord::RecordInvalid) { node.reload.restore_from_trash!(other_trashed, @user1) } | 96 | assert_raises(ActiveRecord::RecordInvalid) { node.reload.restore_from_trash!(@user1) } |
| 97 | |||
| 98 | node.reload.draft.update!(:parent_node_id => other_trashed.id) | ||
| 99 | assert_raises(ActiveRecord::RecordInvalid) { node.reload.restore_from_trash!(@user1) } | ||
| 96 | end | 100 | end |
| 97 | 101 | ||
| 98 | test "destroy_from_trash! refuses nodes outside the Trash" do | 102 | test "destroy_from_trash! refuses nodes outside the Trash" do |
