mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
226007daa1
Fixes: #41453 Closes: #41461 Previously when a model had strict loading set to true and then had a relation set strict_loading to false the false wasn't considered when deciding whether to raise/warn about strict loading. Code example: ```ruby class Dog < ActiveRecord::Base self.strict_loading_by_default = true has_many :treats, strict_loading: false end ``` In the example, `dog.treats` would still raise even though `strict_loading` was set to false. This is a bug effecting more than Active Storage which is why I made this PR superceeding #41461. We need to fix this for all applications since the behavior is a little surprising. I took the test from ##41461 and the code suggestion from #41453 with some additions. Co-authored-by: Radamés Roriz <radamesroriz@gmail.com>
148 lines
4.5 KiB
Ruby
148 lines
4.5 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "test_helper"
|
|
require "database/setup"
|
|
require "active_support/testing/method_call_assertions"
|
|
|
|
class ActiveStorage::AttachmentTest < ActiveSupport::TestCase
|
|
include ActiveJob::TestHelper
|
|
|
|
setup do
|
|
@user = User.create!(name: "Josh")
|
|
end
|
|
|
|
teardown { ActiveStorage::Blob.all.each(&:delete) }
|
|
|
|
test "analyzing a directly-uploaded blob after attaching it" do
|
|
blob = directly_upload_file_blob(filename: "racecar.jpg")
|
|
assert_not blob.analyzed?
|
|
|
|
perform_enqueued_jobs do
|
|
@user.highlights.attach(blob)
|
|
end
|
|
|
|
assert blob.reload.analyzed?
|
|
assert_equal 4104, blob.metadata[:width]
|
|
assert_equal 2736, blob.metadata[:height]
|
|
end
|
|
|
|
test "attaching a un-analyzable blob" do
|
|
blob = create_blob(filename: "blank.txt")
|
|
|
|
assert_not_predicate blob, :analyzed?
|
|
|
|
assert_no_enqueued_jobs do
|
|
@user.highlights.attach(blob)
|
|
end
|
|
|
|
assert_predicate blob.reload, :analyzed?
|
|
end
|
|
|
|
test "mirroring a directly-uploaded blob after attaching it" do
|
|
with_service("mirror") do
|
|
blob = directly_upload_file_blob
|
|
assert_not ActiveStorage::Blob.service.mirrors.second.exist?(blob.key)
|
|
|
|
perform_enqueued_jobs do
|
|
@user.highlights.attach(blob)
|
|
end
|
|
|
|
assert ActiveStorage::Blob.service.mirrors.second.exist?(blob.key)
|
|
end
|
|
end
|
|
|
|
test "directly-uploaded blob identification for one attached occurs before validation" do
|
|
blob = directly_upload_file_blob(filename: "racecar.jpg", content_type: "application/octet-stream")
|
|
|
|
assert_blob_identified_before_owner_validated(@user, blob, "image/jpeg") do
|
|
@user.avatar.attach(blob)
|
|
end
|
|
end
|
|
|
|
test "directly-uploaded blob identification for many attached occurs before validation" do
|
|
blob = directly_upload_file_blob(filename: "racecar.jpg", content_type: "application/octet-stream")
|
|
|
|
assert_blob_identified_before_owner_validated(@user, blob, "image/jpeg") do
|
|
@user.highlights.attach(blob)
|
|
end
|
|
end
|
|
|
|
test "directly-uploaded blob identification for one attached occurs outside transaction" do
|
|
blob = directly_upload_file_blob(filename: "racecar.jpg")
|
|
|
|
assert_blob_identified_outside_transaction(blob) do
|
|
@user.avatar.attach(blob)
|
|
end
|
|
end
|
|
|
|
test "directly-uploaded blob identification for many attached occurs outside transaction" do
|
|
blob = directly_upload_file_blob(filename: "racecar.jpg")
|
|
|
|
assert_blob_identified_outside_transaction(blob) do
|
|
@user.highlights.attach(blob)
|
|
end
|
|
end
|
|
|
|
test "getting a signed blob ID from an attachment" do
|
|
blob = create_blob
|
|
@user.avatar.attach(blob)
|
|
|
|
signed_id = @user.avatar.signed_id
|
|
assert_equal blob, ActiveStorage::Blob.find_signed!(signed_id)
|
|
assert_equal blob, ActiveStorage::Blob.find_signed(signed_id)
|
|
end
|
|
|
|
test "getting a signed blob ID from an attachment with a custom purpose" do
|
|
blob = create_blob
|
|
@user.avatar.attach(blob)
|
|
|
|
signed_id = @user.avatar.signed_id(purpose: :custom_purpose)
|
|
assert_equal blob, ActiveStorage::Blob.find_signed!(signed_id, purpose: :custom_purpose)
|
|
end
|
|
|
|
test "signed blob ID backwards compatibility" do
|
|
blob = create_blob
|
|
@user.avatar.attach(blob)
|
|
|
|
signed_id_generated_old_way = ActiveStorage.verifier.generate(@user.avatar.blob.id, purpose: :blob_id)
|
|
assert_equal blob, ActiveStorage::Blob.find_signed!(signed_id_generated_old_way)
|
|
end
|
|
|
|
test "attaching with strict_loading and getting a signed blob ID from an attachment" do
|
|
blob = create_blob
|
|
@user.strict_loading!(true)
|
|
@user.avatar.attach(blob)
|
|
|
|
signed_id = @user.avatar.signed_id
|
|
assert_equal blob, ActiveStorage::Blob.find_signed(signed_id)
|
|
end
|
|
|
|
private
|
|
def assert_blob_identified_before_owner_validated(owner, blob, content_type)
|
|
validated_content_type = nil
|
|
|
|
owner.class.validate do
|
|
validated_content_type ||= blob.content_type
|
|
end
|
|
|
|
yield
|
|
|
|
assert_equal content_type, validated_content_type
|
|
assert_equal content_type, blob.reload.content_type
|
|
end
|
|
|
|
def assert_blob_identified_outside_transaction(blob)
|
|
baseline_transaction_depth = ActiveRecord::Base.connection.open_transactions
|
|
max_transaction_depth = -1
|
|
|
|
track_transaction_depth = ->(*) do
|
|
max_transaction_depth = [ActiveRecord::Base.connection.open_transactions, max_transaction_depth].max
|
|
end
|
|
|
|
blob.stub(:identify_without_saving, track_transaction_depth) do
|
|
yield
|
|
end
|
|
|
|
assert_equal 0, (max_transaction_depth - baseline_transaction_depth)
|
|
end
|
|
end
|