govspeak 3.6.2 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/lib/govspeak.rb +82 -6
- data/lib/govspeak/blockquote_extra_quote_remover.rb +19 -0
- data/lib/govspeak/extension/attachment.html.erb +65 -0
- data/lib/govspeak/extension/inline_attachment.html.erb +4 -0
- data/lib/govspeak/post_processor.rb +42 -0
- data/lib/govspeak/version.rb +1 -1
- data/lib/presenters/attachment_presenter.rb +241 -0
- data/lib/presenters/h_card_presenter.rb +69 -0
- data/lib/templates/contact.html.erb +42 -0
- data/test/blockquote_extra_quote_remover_test.rb +91 -0
- data/test/govspeak_contacts_test.rb +112 -0
- data/test/govspeak_test.rb +168 -35
- data/test/presenters/h_card_presenter_test.rb +153 -0
- metadata +66 -5
@@ -0,0 +1,69 @@
|
|
1
|
+
class HCardPresenter
|
2
|
+
def self.from_contact(contact)
|
3
|
+
new(contact_properties(contact), contact.country_code)
|
4
|
+
end
|
5
|
+
|
6
|
+
def self.contact_properties(contact)
|
7
|
+
{ 'fn' => contact.recipient,
|
8
|
+
'street-address' => contact.street_address,
|
9
|
+
'postal-code' => contact.postal_code,
|
10
|
+
'locality' => contact.locality,
|
11
|
+
'region' => contact.region,
|
12
|
+
'country-name' => country_name(contact) }
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.country_name(contact)
|
16
|
+
contact.country_name unless contact.country_code == 'GB'
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.property_keys
|
20
|
+
['fn', 'street-address', 'postal-code', 'locality', 'region', 'country-name']
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.address_formats
|
24
|
+
@address_formats ||= YAML.load_file('config/address_formats.yml')
|
25
|
+
end
|
26
|
+
|
27
|
+
attr_reader :properties, :country_code
|
28
|
+
|
29
|
+
def initialize(properties, country_code)
|
30
|
+
@properties = properties
|
31
|
+
@country_code = country_code
|
32
|
+
end
|
33
|
+
|
34
|
+
def render
|
35
|
+
"<p class=\"adr\">\n#{interpolate_address_template}\n</p>\n".html_safe
|
36
|
+
end
|
37
|
+
|
38
|
+
def interpolate_address_property(property_name)
|
39
|
+
value = properties[property_name]
|
40
|
+
|
41
|
+
if value.present?
|
42
|
+
"<span class=\"#{property_name}\">#{ERB::Util.html_escape(value)}</span>"
|
43
|
+
else
|
44
|
+
""
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def interpolate_address_template
|
51
|
+
address = address_template
|
52
|
+
|
53
|
+
self.class.property_keys.each do |key|
|
54
|
+
address.gsub!(/\{\{#{key}\}\}/, interpolate_address_property(key))
|
55
|
+
end
|
56
|
+
|
57
|
+
address.gsub(/^\n/, '') # get rid of blank lines
|
58
|
+
.strip # get rid of any trailing whitespace
|
59
|
+
.gsub(/\n/, "<br />\n") # add break tags where appropriate
|
60
|
+
end
|
61
|
+
|
62
|
+
def address_template
|
63
|
+
(self.class.address_formats[country_code.to_s.downcase] || default_format_string).dup
|
64
|
+
end
|
65
|
+
|
66
|
+
def default_format_string
|
67
|
+
self.class.address_formats['gb']
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
<%
|
2
|
+
extra_class = []
|
3
|
+
extra_class << 'postal-address' if contact.has_postal_address?
|
4
|
+
%>
|
5
|
+
<div id="contact_<%= contact.id %>" class="<%= ['contact', extra_class].flatten.join(' ') %>">
|
6
|
+
<div class="content">
|
7
|
+
<h3><%= contact.title %></h3>
|
8
|
+
<div class="vcard contact-inner">
|
9
|
+
<% if contact.has_postal_address? %>
|
10
|
+
<%= render_hcard_address(contact) %>
|
11
|
+
<% end %>
|
12
|
+
<% if contact.email.present? || contact.contact_form_url.present? || contact.contact_numbers.any? %>
|
13
|
+
<div class="email-url-number">
|
14
|
+
<% if contact.email.present? %>
|
15
|
+
<p class="email">
|
16
|
+
<span class="type"><%= t('contact.email') %></span>
|
17
|
+
<a href="mailto:<%= contact.email %>" class="email"><%= contact.email %></a>
|
18
|
+
</p>
|
19
|
+
<% end %>
|
20
|
+
<% if contact.contact_form_url.present? %>
|
21
|
+
<p class="contact_form_url">
|
22
|
+
<span class="type"><%= t('contact.contact_form') %></span>
|
23
|
+
<a href="<%= contact.contact_form_url %>"><%= contact.contact_form_url.truncate(25) %></a>
|
24
|
+
</p>
|
25
|
+
<% end %>
|
26
|
+
<% contact.contact_numbers.each do |number| %>
|
27
|
+
<p class="tel">
|
28
|
+
<span class="type"><%= number.label %></span>
|
29
|
+
<%= number.number %>
|
30
|
+
</p>
|
31
|
+
<% end %>
|
32
|
+
</div>
|
33
|
+
<% end %>
|
34
|
+
<% if contact.comments.present? %>
|
35
|
+
<p class="comments"><%= auto_link(format_with_html_line_breaks(h(contact.comments))) %></p>
|
36
|
+
<% end %>
|
37
|
+
<% if contact.worldwide_organisation_path %>
|
38
|
+
<a href="<%= contact.worldwide_organisation_path %>">Access and opening times</a>
|
39
|
+
<% end %>
|
40
|
+
</div>
|
41
|
+
</div>
|
42
|
+
</div>
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require "test_helper"
|
4
|
+
|
5
|
+
class BlockquoteExtraQuoteRemoverTest < Minitest::Test
|
6
|
+
def assert_remover_transforms(options)
|
7
|
+
from = options.keys.first
|
8
|
+
to = options.values.first
|
9
|
+
assert_equal to, Govspeak::BlockquoteExtraQuoteRemover.remove(from)
|
10
|
+
end
|
11
|
+
|
12
|
+
def assert_leaves_untouched(candidate)
|
13
|
+
assert_remover_transforms candidate => candidate
|
14
|
+
end
|
15
|
+
|
16
|
+
test "ignores nil" do
|
17
|
+
assert_leaves_untouched nil
|
18
|
+
end
|
19
|
+
|
20
|
+
test "ignores text without double quotes" do
|
21
|
+
assert_leaves_untouched %{no quotes\na few lines,\n\n\n\nbut no quotes\n\n}
|
22
|
+
end
|
23
|
+
|
24
|
+
test "ignores text without a quote symbol" do
|
25
|
+
assert_leaves_untouched %{quotes\n"but not with a > symbol"}
|
26
|
+
end
|
27
|
+
|
28
|
+
test "transforms text with surrounding quotes" do
|
29
|
+
assert_remover_transforms(
|
30
|
+
%{He said:\n> "yes, it's true!"\n\napparently.} =>
|
31
|
+
%{He said:\n> yes, it's true!\n\napparently.}
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
test "leaves quotes in the middle of the string" do
|
36
|
+
assert_remover_transforms(
|
37
|
+
%{He said:\n> "yes, it's true!" whilst sipping a cocktail. "And yes, I did rather enjoy it." \n\napparently.} =>
|
38
|
+
%{He said:\n> yes, it's true!" whilst sipping a cocktail. "And yes, I did rather enjoy it.\n\napparently.}
|
39
|
+
)
|
40
|
+
end
|
41
|
+
|
42
|
+
test "leaves trailing text and quote intact" do
|
43
|
+
assert_remover_transforms(
|
44
|
+
%{He said:\n> "yes, it's true!" whilst sipping a cocktail.} =>
|
45
|
+
%{He said:\n> yes, it's true!" whilst sipping a cocktail.}
|
46
|
+
)
|
47
|
+
end
|
48
|
+
|
49
|
+
test "windows line breaks" do
|
50
|
+
assert_remover_transforms(
|
51
|
+
%{Sir George Young MP, said\r\n> "I welcome the positive public response to the e-petitions site, which is important way of building a bridge between people and Parliament.”\r\n## The special relationship} =>
|
52
|
+
%{Sir George Young MP, said\r\n> I welcome the positive public response to the e-petitions site, which is important way of building a bridge between people and Parliament.\r\n## The special relationship}
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
test "no space in front" do
|
57
|
+
assert_remover_transforms(
|
58
|
+
%{>"As we continue with the redundancy process we will ensure we retain the capabilities that our armed forces will require to meet the challenges of the future. The redundancy programme will not impact adversely on the current operations in Afghanistan, where our armed forces continue to fight so bravely on this country's behalf."} =>
|
59
|
+
%{> As we continue with the redundancy process we will ensure we retain the capabilities that our armed forces will require to meet the challenges of the future. The redundancy programme will not impact adversely on the current operations in Afghanistan, where our armed forces continue to fight so bravely on this country's behalf.}
|
60
|
+
)
|
61
|
+
end
|
62
|
+
|
63
|
+
test "remove double double quotes" do
|
64
|
+
assert_remover_transforms(
|
65
|
+
%{We heard it said:\n\n> ""Today the coalition is remedying those deficiencies by putting in place a new fast track process where the people's elected representatives have responsibility for the final decisions about Britain's future instead of unelected commissioners.""} =>
|
66
|
+
%{We heard it said:\n\n> Today the coalition is remedying those deficiencies by putting in place a new fast track process where the people's elected representatives have responsibility for the final decisions about Britain's future instead of unelected commissioners.}
|
67
|
+
)
|
68
|
+
assert_remover_transforms(
|
69
|
+
%{> ""Today the coalition is remedying those deficiencies by putting in place a new fast track process where the people's elected representatives have responsibility for the final decisions about Britain's future instead of unelected commissioners.} =>
|
70
|
+
%{> Today the coalition is remedying those deficiencies by putting in place a new fast track process where the people's elected representatives have responsibility for the final decisions about Britain's future instead of unelected commissioners.}
|
71
|
+
)
|
72
|
+
end
|
73
|
+
|
74
|
+
test "removes quotes correctly from multi-line blockquotes" do
|
75
|
+
assert_remover_transforms(
|
76
|
+
%{> "Here is a block quote using 2 lines and two of the arrows.\n> I am not sure how this will render. I think it will mash them together."} =>
|
77
|
+
%{> Here is a block quote using 2 lines and two of the arrows.\n> I am not sure how this will render. I think it will mash them together.}
|
78
|
+
)
|
79
|
+
end
|
80
|
+
|
81
|
+
test "preserves multiline blockquotes with plain newlines quotes" do
|
82
|
+
assert_remover_transforms(
|
83
|
+
%{> "line 1\n> \n> "line 2\n> \n> "line 3"} =>
|
84
|
+
%{> line 1\n> \n> line 2\n> \n> line 3}
|
85
|
+
)
|
86
|
+
end
|
87
|
+
|
88
|
+
test "preserve newlines when there's a blockquote with additional text after" do
|
89
|
+
assert_leaves_untouched(%{> \n> blah})
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'ostruct'
|
5
|
+
|
6
|
+
class GovspeakContactsTest < Minitest::Test
|
7
|
+
|
8
|
+
def build_contact(attrs={})
|
9
|
+
OpenStruct.new(
|
10
|
+
has_postal_address?: attrs.fetch(:has_postal_address?, true),
|
11
|
+
id: attrs.fetch(:id, 123456),
|
12
|
+
content_id: attrs.fetch(:content_id, "4f3383e4-48a2-4461-a41d-f85ea8b89ba0"),
|
13
|
+
title: attrs.fetch(:title, "Government Digital Service"),
|
14
|
+
recipient: attrs.fetch(:recipient, ""),
|
15
|
+
street_address: attrs.fetch(:street_address, "125 Kingsway"),
|
16
|
+
postal_code: attrs.fetch(:postal_code, "WC2B 6NH"),
|
17
|
+
locality: attrs.fetch(:locality, "Holborn"),
|
18
|
+
region: attrs.fetch(:region, "London"),
|
19
|
+
country_code: attrs.fetch(:country_code, "gb"),
|
20
|
+
email: attrs.fetch(:email, "people@digital.cabinet-office.gov.uk"),
|
21
|
+
contact_form_url: attrs.fetch(:contact_form_url, ""),
|
22
|
+
contact_numbers: attrs.fetch(:contact_numbers,
|
23
|
+
[OpenStruct.new(label: "helpdesk", number: "+4412345 67890")]),
|
24
|
+
comments: attrs.fetch(:comments, ""),
|
25
|
+
worldwide_organisation_path: attrs.fetch(:worldwide_organisation_path, nil),
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
def compress_html(html)
|
30
|
+
html.gsub(/[\n\r]+[\s]*/,'')
|
31
|
+
end
|
32
|
+
|
33
|
+
test "contact is rendered when present in options[:contacts]" do
|
34
|
+
contact = build_contact
|
35
|
+
govspeak = "[Contact:4f3383e4-48a2-4461-a41d-f85ea8b89ba0]"
|
36
|
+
|
37
|
+
rendered = Govspeak::Document.new(govspeak, { contacts: [contact] }).to_html
|
38
|
+
expected_html_output = %{
|
39
|
+
<div id="contact_123456" class="contact postal-address">
|
40
|
+
<div class="content">
|
41
|
+
<h3>Government Digital Service</h3>
|
42
|
+
<div class="vcard contact-inner">
|
43
|
+
<p class="adr">
|
44
|
+
<span class="street-address">125 Kingsway</span><br>
|
45
|
+
<span class="locality">Holborn</span><br>
|
46
|
+
<span class="region">London</span><br>
|
47
|
+
<span class="postal-code">WC2B 6NH</span>
|
48
|
+
</p>
|
49
|
+
<div class="email-url-number">
|
50
|
+
<p class="email">
|
51
|
+
<span class="type">Email</span>
|
52
|
+
<a href="mailto:people@digital.cabinet-office.gov.uk" class="email">people@digital.cabinet-office.gov.uk</a>
|
53
|
+
</p>
|
54
|
+
<p class="tel">
|
55
|
+
<span class="type">helpdesk</span>
|
56
|
+
+4412345 67890
|
57
|
+
</p>
|
58
|
+
</div>
|
59
|
+
</div>
|
60
|
+
</div>
|
61
|
+
</div>
|
62
|
+
}
|
63
|
+
|
64
|
+
assert_equal(compress_html(expected_html_output), compress_html(rendered))
|
65
|
+
end
|
66
|
+
|
67
|
+
test "no contact is rendered when contact not present in options[:contacts]" do
|
68
|
+
contact = build_contact(content_id: "19f06142-1b4a-47ce-b257-964badd0a5e2")
|
69
|
+
govspeak = "[Contact:4f3383e4-48a2-4461-a41d-f85ea8b89ba0]"
|
70
|
+
rendered = Govspeak::Document.new(govspeak, { contacts: [contact]}).to_html
|
71
|
+
assert_match("", rendered)
|
72
|
+
end
|
73
|
+
|
74
|
+
test "no contact is rendered when no contacts are supplied" do
|
75
|
+
rendered = Govspeak::Document.new("[Contact:4f3383e4-48a2-4461-a41d-f85ea8b89ba0]").to_html
|
76
|
+
assert_match("", rendered)
|
77
|
+
end
|
78
|
+
|
79
|
+
test "contact with no postal address omits the address info" do
|
80
|
+
contact = build_contact(has_postal_address?: false)
|
81
|
+
govspeak = "[Contact:4f3383e4-48a2-4461-a41d-f85ea8b89ba0]"
|
82
|
+
rendered = Govspeak::Document.new(govspeak, { contacts: [contact] }).to_html
|
83
|
+
expected_html_output = %{
|
84
|
+
<div id="contact_123456" class="contact">
|
85
|
+
<div class="content">
|
86
|
+
<h3>Government Digital Service</h3>
|
87
|
+
<div class="vcard contact-inner">
|
88
|
+
<div class="email-url-number">
|
89
|
+
<p class="email">
|
90
|
+
<span class="type">Email</span>
|
91
|
+
<a href="mailto:people@digital.cabinet-office.gov.uk" class="email">people@digital.cabinet-office.gov.uk</a>
|
92
|
+
</p>
|
93
|
+
<p class="tel">
|
94
|
+
<span class="type">helpdesk</span>
|
95
|
+
+4412345 67890
|
96
|
+
</p>
|
97
|
+
</div>
|
98
|
+
</div>
|
99
|
+
</div>
|
100
|
+
</div>
|
101
|
+
}
|
102
|
+
assert_equal(compress_html(expected_html_output), compress_html(rendered))
|
103
|
+
end
|
104
|
+
|
105
|
+
test "worldwide office contact renders worldwide organisation link" do
|
106
|
+
contact = build_contact(worldwide_organisation_path: "/government/world/organisations/british-antarctic-territory")
|
107
|
+
govspeak = "[Contact:4f3383e4-48a2-4461-a41d-f85ea8b89ba0]"
|
108
|
+
rendered = Govspeak::Document.new(govspeak, { contacts: [contact] }).to_html
|
109
|
+
organisation_link = %Q(<a href="/government/world/organisations/british-antarctic-territory">Access and opening times</a>)
|
110
|
+
assert_match(organisation_link, rendered)
|
111
|
+
end
|
112
|
+
end
|
data/test/govspeak_test.rb
CHANGED
@@ -18,11 +18,6 @@ class GovspeakTest < Minitest::Test
|
|
18
18
|
assert_equal "<p><em>this is markdown</em></p>\n", rendered
|
19
19
|
end
|
20
20
|
|
21
|
-
test "simple block extension" do
|
22
|
-
rendered = Govspeak::Document.new("this \n{::reverse}\n*is*\n{:/reverse}\n markdown").to_html
|
23
|
-
assert_equal "<p>this</p>\n\n<p><em>si</em></p>\n\n<p>markdown</p>\n", rendered
|
24
|
-
end
|
25
|
-
|
26
21
|
test "highlight-answer block extension" do
|
27
22
|
rendered = Govspeak::Document.new("this \n{::highlight-answer}Lead in to *BIG TEXT*\n{:/highlight-answer}").to_html
|
28
23
|
assert_equal %Q{<p>this</p>\n\n<div class="highlight-answer">\n<p>Lead in to <em>BIG TEXT</em></p>\n</div>\n}, rendered
|
@@ -106,7 +101,29 @@ Testcase Cliffs
|
|
106
101
|
Teston
|
107
102
|
0123 456 7890 $A }
|
108
103
|
doc = Govspeak::Document.new(input)
|
109
|
-
assert_equal %{\n<div class="address"><div class="adr org fn"><p>\n123 Test Street<br
|
104
|
+
assert_equal %{\n<div class="address"><div class="adr org fn"><p>\n123 Test Street<br>Testcase Cliffs<br>Teston<br>0123 456 7890 \n</p></div></div>\n}, doc.to_html
|
105
|
+
end
|
106
|
+
|
107
|
+
test "should convert barchart" do
|
108
|
+
input = <<-END
|
109
|
+
|col|
|
110
|
+
|---|
|
111
|
+
|val|
|
112
|
+
{barchart}
|
113
|
+
END
|
114
|
+
html = Govspeak::Document.new(input).to_html
|
115
|
+
assert_equal %{<table class=\"js-barchart-table mc-auto-outdent\">\n <thead>\n <tr>\n <th>col</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td>val</td>\n </tr>\n </tbody>\n</table>\n}, html
|
116
|
+
end
|
117
|
+
|
118
|
+
test "should convert barchart with stacked compact and negative" do
|
119
|
+
input = <<-END
|
120
|
+
|col|
|
121
|
+
|---|
|
122
|
+
|val|
|
123
|
+
{barchart stacked compact negative}
|
124
|
+
END
|
125
|
+
html = Govspeak::Document.new(input).to_html
|
126
|
+
assert_equal %{<table class=\"js-barchart-table mc-stacked compact mc-negative mc-auto-outdent\">\n <thead>\n <tr>\n <th>col</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td>val</td>\n </tr>\n </tbody>\n</table>\n}, html
|
110
127
|
end
|
111
128
|
|
112
129
|
test "address div is separated from paragraph text by a couple of line-breaks" do
|
@@ -119,7 +136,7 @@ Testcase Cliffs
|
|
119
136
|
Teston
|
120
137
|
0123 456 7890 $A}
|
121
138
|
doc = Govspeak::Document.new(input)
|
122
|
-
assert_equal %{<p>Paragraph1</p>\n\n<div class="address"><div class="adr org fn"><p>\n123 Test Street<br
|
139
|
+
assert_equal %{<p>Paragraph1</p>\n\n<div class="address"><div class="adr org fn"><p>\n123 Test Street<br>Testcase Cliffs<br>Teston<br>0123 456 7890 \n</p></div></div>\n}, doc.to_html
|
123
140
|
end
|
124
141
|
|
125
142
|
test_given_govspeak("^ I am very informational ^") do
|
@@ -156,7 +173,8 @@ Teston
|
|
156
173
|
|
157
174
|
test_given_govspeak "@ I am very important @" do
|
158
175
|
assert_html_output %{
|
159
|
-
<div role="note" aria-label="Important" class="advisory"
|
176
|
+
<div role="note" aria-label="Important" class="advisory">
|
177
|
+
<p><strong>I am very important</strong></p>
|
160
178
|
</div>}
|
161
179
|
assert_text_output "I am very important"
|
162
180
|
end
|
@@ -168,7 +186,8 @@ Teston
|
|
168
186
|
assert_html_output %{
|
169
187
|
<p>The following is very important</p>
|
170
188
|
|
171
|
-
<div role="note" aria-label="Important" class="advisory"
|
189
|
+
<div role="note" aria-label="Important" class="advisory">
|
190
|
+
<p><strong>I am very important</strong></p>
|
172
191
|
</div>}
|
173
192
|
assert_text_output "The following is very important I am very important"
|
174
193
|
end
|
@@ -212,12 +231,12 @@ Teston
|
|
212
231
|
end
|
213
232
|
|
214
233
|
test_given_govspeak "This is a [link](http://www.gov.uk) isn't it?" do
|
215
|
-
assert_html_output '<p>This is a <a href="http://www.gov.uk">link</a> isn
|
234
|
+
assert_html_output '<p>This is a <a href="http://www.gov.uk">link</a> isn’t it?</p>'
|
216
235
|
assert_text_output "This is a link isn’t it?"
|
217
236
|
end
|
218
237
|
|
219
238
|
test_given_govspeak "This is a [link with an at sign in it](http://www.gov.uk/@dg/@this) isn't it?" do
|
220
|
-
assert_html_output '<p>This is a <a href="http://www.gov.uk/@dg/@this">link with an at sign in it</a> isn
|
239
|
+
assert_html_output '<p>This is a <a href="http://www.gov.uk/@dg/@this">link with an at sign in it</a> isn’t it?</p>'
|
221
240
|
assert_text_output "This is a link with an at sign in it isn’t it?"
|
222
241
|
end
|
223
242
|
|
@@ -281,7 +300,7 @@ Teston
|
|
281
300
|
end
|
282
301
|
|
283
302
|
test_given_govspeak "![image with external url](http://www.example.com/image.jpg)" do
|
284
|
-
assert_html_output '<p><img src="http://www.example.com/image.jpg" alt="image with external url"
|
303
|
+
assert_html_output '<p><img src="http://www.example.com/image.jpg" alt="image with external url"></p>'
|
285
304
|
end
|
286
305
|
|
287
306
|
test "should be able to override default 'document_domains' option" do
|
@@ -299,9 +318,9 @@ Teston
|
|
299
318
|
refute html.include?('rel="external"'), "should not automatically add rel external attribute"
|
300
319
|
end
|
301
320
|
|
302
|
-
test "should be able to override default 'entity output' option" do
|
303
|
-
html = Govspeak::Document.new("&
|
304
|
-
assert html.include?("
|
321
|
+
test "should not be able to override default 'entity output' option" do
|
322
|
+
html = Govspeak::Document.new(">", entity_output: :numeric).to_html
|
323
|
+
assert html.include?(">")
|
305
324
|
end
|
306
325
|
|
307
326
|
test "should assume a link with an invalid uri is internal" do
|
@@ -364,7 +383,7 @@ Teston
|
|
364
383
|
$A" do
|
365
384
|
assert_html_output %{
|
366
385
|
<div class="address"><div class="adr org fn"><p>
|
367
|
-
street<br
|
386
|
+
street<br>road<br>
|
368
387
|
</p></div></div>}
|
369
388
|
assert_text_output "street road"
|
370
389
|
end
|
@@ -444,11 +463,14 @@ $CTA
|
|
444
463
|
" do
|
445
464
|
assert_html_output %{
|
446
465
|
<ol class="steps">
|
447
|
-
<li
|
466
|
+
<li>
|
467
|
+
<p>zippy</p>
|
448
468
|
</li>
|
449
|
-
<li
|
469
|
+
<li>
|
470
|
+
<p>bungle</p>
|
450
471
|
</li>
|
451
|
-
<li
|
472
|
+
<li>
|
473
|
+
<p>george</p>
|
452
474
|
</li>
|
453
475
|
</ol>}
|
454
476
|
assert_text_output "zippy bungle george"
|
@@ -468,9 +490,11 @@ $CTA
|
|
468
490
|
</ul>
|
469
491
|
|
470
492
|
<ol class="steps">
|
471
|
-
<li
|
493
|
+
<li>
|
494
|
+
<p>step</p>
|
472
495
|
</li>
|
473
|
-
<li
|
496
|
+
<li>
|
497
|
+
<p>list</p>
|
474
498
|
</li>
|
475
499
|
</ol>}
|
476
500
|
assert_text_output "unordered list step list"
|
@@ -591,7 +615,8 @@ $CTA
|
|
591
615
|
assert_html_output '
|
592
616
|
<div class="devolved-content scotland">
|
593
617
|
<p class="devolved-header">This section applies to Scotland</p>
|
594
|
-
<div class="devolved-body"
|
618
|
+
<div class="devolved-body">
|
619
|
+
<p>I am very devolved
|
595
620
|
and very scottish</p>
|
596
621
|
</div>
|
597
622
|
</div>
|
@@ -600,7 +625,8 @@ $CTA
|
|
600
625
|
|
601
626
|
test_given_govspeak "@ Message with [a link](http://foo.bar/)@" do
|
602
627
|
assert_html_output %{
|
603
|
-
<div role="note" aria-label="Important" class="advisory"
|
628
|
+
<div role="note" aria-label="Important" class="advisory">
|
629
|
+
<p><strong>Message with <a rel="external" href="http://foo.bar/">a link</a></strong></p>
|
604
630
|
</div>
|
605
631
|
}
|
606
632
|
end
|
@@ -610,19 +636,19 @@ $CTA
|
|
610
636
|
given_govspeak "!!1", images do
|
611
637
|
assert_html_output %Q{
|
612
638
|
<figure class="image embedded">
|
613
|
-
<div class="img"><img alt="my alt" src="http://example.com/image.jpg"
|
639
|
+
<div class="img"><img alt="my alt" src="http://example.com/image.jpg"></div>
|
614
640
|
</figure>
|
615
|
-
|
616
|
-
end
|
641
|
+
}
|
617
642
|
end
|
643
|
+
end
|
618
644
|
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
645
|
+
test "alt text of referenced images is escaped" do
|
646
|
+
images = [OpenStruct.new(alt_text: %Q{my alt '&"<>}, url: "http://example.com/image.jpg")]
|
647
|
+
given_govspeak "!!1", images do
|
648
|
+
assert_html_output %Q{
|
649
|
+
<figure class="image embedded">
|
650
|
+
<div class="img"><img alt="my alt '&"<>" src="http://example.com/image.jpg"></div>
|
651
|
+
</figure>
|
626
652
|
}
|
627
653
|
end
|
628
654
|
end
|
@@ -639,7 +665,7 @@ $CTA
|
|
639
665
|
given_govspeak "!!1", images do
|
640
666
|
assert_html_output %Q{
|
641
667
|
<figure class="image embedded">
|
642
|
-
<div class="img"><img alt="my alt" src="http://example.com/image.jpg"
|
668
|
+
<div class="img"><img alt="my alt" src="http://example.com/image.jpg"></div>
|
643
669
|
<figcaption>My Caption & so on</figcaption>
|
644
670
|
</figure>
|
645
671
|
}
|
@@ -651,7 +677,7 @@ $CTA
|
|
651
677
|
given_govspeak "!!1", images do
|
652
678
|
assert_html_output %Q{
|
653
679
|
<figure class="image embedded">
|
654
|
-
<div class="img"><img alt="my alt" src="http://example.com/image.jpg"
|
680
|
+
<div class="img"><img alt="my alt" src="http://example.com/image.jpg"></div>
|
655
681
|
</figure>
|
656
682
|
}
|
657
683
|
end
|
@@ -810,4 +836,111 @@ $PriorityList:1
|
|
810
836
|
|
|
811
837
|
end
|
812
838
|
end
|
839
|
+
|
840
|
+
test "should remove quotes surrounding a blockquote" do
|
841
|
+
govspeak = %Q{
|
842
|
+
He said:
|
843
|
+
|
844
|
+
> "I'm not sure what you mean!"
|
845
|
+
|
846
|
+
Or so we thought.}
|
847
|
+
|
848
|
+
given_govspeak(govspeak) do
|
849
|
+
assert_html_output %|
|
850
|
+
<p>He said:</p>
|
851
|
+
|
852
|
+
<blockquote>
|
853
|
+
<p class="last-child">I’m not sure what you mean!</p>
|
854
|
+
</blockquote>
|
855
|
+
|
856
|
+
<p>Or so we thought.</p>
|
857
|
+
|
|
858
|
+
end
|
859
|
+
end
|
860
|
+
|
861
|
+
test "should add class to last paragraph of blockquote" do
|
862
|
+
govspeak = "
|
863
|
+
> first line
|
864
|
+
>
|
865
|
+
> last line"
|
866
|
+
|
867
|
+
given_govspeak(govspeak) do
|
868
|
+
assert_html_output %|
|
869
|
+
<blockquote>
|
870
|
+
<p>first line</p>
|
871
|
+
|
872
|
+
<p class="last-child">last line</p>
|
873
|
+
</blockquote>
|
874
|
+
|
|
875
|
+
end
|
876
|
+
end
|
877
|
+
|
878
|
+
test "inline attachment" do
|
879
|
+
attachment = OpenStruct.new(
|
880
|
+
content_id: "2b4d92f3-f8cd-4284-aaaa-25b3a640d26c",
|
881
|
+
id: 456,
|
882
|
+
)
|
883
|
+
govspeak = "[embed:attachments:inline:2b4d92f3-f8cd-4284-aaaa-25b3a640d26c]"
|
884
|
+
rendered = Govspeak::Document.new(govspeak, {attachments: attachment}).to_html
|
885
|
+
assert_match(/<span id=\"attachment_456\" class=\"attachment-inline\">/, rendered)
|
886
|
+
end
|
887
|
+
|
888
|
+
test "attachment" do
|
889
|
+
attachment = OpenStruct.new(
|
890
|
+
url: "www.test.com",
|
891
|
+
content_id: "2b4d92f3-f8cd-4284-aaaa-25b3a640d26c",
|
892
|
+
id: 123,
|
893
|
+
opendocument?: true,
|
894
|
+
order_url: "www.test.com",
|
895
|
+
price: 12.3,
|
896
|
+
csv?: true,
|
897
|
+
unnumbered_command_paper?: true,
|
898
|
+
isbn: 'isbn-123',
|
899
|
+
)
|
900
|
+
govspeak = "[embed:attachments:2b4d92f3-f8cd-4284-aaaa-25b3a640d26c]"
|
901
|
+
rendered = Govspeak::Document.new(govspeak, {attachments: attachment}).to_html
|
902
|
+
assert_match(/<section class=\"attachment embedded\">/, rendered)
|
903
|
+
assert_match(/<div class=\"attachment-thumb\">/, rendered)
|
904
|
+
assert_match(/attachment-123-accessibility-help/, rendered)
|
905
|
+
assert_match(/If you use assistive technology/, rendered)
|
906
|
+
assert_match(/<p class=\"opendocument-help\">/, rendered)
|
907
|
+
assert_match(/<span class=\"price\">£12.30/, rendered)
|
908
|
+
assert_match(/<span class=\"preview\">/, rendered)
|
909
|
+
assert_match(/<span class=\"unnumbered-paper\">/, rendered)
|
910
|
+
assert_match(/<span class=\"references\">/, rendered)
|
911
|
+
end
|
912
|
+
|
913
|
+
test "attachment that isn't provided" do
|
914
|
+
govspeak = "[embed:attachments:906ac8b7-850d-45c6-98e0-9525c680f891]"
|
915
|
+
rendered = Govspeak::Document.new(govspeak).to_html
|
916
|
+
assert_match("", rendered)
|
917
|
+
end
|
918
|
+
|
919
|
+
test "embedded link with link provided" do
|
920
|
+
link = OpenStruct.new(
|
921
|
+
content_id: "5572fee5-f38f-4641-8ffa-64fed9230ad4",
|
922
|
+
url: "https://www.example.com/",
|
923
|
+
title: "Example website"
|
924
|
+
)
|
925
|
+
govspeak = "[embed:link:5572fee5-f38f-4641-8ffa-64fed9230ad4]"
|
926
|
+
rendered = Govspeak::Document.new(govspeak, {links: link}).to_html
|
927
|
+
expected = %r{<a href="https://www.example.com/">Example website</a>}
|
928
|
+
assert_match(expected, rendered)
|
929
|
+
end
|
930
|
+
|
931
|
+
test "embedded link with link not provided" do
|
932
|
+
link = OpenStruct.new(
|
933
|
+
content_id: "e510f1c1-4862-4333-889c-8d3acd443fbf",
|
934
|
+
title: "Example website",
|
935
|
+
)
|
936
|
+
govspeak = "[embed:link:e510f1c1-4862-4333-889c-8d3acd443fbf]"
|
937
|
+
rendered = Govspeak::Document.new(govspeak, {links: link}).to_html
|
938
|
+
assert_match("Example website", rendered)
|
939
|
+
end
|
940
|
+
|
941
|
+
test "embedded link without link object" do
|
942
|
+
govspeak = "[embed:link:0726637c-8c66-47ad-834a-d815cbf51e0e]"
|
943
|
+
rendered = Govspeak::Document.new(govspeak).to_html
|
944
|
+
assert_match("", rendered)
|
945
|
+
end
|
813
946
|
end
|