summaryrefslogtreecommitdiff
path: root/test/models/helpers/node_actions_helper_test.rb
diff options
context:
space:
mode:
authorerdgeist <erdgeist@erdgeist.org>2026-07-16 03:30:01 +0200
committererdgeist <erdgeist@erdgeist.org>2026-07-16 03:30:01 +0200
commit190daaa8a0bb79e750894b83e31b9d99f7d900a4 (patch)
tree308a7bdeba7bd22733729408883e548f851a8812 /test/models/helpers/node_actions_helper_test.rb
parentc0c9250141c2fa64fed967b8b9ad9bada3694c3d (diff)
Add a reader for the action log at admin/logHEADmaster
NodeActionsController#index lists entries newest-first, filterable by node_id or user_id -- the two zoom shapes the log was designed around. Rendering goes through NodeActionsHelper.action_summary, which builds one sentence per entry from metadata alone, so entries referencing deleted users or nodes render from their snapshots; live associations only upgrade names to links. Unknown verbs degrade to a generic sentence rather than an error, since the log outlives its vocabulary. The helper is the escaping boundary: every metadata value passes through h() before assembly. Actor names link to the log's own user zoom rather than the unused users page -- inspecting a suspicious user's other actions is the intended workflow. Publish entries with a translation_diff expose a collapsed per-locale change table linking out to the revision itself. Sentences live in en.yml/de.yml following the existing widget-string convention. nodes#show links to its node's zoomed log.
Diffstat (limited to 'test/models/helpers/node_actions_helper_test.rb')
-rw-r--r--test/models/helpers/node_actions_helper_test.rb85
1 files changed, 85 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..93bbdf6
--- /dev/null
+++ b/test/models/helpers/node_actions_helper_test.rb
@@ -0,0 +1,85 @@
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 teardown
14 I18n.locale = @original_locale
15 end
16
17 def entry action, metadata = {}, node: nil, user: nil, page: nil
18 NodeAction.create!(:node => node, :user => user, :page => page,
19 :action => action, :occurred_at => Time.now,
20 :metadata => { "username" => "quentin",
21 "human_readable_node_name" => "Subject" }.merge(metadata))
22 end
23
24 test "publish renders the title pair" do
25 out = action_summary(entry("publish",
26 { "via" => "draft", "title" => { "from" => "Old", "to" => "New" } }))
27
28 assert_includes out, "quentin"
29 assert_includes out, "Old"
30 end
31
32 test "first publish uses its own sentence" do
33 out = action_summary(entry("publish",
34 { "via" => "draft", "title" => { "from" => nil, "to" => "New" } }))
35
36 assert_includes out, "for the first time"
37 end
38
39 test "rollback publishes get the rollback sentence" do
40 out = action_summary(entry("publish",
41 { "via" => "revision", "title" => { "from" => "Now", "to" => "Then" } }))
42
43 assert_includes out, "rolled"
44 end
45
46 test "move renders the path pair" do
47 out = action_summary(entry("move",
48 { "path" => { "from" => "a/b", "to" => "a/c" } }))
49
50 assert_includes out, "a/b"
51 assert_includes out, "a/c"
52 end
53
54 test "unknown verbs degrade to a generic sentence, never an error" do
55 out = action_summary(entry("frobnicate"))
56
57 assert_includes out, "frobnicate"
58 assert_includes out, "quentin"
59 end
60
61 test "dead references render as plain names from metadata, no links" do
62 out = action_summary(entry("publish",
63 { "title" => { "from" => "Old", "to" => "New" } }))
64
65 assert_not_includes out, "<a "
66 assert_includes out, "Subject"
67 end
68
69 test "metadata values are escaped" do
70 out = action_summary(entry("publish",
71 { "human_readable_node_name" => "<b>bold</b>",
72 "title" => { "from" => "<script>alert(1)</script>", "to" => "x" } }))
73
74 assert_not_includes out, "<script>"
75 assert_not_includes out, "<b>"
76 end
77
78 test "live associations upgrade names to links" do
79 out = action_summary(entry("publish",
80 { "title" => { "from" => "Old", "to" => "New" } },
81 :user => users(:quentin)))
82
83 assert_includes out, "<a "
84 end
85end