diff --git a/lib/tasks/publishing_api.rake b/lib/tasks/publishing_api.rake index 8be5b3076..a689556a7 100644 --- a/lib/tasks/publishing_api.rake +++ b/lib/tasks/publishing_api.rake @@ -84,4 +84,36 @@ namespace :publishing_api do ) puts "Links patched for root page..." end + + desc "Update redirect for an archived tag" + task :update_redirect, %i[content_id new_redirect_path] => :environment do |_task, args| + new_redirect_path = args[:new_redirect_path] + unless new_redirect_path.present? && new_redirect_path.starts_with?("/") + raise "new_redirect_path is missing or invalid" + end + + if Services.content_store.content_item(new_redirect_path) + tag = Tag.find_by(content_id: args[:content_id]) + + raise "No tag can be found for that content id" if tag.blank? + + raise "This task can only be used for archived topics" unless tag.state == "archived" && tag.type == "Topic" + + puts "Updating redirect for #{tag.title}" + puts "From: '#{tag.redirect_routes.pluck(:to_base_path).uniq.first}'" + puts "To: '#{new_redirect_path}'" + + redirects = tag.redirect_routes + + redirects.each do |redirect| + redirect.update!(to_base_path: new_redirect_path) + end + + tag.reload + presenter = ArchivedTagPresenter.new(tag) + ContentItemPublisher.new(presenter).send_to_publishing_api + + puts "Task complete" + end + end end diff --git a/spec/lib/tasks/publishing_api_spec.rb b/spec/lib/tasks/publishing_api_spec.rb index a31495444..1e7198c57 100644 --- a/spec/lib/tasks/publishing_api_spec.rb +++ b/spec/lib/tasks/publishing_api_spec.rb @@ -1,5 +1,6 @@ require "rails_helper" require "gds_api/publishing_api/special_route_publisher" +require "gds_api/test_helpers/content_store" RSpec.describe "rake publishing_api:publish_special_route", type: :task do before do @@ -21,3 +22,78 @@ assert_publishing_api_publish("bb986a97-3b8c-4b1a-89bf-2a9f46be9747") end end + +RSpec.describe "rake publishing_api:update_redirect", type: :task do + include GdsApi::TestHelpers::ContentStore + include GdsApi::TestHelpers::ContentItemHelpers + + before do + Rake::Task["publishing_api:update_redirect"].reenable + stub_any_publishing_api_put_content + stub_any_publishing_api_publish + end + + context "when correct args are passed in" do + let(:redirect_url) { "/i-am-the-redirect" } + let(:content_id) { "i123" } + + it "updates the redirect for an archived tag" do + stub_content_store_has_item(redirect_url) + topic = create(:topic, :archived, content_id:) + create(:redirect_route, from_base_path: topic.base_path, tag: topic) + + Rake::Task["publishing_api:update_redirect"].invoke(content_id, redirect_url) + + assert_publishing_api_put_content( + content_id, + request_json_includes( + "base_path" => topic.base_path, + "schema_name" => "redirect", + "redirects" => [ + { + "path" => topic.base_path, + "destination" => redirect_url, + "type" => "exact", + }, + ], + ), + ) + assert_publishing_api_publish(content_id) + end + end + + context "when invalid args are passed in" do + let(:invalid_redirect_url) { "/i-contain-a-typo" } + let(:valid_redirect_url) { "/i-am-the-redirect" } + + let(:archived_content_id) { "i123" } + let(:published_content_id) { "abce1" } + + it "raises an error if no content item lives at the provided redirect_url" do + stub_content_store_does_not_have_item(invalid_redirect_url) + + archived_topic = create(:topic, :archived, content_id: archived_content_id) + create(:redirect_route, from_base_path: archived_topic.base_path, tag: archived_topic) + + expect { Rake::Task["publishing_api:update_redirect"].invoke(archived_content_id, invalid_redirect_url) }.to raise_error(GdsApi::ContentStore::ItemNotFound) + end + + it "raises an error if we attempt to update the url of a published tag" do + stub_content_store_has_item(valid_redirect_url) + + create(:topic, content_id: published_content_id) + expected_message = "This task can only be used for archived topics" + + expect { Rake::Task["publishing_api:update_redirect"].invoke(published_content_id, valid_redirect_url) }.to raise_error(expected_message) + end + + it "raises an error if we attempt to update the url of a tag that is not a Topic" do + stub_content_store_has_item(valid_redirect_url) + + create(:mainstream_browse_page, content_id: published_content_id) + expected_message = "This task can only be used for archived topics" + + expect { Rake::Task["publishing_api:update_redirect"].invoke(published_content_id, valid_redirect_url) }.to raise_error(expected_message) + end + end +end