Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/models/edition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ class Edition < ApplicationRecord
POST_PUBLICATION_STATES = %w[published superseded withdrawn unpublished].freeze
PUBLICLY_VISIBLE_STATES = %w[published withdrawn].freeze

before_create :set_auth_bypass_id
before_save :set_public_timestamp
after_validation :update_revalidated_at, if: -> { validation_context == :publish }
after_create :update_document_edition_references
Expand Down Expand Up @@ -188,7 +187,8 @@ def create_draft(user, allow_creating_draft_from_deleted_edition: false)
change_note
minor_change
force_published
scheduled_publication]
scheduled_publication
auth_bypass_id]
draft_attributes = attributes.except(*ignorable_attribute_keys)
.merge("state" => "draft", "creator" => user, "previously_published" => previously_published)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class Admin::Editions::Show::PreviewComponentTest < ViewComponent::TestCase
end

test "renders the copy link, regenerate and delete controls when the edition has a preview token" do
edition = build_stubbed(:publication, document: @document)
edition = build_stubbed(:publication, :with_auth_bypass_id, document: @document)

render_inline(Admin::Editions::Show::PreviewComponent.new(edition:))

Expand Down
5 changes: 4 additions & 1 deletion test/factories/editions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
change_note { "change-note" }
summary { "edition-summary" }
previously_published { false }
auth_bypass_id { SecureRandom.uuid }

trait(:with_auth_bypass_id) do
auth_bypass_id { SecureRandom.uuid }
end

trait(:with_organisations) do
transient do
Expand Down
4 changes: 2 additions & 2 deletions test/functional/admin/edition_images_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -700,7 +700,7 @@ class Admin::EditionImagesControllerTest < ActionController::TestCase

test "POST :create passes the edition's auth_bypass_id to the new image assets" do
login_authorised_user
edition = create(:draft_fatality_notice)
edition = create(:draft_fatality_notice, :with_auth_bypass_id)
file = upload_fixture("images/960x640_jpeg.jpg")

AssetManagerCreateAssetJob
Expand All @@ -713,7 +713,7 @@ class Admin::EditionImagesControllerTest < ActionController::TestCase
test "POST :update passes the edition's auth_bypass_id to the cropped image assets" do
login_authorised_user
image = build(:image)
edition = create(:draft_fatality_notice, images: [image])
edition = create(:draft_fatality_notice, :with_auth_bypass_id, images: [image])

AssetManagerCreateAssetJob
.expects(:perform_async)
Expand Down
6 changes: 2 additions & 4 deletions test/functional/admin/editions_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -369,20 +369,18 @@ class Admin::EditionsControllerTest < ActionController::TestCase
assert_not flash["html_safe"]
end

test "update_bypass_id generates a new preview token and redirects with a notice" do
test "update_bypass_id generates a preview token and redirects with a notice" do
edition = create(:draft_publication)
previous_auth_bypass_id = edition.auth_bypass_id

patch :update_bypass_id, params: { id: edition }

assert_not_nil edition.reload.auth_bypass_id
assert_not_equal previous_auth_bypass_id, edition.auth_bypass_id
assert_redirected_to admin_publication_path(edition)
assert_equal "New document preview link generated", flash[:notice]
end

test "destroy_bypass_id deletes the preview token and redirects with a notice" do
edition = create(:draft_publication)
edition = create(:draft_publication, :with_auth_bypass_id)
assert_not_nil edition.auth_bypass_id

delete :destroy_bypass_id, params: { id: edition }
Expand Down
8 changes: 7 additions & 1 deletion test/functional/admin/file_attachments_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,13 @@ def valid_file_attachment_params
attachment = create(:file_attachment, attachable: @edition)
model_type = attachment.attachment_data.class.to_s

AssetManagerCreateAssetJob.expects(:perform_async).with(anything, has_entries("assetable_id" => kind_of(Integer), "asset_variant" => Asset.variants[:original], "assetable_type" => model_type), anything, @edition.class.to_s, @edition.id, [@edition.auth_bypass_id])
AssetManagerCreateAssetJob.expects(:perform_async).with do |_path, asset_params, _draft, attachable_class, attachable_id, _auth_bypass_ids|
asset_params["assetable_id"].is_a?(Integer) &&
asset_params["asset_variant"] == Asset.variants[:original] &&
asset_params["assetable_type"] == model_type &&
attachable_class == @edition.class.to_s &&
attachable_id == @edition.id
end

put :update,
params: {
Expand Down
8 changes: 7 additions & 1 deletion test/functional/admin/uploads_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,13 @@ def post_to_upload_files(*files)
test "POST :create triggers a job to be queued to store the attachments in Asset Manager" do
model_type = AttachmentData.to_s

AssetManagerCreateAssetJob.expects(:perform_async).with(anything, has_entries("assetable_id" => kind_of(Integer), "asset_variant" => Asset.variants[:original], "assetable_type" => model_type), anything, @edition.class.to_s, @edition.id, [@edition.auth_bypass_id]).twice
AssetManagerCreateAssetJob.expects(:perform_async).with { |_path, asset_params, _draft, attachable_class, attachable_id, _auth_bypass_ids|
asset_params["assetable_id"].is_a?(Integer) &&
asset_params["asset_variant"] == Asset.variants[:original] &&
asset_params["assetable_type"] == model_type &&
attachable_class == @edition.class.to_s &&
attachable_id == @edition.id
}.twice

post :create, params: { edition_id: @edition, upload: valid_create_params }
end
Expand Down
194 changes: 71 additions & 123 deletions test/integration/asset_access_options_integration_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,57 +23,83 @@ class AssetAccessOptionsIntegrationTest < ActionDispatch::IntegrationTest
stub_asset(asset_manager_id, draft: true)
end

context "given a draft document with file attachment" do
let(:edition) { create(:detailed_guide, organisations: [organisation]) }

context "forwarding the preview token to Asset Manager" do
before do
add_file_attachment_with_asset("sample.docx", to: edition)
add_file_attachment_with_asset("logo.png", to: edition)
edition.save!
end

context "when document is marked as access limited in Whitehall" do
context "when the draft has a preview token" do
let(:edition) { create(:detailed_guide, :with_auth_bypass_id) }

it "sends the attachment with the document's auth_bypass_id" do
Services.asset_manager.expects(:create_asset).at_least_once.with(
has_entries(auth_bypass_ids: [edition.auth_bypass_id]),
).returns(asset_manager_response)

AssetManagerCreateAssetJob.drain
end
end

context "when the draft has no preview token" do
let(:edition) { create(:detailed_guide) }

it "sends the attachment with an empty auth_bypass_ids" do
Services.asset_manager.expects(:create_asset).at_least_once.with(
has_entries(auth_bypass_ids: []),
).returns(asset_manager_response)

AssetManagerCreateAssetJob.drain
end
end
end

context "applying access limiting to a draft's attachments" do
context "when a draft is marked as access limited" do
let(:edition) { create(:detailed_guide, organisations: [organisation]) }

before do
add_file_attachment_with_asset("sample.docx", to: edition)
edition.save!
visit edit_admin_edition_path(edition)
check "Limit access"
click_button "Save"
assert_text "Your document has been saved"
end

it "marks attachment as access limited in Asset Manager" do
it "marks the attachment as access limited in Asset Manager" do
Services.asset_manager
.expects(:update_asset)
.at_least_once.with(asset_manager_id, has_entry("access_limited_organisation_ids", [organisation.content_id]))

AssetManagerAttachmentMetadataJob.drain
end
end
end

context "given a draft document with an image attachment" do
let(:edition) { create(:draft_detailed_guide) }
context "when a draft is unmarked as access limited" do
let(:edition) { create(:detailed_guide, organisations: [organisation], access_limiting: "organisations") }

before do
visit admin_edition_path(edition)
click_link "Edit draft"
click_link "Images"
attach_file "images[][image_data_attributes][file]", path_to_attachment("minister-of-funk.960x640.jpg")
click_button "Upload"
end
before do
add_file_attachment_with_asset("sample.docx", to: edition)
edition.save!
visit edit_admin_edition_path(edition)
uncheck "Limit access"
click_button "Save"
assert_text "Your document has been saved"
end

# Note that there is no access limiting applied to non attachments. This is existing behaviour that probably needs changing.
it "sends an image to asset manager with the document's auth_bypass_id" do
Services.asset_manager.expects(:create_asset).at_least_once.with(
has_entry(auth_bypass_ids: [edition.auth_bypass_id]),
).returns(asset_manager_response)
it "unmarks the attachment as access limited in Asset Manager" do
Services.asset_manager
.expects(:update_asset)
.at_least_once.with(asset_manager_id, has_entry("access_limited_organisation_ids", []))

AssetManagerCreateAssetJob.drain
AssetManagerAttachmentMetadataJob.drain
end
end
end

context "given an access-limited draft document" do
let(:edition) { create(:detailed_guide, organisations: [organisation], access_limiting: "organisations") }
context "when an attachment is added to an access-limited draft" do
let(:edition) { create(:detailed_guide, organisations: [organisation], access_limiting: "organisations") }

context "when an attachment is added to the draft document" do
before do
visit admin_edition_path(edition)
click_link "Add attachments"
Expand All @@ -84,46 +110,18 @@ class AssetAccessOptionsIntegrationTest < ActionDispatch::IntegrationTest
assert_text "Attachment 'logo.png' uploaded"
end

it "marks attachment as access limited and sends it with an auth_bypass_id in Asset Manager" do
it "marks the attachment as access limited in Asset Manager" do
Services.asset_manager.expects(:create_asset).with(
has_entries(
access_limited_organisation_ids: [organisation.content_id],
auth_bypass_ids: [edition.auth_bypass_id],
),
has_entries(access_limited_organisation_ids: [organisation.content_id]),
).returns(asset_manager_response)

AssetManagerCreateAssetJob.drain
end
end

context "when an html attachment is added to the draft document" do
let(:edition) { create(:publication, :policy_paper) }

before do
visit admin_edition_path(edition)
click_link "Edit attachments"
click_link "Add new HTML attachment"
fill_in "Title", with: "html-attachment"
fill_in "Body", with: "some html content"
end

it "sends an html attachment to publishing api with its edition's auth_bypass_id" do
Services.publishing_api.expects(:put_content)
.with(anything, has_entries(title: edition.title))
Services.publishing_api.expects(:put_content)
.with(anything, has_entries(title: edition.attachments.first.title))
context "when multiple files are uploaded to an access-limited draft" do
let(:edition) { create(:detailed_guide, organisations: [organisation], access_limiting: "organisations") }

Services.publishing_api.expects(:put_content).at_least_once
.with(anything, has_entries(
title: "html-attachment",
auth_bypass_ids: [edition.auth_bypass_id],
))

click_button "Save"
end
end

context "when uploaded to draft document" do
before do
visit admin_edition_path(edition)
click_link "Add attachments"
Expand All @@ -136,49 +134,24 @@ class AssetAccessOptionsIntegrationTest < ActionDispatch::IntegrationTest
assert find("li", text: "logo.png")
end

it "marks attachment as access limited in Asset Manager" do
it "marks each attachment as access limited in Asset Manager" do
Services.asset_manager
.expects(:create_asset)
.at_least(2)
.with(
has_entries(
access_limited_organisation_ids: [organisation.content_id],
auth_bypass_ids: [edition.auth_bypass_id],
),
has_entries(access_limited_organisation_ids: [organisation.content_id]),
).returns(asset_manager_response)

AssetManagerCreateAssetJob.drain
end
end
end

context "given an access-limited draft document and a file attachment" do
let(:edition) { create(:detailed_guide, organisations: [organisation], access_limiting: "organisations") }

before do
add_file_attachment_with_asset("sample.docx", to: edition)
edition.save!
end
context "when an attachment is replaced on an access-limited draft" do
let(:edition) { create(:detailed_guide, organisations: [organisation], access_limiting: "organisations") }

context "when document is unmarked as access limited in Whitehall" do
before do
visit edit_admin_edition_path(edition)
uncheck "Limit access"
click_button "Save"
assert_text "Your document has been saved"
end

it "unmarks attachment as access limited in Asset Manager" do
Services.asset_manager
.expects(:update_asset)
.at_least_once.with(asset_manager_id, has_entry("access_limited_organisation_ids", []))

AssetManagerAttachmentMetadataJob.drain
end
end

context "when attachment is replaced" do
before do
add_file_attachment_with_asset("sample.docx", to: edition)
edition.save!
visit admin_edition_path(edition)
click_link "Edit attachments"
click_link "Edit"
Expand All @@ -187,25 +160,20 @@ class AssetAccessOptionsIntegrationTest < ActionDispatch::IntegrationTest
assert_text "Attachment 'sample.docx' updated"
end

it "marks replacement attachment as access limited in Asset Manager" do
it "marks the replacement attachment as access limited in Asset Manager" do
Services.asset_manager.stubs(:create_asset).returns(asset_manager_response)
Services.asset_manager.expects(:create_asset).with { |params|
params[:access_limited_organisation_ids] == [organisation.content_id] &&
params[:auth_bypass_ids] == [edition.auth_bypass_id]
}.returns(asset_manager_response)
Services.asset_manager.expects(:create_asset).with { |params| params[:access_limited_organisation_ids] == [organisation.content_id] }.returns(asset_manager_response)

AssetManagerCreateAssetJob.drain
end
end
end

context "given a draft access-limited consultation" do
# the edition has to have same organisation as logged in user, otherwise it's not visible when access_limited = true
let(:edition) { create(:consultation, organisations: [organisation], access_limiting: "organisations") }
let(:outcome_attributes) { FactoryBot.attributes_for(:consultation_outcome) }
let!(:outcome) { edition.create_outcome!(outcome_attributes) }
context "when an attachment is added to an access-limited consultation outcome" do
# the edition has to have same organisation as logged in user, otherwise it's not visible when access_limited = true
let(:edition) { create(:consultation, organisations: [organisation], access_limiting: "organisations") }
let(:outcome_attributes) { FactoryBot.attributes_for(:consultation_outcome) }
let!(:outcome) { edition.create_outcome!(outcome_attributes) }

context "when an attachment is added to the consultation's outcome" do
before do
visit admin_consultation_path(edition)
click_link "Edit draft"
Expand All @@ -217,33 +185,13 @@ class AssetAccessOptionsIntegrationTest < ActionDispatch::IntegrationTest
assert_text "Attachment 'asset-title' uploaded"
end

it "marks attachment as access limited in Asset Manager and sends with the consultation's auth_bypass_id" do
it "marks the attachment as access limited in Asset Manager" do
Services.asset_manager.expects(:create_asset).with(
has_entries(
access_limited_organisation_ids: [organisation.content_id],
auth_bypass_ids: [edition.auth_bypass_id],
),
has_entries(access_limited_organisation_ids: [organisation.content_id]),
).returns(asset_manager_response)
AssetManagerCreateAssetJob.drain
end
end

it "sends a consultation form to asset manager with the consultation's auth_bypass_id" do
visit admin_consultation_path(edition)
click_link "Edit draft"
name_of_form_uploader = "edition[consultation_participation_attributes][consultation_response_form_attributes][consultation_response_form_data_attributes][file]"
fill_in "edition[consultation_participation_attributes][consultation_response_form_attributes][title]", with: "Consultation response form"
attach_file name_of_form_uploader, path_to_attachment("simple.pdf")
click_button "Save"

# Note that there is no access limiting applied to non attachments. This is existing behaviour that probably needs changing.
Services.asset_manager.expects(:create_asset).with { |args|
args[:file].path =~ /simple\.pdf/
args[:auth_bypass_ids] == [edition.auth_bypass_id]
}.returns(asset_manager_response)

AssetManagerCreateAssetJob.drain
end
end

private
Expand Down
Loading