govuk_content_models 23.0.0 → 24.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +10 -0
- data/app/models/action.rb +8 -1
- data/app/models/edition.rb +5 -0
- data/app/models/user.rb +28 -2
- data/app/models/workflow.rb +20 -66
- data/app/traits/recordable_actions.rb +53 -0
- data/lib/govuk_content_models.rb +4 -5
- data/lib/govuk_content_models/action_processors.rb +23 -0
- data/lib/govuk_content_models/action_processors/approve_fact_check_processor.rb +6 -0
- data/lib/govuk_content_models/action_processors/approve_review_processor.rb +11 -0
- data/lib/govuk_content_models/action_processors/archive_processor.rb +6 -0
- data/lib/govuk_content_models/action_processors/assign_processor.rb +12 -0
- data/lib/govuk_content_models/action_processors/base_processor.rb +59 -0
- data/lib/govuk_content_models/action_processors/cancel_scheduled_publishing_processor.rb +6 -0
- data/lib/govuk_content_models/action_processors/create_edition_processor.rb +22 -0
- data/lib/govuk_content_models/action_processors/emergency_publish_processor.rb +6 -0
- data/lib/govuk_content_models/action_processors/new_version_processor.rb +23 -0
- data/lib/govuk_content_models/action_processors/publish_processor.rb +6 -0
- data/lib/govuk_content_models/action_processors/receive_fact_check_processor.rb +18 -0
- data/lib/govuk_content_models/action_processors/request_amendments_processor.rb +15 -0
- data/lib/govuk_content_models/action_processors/request_review_processor.rb +6 -0
- data/lib/govuk_content_models/action_processors/schedule_for_publishing_processor.rb +14 -0
- data/lib/govuk_content_models/action_processors/send_fact_check_processor.rb +14 -0
- data/lib/govuk_content_models/action_processors/skip_fact_check_processor.rb +6 -0
- data/lib/govuk_content_models/test_helpers/action_processor_helpers.rb +39 -0
- data/lib/govuk_content_models/version.rb +1 -1
- data/test/models/action_test.rb +13 -0
- data/test/models/edition_test.rb +87 -64
- data/test/models/user_test.rb +2 -2
- data/test/models/workflow_test.rb +160 -55
- data/test/test_helper.rb +2 -0
- metadata +25 -7
- data/app/models/workflow_actor.rb +0 -157
- data/test/models/workflow_actor_test.rb +0 -112
@@ -1,157 +0,0 @@
|
|
1
|
-
require "answer_edition"
|
2
|
-
require "guide_edition"
|
3
|
-
require "local_transaction_edition"
|
4
|
-
require "place_edition"
|
5
|
-
require "programme_edition"
|
6
|
-
require "transaction_edition"
|
7
|
-
|
8
|
-
module WorkflowActor
|
9
|
-
SIMPLE_WORKFLOW_ACTIONS = %w(
|
10
|
-
request_review
|
11
|
-
request_amendments
|
12
|
-
approve_review
|
13
|
-
approve_fact_check
|
14
|
-
archive
|
15
|
-
cancel_scheduled_publishing
|
16
|
-
)
|
17
|
-
|
18
|
-
def record_action(edition, type, options={})
|
19
|
-
type = Action.const_get(type.to_s.upcase)
|
20
|
-
action = edition.new_action(self, type, options)
|
21
|
-
edition.denormalise_users!
|
22
|
-
action
|
23
|
-
end
|
24
|
-
|
25
|
-
def record_action_without_validation(edition, type, options={})
|
26
|
-
type = Action.const_get(type.to_s.upcase)
|
27
|
-
action = edition.new_action_without_validation(self, type, options)
|
28
|
-
edition.denormalise_users!
|
29
|
-
action
|
30
|
-
end
|
31
|
-
|
32
|
-
def can_take_action(action, edition)
|
33
|
-
respond_to?(:"can_#{action}?") ? __send__(:"can_#{action}?", edition) : true
|
34
|
-
end
|
35
|
-
|
36
|
-
def take_action(edition, action, details = {}, action_parameters = [])
|
37
|
-
if can_take_action(action, edition) && edition.send(action, *action_parameters)
|
38
|
-
record_action(edition, action, details)
|
39
|
-
edition
|
40
|
-
else
|
41
|
-
false
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def take_action!(edition, action, details = {}, action_parameters = [])
|
46
|
-
edition = take_action(edition, action, details, action_parameters)
|
47
|
-
edition.save if edition
|
48
|
-
end
|
49
|
-
|
50
|
-
def progress(edition, activity_details)
|
51
|
-
activity = activity_details.delete(:request_type)
|
52
|
-
|
53
|
-
edition = send(activity, edition, activity_details)
|
54
|
-
edition.save if edition
|
55
|
-
end
|
56
|
-
|
57
|
-
def record_note(edition, comment, type = Action::NOTE)
|
58
|
-
edition.new_action(self, type, comment: comment)
|
59
|
-
end
|
60
|
-
|
61
|
-
def resolve_important_note(edition)
|
62
|
-
record_note(edition, nil, Action::IMPORTANT_NOTE_RESOLVED)
|
63
|
-
end
|
64
|
-
|
65
|
-
def create_edition(format, attributes = {})
|
66
|
-
format = "#{format}_edition" unless format.to_s.match(/edition$/)
|
67
|
-
publication_class = format.to_s.camelize.constantize
|
68
|
-
|
69
|
-
item = publication_class.create(attributes)
|
70
|
-
record_action(item, Action::CREATE) if item.persisted?
|
71
|
-
item
|
72
|
-
end
|
73
|
-
|
74
|
-
def new_version(edition, convert_to = nil)
|
75
|
-
return false unless edition.published?
|
76
|
-
|
77
|
-
if not convert_to.nil?
|
78
|
-
convert_to = convert_to.to_s.camelize.constantize
|
79
|
-
new_edition = edition.build_clone(convert_to)
|
80
|
-
else
|
81
|
-
new_edition = edition.build_clone
|
82
|
-
end
|
83
|
-
|
84
|
-
if new_edition
|
85
|
-
record_action new_edition, Action::NEW_VERSION
|
86
|
-
new_edition
|
87
|
-
else
|
88
|
-
false
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
def send_fact_check(edition, details)
|
93
|
-
return false if details[:email_addresses].blank?
|
94
|
-
|
95
|
-
details[:comment] ||= "Fact check requested"
|
96
|
-
|
97
|
-
take_action(edition, __method__, details)
|
98
|
-
end
|
99
|
-
|
100
|
-
# Always records the action.
|
101
|
-
def receive_fact_check(edition, details)
|
102
|
-
edition.perform_event_without_validations(:receive_fact_check)
|
103
|
-
# Fact checks are processed async, so the user doesn't get an opportunity
|
104
|
-
# to retry without the content that (inadvertantly) fails validation, which happens frequently.
|
105
|
-
record_action_without_validation(edition, :receive_fact_check, details)
|
106
|
-
end
|
107
|
-
|
108
|
-
def skip_fact_check(edition, details)
|
109
|
-
edition.skip_fact_check
|
110
|
-
record_action(edition, :skip_fact_check, details)
|
111
|
-
end
|
112
|
-
|
113
|
-
SIMPLE_WORKFLOW_ACTIONS.each do |method|
|
114
|
-
define_method(method) do |edition, details = {}|
|
115
|
-
take_action(edition, __method__, details)
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
def schedule_for_publishing(edition, details)
|
120
|
-
publish_at = details.delete(:publish_at)
|
121
|
-
take_action(edition, __method__, details, [publish_at])
|
122
|
-
end
|
123
|
-
|
124
|
-
def publish(edition, details)
|
125
|
-
take_action(edition, __method__, details)
|
126
|
-
end
|
127
|
-
|
128
|
-
def can_approve_review?(edition)
|
129
|
-
requester_different?(edition)
|
130
|
-
end
|
131
|
-
|
132
|
-
def can_request_amendments?(edition)
|
133
|
-
if edition.in_review?
|
134
|
-
requester_different?(edition)
|
135
|
-
else
|
136
|
-
true
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
def assign(edition, recipient)
|
141
|
-
edition.set(:assigned_to_id, recipient.id)
|
142
|
-
record_action edition.reload, __method__, recipient: recipient
|
143
|
-
end
|
144
|
-
|
145
|
-
private
|
146
|
-
|
147
|
-
def requester_different?(edition)
|
148
|
-
# To accommodate latest_status_action being nil, we'll always return true in
|
149
|
-
# those cases
|
150
|
-
# This is intended as a v.temporary fix until we can remedy the root cause
|
151
|
-
if edition.latest_status_action
|
152
|
-
edition.latest_status_action.requester_id != self.id
|
153
|
-
else
|
154
|
-
true
|
155
|
-
end
|
156
|
-
end
|
157
|
-
end
|
@@ -1,112 +0,0 @@
|
|
1
|
-
require_relative "../test_helper"
|
2
|
-
|
3
|
-
class WorkflowActorTest < ActiveSupport::TestCase
|
4
|
-
|
5
|
-
context "creating a new version of an edition" do
|
6
|
-
setup do
|
7
|
-
@user = User.new
|
8
|
-
@user.stubs(:record_action)
|
9
|
-
@edition = stub("AnswerEdition", :published? => true, :build_clone => :new_version)
|
10
|
-
end
|
11
|
-
|
12
|
-
should "return false if the edition is not published" do
|
13
|
-
@edition.stubs(:published?).returns(false)
|
14
|
-
@edition.expects(:build_clone).never
|
15
|
-
@user.expects(:record_action).never
|
16
|
-
assert_equal false, @user.new_version(@edition)
|
17
|
-
end
|
18
|
-
|
19
|
-
should "build a clone" do
|
20
|
-
@edition.expects(:build_clone).with(nil).returns(:new_verison)
|
21
|
-
@user.new_version(@edition)
|
22
|
-
end
|
23
|
-
|
24
|
-
should "record the action" do
|
25
|
-
@user.expects(:record_action).with(:new_version, Action::NEW_VERSION)
|
26
|
-
@user.new_version(@edition)
|
27
|
-
end
|
28
|
-
|
29
|
-
should "return the new edition" do
|
30
|
-
assert_equal :new_version, @user.new_version(@edition)
|
31
|
-
end
|
32
|
-
|
33
|
-
context "creating an edition of a different type" do
|
34
|
-
should "build a clone of a new type" do
|
35
|
-
@edition.expects(:build_clone).with(GuideEdition).returns(:new_verison)
|
36
|
-
@user.new_version(@edition, "GuideEdition")
|
37
|
-
end
|
38
|
-
|
39
|
-
should "record the action" do
|
40
|
-
@user.expects(:record_action).with(:new_version, Action::NEW_VERSION)
|
41
|
-
@user.new_version(@edition)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
context "when building the edition fails" do
|
46
|
-
setup do
|
47
|
-
@edition.stubs(:build_clone).returns(nil)
|
48
|
-
end
|
49
|
-
|
50
|
-
should "not record the action" do
|
51
|
-
@user.expects(:record_action).never
|
52
|
-
@user.new_version(@edition)
|
53
|
-
end
|
54
|
-
|
55
|
-
should "return false" do
|
56
|
-
assert_equal false, @user.new_version(@edition)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
context "#receive_fact_check" do
|
62
|
-
setup do
|
63
|
-
@edition = FactoryGirl.create(:guide_edition_with_two_parts, state: :fact_check)
|
64
|
-
# Internal links must start with a forward slash eg [link text](/link-destination)
|
65
|
-
@edition.parts.first.update_attribute(:body,
|
66
|
-
"[register and tax your vehicle](registering-an-imported-vehicle)")
|
67
|
-
end
|
68
|
-
|
69
|
-
should "transition an edition with link validation errors to fact_check_received state" do
|
70
|
-
assert @edition.invalid?
|
71
|
-
assert User.new.receive_fact_check(@edition, {})
|
72
|
-
assert_equal "fact_check_received", @edition.reload.state
|
73
|
-
end
|
74
|
-
|
75
|
-
should "record the action" do
|
76
|
-
user = User.new
|
77
|
-
user.receive_fact_check(@edition, {})
|
78
|
-
|
79
|
-
assert_equal 1, @edition.actions.count
|
80
|
-
assert_equal "receive_fact_check", @edition.actions.last.request_type
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
context "#schedule_for_publishing" do
|
85
|
-
setup do
|
86
|
-
@user = FactoryGirl.build(:user)
|
87
|
-
@publish_at = 1.day.from_now
|
88
|
-
@activity_details = { publish_at: @publish_at, comment: "Go schedule !" }
|
89
|
-
end
|
90
|
-
|
91
|
-
should "return false when scheduling an already published edition" do
|
92
|
-
edition = FactoryGirl.create(:edition, state: 'published')
|
93
|
-
refute @user.schedule_for_publishing(edition, @activity_details)
|
94
|
-
end
|
95
|
-
|
96
|
-
should "schedule an edition for publishing if it is ready" do
|
97
|
-
edition = FactoryGirl.create(:edition, state: 'ready')
|
98
|
-
|
99
|
-
edition = @user.schedule_for_publishing(edition, @activity_details)
|
100
|
-
|
101
|
-
assert edition.scheduled_for_publishing?
|
102
|
-
assert_equal @publish_at.to_i, edition.publish_at.to_i
|
103
|
-
end
|
104
|
-
|
105
|
-
should "record the action" do
|
106
|
-
edition = FactoryGirl.create(:edition, state: 'ready')
|
107
|
-
@user.expects(:record_action).with(edition, :schedule_for_publishing, { comment: "Go schedule !" })
|
108
|
-
|
109
|
-
@user.schedule_for_publishing(edition, @activity_details)
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|