summaryrefslogtreecommitdiff
path: root/test/models/node_test.rb
diff options
context:
space:
mode:
Diffstat (limited to 'test/models/node_test.rb')
-rw-r--r--test/models/node_test.rb252
1 files changed, 251 insertions, 1 deletions
diff --git a/test/models/node_test.rb b/test/models/node_test.rb
index 959387d..d7e4dd0 100644
--- a/test/models/node_test.rb
+++ b/test/models/node_test.rb
@@ -268,7 +268,6 @@ class NodeTest < ActiveSupport::TestCase
268 assert_equal "quentin", node.head.user.login 268 assert_equal "quentin", node.head.user.login
269 end 269 end
270 270
271
272 test "update?" do 271 test "update?" do
273 Node.root.descendants.delete_all 272 Node.root.descendants.delete_all
274 updates = Node.root.children.create!( :slug => "updates" ) 273 updates = Node.root.children.create!( :slug => "updates" )
@@ -359,6 +358,16 @@ class NodeTest < ActiveSupport::TestCase
359 assert_equal @user1, node.reload.lock_owner 358 assert_equal @user1, node.reload.lock_owner
360 end 359 end
361 360
361 test "title reads from autosave when neither draft nor head exists yet" do
362 node = Node.root.children.create!(:slug => "title_autosave_only_test")
363 node.draft.destroy
364 node.update_column(:draft_id, nil)
365 node.lock_for_editing!(users(:quentin))
366 node.autosave!({ :title => "autosave-only title" }, users(:quentin))
367
368 assert_equal "autosave-only title", node.reload.title
369 end
370
362 test "revert! is a safe no-op on a fresh node with only a draft" do 371 test "revert! is a safe no-op on a fresh node with only a draft" do
363 node = create_node_with_draft 372 node = create_node_with_draft
364 node.lock_for_editing!(@user1) 373 node.lock_for_editing!(@user1)
@@ -621,4 +630,245 @@ class NodeTest < ActiveSupport::TestCase
621 assert_equal "Edited directly on autosave", Globalize.with_locale(:en) { autosave.title } 630 assert_equal "Edited directly on autosave", Globalize.with_locale(:en) { autosave.title }
622 assert_equal "v2", Globalize.with_locale(:de) { autosave.title } 631 assert_equal "v2", Globalize.with_locale(:de) { autosave.title }
623 end 632 end
633
634 test "publish_draft! logs a NodeAction crediting the actual publisher" do
635 node = Node.root.children.create!(:slug => "publish_log_test")
636 node.draft.update!(:title => "Version one")
637
638 node.publish_draft!(@user1)
639
640 action = NodeAction.last
641 assert_equal node, action.node
642 assert_equal node.head, action.page
643 assert_equal @user1, action.user
644 assert_equal "publish", action.action
645 assert_equal "draft", action.metadata["via"]
646 end
647
648 test "publish_draft! called with no user logs no actor, not a guessed one" do
649 node = Node.root.children.create!(:slug => "publish_log_no_user_test")
650 node.draft.update!(:title => "Version one")
651
652 node.publish_draft!
653
654 action = NodeAction.last
655 assert_nil action.user
656 assert_nil action.metadata["username"]
657 end
658
659 test "publish_draft! with nothing pending creates no NodeAction" do
660 node = Node.root.children.create!(:slug => "publish_log_noop_test")
661 node.publish_draft!
662 count_before = NodeAction.count
663
664 result = node.publish_draft!
665
666 assert_nil result
667 assert_equal count_before, NodeAction.count
668 end
669
670 test "revert! logs discard_autosave for an in-progress autosave" do
671 node = create_node_with_published_page
672 node.lock_for_editing!(@user1)
673 node.autosave!({:title => "in progress"}, @user1)
674
675 node.revert!(@user1)
676
677 action = NodeAction.last
678 assert_equal node, action.node
679 assert_equal @user1, action.user
680 assert_equal "discard_autosave", action.action
681 end
682
683 test "revert! logs destroy_draft for a draft with a head behind it" do
684 node = create_node_with_published_page
685 find_or_create_draft(node, @user1)
686
687 node.revert!(@user1)
688
689 action = NodeAction.last
690 assert_equal node, action.node
691 assert_equal @user1, action.user
692 assert_equal "destroy_draft", action.action
693 end
694
695 test "revert! with nothing to revert logs nothing" do
696 node = create_node_with_published_page
697 node.lock_for_editing!(@user1)
698 count_before = NodeAction.count
699
700 node.revert!(@user1)
701
702 assert_equal count_before, NodeAction.count
703 end
704
705 test "publish_draft! records the title diff in metadata" do
706 node = create_node_with_published_page
707 Globalize.with_locale(:de) { node.head.update!(:title => "Original Title") }
708 find_or_create_draft(node, @user1)
709 Globalize.with_locale(:de) { node.draft.update!(:title => "New Title") }
710
711 node.publish_draft!(@user1)
712
713 action = NodeAction.last
714 assert_equal "draft", action.metadata["via"]
715 assert_equal "Original Title", action.metadata.dig("title", "from")
716 assert_equal "New Title", action.metadata.dig("title", "to")
717 end
718
719 test "publishing a staged slug change logs a move with the path pair" do
720 node = create_node_with_published_page
721 path_before = node.unique_name
722 node.staged_slug = "moved-#{node.slug}"
723 node.save!
724 publish_count_before = NodeAction.where(:action => "publish").count
725
726 node.publish_draft!(@user1)
727
728 node.reload
729 assert_not_equal path_before, node.unique_name
730
731 action = NodeAction.where(:action => "move").last
732 assert_equal node, action.node
733 assert_equal @user1, action.user
734 assert_equal path_before, action.metadata.dig("path", "from")
735 assert_equal node.unique_name, action.metadata.dig("path", "to")
736
737 # No draft was pending: path change alone must not fabricate a publish.
738 assert_equal publish_count_before, NodeAction.where(:action => "publish").count
739 end
740
741 test "publishing a draft together with a staged move logs two entries" do
742 node = create_node_with_published_page
743 find_or_create_draft(node, @user1)
744 node.staged_slug = "relocated-#{node.slug}"
745 node.save!
746
747 assert_difference "NodeAction.count", 2 do
748 node.publish_draft!(@user1)
749 end
750
751 assert_equal %w[move publish],
752 NodeAction.order(:id).last(2).map(&:action).sort
753 end
754
755 test "restore_revision! logs a publish via revision" do
756 node = create_node_with_published_page
757 Globalize.with_locale(:de) { node.head.update!(:title => "First") }
758 first_head = node.head
759 find_or_create_draft(node, @user1)
760 Globalize.with_locale(:de) { node.draft.update!(:title => "Second") }
761 node.publish_draft!(@user1)
762
763 node.restore_revision!(first_head.revision, @user1)
764
765 action = NodeAction.last
766 assert_equal "publish", action.action
767 assert_equal "revision", action.metadata["via"]
768 assert_equal first_head, action.page
769 assert_equal @user1, action.user
770 assert_equal "Second", action.metadata.dig("title", "from")
771 assert_equal "First", action.metadata.dig("title", "to")
772 end
773
774 test "default_template_name rejects values not present in the template directory" do
775 node = Node.root.children.build(:slug => "template_guard_test",
776 :default_template_name => "../../layouts/admin")
777 assert_not node.valid?
778
779 node.default_template_name = "standard_template"
780 assert node.valid?
781 end
782
783 test "destroying a node with children is refused" do
784 parent = Node.root.children.create!(:slug => "destroy_guard_parent")
785 parent.children.create!(:slug => "destroy_guard_child")
786
787 assert_no_difference "Node.count" do
788 assert_not parent.destroy
789 end
790 assert parent.errors[:base].any?
791 end
792
793 test "destroying a childless node leaves no orphaned pages or asset links" do
794 node = create_node_with_published_page
795 page_ids = node.pages.pluck(:id)
796 asset = Asset.create!(:name => "destroy cascade probe",
797 :upload_file_name => "test_image.png",
798 :upload_content_type => "image/png",
799 :upload_file_size => 49854,
800 :upload_updated_at => Time.current)
801 node.head.related_assets.create!(:asset_id => asset.id, :position => 1)
802
803 node.destroy
804
805 assert_equal 0, Page.where(:id => page_ids).count
806 assert_equal 0, RelatedAsset.where(:page_id => page_ids).count
807 end
808
809 test "destroying a node also removes its autosave page" do
810 node = create_node_with_published_page
811 node.lock_for_editing!(@user1)
812 node.autosave!({:title => "in flight"}, @user1)
813 autosave_id = node.autosave_id
814
815 node.destroy
816
817 assert_equal 0, Page.where(:id => autosave_id).count
818 end
819
820 test "Node.trash lazily creates the container exactly once" do
821 assert_difference "Node.count", 1 do
822 Node.trash
823 end
824 assert_no_difference "Node.count" do
825 assert_equal Node.trash, Node.trash
826 end
827 assert Node.trash.trash_node?
828 assert_not Node.trash.in_trash?
829 assert_equal "Trash", Globalize.with_locale(I18n.default_locale) { Node.trash.draft.title }
830 end
831
832 test "in_trash? walks the whole parent chain" do
833 child = Node.trash.children.create!(:slug => "trashed_thing")
834 grandchild = child.children.create!(:slug => "trashed_deeper")
835
836 assert child.in_trash?
837 assert grandchild.in_trash?
838 assert_not Node.root.children.create!(:slug => "living_thing").in_trash?
839 end
840
841 test "the reserved slug is refused for other root children, live and staged" do
842 Node.trash
843
844 assert_not Node.root.children.build(:slug => CccConventions::TRASH_SLUG).valid?
845 assert_not Node.root.children.build(:slug => "fine", :staged_slug => CccConventions::TRASH_SLUG).valid?
846 assert Node.trash.children.create!(:slug => "sub").children.build(:slug => CccConventions::TRASH_SLUG).valid?
847 end
848
849 test "the Trash node refuses rename, move, and destroy" do
850 trash = Node.trash
851 other = Node.root.children.create!(:slug => "not_the_trash")
852
853 trash.slug = "recycling"
854 assert_not trash.valid?
855
856 trash.reload.parent_id = other.id
857 assert_not trash.valid?
858
859 assert_no_difference "Node.count" do
860 assert_not trash.reload.destroy
861 end
862 end
863
864 test "a head cannot exist inside the Trash, and publishing there is refused" do
865 node = Node.trash.children.create!(:slug => "no_publish_here")
866 page = node.pages.create!
867
868 node.head = page
869 assert_not node.valid?
870
871 node.reload
872 assert_raises(ActiveRecord::RecordInvalid) { node.publish_draft! }
873 end
624end 874end