govuk_content_models 15.1.2 → 16.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 16.0.0
2
+
3
+ * Adds a workflow for Tags.
4
+ * BREAKING CHANGE: Tags are no longer live by default. Tests which create tags
5
+ should migrate to use the new `:live_tag` factory when creating stub data.
6
+
1
7
  ## 15.1.2
2
8
  * Use string-based keys rather than symbols when manipulating
3
9
  tuple hashes for tags on an artefact.
data/app/models/tag.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require "safe_html"
2
2
  require 'tag_id_validator'
3
+ require 'state_machine'
3
4
 
4
5
  class Tag
5
6
  include Mongoid::Document
@@ -10,7 +11,7 @@ class Tag
10
11
  field :description, type: String
11
12
  field :short_description, type: String
12
13
  field :parent_id, type: String
13
- field :state, type: String, default: 'live'
14
+ field :state, type: String, default: 'draft'
14
15
 
15
16
  GOVSPEAK_FIELDS = []
16
17
  STATES = ['draft', 'live']
@@ -24,6 +25,8 @@ class Tag
24
25
  validates_with TagIdValidator
25
26
  validates_with SafeHtml
26
27
 
28
+ attr_protected :state
29
+
27
30
  validates :state, inclusion: { in: STATES }
28
31
 
29
32
  class MissingTags < RuntimeError
@@ -39,6 +42,12 @@ class Tag
39
42
  # should go through them and set this attribute manually
40
43
  attr_accessor :uniquely_named
41
44
 
45
+ state_machine initial: :draft do
46
+ event :publish do
47
+ transition draft: :live
48
+ end
49
+ end
50
+
42
51
  def as_json(options = {})
43
52
  {
44
53
  id: self.tag_id,
@@ -19,6 +19,17 @@ FactoryGirl.define do
19
19
  sequence(:tag_id) { |n| "crime-and-justice-#{n}" }
20
20
  sequence(:title) { |n| "The title #{n}" }
21
21
  tag_type "section"
22
+
23
+ trait :draft do
24
+ state "draft"
25
+ end
26
+
27
+ trait :live do
28
+ state "live"
29
+ end
30
+
31
+ factory :draft_tag, traits: [:draft]
32
+ factory :live_tag, traits: [:live]
22
33
  end
23
34
 
24
35
  factory :artefact do
@@ -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 = "15.1.2"
3
+ VERSION = "16.0.0"
4
4
  end
@@ -8,15 +8,15 @@ class ArtefactTagTest < ActiveSupport::TestCase
8
8
  ]
9
9
 
10
10
  setup do
11
- parent_section = FactoryGirl.create(:tag, :tag_id => 'crime', :tag_type => 'section', :title => 'Crime')
12
- FactoryGirl.create(:tag, :tag_id => 'crime/the-police', :tag_type => 'section', :title => 'The Police', :parent_id => parent_section.id)
13
- FactoryGirl.create(:tag, :tag_id => 'crime/batman', :tag_type => 'section', :title => 'Batman', :parent_id => parent_section.id)
11
+ parent_section = FactoryGirl.create(:live_tag, :tag_id => 'crime', :tag_type => 'section', :title => 'Crime')
12
+ FactoryGirl.create(:live_tag, :tag_id => 'crime/the-police', :tag_type => 'section', :title => 'The Police', :parent_id => parent_section.id)
13
+ FactoryGirl.create(:live_tag, :tag_id => 'crime/batman', :tag_type => 'section', :title => 'Batman', :parent_id => parent_section.id)
14
14
 
15
15
  TEST_KEYWORDS.each do |tag_id, title|
16
- FactoryGirl.create(:tag, :tag_id => tag_id, :tag_type => 'keyword', :title => title)
16
+ FactoryGirl.create(:live_tag, :tag_id => tag_id, :tag_type => 'keyword', :title => title)
17
17
  end
18
18
  TEST_LEGACY_SOURCES.each do |tag_id, title|
19
- FactoryGirl.create(:tag, :tag_id => tag_id, :tag_type => 'legacy_source', :title => title)
19
+ FactoryGirl.create(:live_tag, :tag_id => tag_id, :tag_type => 'legacy_source', :title => title)
20
20
  end
21
21
  end
22
22
 
@@ -356,7 +356,7 @@ class ArtefactTest < ActiveSupport::TestCase
356
356
  # should continue to work in the way it has been:
357
357
  # i.e. you can edit everything but the name/title for published content in panop
358
358
  test "on save title should not be applied to already published content" do
359
- FactoryGirl.create(:tag, tag_id: "test-section", title: "Test section", tag_type: "section")
359
+ FactoryGirl.create(:live_tag, tag_id: "test-section", title: "Test section", tag_type: "section")
360
360
  artefact = FactoryGirl.create(:artefact,
361
361
  slug: "foo-bar",
362
362
  kind: "answer",
@@ -503,10 +503,10 @@ class ArtefactTest < ActiveSupport::TestCase
503
503
  context "returning json representation" do
504
504
  context "returning tags" do
505
505
  setup do
506
- FactoryGirl.create(:tag, :tag_type => 'section', :tag_id => 'crime', :title => 'Crime')
507
- FactoryGirl.create(:tag, :tag_type => 'section', :tag_id => 'justice', :title => 'Justice', :description => "All about justice")
508
- FactoryGirl.create(:tag, :tag_type => 'legacy_source', :tag_id => 'directgov', :title => 'Directgov')
509
- FactoryGirl.create(:tag, :tag_type => 'legacy_source', :tag_id => 'businesslink', :title => 'Business Link')
506
+ FactoryGirl.create(:live_tag, :tag_type => 'section', :tag_id => 'crime', :title => 'Crime')
507
+ FactoryGirl.create(:live_tag, :tag_type => 'section', :tag_id => 'justice', :title => 'Justice', :description => "All about justice")
508
+ FactoryGirl.create(:live_tag, :tag_type => 'legacy_source', :tag_id => 'directgov', :title => 'Directgov')
509
+ FactoryGirl.create(:live_tag, :tag_type => 'legacy_source', :tag_id => 'businesslink', :title => 'Business Link')
510
510
 
511
511
  @a = FactoryGirl.create(:artefact, :slug => 'fooey')
512
512
  end
@@ -588,10 +588,10 @@ class ArtefactTest < ActiveSupport::TestCase
588
588
 
589
589
  context "related artefacts grouped by section tags" do
590
590
  setup do
591
- FactoryGirl.create(:tag, :tag_id => "fruit", :tag_type => 'section', :title => "Fruit")
592
- FactoryGirl.create(:tag, :tag_id => "fruit/simple", :tag_type => 'section', :title => "Simple fruits", :parent_id => "fruit")
593
- FactoryGirl.create(:tag, :tag_id => "fruit/aggregate", :tag_type => 'section', :title => "Aggregrate fruits", :parent_id => "fruit")
594
- FactoryGirl.create(:tag, :tag_id => "vegetables", :tag_type => 'section', :title => "Vegetables")
591
+ FactoryGirl.create(:live_tag, :tag_id => "fruit", :tag_type => 'section', :title => "Fruit")
592
+ FactoryGirl.create(:live_tag, :tag_id => "fruit/simple", :tag_type => 'section', :title => "Simple fruits", :parent_id => "fruit")
593
+ FactoryGirl.create(:live_tag, :tag_id => "fruit/aggregate", :tag_type => 'section', :title => "Aggregrate fruits", :parent_id => "fruit")
594
+ FactoryGirl.create(:live_tag, :tag_id => "vegetables", :tag_type => 'section', :title => "Vegetables")
595
595
 
596
596
  @artefact = Artefact.create!(slug: "apple", name: "Apple", sections: [], kind: "guide", need_ids: ["100001"], owning_app: "x")
597
597
  end
@@ -9,7 +9,7 @@ class CuratedListTest < ActiveSupport::TestCase
9
9
 
10
10
  test "should include ability to have a section tag" do
11
11
  cl = FactoryGirl.create(:curated_list)
12
- tag = FactoryGirl.create(:tag, tag_id: 'batman', title: 'Batman', tag_type: 'section')
12
+ tag = FactoryGirl.create(:live_tag, tag_id: 'batman', title: 'Batman', tag_type: 'section')
13
13
 
14
14
  cl.sections = ['batman']
15
15
  cl.save
@@ -29,4 +29,4 @@ class CuratedListTest < ActiveSupport::TestCase
29
29
  cl = FactoryGirl.create(:curated_list, artefact_ids: [a.id.to_s])
30
30
  assert cl.artefact_ids.first.is_a?(BSON::ObjectId)
31
31
  end
32
- end
32
+ end
@@ -366,7 +366,7 @@ class EditionTest < ActiveSupport::TestCase
366
366
  end
367
367
 
368
368
  test "should create a publication based on data imported from panopticon" do
369
- section = FactoryGirl.create(:tag, tag_id: "test-section", title: "Test section", tag_type: "section")
369
+ section = FactoryGirl.create(:live_tag, tag_id: "test-section", title: "Test section", tag_type: "section")
370
370
  artefact = FactoryGirl.create(:artefact,
371
371
  slug: "foo-bar",
372
372
  kind: "answer",
@@ -393,7 +393,7 @@ class EditionTest < ActiveSupport::TestCase
393
393
  end
394
394
 
395
395
  test "should not change edition metadata if archived" do
396
- FactoryGirl.create(:tag, tag_id: "test-section", title: "Test section", tag_type: "section")
396
+ FactoryGirl.create(:live_tag, tag_id: "test-section", title: "Test section", tag_type: "section")
397
397
  artefact = FactoryGirl.create(:artefact,
398
398
  slug: "foo-bar",
399
399
  kind: "answer",
@@ -492,8 +492,8 @@ class EditionTest < ActiveSupport::TestCase
492
492
  end
493
493
 
494
494
  test "should also delete associated artefact" do
495
-
496
- FactoryGirl.create(:tag, tag_id: "test-section", title: "Test section", tag_type: "section")
495
+
496
+ FactoryGirl.create(:live_tag, tag_id: "test-section", title: "Test section", tag_type: "section")
497
497
 
498
498
  user1 = FactoryGirl.create(:user)
499
499
  edition = AnswerEdition.find_or_create_from_panopticon_data(@artefact.id, user1, {})
@@ -504,8 +504,8 @@ class EditionTest < ActiveSupport::TestCase
504
504
  end
505
505
 
506
506
  test "should not delete associated artefact if there are other editions of this publication" do
507
-
508
- FactoryGirl.create(:tag, tag_id: "test-section", title: "Test section", tag_type: "section")
507
+
508
+ FactoryGirl.create(:live_tag, tag_id: "test-section", title: "Test section", tag_type: "section")
509
509
  user1 = FactoryGirl.create(:user)
510
510
  edition = AnswerEdition.find_or_create_from_panopticon_data(@artefact.id, user1, {})
511
511
  edition.update_attribute(:state, "published")
@@ -902,7 +902,7 @@ class EditionTest < ActiveSupport::TestCase
902
902
 
903
903
  test "should denormalise a creator's name when an edition is created" do
904
904
  @user = FactoryGirl.create(:user)
905
- FactoryGirl.create(:tag, tag_id: "test-section", title: "Test section", tag_type: "section")
905
+ FactoryGirl.create(:live_tag, tag_id: "test-section", title: "Test section", tag_type: "section")
906
906
  artefact = FactoryGirl.create(:artefact,
907
907
  slug: "foo-bar",
908
908
  kind: "answer",
@@ -2,10 +2,10 @@ require "test_helper"
2
2
 
3
3
  class TagTest < ActiveSupport::TestCase
4
4
  test "should return a hash of the fields" do
5
- tag = Tag.new(
5
+ tag = FactoryGirl.build(:live_tag,
6
6
  tag_id: "crime",
7
7
  tag_type: "section",
8
- title: "Crime"
8
+ title: "Crime",
9
9
  )
10
10
  expected_hash = {
11
11
  id: "crime",
@@ -19,12 +19,12 @@ class TagTest < ActiveSupport::TestCase
19
19
 
20
20
  setup do
21
21
  %w(crime business housing).each do |section|
22
- FactoryGirl.create(:tag, :tag_id => section, :title => section.capitalize)
22
+ FactoryGirl.create(:live_tag, :tag_id => section, :title => section.capitalize)
23
23
  end
24
24
 
25
25
  %w(pie mash chips).each do |keyword|
26
26
  FactoryGirl.create(
27
- :tag,
27
+ :live_tag,
28
28
  :tag_id => keyword,
29
29
  :title => keyword.capitalize,
30
30
  :tag_type => "keyword"
@@ -68,11 +68,10 @@ class TagTest < ActiveSupport::TestCase
68
68
  end
69
69
 
70
70
  test "should not return draft tags unless requested" do
71
- draft_tag = FactoryGirl.create(:tag,
71
+ draft_tag = FactoryGirl.create(:draft_tag,
72
72
  tag_id: "draft-tag",
73
73
  tag_type: "section",
74
74
  title: "A draft tag",
75
- state: "draft"
76
75
  )
77
76
 
78
77
  tag_ids = %w(crime business draft-tag housing)
@@ -134,32 +133,56 @@ class TagTest < ActiveSupport::TestCase
134
133
  @atts = { tag_type: 'section', tag_id: 'test', title: 'Test' }
135
134
  end
136
135
 
137
- should "be created in live state" do
138
- tag = Tag.create(@atts.merge(state: 'live'))
136
+ should "be created in draft state by default" do
137
+ tag = Tag.create(@atts)
139
138
 
140
139
  assert tag.persisted?
140
+ assert_equal 'draft', tag.state
141
+ end
142
+
143
+ should "be able to be set to live" do
144
+ tag = Tag.new(@atts)
145
+ tag.state = 'live'
146
+ tag.save
147
+
148
+ tag.reload
141
149
  assert_equal 'live', tag.state
142
150
  end
143
151
 
144
- should "be created in draft state" do
145
- tag = Tag.create(@atts.merge(state: 'draft'))
152
+ should "not mass-assign the state attribute" do
153
+ tag = Tag.create(@atts.merge(state: 'live'))
154
+ tag.reload
146
155
 
147
- assert tag.persisted?
148
- assert_equal 'draft', tag.state
156
+ refute_equal 'live', tag.state
149
157
  end
150
158
 
151
159
  should "not be created in another state" do
152
- tag = Tag.create(@atts.merge(state: 'foo'))
160
+ tag = Tag.new(@atts)
161
+ tag.state = 'foo'
153
162
 
154
163
  assert !tag.valid?
155
164
  assert tag.errors.has_key?(:state)
156
165
  end
157
166
 
158
- should "be created in live state by default" do
167
+ should "be set to live when published" do
159
168
  tag = Tag.create(@atts)
160
169
 
161
- assert tag.persisted?
170
+ assert_equal 'draft', tag.state
171
+ tag.publish!
172
+
173
+ tag.reload
162
174
  assert_equal 'live', tag.state
163
175
  end
176
+
177
+ should "not be published more than once" do
178
+ tag = Tag.create(@atts)
179
+
180
+ tag.publish!
181
+ tag.reload
182
+
183
+ assert_raises StateMachine::InvalidTransition do
184
+ tag.publish!
185
+ end
186
+ end
164
187
  end
165
188
  end
@@ -6,13 +6,13 @@ class TaggableTest < ActiveSupport::TestCase
6
6
  TEST_KEYWORDS = [['cheese', 'Cheese'], ['bacon', 'Bacon']]
7
7
 
8
8
  setup do
9
- @parent_section = FactoryGirl.create(:tag, :tag_id => 'crime', :tag_type => 'section', :title => 'Crime')
10
- FactoryGirl.create(:tag, :tag_id => 'crime/the-police', :tag_type => 'section', :title => 'The Police', :parent_id => @parent_section.id)
11
- FactoryGirl.create(:tag, :tag_id => 'crime/batman', :tag_type => 'section', :title => 'Batman', :parent_id => @parent_section.id)
12
- @draft_section = FactoryGirl.create(:tag, parent_id: @parent_section.id, state: 'draft')
9
+ @parent_section = FactoryGirl.create(:live_tag, :tag_id => 'crime', :tag_type => 'section', :title => 'Crime')
10
+ FactoryGirl.create(:live_tag, :tag_id => 'crime/the-police', :tag_type => 'section', :title => 'The Police', :parent_id => @parent_section.id)
11
+ FactoryGirl.create(:live_tag, :tag_id => 'crime/batman', :tag_type => 'section', :title => 'Batman', :parent_id => @parent_section.id)
12
+ @draft_section = FactoryGirl.create(:draft_tag, parent_id: @parent_section.id)
13
13
 
14
14
  TEST_KEYWORDS.each do |tag_id, title|
15
- FactoryGirl.create(:tag, :tag_id => tag_id, :tag_type => 'keyword', :title => title)
15
+ FactoryGirl.create(:live_tag, :tag_id => tag_id, :tag_type => 'keyword', :title => title)
16
16
  end
17
17
 
18
18
  @item = FactoryGirl.create(:artefact)
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: 15.1.2
4
+ version: 16.0.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-07-23 00:00:00.000000000 Z
12
+ date: 2014-07-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bson_ext
@@ -466,7 +466,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
466
466
  version: '0'
467
467
  segments:
468
468
  - 0
469
- hash: -641385530309798652
469
+ hash: -1246027544295212288
470
470
  required_rubygems_version: !ruby/object:Gem::Requirement
471
471
  none: false
472
472
  requirements:
@@ -475,7 +475,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
475
475
  version: '0'
476
476
  segments:
477
477
  - 0
478
- hash: -641385530309798652
478
+ hash: -1246027544295212288
479
479
  requirements: []
480
480
  rubyforge_project:
481
481
  rubygems_version: 1.8.23