From bc03601ee5c7acd4ef012ec4a404bd7b76bceaa0 Mon Sep 17 00:00:00 2001 From: erdgeist Date: Wed, 8 Jul 2026 17:32:17 +0200 Subject: Add revert!/discard and rebuild nodes#edit around the new hierarchy revert! discards exactly the topmost non-empty layer -- autosave if present, else draft -- and reveals whatever's beneath it, releasing the lock only once nothing is left to protect. Guards against destroying a brand-new, never-published node's only draft, which would violate the (head | draft) invariant every other method here assumes holds; the view's Destroy/Discard button is gated the same way. nodes#edit now calls lock_for_editing! instead of find_or_create_draft, and always displays autosave || draft || head, resurrecting an abandoned session's unsaved content by default with an explicit flash explaining what's shown and how to get back to the last saved version. The view drops content_for :subnavigation entirely: Show becomes "Unlock + Back", Preview stays a plain link, metadata's own
already replaced the old toggle, and Publish moves off this page for good, per the earlier decision to manage the publish lifecycle entirely from nodes#show. Save Draft and Save + Unlock + Exit appear both above and below the form, given the body field alone runs 600px on desktop. --- test/models/node_test.rb | 87 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) (limited to 'test/models/node_test.rb') diff --git a/test/models/node_test.rb b/test/models/node_test.rb index bdf556d..2138c19 100644 --- a/test/models/node_test.rb +++ b/test/models/node_test.rb @@ -379,6 +379,93 @@ class NodeTest < ActiveSupport::TestCase assert_nil node.autosave assert_nil node.lock_owner end + + test "revert! is a safe no-op on a fresh node with only a draft" do + node = create_node_with_draft + node.lock_for_editing!(@user1) + + node.revert!(@user1) + node.reload + + assert_not_nil node.draft + assert_equal @user1, node.lock_owner + end + + test "revert! discards an autosave on a fresh node without touching its only draft" do + node = create_node_with_draft + node.lock_for_editing!(@user1) + node.autosave!({ :title => "typing" }, @user1) + + node.revert!(@user1) + node.reload + + assert_nil node.autosave + assert_not_nil node.draft + assert_equal @user1, node.lock_owner + end + + test "revert! does nothing when a published node has no draft or autosave" do + node = create_node_with_published_page + node.lock_for_editing!(@user1) + + node.revert!(@user1) + node.reload + + assert_not_nil node.head + assert_nil node.draft + end + + test "revert! discards a fresh autosave and releases the lock when no draft exists" do + node = create_node_with_published_page + node.lock_for_editing!(@user1) + node.autosave!({ :title => "in progress" }, @user1) + + node.revert!(@user1) + node.reload + + assert_nil node.autosave + assert_nil node.draft + assert_nil node.lock_owner + end + + test "revert! destroys an existing draft and releases the lock" do + node = create_node_with_published_page + head_title = node.head.title + node.lock_for_editing!(@user1) + node.autosave!({ :title => "second version" }, @user1) + node.save_draft!(@user1) + + node.revert!(@user1) + node.reload + + assert_nil node.draft + assert_equal head_title, node.head.title + assert_nil node.lock_owner + end + + test "revert! discards only the autosave when a draft survives beneath it" do + node = create_node_with_published_page + node.lock_for_editing!(@user1) + node.autosave!({ :title => "second version" }, @user1) + node.save_draft!(@user1) + node.autosave!({ :title => "third version, still typing" }, @user1) + + node.revert!(@user1) + node.reload + + assert_nil node.autosave + assert_not_nil node.draft + assert_equal "second version", node.draft.title + assert_equal @user1, node.lock_owner + end + + test "revert! raises LockedByAnotherUser for a non-owner" do + node = create_node_with_published_page + node.lock_for_editing!(@user1) + + assert_raise(LockedByAnotherUser) { node.revert!(@user2) } + assert_equal @user1, node.reload.lock_owner + end def create_revisions node, count count.times do -- cgit v1.3