Skip to content

Commit

Permalink
Merge pull request #2431 from alphagov/472_Admin-tab_Update-content-type
Browse files Browse the repository at this point in the history
472 admin tab update content type
  • Loading branch information
davidtrussler authored Nov 28, 2024
2 parents fd8ce7d + f9e92cc commit df13c6e
Show file tree
Hide file tree
Showing 7 changed files with 213 additions and 9 deletions.
23 changes: 22 additions & 1 deletion app/controllers/editions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,35 @@ def index

def show
@artefact = @resource.artefact

render action: "show"
end

alias_method :metadata, :show
alias_method :unpublish, :show
alias_method :admin, :show

def duplicate
command = EditionDuplicator.new(@resource, current_user)
target_edition_class_name = "#{params[:to]}_edition".classify if params[:to]

if !@resource.can_create_new_edition?
flash[:warning] = "Another person has created a newer edition"
redirect_to edition_path(resource)
elsif command.duplicate(target_edition_class_name, current_user)
new_edition = command.new_edition
UpdateWorker.perform_async(new_edition.id.to_s)
flash[:success] = "New edition created"
redirect_to edition_path(new_edition)
else
flash[:danger] = command.error_message
redirect_to edition_path(resource)
end
rescue StandardError => e
Rails.logger.error "Error #{e.class} #{e.message}"
@resource.errors.add(:show, "Due to a service problem, the edition couldn't be duplicated")
render "show"
end

def update
@resource.assign_attributes(permitted_update_params)

Expand Down
23 changes: 22 additions & 1 deletion app/helpers/editions_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,32 @@ def legacy_resource_form(resource, &form_definition)
nested_form_for resource, as: :edition, url: edition_path(resource), html: html_options, &form_definition
end

def format_conversion_select_options(edition)
def legacy_format_conversion_select_options(edition)
possible_target_formats = Edition.convertible_formats - [edition.artefact.kind]
possible_target_formats.map { |format_name| [format_name.humanize, format_name] }
end

def conversion_items(edition)
radio_options_hints = {
"answer" => "One page guidance",
"completed_transaction" => "Done page for end of a service",
"guide" => "Multi-page guidance",
"help_page" => "Info about GOV.UK website, for example Privacy",
"place" => "Postcode look-up for places/services near you",
"simple_smart_answer" => "Simple questions and answers that route users to relevant outcomes",
"transaction" => "Start page for a service",
}

possible_target_formats = Edition.convertible_formats - [edition.artefact.kind]
possible_target_formats.map do |format_name|
{
text: format_name.humanize,
value: format_name,
hint_text: radio_options_hints[format_name],
}
end
end

def legacy_format_filter_selection_options
[%w[All edition]] +
Artefact::FORMATS_BY_DEFAULT_OWNING_APP["publisher"].map do |format_name|
Expand Down
36 changes: 30 additions & 6 deletions app/views/editions/secondary_nav_tabs/_admin.html.erb
Original file line number Diff line number Diff line change
@@ -1,12 +1,36 @@
<% @edition = @resource %>

<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds editions__admin__tab">
<%= header_for("Admin") %>
<%= render "govuk_publishing_components/components/list", {
items: [
( primary_button_for(@edition, skip_fact_check_edition_path(@edition), "Skip fact check") if @edition.fact_check? ),
( link_to("Delete edition #{@edition.version_number}", confirm_destroy_edition_path(@resource), class: "govuk-link gem-link--destructive") if @edition.can_destroy? ),
],
} %>

<% if @edition.can_create_new_edition? && @edition.published? %>
<p class="govuk-body">No content will be lost, but content in some fields might not make it into the new edition. If it can't be copied to a new content type it will still be available in the previous edition. Content in multiple fields might be combined into a single field.</p>

<% if @edition.respond_to?(:parts) %>
<p class="govuk-body">All parts of Guide Editions will be copied across. If the format you are converting to doesn't have parts, the content of all the parts will be copied into the body, with the part title displayed as a top-level sub-heading.</p>
<% end %>

<%= form_for @resource, url: duplicate_edition_path(@resource), method: "post" do %>
<%= render "govuk_publishing_components/components/radio", {
heading: "Update content type",
heading_level: 0,
heading_size: "s",
name: "to",
items: conversion_items(@resource),
} %>

<%= render "govuk_publishing_components/components/button", {
text: "Update",
} %>
<% end %>
<% else %>
<%= render "govuk_publishing_components/components/list", {
items: [
( primary_button_for(@edition, skip_fact_check_edition_path(@edition), "Skip fact check") if @edition.fact_check? ),
( link_to("Delete edition #{@edition.version_number}", confirm_destroy_edition_path(@resource), class: "govuk-link gem-link--destructive") if @edition.can_destroy? ),
],
} %>
<% end %>
</div>
</div>
2 changes: 1 addition & 1 deletion app/views/shared/_clone_buttons.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

<%= form_for @resource, url: duplicate_edition_path(@resource, from: edition_class.to_s), method: "post" do |f| %>
<%= f.label :to, "Create as new", for: :to %>
<%= select_tag :to, options_for_select(format_conversion_select_options(@resource)), class: "form-control input-md-3 add-bottom-margin" %>
<%= select_tag :to, options_for_select(legacy_format_conversion_select_options(@resource)), class: "form-control input-md-3 add-bottom-margin" %>
<%= f.submit "Change format", class: "btn btn-default" %>
<% end %>
<% end %>
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
get "metadata"
get "history"
get "admin"
post "duplicate"
get "related_external_links", to: "editions#linking"
get "tagging", to: "editions#linking"
get "unpublish"
Expand Down
44 changes: 44 additions & 0 deletions test/functional/editions_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,50 @@ class EditionsControllerTest < ActionController::TestCase
end
end

context "#duplicate" do
setup do
@answer = FactoryBot.create(:answer_edition)
@help = FactoryBot.create(:help_page_edition)
end

should "redirect to the edit tab of the newly created edition and show success message when user saves successfully" do
EditionDuplicator.any_instance.expects(:duplicate).returns(true)
EditionDuplicator.any_instance.expects(:new_edition).returns(@help)

post :duplicate, params: { id: @edition.id, to: "help_page" }

assert_redirected_to edition_path(@help)
assert_equal "New edition created", flash[:success]
end

should "redirect to the edit tab and show a failure message when saving the new edition fails" do
EditionDuplicator.any_instance.expects(:duplicate).returns(false)

post :duplicate, params: { id: @edition.id, to: "help_page" }

assert_response :found
assert_equal "Failed to create new edition: couldn't initialise", flash[:danger]
end

should "redirect to the edit tab and show a failure message when another user has already created a new edition" do
FactoryBot.create(:edition, panopticon_id: @edition.artefact.id)

post :duplicate, params: { id: @edition.id, to: "help_page" }

assert_response :found
assert_equal "Another person has created a newer edition", flash[:warning]
end

should "render the edit tab and show a failure message when there is a service problem" do
EditionDuplicator.any_instance.expects(:duplicate).raises(StandardError)

post :duplicate, params: { id: @edition.id, to: "help_page" }

assert_template "show"
assert_select ".gem-c-error-summary__list-item", "Due to a service problem, the edition couldn't be duplicated"
end
end

context "#progress" do
context "Welsh editor" do
setup do
Expand Down
93 changes: 93 additions & 0 deletions test/integration/edition_edit_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class EditionEditTest < IntegrationTest
login_as(@govuk_editor)
test_strategy = Flipflop::FeatureSet.current.test!
test_strategy.switch!(:design_system_edit, true)
stub_holidays_used_by_fact_check
stub_linkables
end

Expand Down Expand Up @@ -165,6 +166,19 @@ class EditionEditTest < IntegrationTest
end

context "user has required permissions" do
%i[draft amends_needed in_review fact_check_received ready archived scheduled_for_publishing].each do |state|
context "when state is '#{state}'" do
setup do
send "visit_#{state}_edition"
click_link("Admin")
end

should "not show the 'Update content type' form" do
assert page.has_no_text?("Update content type")
end
end
end

%i[published archived scheduled_for_publishing].each do |state|
context "when state is '#{state}'" do
setup do
Expand Down Expand Up @@ -249,6 +263,56 @@ class EditionEditTest < IntegrationTest
end
end

context "when state is 'published'" do
context "content type is retired" do
setup do
visit_retired_edition_in_published
click_link("Admin")
end

should "not show the 'Update content type' form" do
assert page.has_no_text?("Update content type")
end
end

context "edition is not the latest version of a publication" do
setup do
visit_old_edition_of_published_edition
click_link("Admin")
end

should "not show the 'Update content type' form" do
assert page.has_no_text?("Update content type")
end
end

context "content type is not retired, edition is the latest version of a publication" do
setup do
visit_published_edition
click_link("Admin")
end

should "show the 'Update content type' form" do
assert page.has_text?("Update content type")
end

should "show radio buttons for all content types excluding current one (answer)" do
assert page.has_no_selector?(".gem-c-radio input[value='answer']")
assert page.has_selector?(".gem-c-radio input[value='completed_transaction']")
assert page.has_selector?(".gem-c-radio input[value='guide']")
assert page.has_selector?(".gem-c-radio input[value='help_page']")
assert page.has_selector?(".gem-c-radio input[value='place']")
assert page.has_selector?(".gem-c-radio input[value='simple_smart_answer']")
assert page.has_selector?(".gem-c-radio input[value='transaction']")
end

should "show common explanatory text for all content types and not show explanatory text specific to Guides" do
assert page.has_text?("No content will be lost, but content in some fields might not make it into the new edition. If it can't be copied to a new content type it will still be available in the previous edition. Content in multiple fields might be combined into a single field.")
assert page.has_no_text?("All parts of Guide Editions will be copied across. If the format you are converting to doesn't have parts, the content of all the parts will be copied into the body, with the part title displayed as a top-level sub-heading.")
end
end
end

context "confirm delete" do
setup do
visit_draft_edition
Expand Down Expand Up @@ -537,5 +601,34 @@ def create_published_edition
state: "published",
slug: "can-i-get-a-driving-licence",
)
visit edition_path(@published_edition)
end

def visit_retired_edition_in_published
@published_edition = FactoryBot.create(
:campaign_edition,
state: "published",
)
visit edition_path(@published_edition)
end

def visit_old_edition_of_published_edition
published_edition = FactoryBot.create(
:edition,
panopticon_id: FactoryBot.create(
:artefact,
slug: "can-i-get-a-driving-licence",
).id,
state: "published",
sibling_in_progress: 2,
)
FactoryBot.create(
:edition,
panopticon_id: published_edition.artefact.id,
state: "draft",
version_number: 2,
change_note: "The change note",
)
visit edition_path(published_edition)
end
end

0 comments on commit df13c6e

Please sign in to comment.