Skip to content

Commit

Permalink
Merge pull request #9447 from alphagov/550-cache-busting
Browse files Browse the repository at this point in the history
content-modelling/550 cache busting
  • Loading branch information
Harriethw authored Sep 19, 2024
2 parents b720a48 + c5b9360 commit 084c94b
Show file tree
Hide file tree
Showing 8 changed files with 292 additions and 1 deletion.
2 changes: 1 addition & 1 deletion db/seeds.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
gds_organisation_id = "af07d5a5-df63-4ddc-9383-6a666845ebe9"
User.create!(
name: "Test user",
permissions: ["signin", "GDS Admin", "GDS Editor", "Managing Editor", "Export data"],
permissions: ["signin", "GDS Admin", "GDS Editor", "Managing Editor", "Export data", "Sidekiq Admin"],
organisation_content_id: gds_organisation_id,
organisation_slug: "government-digital-service",
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def publish_with_rollback(schema:, title:, details:)
publish_publishing_api_edition(content_id:)
update_content_block_document_with_live_edition(content_block_edition)
content_block_edition.public_send(:publish!)
remove_cache_for_host_content(content_block_edition:)
rescue PublishingFailureError => e
discard_publishing_api_edition(content_id:)
raise e
Expand Down Expand Up @@ -51,6 +52,15 @@ def update_content_block_document(new_content_block_edition:, update_document_pa

private

def remove_cache_for_host_content(content_block_edition:)
host_content_items = ContentObjectStore::GetHostContentItems.by_embedded_document(
content_block_document: content_block_edition.document,
)
host_content_items.each do |host_content_item|
ContentObjectStore::PublishIntentWorker.perform_async(host_content_item.base_path, Time.zone.now.to_s)
end
end

def create_publishing_api_edition(content_id:, schema_id:, title:, details:, links:)
Services.publishing_api.put_content(content_id, {
schema_name: schema_id,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
require "sidekiq/api"

module ContentObjectStore
class PublishIntentWorker < WorkerBase
sidekiq_options queue: :content_block_publishing

def perform(base_path, publish_timestamp)
publish_timestamp = Time.zone.parse(publish_timestamp)
publish_intent = PublishingApi::PublishIntentPresenter.new(base_path, publish_timestamp)

Services.publishing_api.put_intent(base_path, publish_intent.as_json)
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ class ContentObjectStore::ContentBlock::WorkflowTest < ActionDispatch::Integrati
"major",
]

fake_embedded_content_response = GdsApi::Response.new(stub("http_response",
code: 200, body: {
"total" => 0,
"results" => [],
}.to_json))

publishing_api_mock.expect :get_content_by_embedded_document, fake_embedded_content_response, [@content_id]

Services.stub :publishing_api, publishing_api_mock do
post content_object_store.publish_content_object_store_content_block_edition_path(id: edition.id), params: {
id: edition.id,
Expand All @@ -67,6 +75,86 @@ class ContentObjectStore::ContentBlock::WorkflowTest < ActionDispatch::Integrati
end
end

test "#publish creates publish intents for all host documents" do
details = {
foo: "Foo text",
bar: "Bar text",
}

organisation = create(:organisation)
document = create(:content_block_document, :email_address, content_id: @content_id, title: "Some Title")
edition = create(:content_block_edition, document:, details:, organisation:)

fake_put_content_response = GdsApi::Response.new(
stub("http_response", code: 200, body: {}),
)
fake_publish_content_response = GdsApi::Response.new(
stub("http_response", code: 200, body: {}),
)

publishing_api_mock = Minitest::Mock.new
publishing_api_mock.expect :put_content, fake_put_content_response, [
@content_id,
{
schema_name: "content_block_type",
document_type: "content_block_type",
publishing_app: "whitehall",
title: "Some Title",
details: {
"foo" => "Foo text",
"bar" => "Bar text",
},
links: {
primary_publishing_organisation: [organisation.content_id],
},
},
]
publishing_api_mock.expect :publish, fake_publish_content_response, [
@content_id,
"major",
]

host_content =
[
{
"title" => "Content title",
"document_type" => "document",
"base_path" => "/host-document",
"content_id" => "1234abc",
"primary_publishing_organisation" => {
"content_id" => "456abc",
"title" => "Organisation",
"base_path" => "/organisation/org",
},
},
]

fake_embedded_content_response = GdsApi::Response.new(stub("http_response",
code: 200, body: {
"total" => 1,
"results" => host_content,
}.to_json))

publishing_api_mock.expect :get_content_by_embedded_document, fake_embedded_content_response, [@content_id]

publishing_api_mock.expect :put_intent, {}, ["/host-document",
{
publish_time: Time.zone.now,
publishing_app: "whitehall",
rendering_app: "government-frontend",
routes: [{ path: "/host-document", type: "exact" }],
}]

Sidekiq::Testing.inline! do
Services.stub :publishing_api, publishing_api_mock do
post content_object_store.publish_content_object_store_content_block_edition_path(id: edition.id), params: {
id: edition.id,
}
publishing_api_mock.verify
end
end
end

test "#update schedules the publication of an edition" do
organisation = create(:organisation)

Expand Down Expand Up @@ -145,6 +233,99 @@ class ContentObjectStore::ContentBlock::WorkflowTest < ActionDispatch::Integrati
assert_not_equal first_job_id, second_job_id
end
end

test "#update creates publish intents for host content" do
details = {
foo: "Foo text",
bar: "Bar text",
}

organisation = create(:organisation)
document = create(:content_block_document, :email_address, content_id: @content_id, title: "Some Title")
edition = create(:content_block_edition, document:, details:, organisation:)

fake_put_content_response = GdsApi::Response.new(
stub("http_response", code: 200, body: {}),
)
fake_publish_content_response = GdsApi::Response.new(
stub("http_response", code: 200, body: {}),
)

publishing_api_mock = Minitest::Mock.new
publishing_api_mock.expect :put_content, fake_put_content_response, [
@content_id,
{
schema_name: "content_block_type",
document_type: "content_block_type",
publishing_app: "whitehall",
title: "Another email",
details: {
"foo" => "[email protected]",
"bar" => "edited",
},
links: {
primary_publishing_organisation: [organisation.content_id],
},
},
]
publishing_api_mock.expect :publish, fake_publish_content_response, [
@content_id,
"major",
]

host_content =
[
{
"title" => "Content title",
"document_type" => "document",
"base_path" => "/host-document",
"content_id" => "1234abc",
"primary_publishing_organisation" => {
"content_id" => "456abc",
"title" => "Organisation",
"base_path" => "/organisation/org",
},
},
]

fake_embedded_content_response = GdsApi::Response.new(stub("http_response",
code: 200, body: {
"total" => 1,
"results" => host_content,
}.to_json))

publishing_api_mock.expect :get_content_by_embedded_document, fake_embedded_content_response, [@content_id]

publishing_api_mock.expect :put_intent, {}, ["/host-document",
{
publish_time: Time.zone.now,
publishing_app: "whitehall",
rendering_app: "government-frontend",
routes: [{ path: "/host-document", type: "exact" }],
}]

Sidekiq::Testing.inline! do
Services.stub :publishing_api, publishing_api_mock do
patch content_object_store.content_object_store_content_block_edition_path(edition), params: {
id: edition.id,
schedule_publishing: "schedule",
scheduled_at: {
"scheduled_publication(3i)": "2",
"scheduled_publication(2i)": "9",
"scheduled_publication(1i)": "2024",
"scheduled_publication(4i)": "10",
"scheduled_publication(5i)": "05",
},
"content_block/edition": {
creator: "1",
details: { foo: "[email protected]", bar: "edited" },
document_attributes: { block_type: "email_address", title: "Another email" },
organisation_id: organisation.id,
},
}
end
end
end
end

def stub_request_for_schema(block_type)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ class ContentObjectStore::PublishEditionServiceTest < ActiveSupport::TestCase
ContentObjectStore::ContentBlock::Schema.stubs(:find_by_block_type)
.returns(schema)
@organisation = create(:organisation)

stub_publishing_api_has_embedded_content(content_id:, total: 0, results: [])
end

test "returns a ContentBlockEdition" do
Expand Down Expand Up @@ -57,6 +59,13 @@ class ContentObjectStore::PublishEditionServiceTest < ActiveSupport::TestCase
"major",
]

fake_embedded_content_response = GdsApi::Response.new(stub("http_response",
code: 200, body: { "content_id" => "1234abc",
"total" => 0,
"results" => [] }.to_json))

publishing_api_mock.expect :get_content_by_embedded_document, fake_embedded_content_response, [content_id]

Services.stub :publishing_api, publishing_api_mock do
ContentObjectStore::PublishEditionService.new(schema).call(edition)

Expand All @@ -66,6 +75,29 @@ class ContentObjectStore::PublishEditionServiceTest < ActiveSupport::TestCase
end
end

test "it queues publishing intents for host content on the Publishing API" do
host_content =
[
{
"title" => "Content title",
"document_type" => "document",
"base_path" => "/host-document",
"content_id" => "1234abc",
"primary_publishing_organisation" => {
"content_id" => "456abc",
"title" => "Organisation",
"base_path" => "/organisation/org",
},
},
]

stub_publishing_api_has_embedded_content(content_id:, total: 0, results: host_content)

ContentObjectStore::PublishIntentWorker.expects(:perform_async).with("/host-document", Time.zone.now.to_s).once

ContentObjectStore::PublishEditionService.new(schema).call(edition)
end

test "if the publishing API request fails, the Whitehall ContentBlockEdition and ContentBlockDocument are rolled back" do
exception = GdsApi::HTTPErrorResponse.new(
422,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ class ContentObjectStore::UpdateEditionServiceTest < ActiveSupport::TestCase
document: create(:content_block_document, :email_address, content_id:),
details: { "foo" => "Foo text", "bar" => "Bar text" },
organisation: create(:organisation))

stub_publishing_api_has_embedded_content(content_id:, total: 0, results: [])
end

describe "#call" do
Expand Down Expand Up @@ -125,6 +127,13 @@ class ContentObjectStore::UpdateEditionServiceTest < ActiveSupport::TestCase
"major",
]

fake_embedded_content_response = GdsApi::Response.new(stub("http_response",
code: 200, body: { "content_id" => "1234abc",
"total" => 0,
"results" => [] }.to_json))

publishing_api_mock.expect :get_content_by_embedded_document, fake_embedded_content_response, [content_id]

Services.stub :publishing_api, publishing_api_mock do
ContentObjectStore::UpdateEditionService
.new(schema, @original_content_block_edition)
Expand Down Expand Up @@ -218,6 +227,13 @@ class ContentObjectStore::UpdateEditionServiceTest < ActiveSupport::TestCase
"major",
]

fake_embedded_content_response = GdsApi::Response.new(stub("http_response",
code: 200, body: { "content_id" => "1234abc",
"total" => 0,
"results" => [] }.to_json))

publishing_api_mock.expect :get_content_by_embedded_document, fake_embedded_content_response, [content_id]

Services.stub :publishing_api, publishing_api_mock do
ContentObjectStore::UpdateEditionService
.new(schema, @original_content_block_edition)
Expand All @@ -227,6 +243,31 @@ class ContentObjectStore::UpdateEditionServiceTest < ActiveSupport::TestCase
end
end

test "it queues publishing intents for dependent content" do
dependent_content =
[
{
"title" => "Content title",
"document_type" => "document",
"base_path" => "/host-document",
"content_id" => "1234abc",
"primary_publishing_organisation" => {
"content_id" => "456abc",
"title" => "Organisation",
"base_path" => "/organisation/org",
},
},
]

stub_publishing_api_has_embedded_content(content_id:, total: 0, results: dependent_content)

ContentObjectStore::PublishIntentWorker.expects(:perform_async).with("/host-document", Time.zone.now.to_s).once

ContentObjectStore::UpdateEditionService
.new(schema, @original_content_block_edition)
.call(edition_params)
end

test "if the publishing API request fails, the Whitehall ContentBlockEdition and ContentBlockDocument are rolled back" do
exception = GdsApi::HTTPErrorResponse.new(
422,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
require "test_helper"

class ContentObjectStore::PublishIntentWorkerTest < ActiveSupport::TestCase
test "#perform adds a publishing intent to the Publishing API" do
base_path = "/base-path"
timestamp = Time.zone.now.to_s
publish_intent = { foo: "bar" }

PublishingApi::PublishIntentPresenter.expects(:new).with(base_path, timestamp).once.returns(publish_intent)
Services.publishing_api.expects(:put_intent).once.with(base_path, publish_intent.as_json)
ContentObjectStore::PublishIntentWorker.new.perform(base_path, timestamp)
end
end

0 comments on commit 084c94b

Please sign in to comment.