govspeak 6.5.0 → 6.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +24 -2
- data/README.md +6 -5
- data/Rakefile +7 -4
- data/lib/govspeak.rb +116 -116
- data/lib/govspeak/header_extractor.rb +1 -1
- data/lib/govspeak/html_sanitizer.rb +12 -9
- data/lib/govspeak/kramdown_overrides.rb +2 -2
- data/lib/govspeak/link_extractor.rb +6 -6
- data/lib/govspeak/post_processor.rb +34 -14
- data/lib/govspeak/presenters/attachment_presenter.rb +39 -39
- data/lib/govspeak/presenters/contact_presenter.rb +2 -2
- data/lib/govspeak/presenters/h_card_presenter.rb +3 -3
- data/lib/govspeak/presenters/image_presenter.rb +4 -4
- data/lib/govspeak/structured_header_extractor.rb +2 -2
- data/lib/govspeak/version.rb +1 -1
- data/lib/kramdown/parser/govuk.rb +6 -7
- data/test/blockquote_extra_quote_remover_test.rb +24 -26
- data/test/govspeak_attachment_link_test.rb +0 -2
- data/test/govspeak_attachment_test.rb +0 -2
- data/test/govspeak_attachments_image_test.rb +12 -14
- data/test/govspeak_attachments_inline_test.rb +22 -24
- data/test/govspeak_button_test.rb +29 -31
- data/test/govspeak_contacts_test.rb +29 -31
- data/test/govspeak_extract_contact_content_ids_test.rb +1 -3
- data/test/govspeak_images_bang_test.rb +37 -39
- data/test/govspeak_images_test.rb +43 -45
- data/test/govspeak_link_extractor_test.rb +1 -1
- data/test/govspeak_link_test.rb +1 -3
- data/test/govspeak_structured_headers_test.rb +7 -6
- data/test/govspeak_table_with_headers_test.rb +68 -21
- data/test/govspeak_test.rb +98 -101
- data/test/govspeak_test_helper.rb +1 -1
- data/test/html_sanitizer_test.rb +17 -9
- data/test/html_validator_test.rb +2 -2
- data/test/presenters/h_card_presenter_test.rb +39 -41
- data/test/test_helper.rb +12 -8
- metadata +52 -40
@@ -49,7 +49,7 @@ module GovspeakTestHelper
|
|
49
49
|
lines = text.split "\n"
|
50
50
|
digits = Math.log10(lines.size + 2).ceil
|
51
51
|
lines.map
|
52
|
-
.with_index { |line, i| "%<number>#{digits}d: %<line>s"
|
52
|
+
.with_index { |line, i| sprintf("%<number>#{digits}d: %<line>s", number: i + 1, line: line) }
|
53
53
|
.join("\n")
|
54
54
|
end
|
55
55
|
end
|
data/test/html_sanitizer_test.rb
CHANGED
@@ -31,7 +31,7 @@ class HtmlSanitizerTest < Minitest::Test
|
|
31
31
|
html = "<a href='#' data-module='cross-domain-tracking' data-tracking-code='UA-XXXXXX-Y' data-tracking-name='govspeakButtonTracker'></a>"
|
32
32
|
assert_equal(
|
33
33
|
"<a href=\"#\" data-module=\"cross-domain-tracking\" data-tracking-code=\"UA-XXXXXX-Y\" data-tracking-name=\"govspeakButtonTracker\"></a>",
|
34
|
-
Govspeak::HtmlSanitizer.new(html).sanitize
|
34
|
+
Govspeak::HtmlSanitizer.new(html).sanitize,
|
35
35
|
)
|
36
36
|
end
|
37
37
|
|
@@ -40,19 +40,28 @@ class HtmlSanitizerTest < Minitest::Test
|
|
40
40
|
|
41
41
|
assert_equal(
|
42
42
|
"<a href=\"/\" data-module=\"track-click\" data-ecommerce-path=\"/\" data-track-category=\"linkClicked\">Test Link</a>",
|
43
|
-
Govspeak::HtmlSanitizer.new(html).sanitize
|
43
|
+
Govspeak::HtmlSanitizer.new(html).sanitize,
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
47
|
+
test "allow data attributes on divs" do
|
48
|
+
html = "<div data-module='toggle' data-ecommerce-path='/' data-track-category='someDiv'>Test Div</div>"
|
49
|
+
|
50
|
+
assert_equal(
|
51
|
+
"<div data-module=\"toggle\" data-ecommerce-path=\"/\" data-track-category=\"someDiv\">Test Div</div>",
|
52
|
+
Govspeak::HtmlSanitizer.new(html).sanitize,
|
44
53
|
)
|
45
54
|
end
|
46
55
|
|
47
56
|
test "allows images on whitelisted domains" do
|
48
57
|
html = "<img src='http://allowed.com/image.jgp'>"
|
49
|
-
sanitized_html = Govspeak::HtmlSanitizer.new(html, allowed_image_hosts: [
|
58
|
+
sanitized_html = Govspeak::HtmlSanitizer.new(html, allowed_image_hosts: ["allowed.com"]).sanitize
|
50
59
|
assert_equal "<img src=\"http://allowed.com/image.jgp\">", sanitized_html
|
51
60
|
end
|
52
61
|
|
53
62
|
test "removes images not on whitelisted domains" do
|
54
63
|
html = "<img src='http://evil.com/image.jgp'>"
|
55
|
-
assert_equal "", Govspeak::HtmlSanitizer.new(html, allowed_image_hosts: [
|
64
|
+
assert_equal "", Govspeak::HtmlSanitizer.new(html, allowed_image_hosts: ["allowed.com"]).sanitize
|
56
65
|
end
|
57
66
|
|
58
67
|
test "allows table cells and table headings without a style attribute" do
|
@@ -62,15 +71,14 @@ class HtmlSanitizerTest < Minitest::Test
|
|
62
71
|
|
63
72
|
test "strips table cells and headings that appear outside a table" do
|
64
73
|
html = "<th>thing</th></tr><tr><td>thing</td>"
|
65
|
-
assert_equal
|
74
|
+
assert_equal "thingthing", Govspeak::HtmlSanitizer.new(html).sanitize
|
66
75
|
end
|
67
76
|
|
68
77
|
test "normalizes table tags to inject missing rows and bodies like a browser does" do
|
69
78
|
html = "<table><th>thing</th><td>thing</td></table>"
|
70
|
-
assert_equal
|
79
|
+
assert_equal "<table><tbody><tr><th>thing</th><td>thing</td></tr></tbody></table>", Govspeak::HtmlSanitizer.new(html).sanitize
|
71
80
|
end
|
72
81
|
|
73
|
-
|
74
82
|
test "allows valid text-align properties on the style attribute for table cells and table headings" do
|
75
83
|
%w[left right center].each do |alignment|
|
76
84
|
html = "<table><thead><tr><th style=\"text-align: #{alignment}\">thing</th></tr></thead><tbody><tr><td style=\"text-align: #{alignment}\">thing</td></tr></tbody></table>"
|
@@ -82,10 +90,10 @@ class HtmlSanitizerTest < Minitest::Test
|
|
82
90
|
"text-align: middle",
|
83
91
|
"text-align: left; width: 10px",
|
84
92
|
"background-image: url(javascript:alert('XSS'))",
|
85
|
-
"expression(alert('XSS'));"
|
93
|
+
"expression(alert('XSS'));",
|
86
94
|
].each do |style|
|
87
95
|
html = "<table><thead><tr><th style=\"#{style}\">thing</th></tr></thead><tbody><tr><td style=\"#{style}\">thing</td></tr></tbody></table>"
|
88
|
-
assert_equal
|
96
|
+
assert_equal "<table><thead><tr><th>thing</th></tr></thead><tbody><tr><td>thing</td></tr></tbody></table>", Govspeak::HtmlSanitizer.new(html).sanitize
|
89
97
|
end
|
90
98
|
end
|
91
99
|
end
|
data/test/html_validator_test.rb
CHANGED
@@ -51,7 +51,7 @@ class HtmlValidatorTest < Minitest::Test
|
|
51
51
|
$P
|
52
52
|
",
|
53
53
|
":england:content goes here:england:",
|
54
|
-
":scotland:content goes here:scotland:"
|
54
|
+
":scotland:content goes here:scotland:",
|
55
55
|
]
|
56
56
|
values.each do |value|
|
57
57
|
assert Govspeak::HtmlValidator.new(value).valid?
|
@@ -88,7 +88,7 @@ class HtmlValidatorTest < Minitest::Test
|
|
88
88
|
|
89
89
|
test "optionally disallow images not on a whitelisted domain" do
|
90
90
|
html = "<img src='http://evil.com/image.jgp'>"
|
91
|
-
assert Govspeak::HtmlValidator.new(html, allowed_image_hosts: [
|
91
|
+
assert Govspeak::HtmlValidator.new(html, allowed_image_hosts: ["allowed.com"]).invalid?
|
92
92
|
end
|
93
93
|
|
94
94
|
test "allow <div> and <span> HTML elements" do
|
@@ -1,93 +1,91 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require 'test_helper'
|
4
|
-
require 'ostruct'
|
1
|
+
require "test_helper"
|
2
|
+
require "ostruct"
|
5
3
|
|
6
4
|
class HCardPresenterTest < Minitest::Test
|
7
5
|
def unindent(html)
|
8
|
-
html.gsub(/^\s+/,
|
6
|
+
html.gsub(/^\s+/, "")
|
9
7
|
end
|
10
8
|
|
11
9
|
test "renders address in UK format" do
|
12
|
-
assert_equal unindent(gb_addr), HCardPresenter.new(addr_fields,
|
10
|
+
assert_equal unindent(gb_addr), HCardPresenter.new(addr_fields, "GB").render
|
13
11
|
end
|
14
12
|
|
15
13
|
test "renders address in Spanish format" do
|
16
|
-
assert_equal unindent(es_addr), HCardPresenter.new(addr_fields,
|
14
|
+
assert_equal unindent(es_addr), HCardPresenter.new(addr_fields, "ES").render
|
17
15
|
end
|
18
16
|
|
19
17
|
test "renders address in Japanese format" do
|
20
|
-
assert_equal unindent(jp_addr), HCardPresenter.new(addr_fields,
|
18
|
+
assert_equal unindent(jp_addr), HCardPresenter.new(addr_fields, "JP").render
|
21
19
|
end
|
22
20
|
|
23
21
|
test "doesn't clobber address formats" do
|
24
|
-
gb_format_before = HCardPresenter.address_formats[
|
25
|
-
HCardPresenter.new(addr_fields,
|
22
|
+
gb_format_before = HCardPresenter.address_formats["gb"].dup
|
23
|
+
HCardPresenter.new(addr_fields, "GB").render
|
26
24
|
|
27
|
-
assert_equal unindent(gb_format_before), HCardPresenter.address_formats[
|
25
|
+
assert_equal unindent(gb_format_before), HCardPresenter.address_formats["gb"]
|
28
26
|
end
|
29
27
|
|
30
28
|
test "blank properties do not render extra line breaks" do
|
31
29
|
fields_without_region = addr_fields
|
32
|
-
fields_without_region.delete(
|
30
|
+
fields_without_region.delete("region")
|
33
31
|
|
34
|
-
assert_equal unindent(addr_without_region), HCardPresenter.new(fields_without_region,
|
32
|
+
assert_equal unindent(addr_without_region), HCardPresenter.new(fields_without_region, "GB").render
|
35
33
|
end
|
36
34
|
|
37
35
|
test "doesn't render a property when it's a blank string" do
|
38
36
|
fields = addr_fields
|
39
37
|
|
40
|
-
fields[
|
41
|
-
assert_equal unindent(addr_without_region), HCardPresenter.new(fields,
|
38
|
+
fields["region"] = ""
|
39
|
+
assert_equal unindent(addr_without_region), HCardPresenter.new(fields, "GB").render
|
42
40
|
|
43
|
-
fields[
|
44
|
-
assert_equal unindent(addr_without_region), HCardPresenter.new(fields,
|
41
|
+
fields["region"] = " "
|
42
|
+
assert_equal unindent(addr_without_region), HCardPresenter.new(fields, "GB").render
|
45
43
|
end
|
46
44
|
|
47
|
-
test
|
45
|
+
test "uses html escaping on property values" do
|
48
46
|
fields = addr_fields
|
49
47
|
|
50
|
-
fields[
|
51
|
-
assert_includes HCardPresenter.new(fields,
|
48
|
+
fields["region"] = "UK & Channel Islands"
|
49
|
+
assert_includes HCardPresenter.new(fields, "GB").render, "UK & Channel Islands"
|
52
50
|
end
|
53
51
|
|
54
52
|
test "it defaults to UK format" do
|
55
|
-
assert_equal unindent(gb_addr), HCardPresenter.new(addr_fields,
|
53
|
+
assert_equal unindent(gb_addr), HCardPresenter.new(addr_fields, "FUBAR").render
|
56
54
|
end
|
57
55
|
|
58
56
|
test "it builds from a Contact" do
|
59
|
-
contact = OpenStruct.new(recipient:
|
60
|
-
street_address:
|
61
|
-
locality:
|
62
|
-
region:
|
63
|
-
postal_code:
|
64
|
-
country_name:
|
65
|
-
country_code:
|
57
|
+
contact = OpenStruct.new(recipient: "Recipient",
|
58
|
+
street_address: "Street",
|
59
|
+
locality: "Locality",
|
60
|
+
region: "Region",
|
61
|
+
postal_code: "Postcode",
|
62
|
+
country_name: "Country",
|
63
|
+
country_code: "ES")
|
66
64
|
hcard = HCardPresenter.from_contact(contact)
|
67
65
|
|
68
66
|
assert_equal unindent(es_addr), hcard.render
|
69
67
|
end
|
70
68
|
|
71
69
|
test "it leaves out the country name when building a GB contact" do
|
72
|
-
contact = OpenStruct.new(recipient:
|
73
|
-
street_address:
|
74
|
-
locality:
|
75
|
-
region:
|
76
|
-
postal_code:
|
77
|
-
country_name:
|
78
|
-
country_code:
|
70
|
+
contact = OpenStruct.new(recipient: "Recipient",
|
71
|
+
street_address: "Street",
|
72
|
+
locality: "Locality",
|
73
|
+
region: "Region",
|
74
|
+
postal_code: "Postcode",
|
75
|
+
country_name: "Country",
|
76
|
+
country_code: "GB")
|
79
77
|
hcard = HCardPresenter.from_contact(contact)
|
80
78
|
|
81
79
|
assert_equal unindent(addr_without_country), hcard.render
|
82
80
|
end
|
83
81
|
|
84
82
|
def addr_fields
|
85
|
-
{
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
83
|
+
{ "fn" => "Recipient",
|
84
|
+
"street-address" => "Street",
|
85
|
+
"postal-code" => "Postcode",
|
86
|
+
"locality" => "Locality",
|
87
|
+
"region" => "Region",
|
88
|
+
"country-name" => "Country" }
|
91
89
|
end
|
92
90
|
|
93
91
|
def gb_addr
|
data/test/test_helper.rb
CHANGED
@@ -1,22 +1,26 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "simplecov"
|
2
|
+
require "simplecov-rcov"
|
3
3
|
|
4
4
|
SimpleCov.start
|
5
5
|
SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
|
6
6
|
|
7
|
-
|
7
|
+
$LOAD_PATH.unshift(File.expand_path("../lib")) unless $LOAD_PATH.include?(File.expand_path("../lib"))
|
8
8
|
|
9
|
-
require
|
9
|
+
require "bundler"
|
10
10
|
Bundler.setup :default, :development, :test
|
11
11
|
|
12
|
-
require
|
12
|
+
require "minitest/autorun"
|
13
13
|
|
14
14
|
class Minitest::Test
|
15
15
|
class << self
|
16
16
|
def test(name, &block)
|
17
|
-
clean_name = name.gsub(/\s+/,
|
17
|
+
clean_name = name.gsub(/\s+/, "_")
|
18
18
|
method = "test_#{clean_name.gsub(/\s+/, '_')}".to_sym
|
19
|
-
already_defined =
|
19
|
+
already_defined = begin
|
20
|
+
instance_method(method)
|
21
|
+
rescue StandardError
|
22
|
+
false
|
23
|
+
end
|
20
24
|
raise "#{method} exists" if already_defined
|
21
25
|
|
22
26
|
define_method(method, &block)
|
@@ -24,4 +28,4 @@ class Minitest::Test
|
|
24
28
|
end
|
25
29
|
end
|
26
30
|
|
27
|
-
require
|
31
|
+
require "govspeak"
|
metadata
CHANGED
@@ -1,29 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: govspeak
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.5.
|
4
|
+
version: 6.5.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GOV.UK Dev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-08-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionview
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '5.0'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '7'
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
|
-
- - "
|
27
|
+
- - ">="
|
25
28
|
- !ruby/object:Gem::Version
|
26
29
|
version: '5.0'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '7'
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: addressable
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -48,16 +54,16 @@ dependencies:
|
|
48
54
|
name: govuk_publishing_components
|
49
55
|
requirement: !ruby/object:Gem::Requirement
|
50
56
|
requirements:
|
51
|
-
- - "
|
57
|
+
- - "~>"
|
52
58
|
- !ruby/object:Gem::Version
|
53
|
-
version: '
|
59
|
+
version: '21.4'
|
54
60
|
type: :runtime
|
55
61
|
prerelease: false
|
56
62
|
version_requirements: !ruby/object:Gem::Requirement
|
57
63
|
requirements:
|
58
|
-
- - "
|
64
|
+
- - "~>"
|
59
65
|
- !ruby/object:Gem::Version
|
60
|
-
version: '
|
66
|
+
version: '21.4'
|
61
67
|
- !ruby/object:Gem::Dependency
|
62
68
|
name: htmlentities
|
63
69
|
requirement: !ruby/object:Gem::Requirement
|
@@ -146,44 +152,36 @@ dependencies:
|
|
146
152
|
name: sanitize
|
147
153
|
requirement: !ruby/object:Gem::Requirement
|
148
154
|
requirements:
|
149
|
-
- - "
|
155
|
+
- - ">="
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: 5.2.1
|
158
|
+
- - "<"
|
150
159
|
- !ruby/object:Gem::Version
|
151
|
-
version: '
|
160
|
+
version: '6'
|
152
161
|
type: :runtime
|
153
162
|
prerelease: false
|
154
163
|
version_requirements: !ruby/object:Gem::Requirement
|
155
164
|
requirements:
|
156
|
-
- - "
|
157
|
-
- !ruby/object:Gem::Version
|
158
|
-
version: '5'
|
159
|
-
- !ruby/object:Gem::Dependency
|
160
|
-
name: govuk-lint
|
161
|
-
requirement: !ruby/object:Gem::Requirement
|
162
|
-
requirements:
|
163
|
-
- - "~>"
|
165
|
+
- - ">="
|
164
166
|
- !ruby/object:Gem::Version
|
165
|
-
version:
|
166
|
-
|
167
|
-
prerelease: false
|
168
|
-
version_requirements: !ruby/object:Gem::Requirement
|
169
|
-
requirements:
|
170
|
-
- - "~>"
|
167
|
+
version: 5.2.1
|
168
|
+
- - "<"
|
171
169
|
- !ruby/object:Gem::Version
|
172
|
-
version:
|
170
|
+
version: '6'
|
173
171
|
- !ruby/object:Gem::Dependency
|
174
172
|
name: minitest
|
175
173
|
requirement: !ruby/object:Gem::Requirement
|
176
174
|
requirements:
|
177
175
|
- - "~>"
|
178
176
|
- !ruby/object:Gem::Version
|
179
|
-
version: 5.
|
177
|
+
version: 5.14.1
|
180
178
|
type: :development
|
181
179
|
prerelease: false
|
182
180
|
version_requirements: !ruby/object:Gem::Requirement
|
183
181
|
requirements:
|
184
182
|
- - "~>"
|
185
183
|
- !ruby/object:Gem::Version
|
186
|
-
version: 5.
|
184
|
+
version: 5.14.1
|
187
185
|
- !ruby/object:Gem::Dependency
|
188
186
|
name: pry-byebug
|
189
187
|
requirement: !ruby/object:Gem::Requirement
|
@@ -212,6 +210,20 @@ dependencies:
|
|
212
210
|
- - "~>"
|
213
211
|
- !ruby/object:Gem::Version
|
214
212
|
version: 0.9.0
|
213
|
+
- !ruby/object:Gem::Dependency
|
214
|
+
name: rubocop-govuk
|
215
|
+
requirement: !ruby/object:Gem::Requirement
|
216
|
+
requirements:
|
217
|
+
- - "~>"
|
218
|
+
- !ruby/object:Gem::Version
|
219
|
+
version: 3.3.2
|
220
|
+
type: :development
|
221
|
+
prerelease: false
|
222
|
+
version_requirements: !ruby/object:Gem::Requirement
|
223
|
+
requirements:
|
224
|
+
- - "~>"
|
225
|
+
- !ruby/object:Gem::Version
|
226
|
+
version: 3.3.2
|
215
227
|
- !ruby/object:Gem::Dependency
|
216
228
|
name: simplecov
|
217
229
|
requirement: !ruby/object:Gem::Requirement
|
@@ -359,23 +371,23 @@ signing_key:
|
|
359
371
|
specification_version: 4
|
360
372
|
summary: Markup language for single domain
|
361
373
|
test_files:
|
374
|
+
- test/blockquote_extra_quote_remover_test.rb
|
375
|
+
- test/govspeak_test_helper.rb
|
376
|
+
- test/govspeak_structured_headers_test.rb
|
362
377
|
- test/govspeak_attachment_link_test.rb
|
378
|
+
- test/govspeak_attachments_image_test.rb
|
363
379
|
- test/test_helper.rb
|
380
|
+
- test/govspeak_attachments_inline_test.rb
|
381
|
+
- test/html_sanitizer_test.rb
|
364
382
|
- test/govspeak_button_test.rb
|
365
|
-
- test/
|
383
|
+
- test/govspeak_images_bang_test.rb
|
384
|
+
- test/govspeak_images_test.rb
|
366
385
|
- test/html_validator_test.rb
|
367
386
|
- test/govspeak_attachment_test.rb
|
368
|
-
- test/govspeak_contacts_test.rb
|
369
|
-
- test/govspeak_test_helper.rb
|
370
|
-
- test/blockquote_extra_quote_remover_test.rb
|
371
|
-
- test/govspeak_table_with_headers_test.rb
|
372
|
-
- test/govspeak_attachments_image_test.rb
|
373
|
-
- test/html_sanitizer_test.rb
|
374
|
-
- test/govspeak_link_test.rb
|
375
387
|
- test/govspeak_extract_contact_content_ids_test.rb
|
376
|
-
- test/
|
377
|
-
- test/govspeak_images_test.rb
|
378
|
-
- test/presenters/h_card_presenter_test.rb
|
379
|
-
- test/govspeak_images_bang_test.rb
|
388
|
+
- test/govspeak_test.rb
|
380
389
|
- test/govspeak_link_extractor_test.rb
|
381
|
-
- test/
|
390
|
+
- test/govspeak_link_test.rb
|
391
|
+
- test/govspeak_contacts_test.rb
|
392
|
+
- test/presenters/h_card_presenter_test.rb
|
393
|
+
- test/govspeak_table_with_headers_test.rb
|