summaryrefslogtreecommitdiff
path: root/test/models/helpers/node_actions_helper_test.rb
diff options
context:
space:
mode:
Diffstat (limited to 'test/models/helpers/node_actions_helper_test.rb')
-rw-r--r--test/models/helpers/node_actions_helper_test.rb146
1 files changed, 146 insertions, 0 deletions
diff --git a/test/models/helpers/node_actions_helper_test.rb b/test/models/helpers/node_actions_helper_test.rb
new file mode 100644
index 0000000..1b72ec9
--- /dev/null
+++ b/test/models/helpers/node_actions_helper_test.rb
@@ -0,0 +1,146 @@
1require 'test_helper'
2
3class NodeActionsHelperTest < ActionView::TestCase
4 def setup
5 @original_locale = I18n.locale
6 I18n.locale = :en
7 end
8
9 def default_url_options
10 { :locale => nil }
11 end
12
13 def icon(_name, **)
14 '<svg class="stub-icon"></svg>'.html_safe
15 end
16
17 def teardown
18 I18n.locale = @original_locale
19 end
20
21 def entry action, metadata = {}, node: nil, user: nil, page: nil
22 NodeAction.create!(:node => node, :user => user, :page => page,
23 :action => action, :occurred_at => Time.now,
24 :metadata => { "username" => "quentin",
25 "human_readable_node_name" => "Subject" }.merge(metadata))
26 end
27
28 test "publish renders the revision sentence, not the titles" do
29 out = action_summary(entry("publish",
30 { "via" => "draft", "title" => { "from" => "Old", "to" => "New" } }))
31
32 assert_includes out, "quentin"
33 assert_includes out, "new revision"
34 assert_not_includes out, "Old"
35 end
36
37 test "first publish uses its own sentence" do
38 out = action_summary(entry("publish",
39 { "via" => "draft", "title" => { "from" => nil, "to" => "New" } }))
40
41 assert_includes out, "for the first time"
42 end
43
44 test "rollback publishes get the rollback sentence" do
45 out = action_summary(entry("publish",
46 { "via" => "revision", "title" => { "from" => "Now", "to" => "Then" } }))
47
48 assert_includes out, "rolled"
49 end
50
51 test "move renders the path pair" do
52 out = action_summary(entry("move",
53 { "path" => { "from" => "a/b", "to" => "a/c" } }))
54
55 assert_includes out, "a/b"
56 assert_includes out, "a/c"
57 end
58
59 test "unknown verbs degrade to a generic sentence, never an error" do
60 out = action_summary(entry("frobnicate"))
61
62 assert_includes out, "frobnicate"
63 assert_includes out, "quentin"
64 end
65
66 test "dead references render as plain names from metadata, no links" do
67 out = action_summary(entry("publish",
68 { "title" => { "from" => "Old", "to" => "New" } }))
69
70 assert_not_includes out, "<a "
71 assert_includes out, "Subject"
72 end
73
74 test "metadata values are escaped" do
75 out = action_summary(entry("publish",
76 { "human_readable_node_name" => "<b>bold</b>" }))
77
78 assert_not_includes out, "<b>"
79 end
80
81 test "live associations upgrade names to links" do
82 out = action_summary(entry("publish",
83 { "title" => { "from" => "Old", "to" => "New" } },
84 :user => users(:quentin)))
85
86 assert_includes out, "<a "
87 end
88
89 test "details are guarded off when nothing but an unchanged title is present" do
90 unchanged = entry("publish", { "title" => { "from" => "Same", "to" => "Same" } })
91 changed = entry("publish", { "title" => { "from" => "Old", "to" => "New" } })
92
93 assert_not action_details?(unchanged)
94 assert action_details?(changed)
95 end
96
97 test "first publish with a byline names the author" do
98 out = action_summary(entry("publish",
99 { "title" => { "from" => nil, "to" => "New" },
100 "author" => { "from" => nil, "to" => "quentin" } }))
101
102 assert_includes out, "author"
103 end
104
105 test "create entries with their flat title render and are guarded off details" do
106 e = entry("create", { "title" => "Initial", "path" => "a/b" })
107
108 assert_includes action_summary(e), "a/b"
109 assert_not action_details?(e)
110 end
111
112 test "trash, restore, and destroy render their paths" do
113 trash = entry("trash", { "path" => { "from" => "club/old", "to" => "trash/old" } })
114 restore = entry("restore_from_trash", { "path" => { "from" => "trash/old", "to" => "club/new" } })
115 doomed = entry("destroy", { "path" => "trash/old" })
116
117 assert_includes action_summary(trash), "club/old"
118 assert_includes action_summary(restore), "club/new"
119 assert_includes action_summary(doomed), "trash/old"
120 end
121
122 test "revision lifecycle badges cover create, publish, rollback, and inference" do
123 created = entry("create", { "title" => "x", "path" => "a/b" })
124 published = entry("publish", { "via" => "draft", "title" => { "from" => nil, "to" => "x" } })
125 restored = entry("publish", { "via" => "revision", "title" => { "from" => "y", "to" => "x" } })
126 restored.update!(:inferred_from => "from_page_revision")
127
128 out = revision_lifecycle_badges([created, published, restored])
129
130 assert_includes out, "created"
131 assert_includes out, "published"
132 assert_includes out, "restored"
133 assert_includes out, "quentin"
134 assert_includes out, "node_action_inferred"
135 assert_includes out, "<span"
136 assert_not_includes out, "&lt;span"
137
138 assert_equal "", revision_lifecycle_badges(nil)
139 end
140
141 test "verb icons map known verbs, distinguish rollbacks, and fall back" do
142 assert_includes verb_icon(entry("trash", { "path" => { "from" => "a", "to" => "t/a" } })), "node_action_icon--trash"
143 assert_includes verb_icon(entry("publish", { "via" => "revision" })), "node_action_icon--history"
144 assert_includes verb_icon(entry("frobnicate")), "node_action_icon--circle-dashed"
145 end
146end