carrierwave_direct
carrierwave_direct copied to clipboard
How to Properly Configure Test Environment?
This is what I have:
CarrierWave.configure do |config|
config.storage = :file
config.enable_processing = false
config.asset_host = ActionController::Base.asset_host
end
# Still must be set even though we've set it above in configure
DirectUploader.storage = :file
Seemed to be working fine, doing things like:
# io is from File.open
model.create_attachment!(file: io)
Until I added code like this:
model.remote_whatever_key = "https://example.com/foo/bar"
Then I get:
WebMock::NetConnectNotAllowedError:
Real HTTP connections are disabled. Unregistered request: GET https://example.com/foo/bar
Looking at the docs I see this but adding that results in the same WebMock error.
When I add it and remove the file
settings above calls to:
model.create_attachment!(file: io)
Fail with:
Excon::Error::NotFound:
Expected(200) <=> Actual(404 Not Found)
How can I configure this so that both styles of uploading are stored locally and do not result in network requests?
Running into this issue with the Excon::Error::NotFound: Expected(200) <=> Actual(404 Not Found)
error when creating objects for my tests using the standard Fog.mock! setup when upgrading a long-running Rails app from Ruby/Rails 2.6/6.0 to 3.0/6.1, and carrierwave_direct from 0.0.15 to current 3.0.0.
Running the CarrierWave, CarrierWaveDirect, and Fog gems locally, I have isolated the problem to CarrierWaveDirect::Uploader lines 20-24:
fog_credentials.keys.each do |key|
define_method(key) do
fog_credentials[key]
end
end
It appears that CarrierWaveDirect's referencing fog_credentials
in the Uploader's included
block results in cacheing a Fog connection that is invalid for testing purposes. Simply referencing this fog_credentials
hash as part of the included
block triggers the error, and removing this block allows the test objects to be created without error.
The CarrierWave gem contains an eager_load
initializer that creates and caches a new Fog connection during initialization, keyed off the credentials:
def eager_load
# see #1198. This will hopefully no longer be necessary in future release of fog
fog_credentials = CarrierWave::Uploader::Base.fog_credentials
if fog_credentials.present?
CarrierWave::Storage::Fog.connection_cache[fog_credentials] ||= ::Fog::Storage.new(fog_credentials)
end
end
In the testing environment, it seems like the testing configuration is being overridden with the result of this eager_load method Fog::Storage.new(fog_credentials)
.
This eager_load method is ~3 years old (relatively new, at least in terms of our use of the gem).
Discovered a workaround after watching the load sequence; it looked like Fog was initializing with credentials first out of the .env environment variables, and then being overridden with the credentials in the spec initializer. For some reason, the aws_access_key_id
being set to the non-test value initially was the issue. The "fix" at the moment is hacking config/initializers/carrierwave.rb so that the aws_access_key_id is given the test value in the test environment:
CarrierWave.configure do |config|
config.storage = :fog
config.fog_credentials = {
provider: 'AWS',
aws_access_key_id: Rails.env.test? ? 'aws_access_key_id' : ENV['AWS_ACCESS_KEY_ID'],
aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY']
}
...