Skip to content

Commit

Permalink
Allow users to bulk republish by organisation
Browse files Browse the repository at this point in the history
This adds a page where users can enter an organisation slug, followed by
a page where users confirm that they want all documents associated with
that organisation to be republished. Users are then redirected back to
the index with a flashed confirmation message
  • Loading branch information
yndajas committed Jun 14, 2024
1 parent cca0972 commit 78d4c62
Show file tree
Hide file tree
Showing 8 changed files with 211 additions and 7 deletions.
49 changes: 47 additions & 2 deletions app/controllers/admin/bulk_republishing_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,58 @@ def republish
end
end

def new_documents_by_organisation; end

def search_documents_by_organisation
@organisation = Organisation.find_by(slug: params[:organisation_slug])

unless @organisation
flash[:alert] = "Organisation with slug '#{params[:organisation_slug]}' not found"
return redirect_to(admin_bulk_republishing_documents_by_organisation_new_path)
end

redirect_to(admin_bulk_republishing_documents_by_organisation_confirm_path(params[:organisation_slug]))
end

def confirm_documents_by_organisation
unless @organisation&.slug == params[:organisation_slug]
@organisation = Organisation.find_by(slug: params[:organisation_slug])
render "admin/errors/not_found", status: :not_found unless @organisation
end

@bulk_content_type_metadata = bulk_content_type_metadata.fetch(:all_documents_by_organisation)
@republishing_event = RepublishingEvent.new
end

def republish_documents_by_organisation
unless @organisation&.slug == params[:organisation_slug]
@organisation = Organisation.find_by(slug: params[:organisation_slug])
return render "admin/errors/not_found", status: :not_found unless @organisation
end

bulk_content_type_key = :all_documents_by_organisation
@bulk_content_type_metadata = bulk_content_type_metadata.fetch(bulk_content_type_key)
action = "#{@bulk_content_type_metadata[:name].upcase_first} '#{@organisation.name}' have been queued for republishing"
bulk_content_type_value = RepublishingEvent.bulk_content_types.fetch(bulk_content_type_key)
@republishing_event = build_republishing_event(action:, bulk_content_type: bulk_content_type_value, organisation_id: @organisation.id)

if @republishing_event.save
@bulk_content_type_metadata[:republish_method].call(@organisation)

flash[:notice] = action
redirect_to(admin_republishing_index_path)
else
render "confirm_documents_by_organisation"
end
end

private

def enforce_permissions!
enforce_permission!(:administer, :republish_content)
end

def build_republishing_event(action:, bulk_content_type:)
RepublishingEvent.new(user: current_user, reason: params.fetch(:reason), action:, bulk_content_type:, bulk: true)
def build_republishing_event(action:, bulk_content_type:, organisation_id: nil)
RepublishingEvent.new(user: current_user, reason: params.fetch(:reason), action:, bulk_content_type:, bulk: true, organisation_id:)
end
end
8 changes: 7 additions & 1 deletion app/helpers/admin/republishing_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ def bulk_content_type_metadata
confirmation_path: admin_bulk_republishing_confirm_path("all-published-organisation-about-us-pages"),
republish_method: -> { BulkRepublisher.new.republish_all_published_organisation_about_us_pages },
},
all_documents_by_organisation: {
id: "all-documents-by-organisation",
name: "all documents by organisation",
new_path: admin_bulk_republishing_documents_by_organisation_new_path,
republish_method: ->(organisation) { BulkRepublisher.new.republish_all_documents_by_organisation(organisation) },
},
}
end

Expand All @@ -68,7 +74,7 @@ def republishing_index_bulk_republishing_rows
},
{
text: link_to(sanitize("Republish #{tag.span(content_type[:name], class: 'govuk-visually-hidden')}"),
content_type[:confirmation_path],
content_type[:new_path] || content_type[:confirmation_path],
id: content_type[:id],
class: "govuk-link"),
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<% content_for :page_title, "Republish #{@bulk_content_type_metadata[:name]} '#{@organisation.name}'" %>
<% content_for :title, "Are you sure you want to republish #{@bulk_content_type_metadata[:name]} '#{@organisation.name}'?" %>
<% content_for :title_margin_bottom, 6 %>
<% content_for :error_summary, render(Admin::ErrorSummaryComponent.new(object: @republishing_event)) %>

<div class="govuk-grid-row">
<section class="govuk-grid-column-two-thirds">
<p class="govuk-body govuk-!-margin-bottom-7">
This will queue all documents associated with the organisation <%= link_to @organisation.name, @organisation.public_url, { class: "govuk-link" } %> to be republished.
</p>
<%= render partial: "shared/republishing_form", locals: {
republishing_event: @republishing_event,
republishing_path: admin_bulk_republishing_documents_by_organisation_republish_path(@organisation.slug),
} %>
</section>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<% content_for :page_title, "Republish all by organisation" %>
<% content_for :title, "What organisation's documents would you like to republish?" %>
<% content_for :title_margin_bottom, 6 %>

<div class="govuk-grid-row">
<section class="govuk-grid-column-two-thirds">
<%= form_with(url: admin_bulk_republishing_documents_by_organisation_search_path, method: :post) do %>
<%= render "govuk_publishing_components/components/input", {
label: {
text: "Enter the slug for the organisation",
},
hint: "You can get the slug from the last part of the public URL - everything after '/government/organisations/'.",
name: "organisation_slug",
} %>
<%= render "govuk_publishing_components/components/button", {
text: "Continue",
} %>
<% end %>
</section>
</div>
6 changes: 6 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ def redirect(path, options = { prefix: Whitehall.router_prefix })
post "/:document_slug/republish" => "republishing#republish_document", as: :republishing_document_republish
end
scope :bulk do
scope "documents-by-organisation" do
get "/new" => "bulk_republishing#new_documents_by_organisation", as: :bulk_republishing_documents_by_organisation_new
post "/search" => "bulk_republishing#search_documents_by_organisation", as: :bulk_republishing_documents_by_organisation_search
get "/:organisation_slug/confirm" => "bulk_republishing#confirm_documents_by_organisation", as: :bulk_republishing_documents_by_organisation_confirm
post "/:organisation_slug/republish" => "bulk_republishing#republish_documents_by_organisation", as: :bulk_republishing_documents_by_organisation_republish
end
get "/:bulk_content_type/confirm" => "bulk_republishing#confirm", as: :bulk_republishing_confirm
post "/:bulk_content_type/republish" => "bulk_republishing#republish", as: :bulk_republishing_republish
end
Expand Down
105 changes: 105 additions & 0 deletions test/functional/admin/bulk_republishing_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,109 @@ class Admin::BulkRepublishingControllerTest < ActionController::TestCase
post :republish, params: { bulk_content_type: "all-published-organisation-about-us-pages", reason: "this needs republishing" }
assert_response :forbidden
end

test "GDS Admin users should be able to GET :new_documents_by_organisation" do
get :new_documents_by_organisation
assert_response :ok
end

test "Non-GDS Admin users should not be able to GET :new_documents_by_organisation" do
login_as :writer

get :new_documents_by_organisation
assert_response :forbidden
end

test "GDS Admin users should be able to POST :search_documents_by_organisation with an existing organisation slug" do
create(:organisation, slug: "an-existing-organisation")

post :search_documents_by_organisation, params: { organisation_slug: "an-existing-organisation" }

assert_redirected_to admin_bulk_republishing_documents_by_organisation_confirm_path("an-existing-organisation")
end

test "GDS Admin users should be redirected back to :new_documents_by_organisation when trying to POST :search_documents_by_organisation with a nonexistent organisation slug" do
post :search_documents_by_organisation, params: { organisation_slug: "not-an-existing-organisation" }

assert_redirected_to admin_bulk_republishing_documents_by_organisation_new_path
assert_equal "Organisation with slug 'not-an-existing-organisation' not found", flash[:alert]
end

test "Non-GDS Admin users should not be able to POST :search_documents_by_organisation" do
create(:organisation, slug: "an-existing-organisation")

login_as :writer

post :search_documents_by_organisation, params: { organisation_slug: "an-existing-organisation" }
assert_response :forbidden
end

test "GDS Admin users should be able to GET :confirm_documents_by_organisation with an existing organisation slug" do
create(:organisation, slug: "an-existing-organisation")

get :confirm_documents_by_organisation, params: { organisation_slug: "an-existing-organisation" }
assert_response :ok
end

test "GDS Admin users should see a 404 page when trying to GET :confirm_documents_by_organisation with a nonexistent organisation slug" do
get :confirm_documents_by_organisation, params: { organisation_slug: "not-an-existing-organisation" }
assert_response :not_found
end

test "Non-GDS Admin users should not be able to access :confirm_documents_by_organisation" do
create(:organisation, slug: "an-existing-organisation")

login_as :writer

get :confirm_documents_by_organisation, params: { organisation_slug: "organisation" }
assert_response :forbidden
end

test "GDS Admin users should be able to POST :republish_documents_by_organisation with an existing organisation slug, creating a RepublishingEvent for the current user" do
organisation = create(:organisation, id: "1234", slug: "an-existing-organisation", name: "An Existing Organisation")

BulkRepublisher.any_instance.expects(:republish_all_documents_by_organisation).with(organisation).once

post :republish_documents_by_organisation, params: { organisation_slug: "an-existing-organisation", reason: "this needs republishing" }

newly_created_event = RepublishingEvent.last
assert_equal current_user, newly_created_event.user
assert_equal "this needs republishing", newly_created_event.reason
assert_equal "All documents by organisation 'An Existing Organisation' have been queued for republishing", newly_created_event.action
assert_equal true, newly_created_event.bulk
assert_equal "all_documents_by_organisation", newly_created_event.bulk_content_type
assert_equal "1234", newly_created_event.organisation_id

assert_redirected_to admin_republishing_index_path
assert_equal "All documents by organisation 'An Existing Organisation' have been queued for republishing", flash[:notice]
end

test "GDS Admin users should encounter an error on POST :republish_documents_by_organisation without a `reason` and be sent back to the confirm page" do
organisation = create(:organisation, slug: "an-existing-organisation", name: "An Existing Organisation")

BulkRepublisher.any_instance.expects(:republish_all_documents_by_organisation).with(organisation).never

post :republish_documents_by_organisation, params: { organisation_slug: "an-existing-organisation", reason: "" }

assert_equal ["Reason can't be blank"], assigns(:republishing_event).errors.full_messages
assert_template "confirm_documents_by_organisation"
end

test "GDS Admin users should see a 404 page when trying to POST :republish_documents_by_organisation with a nonexistent organisation slug" do
BulkRepublisher.any_instance.expects(:republish_all_documents_by_organisation).never

post :republish_documents_by_organisation, params: { organisation_slug: "not-an-existing-organisation" }
assert_response :not_found
end

test "Non-GDS Admin users should not be able to POST :republish_documents_by_organisation" do
organisation = create(:organisation, slug: "an-existing-organisation", name: "An Existing Organisation")

BulkRepublisher.any_instance.expects(:republish_all_documents_by_organisation).with(organisation).never

login_as :writer

post :republish_documents_by_organisation, params: { organisation_slug: "an-existing-organisation" }
assert_response :forbidden
end
end
1 change: 1 addition & 0 deletions test/functional/admin/republishing_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class Admin::RepublishingControllerTest < ActionController::TestCase
assert_select ".govuk-table:nth-of-type(3) .govuk-table__body .govuk-table__row:nth-child(4) .govuk-table__cell:nth-child(2) a[href='/government/admin/republishing/bulk/all-documents-with-publicly-visible-editions-with-attachments/confirm']", text: "Republish all documents with publicly-visible editions with attachments"
assert_select ".govuk-table:nth-of-type(3) .govuk-table__body .govuk-table__row:nth-child(5) .govuk-table__cell:nth-child(2) a[href='/government/admin/republishing/bulk/all-documents-with-publicly-visible-editions-with-html-attachments/confirm']", text: "Republish all documents with publicly-visible editions with HTML attachments"
assert_select ".govuk-table:nth-of-type(3) .govuk-table__body .govuk-table__row:nth-child(6) .govuk-table__cell:nth-child(2) a[href='/government/admin/republishing/bulk/all-published-organisation-about-us-pages/confirm']", text: "Republish all published organisation 'About us' pages"
assert_select ".govuk-table:nth-of-type(3) .govuk-table__body .govuk-table__row:nth-child(7) .govuk-table__cell:nth-child(2) a[href='/government/admin/republishing/bulk/documents-by-organisation/new']", text: "Republish all documents by organisation"

assert_response :ok
end
Expand Down
13 changes: 9 additions & 4 deletions test/unit/app/helpers/admin/republishing_helper_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,16 @@ class Admin::RepublishingHelperTest < ActionView::TestCase
assert_equal first_bulk_content_type, "All documents"
end

test "#republishing_index_bulk_republishing_rows creates a link to the specific bulk republishing confirmation page" do
first_link = republishing_index_bulk_republishing_rows.first[1][:text]
expected_link = '<a id="all-documents" class="govuk-link" href="/government/admin/republishing/bulk/all-documents/confirm">Republish <span class="govuk-visually-hidden">all documents</span></a>'
# this can be removed when rebased on the by type branch
test "#republishing_index_bulk_republishing_rows creates a link to the new page for content types that require extra input" do
_all_documents_by_organisation_description, all_documents_by_organisation_action_link = republishing_index_bulk_republishing_rows.find do |row|
description_column = row[0]
description_column == "All documents by organisation"
end

assert_equal first_link, expected_link
expected_link = '<a id="all-documents-by-organisation" class="govuk-link" href="/government/admin/republishing/bulk/documents-by-organisation/new">Republish <span class="govuk-visually-hidden">all documents by organisation</span></a>'

assert_equal all_documents_by_organisation_action_link, expected_link
end
end

Expand Down

0 comments on commit 78d4c62

Please sign in to comment.