Skip to content

Commit 8644b69

Browse files
committed
Prevent publishing a standard edition with invalid tab form
We have agreed to only send a globally valid edition to Publishing API. In that sense, the Edition Publisher now collects each tab's failure reasons (e.g. "Social media accounts tab is invalid") so publishers see useful messages rather than a generic one. Also, the Draft Edition Updater skips pushing to Publishing API if any tab is invalid.
1 parent c108e00 commit 8644b69

4 files changed

Lines changed: 81 additions & 1 deletion

File tree

app/services/draft_edition_updater.rb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
class DraftEditionUpdater < EditionService
22
def perform!
33
if can_perform?
4-
update_publishing_api!
4+
update_publishing_api! if can_push_draft?
55
notify!
66
true
77
end
@@ -30,4 +30,12 @@ def should_check_current_user_will_retain_access?
3030
def access_limit_excludes_current_user?
3131
edition.organisation_association_enabled? && edition.edition_organisations.map(&:organisation_id).exclude?(@options[:current_user].organisation.id)
3232
end
33+
34+
def can_push_draft?
35+
return true unless edition.is_a?(StandardEdition)
36+
37+
edition.type_instance.form_keys.all? do |tab_key|
38+
StandardEdition::TabForm.new(edition, tab_key).valid?
39+
end
40+
end
3341
end

app/services/edition_publisher.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ def failure_reasons
88

99
reasons = []
1010
reasons << "This edition is invalid: #{edition.errors.full_messages.to_sentence}" unless edition.valid?(:publish)
11+
reasons.concat(invalid_tab_reasons) if edition.is_a?(StandardEdition)
1112
reasons << "An edition that is #{edition.current_state} cannot be #{past_participle}" unless can_transition?
1213
reasons << "Scheduled editions cannot be published. This edition is scheduled for publication on #{edition.scheduled_publication}" if scheduled_for_publication?
1314

@@ -38,6 +39,16 @@ def fire_transition!
3839
delete_unpublishing!
3940
end
4041

42+
def invalid_tab_reasons
43+
edition.type_instance.form_keys.filter_map do |tab_key|
44+
tab_form = StandardEdition::TabForm.new(edition, tab_key)
45+
unless tab_form.valid?(:publish)
46+
tab_label = edition.type_instance.form(tab_key)["label"] || tab_key.humanize
47+
"#{tab_label} tab is invalid"
48+
end
49+
end
50+
end
51+
4152
def editions_to_supersede
4253
edition.document.editions
4354
.where(state: %i[published unpublished])

test/unit/app/services/draft_edition_updater_test.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,15 @@ class DraftEditionUpdaterTest < ActiveSupport::TestCase
4747

4848
updater.perform!
4949
end
50+
51+
test "#perform! skips update_publishing_api! when a draft edition is invalid" do
52+
edition = create(:draft_edition)
53+
edition.freeze
54+
updater = DraftEditionUpdater.new(edition)
55+
updater.stubs(:can_push_draft?).returns(false)
56+
updater.expects(:update_publishing_api!).never
57+
updater.expects(:notify!).once
58+
59+
updater.perform!
60+
end
5061
end

test/unit/app/services/edition_publisher_test.rb

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,56 @@ class EditionPublisherTest < ActiveSupport::TestCase
5151
assert_equal "This edition is invalid: Title cannot be blank", publisher.failure_reason
5252
end
5353

54+
test "#perform! with an invalid form tab on a standard edition refuses to publish" do
55+
configurable_document_type = build_configurable_document_type("test_type", {
56+
"forms" => {
57+
"documents" => {
58+
"fields" => {
59+
"body" => {
60+
"title" => "Body",
61+
"block" => "govspeak",
62+
"attribute_path" => %w[block_content body],
63+
},
64+
},
65+
},
66+
"extra_tab" => {
67+
"dynamic" => true,
68+
"label" => "Extra tab",
69+
"fields" => {
70+
"sidebar" => {
71+
"title" => "Sidebar",
72+
"block" => "govspeak",
73+
"attribute_path" => %w[block_content sidebar],
74+
},
75+
},
76+
},
77+
},
78+
"schema" => {
79+
"attributes" => {
80+
"body" => { "type" => "string" },
81+
"sidebar" => { "type" => "string" },
82+
},
83+
"validations" => {
84+
"presence" => { "attributes" => %w[body sidebar] },
85+
},
86+
},
87+
})
88+
ConfigurableDocumentType.setup_test_types(configurable_document_type)
89+
90+
edition = create(:submitted_standard_edition, :with_organisations,
91+
configurable_document_type: "test_type",
92+
title: "Title", summary: "Summary",
93+
block_content: { body: "Content", sidebar: "Sidebar content" })
94+
edition.translations.update_all(block_content: { body: "New content", sidebar: "" })
95+
edition.reload
96+
97+
publisher = EditionPublisher.new(edition)
98+
99+
assert_not publisher.perform!
100+
assert_not edition.published?
101+
assert_includes publisher.failure_reasons, "Extra tab tab is invalid"
102+
end
103+
54104
test "#perform! with a re-editioned document updates the version numbers" do
55105
published_edition = create(:published_edition, major_change_published_at: 1.week.ago)
56106
edition = published_edition.create_draft(create(:writer))

0 commit comments

Comments
 (0)