Skip to content

Commit d46f639

Browse files
committed
Raise errors when setting HTML for text content
This adds in a check when specifying HTML in a smart answer (via govspeak_for or html_for) that it is not for a field that is text only. This is put in to address a concern that it could be rather easy for someone to specify `govspeak_for(:title) { "my govspeak" }` and this produce an unexpected output that no-one notices. As part of this I removed the govspeak option in DEFAULT_FORMATS as I didn't think it affected the outcome of any method calls.
1 parent ec2fbe7 commit d46f639

File tree

2 files changed

+37
-7
lines changed

2 files changed

+37
-7
lines changed

lib/smart_answer/erb_renderer/format_capture_helper.rb

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@ module SmartAnswer
22
module ErbRenderer::FormatCaptureHelper
33
class InvalidFormatType < RuntimeError; end
44

5-
DEFAULT_FORMATS = {
6-
govspeak: [/^body$/, /^post_body$/, /^next_steps$/],
7-
text: [/^title$/, /^meta_description$/, /^hint$/, /^label$/, /^suffix_label$/, /^error_*./],
8-
}.freeze
5+
TEXT_CONTENT = [
6+
:title,
7+
:meta_description,
8+
:hint,
9+
:label,
10+
:suffix_label,
11+
/^error_/,
12+
].freeze
913

1014
def render_content_for(name, options = {}, &block)
1115
format = options.fetch(:format, default_format(name))
@@ -30,10 +34,14 @@ def text_for(name, &block)
3034
end
3135

3236
def govspeak_for(name, &block)
37+
raise ArgumentError, text_only_error_message(name) if text_only?(name)
38+
3339
content_for(name, render_govspeak(capture_content(&block)))
3440
end
3541

3642
def html_for(name, &block)
43+
raise ArgumentError, text_only_error_message(name) if text_only?(name)
44+
3745
content_for(name, capture_content(&block).html_safe)
3846
end
3947

@@ -46,11 +54,17 @@ def capture_content(&block)
4654
end
4755

4856
def default_format(name)
49-
DEFAULT_FORMATS.each do |format, patterns|
50-
return format if patterns.any? { |pattern| pattern.match?(name) }
57+
text_only?(name) ? :text : :govspeak
58+
end
59+
60+
def text_only?(name)
61+
TEXT_CONTENT.any? do |item|
62+
item.is_a?(Regexp) ? name.match?(item) : name == item
5163
end
64+
end
5265

53-
:govspeak
66+
def text_only_error_message(name)
67+
"#{name} can only be used to display text. Please use #text_for"
5468
end
5569

5670
def render_govspeak(content)

test/unit/format_capture_helper_test.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,14 @@ def render(component, &block)
6767
@test_obj.govspeak_for(:name) { " content" }
6868
assert_match @test_obj.content_for(:name), "<govspeak><p>content</p>\n</govspeak>"
6969
end
70+
71+
should "raise an error when rendering a text only field" do
72+
error = assert_raises ArgumentError do
73+
@test_obj.govspeak_for(:title) { "Text" }
74+
end
75+
assert_match "title can only be used to display text. Please use #text_for",
76+
error.message
77+
end
7078
end
7179

7280
context "#html_for" do
@@ -79,6 +87,14 @@ def render(component, &block)
7987
@test_obj.html_for(:name) { "<p>content</p>" }
8088
assert @test_obj.content_for(:name).html_safe?
8189
end
90+
91+
should "raise an error when rendering a text only field" do
92+
error = assert_raises ArgumentError do
93+
@test_obj.html_for(:title) { "Text" }
94+
end
95+
assert_match "title can only be used to display text. Please use #text_for",
96+
error.message
97+
end
8298
end
8399

84100
context "#render_content_for" do

0 commit comments

Comments
 (0)