govuk_content_models 12.0.0 → 12.1.0

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.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## 12.1.0
2
+
3
+ * Add LinkValidator, which checks that links in Govspeak fields are properly
4
+ formed and do not contain title text or rel=external. Remove
5
+ GovspeakSmartQuotesFixer which is irrelevant now title text is no longer
6
+ allowed.
7
+
1
8
  ## 12.0.0
2
9
 
3
10
  * Remove `SpecialistDocumentEdition` model. It is only used by the
@@ -48,6 +48,7 @@ class Edition
48
48
  validates :version_number, presence: true, uniqueness: {scope: :panopticon_id}
49
49
  validates :panopticon_id, presence: true
50
50
  validates_with SafeHtml
51
+ validates_with LinkValidator
51
52
 
52
53
  before_save :check_for_archived_artefact
53
54
  before_destroy :destroy_artefact
data/app/models/part.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  require "safe_html"
2
- require 'govspeak_smart_quotes_fixer'
3
2
 
4
3
  class Part
5
4
  include Mongoid::Document
@@ -18,11 +17,10 @@ class Part
18
17
 
19
18
  GOVSPEAK_FIELDS = [:body]
20
19
 
21
- include GovspeakSmartQuotesFixer
22
-
23
20
  validates_presence_of :title
24
21
  validates_presence_of :slug
25
22
  validates_exclusion_of :slug, in: ["video"], message: "Can not be video"
26
23
  validates_format_of :slug, with: /^[a-z0-9\-]+$/i
27
24
  validates_with SafeHtml
25
+ validates_with LinkValidator
28
26
  end
@@ -2,7 +2,6 @@ require 'attachable'
2
2
  require 'parted'
3
3
  require 'state_machine'
4
4
  require 'safe_html'
5
- require 'govspeak_smart_quotes_fixer'
6
5
 
7
6
  class TravelAdviceEdition
8
7
  include Mongoid::Document
@@ -38,7 +37,6 @@ class TravelAdviceEdition
38
37
  "avoid_all_travel_to_whole_country",
39
38
  ]
40
39
 
41
- include GovspeakSmartQuotesFixer
42
40
  before_validation :populate_version_number, :on => :create
43
41
 
44
42
  validates_presence_of :country_slug, :title
@@ -47,6 +45,7 @@ class TravelAdviceEdition
47
45
  validate :alert_status_contains_valid_values
48
46
  validate :first_version_cant_be_minor_update
49
47
  validates_with SafeHtml
48
+ validates_with LinkValidator
50
49
 
51
50
  scope :published, where(:state => "published")
52
51
 
@@ -0,0 +1,48 @@
1
+ class LinkValidator < ActiveModel::Validator
2
+ def validate(record)
3
+ record.changes.each do |field_name, (_, new_value)|
4
+ if govspeak_fields(record).include?(field_name.to_sym)
5
+ messages = errors(new_value)
6
+ record.errors[field_name] << messages if messages
7
+ end
8
+ end
9
+ end
10
+
11
+ def errors(string)
12
+ link_regex = %r{
13
+ \[.*?\] # link text in literal square brackets
14
+ \( # literal opening parenthesis
15
+ (\S*?) # containing URL
16
+ (\s+"[^"]+")? # and optional space followed by title text in quotes
17
+ \) # literal close paren
18
+ (\{:rel=["']external["']\})? # optional :rel=external in literal curly brackets.
19
+ }x
20
+
21
+ errors = []
22
+
23
+ string.scan(link_regex) do |match|
24
+
25
+ error = if match[0] !~ %r{^(?:https?://|mailto:|/)}
26
+ 'Internal links must start with a forward slash eg [link text](/link-destination). External links must start with http://, https://, or mailto: eg [external link text](https://www.google.co.uk)'
27
+ elsif match[1]
28
+ %q-Don't include hover text in links. Delete the text in quotation marks eg "This appears when you hover over the link."-
29
+ elsif match[2]
30
+ 'Delete {:rel="external"} in links.'
31
+ end
32
+
33
+ errors << error if error
34
+ end
35
+ errors
36
+ end
37
+
38
+ protected
39
+
40
+ def govspeak_fields(record)
41
+ if record.class.const_defined?(:GOVSPEAK_FIELDS)
42
+ record.class.const_get(:GOVSPEAK_FIELDS)
43
+ else
44
+ []
45
+ end
46
+ end
47
+ end
48
+
@@ -1,4 +1,4 @@
1
1
  module GovukContentModels
2
2
  # Changing this causes Jenkins to tag and release the gem into the wild
3
- VERSION = "12.0.0"
3
+ VERSION = "12.1.0"
4
4
  end
@@ -213,28 +213,6 @@ class TravelAdviceEditionTest < ActiveSupport::TestCase
213
213
  end
214
214
  end
215
215
 
216
- context "fixing user input" do
217
- setup do
218
- @ed = FactoryGirl.build(:travel_advice_edition)
219
- end
220
-
221
- should "convert smart quotes in the summary field" do
222
- @ed.summary = "This is a [link](https://www.gov.uk/ “link”)"
223
- @ed.save!
224
-
225
- @ed.reload
226
- assert_equal 'This is a [link](https://www.gov.uk/ "link")', @ed.summary
227
- end
228
-
229
- should "convert smart quotes in part bodies" do
230
- @ed.parts.build(:title => 'One', :slug => 'one', :body => "This is a [link](https://www.gov.uk/ “link”)")
231
- @ed.save!
232
-
233
- @ed.reload
234
- assert_equal 'This is a [link](https://www.gov.uk/ "link")', @ed.parts.first.body
235
- end
236
- end
237
-
238
216
  should "have a published scope" do
239
217
  e1 = FactoryGirl.create(:draft_travel_advice_edition)
240
218
  e2 = FactoryGirl.create(:published_travel_advice_edition)
@@ -0,0 +1,36 @@
1
+ require 'test_helper'
2
+
3
+ class LinkValidatorTest < ActiveSupport::TestCase
4
+ class Dummy
5
+ include Mongoid::Document
6
+
7
+ field "body", type: String
8
+ GOVSPEAK_FIELDS = [:body]
9
+
10
+ validates_with LinkValidator
11
+ end
12
+
13
+ context "links" do
14
+ should "start with http[s]://, mailto: or /" do
15
+ doc = Dummy.new(body: "abc [external](external.com)")
16
+ assert doc.invalid?
17
+ assert_includes doc.errors.keys, :body
18
+
19
+ doc = Dummy.new(body: "abc [external](http://external.com)")
20
+ assert doc.valid?
21
+
22
+ doc = Dummy.new(body: "abc [internal](/internal)")
23
+ assert doc.valid?
24
+ end
25
+ should "start not contain hover text" do
26
+ doc = Dummy.new(body: 'abc [foobar](foobar.com "hover")')
27
+ assert doc.invalid?
28
+ assert_includes doc.errors.keys, :body
29
+ end
30
+ should "start not set rel=external" do
31
+ doc = Dummy.new(body: 'abc [foobar](foobar.com){:rel="external"}')
32
+ assert doc.invalid?
33
+ assert_includes doc.errors.keys, :body
34
+ end
35
+ end
36
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: govuk_content_models
3
3
  version: !ruby/object:Gem::Version
4
- version: 12.0.0
4
+ version: 12.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-06-09 00:00:00.000000000 Z
12
+ date: 2014-06-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bson_ext
@@ -389,8 +389,8 @@ files:
389
389
  - app/models/workflow.rb
390
390
  - app/models/workflow_actor.rb
391
391
  - app/traits/attachable.rb
392
- - app/traits/govspeak_smart_quotes_fixer.rb
393
392
  - app/traits/taggable.rb
393
+ - app/validators/link_validator.rb
394
394
  - app/validators/safe_html.rb
395
395
  - app/validators/slug_validator.rb
396
396
  - app/validators/tag_id_validator.rb
@@ -447,6 +447,7 @@ files:
447
447
  - test/test_helper.rb
448
448
  - test/traits/attachable_test.rb
449
449
  - test/traits/taggable_test.rb
450
+ - test/validators/link_validator_test.rb
450
451
  - test/validators/safe_html_validator_test.rb
451
452
  - test/validators/slug_validator_test.rb
452
453
  - test/validators/tag_id_validator_test.rb
@@ -465,7 +466,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
465
466
  version: '0'
466
467
  segments:
467
468
  - 0
468
- hash: 3589363428373326753
469
+ hash: 4316099945977506650
469
470
  required_rubygems_version: !ruby/object:Gem::Requirement
470
471
  none: false
471
472
  requirements:
@@ -474,7 +475,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
474
475
  version: '0'
475
476
  segments:
476
477
  - 0
477
- hash: 3589363428373326753
478
+ hash: 4316099945977506650
478
479
  requirements: []
479
480
  rubyforge_project:
480
481
  rubygems_version: 1.8.23
@@ -525,6 +526,7 @@ test_files:
525
526
  - test/test_helper.rb
526
527
  - test/traits/attachable_test.rb
527
528
  - test/traits/taggable_test.rb
529
+ - test/validators/link_validator_test.rb
528
530
  - test/validators/safe_html_validator_test.rb
529
531
  - test/validators/slug_validator_test.rb
530
532
  - test/validators/tag_id_validator_test.rb
@@ -1,19 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- module GovspeakSmartQuotesFixer
4
- def self.included(model)
5
- model.class_eval do
6
- before_validation :fix_smart_quotes_in_govspeak
7
- end
8
- end
9
-
10
- private
11
-
12
- def fix_smart_quotes_in_govspeak
13
- self.class::GOVSPEAK_FIELDS.each do |field|
14
- if self.send(field) =~ /[“”]/
15
- self.send(field).gsub!(/[“”]/, '"')
16
- end
17
- end
18
- end
19
- end