govuk_content_models 29.1.1 → 29.1.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 50dc520a74843e9a3ccd9b5a0427b966711f30b5
4
- data.tar.gz: 8ba0639769f9c134d133ff996e9d2d41d4d0ed77
3
+ metadata.gz: ab1abf4484762f870e3d8e538b706e5cd426a66d
4
+ data.tar.gz: b6545c3d24622aaf2b7d912bec0612063dc7efad
5
5
  SHA512:
6
- metadata.gz: 1360728473419a672030754f02164c27f17fb790ef0acf0a1abcac89bb659680e778c6c32ecd894d5e219c65a774fe33e322d499dafd337b39e5b08b96d51ca5
7
- data.tar.gz: 7651c6ef9eef44d07dabe3ebe997179f1aa20b89d6e26b5d785a89d66e0343c1c22b8f2d699f4d57fd62740fad031cdd60c5f9f2aa7d4dccdb5184ada39f3c7c
6
+ metadata.gz: 7e6a87f32f108d5ad7fde9fbcd35a962ff99f15cc93fddb9bc72fb02e8ef3b10f7a803eb6d30c2be0da930b434a125e6313188a13509fc43041a2de2ca965be1
7
+ data.tar.gz: d264ff8d7bdca85773d58504fcd3e2e4dbafc09df865638bad3386e0715bea87e779ce8e227eca83c8b93443fd2f8d17262699afcc1ad2267b07ac8f9e237d87
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 29.1.2
4
+
5
+ - Bugfix: revert removal of specialist publisher code since it breaks Panopticon integration
6
+
3
7
  ## 29.1.1
4
8
 
5
9
  - Bugfix: update question options slugs when their labels are updated
@@ -37,6 +37,7 @@ class Artefact
37
37
  field "publication_id", type: String
38
38
  field "description", type: String
39
39
  field "state", type: String, default: "draft"
40
+ field "specialist_body", type: String
40
41
  field "language", type: String, default: "en"
41
42
  field "need_extended_font", type: Boolean, default: false
42
43
  field "latest_change_note", type: String
@@ -74,6 +75,17 @@ class Artefact
74
75
  "smartanswers" => ["smart-answer"],
75
76
  "custom-application" => ["custom-application"], # In this case the owning_app is overriden. eg calendars, licencefinder
76
77
  "travel-advice-publisher" => ["travel-advice"],
78
+ "specialist-publisher" => ["aaib_report",
79
+ "cma_case",
80
+ "countryside_stewardship_grant",
81
+ "drug_safety_update",
82
+ "european_structural_investment_fund",
83
+ "international_development_fund",
84
+ "maib_report",
85
+ "manual",
86
+ "medical_safety_alert",
87
+ "raib_report",
88
+ "vehicle_recalls_and_faults_alert"],
77
89
  "finder-api" => ["finder",
78
90
  "finder_email_signup"],
79
91
  "whitehall" => ["announcement",
@@ -0,0 +1,13 @@
1
+ module PrerenderedEntity
2
+ def create_or_update_by_slug!(attributes)
3
+ find_or_initialize_by(
4
+ slug: attributes.fetch(:slug)
5
+ ).tap do |doc|
6
+ doc.update_attributes!(attributes)
7
+ end
8
+ end
9
+
10
+ def find_by_slug(slug)
11
+ where(slug: slug).first
12
+ end
13
+ end
@@ -0,0 +1,17 @@
1
+ require "prerendered_entity"
2
+
3
+ class RenderedManual
4
+ include Mongoid::Document
5
+ include Mongoid::Timestamps
6
+ extend PrerenderedEntity
7
+
8
+ field :manual_id, type: String
9
+ field :slug, type: String
10
+ field :title, type: String
11
+ field :summary, type: String
12
+ field :section_groups, type: Array
13
+
14
+ index "slug", unique: true
15
+
16
+ validates_uniqueness_of :slug
17
+ end
@@ -0,0 +1,19 @@
1
+ require "prerendered_entity"
2
+
3
+ class RenderedSpecialistDocument
4
+ include Mongoid::Document
5
+ include Mongoid::Timestamps
6
+ extend PrerenderedEntity
7
+
8
+ field :slug, type: String
9
+ field :title, type: String
10
+ field :summary, type: String
11
+ field :body, type: String
12
+ field :published_at, type: DateTime
13
+
14
+ field :details, type: Hash
15
+
16
+ index "slug", unique: true
17
+
18
+ validates :slug, uniqueness: true
19
+ end
@@ -7,6 +7,8 @@ class SlugValidator < ActiveModel::EachValidator
7
7
  HelpPageValidator,
8
8
  FinderEmailSignupValidator,
9
9
  GovernmentPageValidator,
10
+ ManualPageValidator,
11
+ SpecialistDocumentPageValidator,
10
12
  BrowsePageValidator,
11
13
  DetailedGuideValidator,
12
14
  DefaultValidator
@@ -115,6 +117,63 @@ protected
115
117
  end
116
118
  end
117
119
 
120
+ class ManualPageValidator < InstanceValidator
121
+ def applicable?
122
+ of_kind?('manual')
123
+ end
124
+
125
+ def validate!
126
+ validate_number_of_parts!
127
+ validate_guidance_prefix!
128
+ validate_parts_as_slugs!
129
+ end
130
+
131
+ private
132
+ def validate_number_of_parts!
133
+ unless [2, 3].include?(url_parts.size)
134
+ record.errors[attribute] << 'must contains two or three path parts'
135
+ end
136
+ end
137
+
138
+ def validate_guidance_prefix!
139
+ unless starts_with?('guidance/')
140
+ record.errors[attribute] << 'must have a guidance/ prefix'
141
+ end
142
+ end
143
+
144
+ def validate_parts_as_slugs!
145
+ unless url_parts.all? { |url_part| valid_slug?(url_part) }
146
+ record.errors[attribute] << 'must be usable in a URL'
147
+ end
148
+ end
149
+ end
150
+
151
+ class SpecialistDocumentPageValidator < InstanceValidator
152
+ def applicable?
153
+ of_kind?(acceptable_formats)
154
+ end
155
+
156
+ def validate!
157
+ unless url_parts.size == 2
158
+ record.errors[attribute] << "must be of form <finder-slug>/<specialist-document-slug>"
159
+ end
160
+ unless url_parts.all? { |url_part| valid_slug?(url_part) }
161
+ record.errors[attribute] << "must be usable in a URL"
162
+ end
163
+ end
164
+
165
+ private
166
+ def acceptable_formats
167
+ Artefact::FORMATS_BY_DEFAULT_OWNING_APP["specialist-publisher"] - unacceptable_formats
168
+ end
169
+
170
+ def unacceptable_formats
171
+ [
172
+ "manual",
173
+ ]
174
+ end
175
+ end
176
+
118
177
  class BrowsePageValidator < InstanceValidator
119
178
  def applicable?
120
179
  of_kind?('specialist_sector')
@@ -252,6 +252,25 @@ FactoryGirl.define do
252
252
  end
253
253
  end
254
254
 
255
+ factory :rendered_specialist_document do
256
+ sequence(:slug) {|n| "test-rendered-specialist-document-#{n}" }
257
+ sequence(:title) {|n| "Test Rendered Specialist Document #{n}" }
258
+ summary "My summary"
259
+ body "<p>My body</p>"
260
+ details({
261
+ "opened_date" => "2013-04-20",
262
+ "market_sector" => "some-market-sector",
263
+ "case_type" => "a-case-type",
264
+ "case_state" => "open",
265
+ })
266
+ end
267
+
268
+ factory :rendered_manual do
269
+ sequence(:slug) {|n| "test-rendered-manual-#{n}" }
270
+ sequence(:title) {|n| "Test Rendered Manual #{n}" }
271
+ summary "My summary"
272
+ end
273
+
255
274
  factory :simple_smart_answer_edition, :parent => :edition, :class => "SimpleSmartAnswerEdition" do
256
275
  title "Simple smart answer"
257
276
  body "Introduction to the smart answer"
@@ -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 = "29.1.1"
3
+ VERSION = "29.1.2"
4
4
  end
@@ -0,0 +1,16 @@
1
+ module SpecialistDocumentFixtures
2
+ def basic_specialist_document_fields
3
+ {
4
+ slug: 'cma-cases/merger-investigation-2014',
5
+ title: "Merger Investigation 2014",
6
+ summary: "This is the summary of stuff going on in the Merger Investigation 2014",
7
+ state: "published",
8
+ body: "A body",
9
+ opened_date: '2012-04-21',
10
+ document_id: 'a-document-id',
11
+ market_sector: 'oil-and-gas',
12
+ case_type: 'some-case-type',
13
+ case_state: 'open'
14
+ }
15
+ end
16
+ end
@@ -424,6 +424,15 @@ class ArtefactTest < ActiveSupport::TestCase
424
424
  assert artefact.any_editions_published?
425
425
  end
426
426
 
427
+ test "should have a specialist_body field present for markdown content" do
428
+ artefact = Artefact.create!(slug: "parent", name: "Harry Potter", kind: "guide", owning_app: "x")
429
+ refute_includes artefact.attributes, "specialist_body"
430
+
431
+ artefact.specialist_body = "Something wicked this way comes"
432
+ assert_includes artefact.attributes, "specialist_body"
433
+ assert_equal "Something wicked this way comes", artefact.specialist_body
434
+ end
435
+
427
436
  test "should have 'video' as a supported FORMAT" do
428
437
  assert_includes Artefact::FORMATS, "video"
429
438
  end
@@ -0,0 +1,46 @@
1
+ # include in a test class and define a #model_class instance method
2
+
3
+ module PrerenderedEntityTests
4
+ def test_duplicate_slug_not_allowed
5
+ model_class.create(slug: "my-slug")
6
+ second = model_class.create(slug: "my-slug")
7
+
8
+ refute second.valid?
9
+ assert_equal 1, model_class.count
10
+ end
11
+
12
+ def test_has_no_govspeak_fields
13
+ refute model_class.const_defined?(:GOVSPEAK_FIELDS)
14
+ end
15
+
16
+ def test_create_or_update_by_slug
17
+ slug = "a-slug"
18
+ original_body = "Original body"
19
+
20
+ version1_attrs= {
21
+ slug: slug,
22
+ body: original_body,
23
+ }
24
+
25
+ created = model_class.create_or_update_by_slug!(version1_attrs)
26
+
27
+ assert created.is_a?(model_class)
28
+ assert created.persisted?
29
+
30
+ version2_attrs = version1_attrs.merge(
31
+ body: "Updated body",
32
+ )
33
+
34
+ version2 = model_class.create_or_update_by_slug!(version2_attrs)
35
+
36
+ assert version2.persisted?
37
+ assert_equal "Updated body", version2.body
38
+ end
39
+
40
+ def test_find_by_slug
41
+ created = model_class.create!(slug: "find-by-this-slug")
42
+ found = model_class.find_by_slug("find-by-this-slug")
43
+
44
+ assert_equal created, found
45
+ end
46
+ end
@@ -0,0 +1,10 @@
1
+ require "test_helper"
2
+ require_relative "prerendered_entity_tests"
3
+
4
+ class RenderedManualTest < ActiveSupport::TestCase
5
+ include PrerenderedEntityTests
6
+
7
+ def model_class
8
+ RenderedManual
9
+ end
10
+ end
@@ -0,0 +1,12 @@
1
+ require "test_helper"
2
+ require "fixtures/specialist_document_fixtures"
3
+ require "models/prerendered_entity_tests"
4
+
5
+ class RenderedSpecialistDocumentTest < ActiveSupport::TestCase
6
+ include SpecialistDocumentFixtures
7
+ include PrerenderedEntityTests
8
+
9
+ def model_class
10
+ RenderedSpecialistDocument
11
+ end
12
+ end
@@ -76,6 +76,16 @@ class SlugTest < ActiveSupport::TestCase
76
76
  end
77
77
  end
78
78
 
79
+ context "Specialist documents" do
80
+ should "all url nested one level deep" do
81
+ assert document_with_slug("some-finder/my-specialist-document", kind: "cma_case").valid?;
82
+ end
83
+
84
+ should "not allow deeper nesting" do
85
+ refute document_with_slug("some-finder/my-specialist-document/not-allowed", kind: "cma_case").valid?
86
+ end
87
+ end
88
+
79
89
  context "Specialist sector browse pages" do
80
90
  should "allow a single path part" do
81
91
  assert document_with_slug("oil-and-gas", kind: "specialist_sector").valid?
@@ -108,4 +118,20 @@ class SlugTest < ActiveSupport::TestCase
108
118
  end
109
119
  #TODO: disallow this once guidance migration has been complete
110
120
  end
121
+
122
+ context "Manual pages" do
123
+ should "allow slugs starting guidance/" do
124
+ refute document_with_slug("manuals/a-manual", kind: "manual").valid?
125
+ assert document_with_slug("guidance/a-manual", kind: "manual").valid?
126
+ end
127
+
128
+ should "allow two or three path parts" do
129
+ refute document_with_slug("guidance", kind: "manual").valid?
130
+ assert document_with_slug("guidance/a-manual", kind: "manual").valid?
131
+ end
132
+
133
+ should "not allow invalid path segments" do
134
+ refute document_with_slug("guidance/bad.manual.slug", kind: "manual").valid?
135
+ end
136
+ end
111
137
  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: 29.1.1
4
+ version: 29.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Battley
@@ -307,7 +307,10 @@ files:
307
307
  - app/models/part.rb
308
308
  - app/models/parted.rb
309
309
  - app/models/place_edition.rb
310
+ - app/models/prerendered_entity.rb
310
311
  - app/models/programme_edition.rb
312
+ - app/models/rendered_manual.rb
313
+ - app/models/rendered_specialist_document.rb
311
314
  - app/models/simple_smart_answer_edition.rb
312
315
  - app/models/simple_smart_answer_edition/node.rb
313
316
  - app/models/simple_smart_answer_edition/node/option.rb
@@ -357,6 +360,7 @@ files:
357
360
  - lib/govuk_content_models/version.rb
358
361
  - lib/mongoid/monkey_patches.rb
359
362
  - test/fixtures/contactotron_api_response.json
363
+ - test/fixtures/specialist_document_fixtures.rb
360
364
  - test/fixtures/uploads/image.jpg
361
365
  - test/models/action_test.rb
362
366
  - test/models/artefact_action_test.rb
@@ -384,6 +388,9 @@ files:
384
388
  - test/models/local_transaction_edition_test.rb
385
389
  - test/models/overview_dashboard_test.rb
386
390
  - test/models/parted_test.rb
391
+ - test/models/prerendered_entity_tests.rb
392
+ - test/models/rendered_manual_test.rb
393
+ - test/models/rendered_specialist_document_test.rb
387
394
  - test/models/simple_smart_answer_edition_test.rb
388
395
  - test/models/simple_smart_answer_node_test.rb
389
396
  - test/models/simple_smart_answer_option_test.rb
@@ -429,6 +436,7 @@ specification_version: 4
429
436
  summary: Shared models for Panopticon and Publisher, as a Rails Engine
430
437
  test_files:
431
438
  - test/fixtures/contactotron_api_response.json
439
+ - test/fixtures/specialist_document_fixtures.rb
432
440
  - test/fixtures/uploads/image.jpg
433
441
  - test/models/action_test.rb
434
442
  - test/models/artefact_action_test.rb
@@ -456,6 +464,9 @@ test_files:
456
464
  - test/models/local_transaction_edition_test.rb
457
465
  - test/models/overview_dashboard_test.rb
458
466
  - test/models/parted_test.rb
467
+ - test/models/prerendered_entity_tests.rb
468
+ - test/models/rendered_manual_test.rb
469
+ - test/models/rendered_specialist_document_test.rb
459
470
  - test/models/simple_smart_answer_edition_test.rb
460
471
  - test/models/simple_smart_answer_node_test.rb
461
472
  - test/models/simple_smart_answer_option_test.rb