rails--rails/activestorage/test/test_helper.rb

195 lines
7.3 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
ENV["RAILS_ENV"] ||= "test"
require_relative "dummy/config/environment.rb"
2017-07-21 21:12:29 +00:00
2017-07-01 10:06:08 +00:00
require "bundler/setup"
require "active_support"
2017-07-04 16:10:53 +00:00
require "active_support/test_case"
require "active_support/core_ext/object/try"
2017-07-01 10:06:08 +00:00
require "active_support/testing/autorun"
require "active_support/configuration_file"
2019-05-22 19:07:35 +00:00
require "active_storage/service/mirror_service"
Use ImageProcessing gem for ActiveStorage variants ImageProcessing gem is a wrapper around MiniMagick and ruby-vips, and implements an interface for common image resizing and processing. This is the canonical image processing gem recommended in [Shrine], and that's where it developed from. The initial implementation was extracted from Refile, which also implements on-the-fly transformations. Some features that ImageProcessing gem adds on top of MiniMagick: * resizing macros - #resize_to_limit - #resize_to_fit - #resize_to_fill - #resize_and_pad * automatic orientation * automatic thumbnail sharpening * avoids the complex and inefficient MiniMagick::Image class * will use "magick" instead of "convert" on ImageMagick 7 However, the biggest feature of the ImageProcessing gem is that it has an alternative implementation that uses libvips. Libvips is an alternative to ImageMagick that can process images very rapidly (we've seen up 10x faster than ImageMagick). What's great is that the ImageProcessing gem provides the same interface for both implementations. The macros are named the same, and the libvips implementation does auto orientation and thumbnail sharpening as well; only the operations/options specific to ImageMagick/libvips differ. The integration provided by this PR should work for both implementations. The plan is to introduce the ImageProcessing backend in Rails 6.0 as the default backend and deprecate the MiniMagick backend, then in Rails 6.1 remove the MiniMagick backend.
2018-04-05 23:48:29 +00:00
require "image_processing/mini_magick"
2017-07-22 15:00:16 +00:00
require "active_job"
ActiveJob::Base.queue_adapter = :test
ActiveJob::Base.logger = ActiveSupport::Logger.new(nil)
2017-07-22 15:00:16 +00:00
2017-07-09 16:03:13 +00:00
SERVICE_CONFIGURATIONS = begin
ActiveSupport::ConfigurationFile.parse(File.expand_path("service/configurations.yml", __dir__)).deep_symbolize_keys
2017-07-09 16:03:13 +00:00
rescue Errno::ENOENT
puts "Missing service configuration file in test/service/configurations.yml"
{}
end
# Azure service tests are currently failing on the main branch.
# We temporarily disable them while we get things working again.
if ENV["CI"]
SERVICE_CONFIGURATIONS.delete(:azure)
SERVICE_CONFIGURATIONS.delete(:azure_public)
end
2017-07-09 16:03:13 +00:00
require "tmpdir"
Rails.configuration.active_storage.service_configurations = SERVICE_CONFIGURATIONS.merge(
"local" => { "service" => "Disk", "root" => Dir.mktmpdir("active_storage_tests") },
"local_public" => { "service" => "Disk", "root" => Dir.mktmpdir("active_storage_tests"), "public" => true },
"disk_mirror_1" => { "service" => "Disk", "root" => Dir.mktmpdir("active_storage_tests_1") },
"disk_mirror_2" => { "service" => "Disk", "root" => Dir.mktmpdir("active_storage_tests_2") },
"disk_mirror_3" => { "service" => "Disk", "root" => Dir.mktmpdir("active_storage_tests_3") },
"mirror" => { "service" => "Mirror", "primary" => "local", "mirrors" => ["disk_mirror_1", "disk_mirror_2", "disk_mirror_3"] }
).deep_stringify_keys
Rails.configuration.active_storage.service = "local"
2017-07-03 19:06:09 +00:00
ActiveStorage.logger = ActiveSupport::Logger.new(nil)
ActiveStorage.verifier = ActiveSupport::MessageVerifier.new("Testing")
ActiveStorage::FixtureSet.file_fixture_path = File.expand_path("fixtures/files", __dir__)
2017-07-11 16:53:17 +00:00
2017-07-04 16:10:53 +00:00
class ActiveSupport::TestCase
self.file_fixture_path = ActiveStorage::FixtureSet.file_fixture_path
include ActiveRecord::TestFixtures
Fix Flaky ActiveStorage test (#41225) Fixes a flaky Active Storage test introduced by [rails/rails#41065][], and improves the documentation. It seems that the test is covering the backwards compatibility of an older interface for retrieving records through `ActiveStorage::Record#find_signed!`. The test itself would pass unpredictably. To isolate the failure and reproduce it consistently, a see value was found after some trial and error: ``` SEED=59729 bin/test test/fixture_set_test.rb test/models/attachment_test.rb ``` This _used_ to pass consistently because [rails/rails][#41065] introduced a call to `fixtures :all`, which introduces more variation in the database's ID generation sequence. Without that line, `id` values start at `1`, so the fact that calls to `ActiveStorage::Attached::One#id` and `ActiveStorage::Blob#id` **both return `1`** is purely coincidence. The proposed resolution changes the test slightly. Prior to this change, the identifier used during retrieval and verification fetched from `@user.avatar.id`, where `@user.avatar` is an instance of `ActiveStorage::Attached::One`. The verifier/retriever combination in that test expected a signed identifier for an `ActiveStorage::Blob` instance. The change involved retrieving an instance through `@user.avatar.blob`. To better emphasize how global the `fixtures :all` declaration is, move it from the `test/fixture_set_test.rb` file to the `test/test_helper.rb` file. [rails/rails#41065]: https://github.com/rails/rails/pull/41065
2021-01-24 17:29:11 +00:00
self.fixture_path = File.expand_path("fixtures", __dir__)
setup do
ActiveStorage::Current.url_options = { protocol: "https://", host: "example.com", port: nil }
end
teardown do
ActiveStorage::Current.reset
end
def assert_queries(expected_count)
ActiveRecord::Base.connection.materialize_transactions
queries = []
ActiveSupport::Notifications.subscribe("sql.active_record") do |*, payload|
queries << payload[:sql] unless %w[ SCHEMA TRANSACTION ].include?(payload[:name])
end
yield.tap do
assert_equal expected_count, queries.size, "#{queries.size} instead of #{expected_count} queries were executed. #{queries.inspect}"
end
end
def assert_no_queries(&block)
assert_queries(0, &block)
end
2017-07-04 16:10:53 +00:00
private
def create_blob(key: nil, data: "Hello world!", filename: "hello.txt", content_type: "text/plain", identify: true, service_name: nil, record: nil)
ActiveStorage::Blob.create_and_upload! key: key, io: StringIO.new(data), filename: filename, content_type: content_type, identify: identify, service_name: service_name, record: record
2017-07-04 16:10:53 +00:00
end
def create_file_blob(key: nil, filename: "racecar.jpg", content_type: "image/jpeg", metadata: nil, service_name: nil, record: nil)
ActiveStorage::Blob.create_and_upload! io: file_fixture(filename).open, filename: filename, content_type: content_type, metadata: metadata, service_name: service_name, record: record
end
def create_blob_before_direct_upload(key: nil, filename: "hello.txt", byte_size:, checksum:, content_type: "text/plain", record: nil)
ActiveStorage::Blob.create_before_direct_upload! key: key, filename: filename, byte_size: byte_size, checksum: checksum, content_type: content_type, record: record
end
def build_blob_after_unfurling(key: nil, data: "Hello world!", filename: "hello.txt", content_type: "text/plain", identify: true, record: nil)
ActiveStorage::Blob.build_after_unfurling key: key, io: StringIO.new(data), filename: filename, content_type: content_type, identify: identify, record: record
end
def directly_upload_file_blob(filename: "racecar.jpg", content_type: "image/jpeg", record: nil)
file = file_fixture(filename)
byte_size = file.size
checksum = OpenSSL::Digest::MD5.file(file).base64digest
create_blob_before_direct_upload(filename: filename, byte_size: byte_size, checksum: checksum, content_type: content_type, record: record).tap do |blob|
2019-05-22 19:07:35 +00:00
service = ActiveStorage::Blob.service.try(:primary) || ActiveStorage::Blob.service
service.upload(blob.key, file.open)
end
end
2017-09-28 20:43:37 +00:00
def read_image(blob_or_variant)
MiniMagick::Image.open blob_or_variant.service.send(:path_for, blob_or_variant.key)
end
def extract_metadata_from(blob)
blob.tap(&:analyze).metadata
end
def fixture_file_upload(filename)
Rack::Test::UploadedFile.new file_fixture(filename).to_s
end
def with_service(service_name)
previous_service = ActiveStorage::Blob.service
ActiveStorage::Blob.service = service_name ? ActiveStorage::Blob.services.fetch(service_name) : nil
yield
ensure
ActiveStorage::Blob.service = previous_service
end
def with_strict_loading_by_default(&block)
strict_loading_was = ActiveRecord::Base.strict_loading_by_default
ActiveRecord::Base.strict_loading_by_default = true
yield
ActiveRecord::Base.strict_loading_by_default = strict_loading_was
end
def without_variant_tracking(&block)
variant_tracking_was = ActiveStorage.track_variants
ActiveStorage.track_variants = false
yield
ActiveStorage.track_variants = variant_tracking_was
end
2021-08-06 22:14:19 +00:00
def with_raise_on_open_redirects(service)
old_raise_on_open_redirects = ActionController::Base.raise_on_open_redirects
old_service = ActiveStorage::Blob.service
ActionController::Base.raise_on_open_redirects = true
ActiveStorage::Blob.service = ActiveStorage::Service.configure(service, SERVICE_CONFIGURATIONS)
yield
ensure
ActionController::Base.raise_on_open_redirects = old_raise_on_open_redirects
ActiveStorage::Blob.service = old_service
end
2021-08-04 03:53:58 +00:00
def subscribe_events_from(name)
events = []
ActiveSupport::Notifications.subscribe(name) do |*args|
events << ActiveSupport::Notifications::Event.new(*args)
end
events
end
2017-07-05 13:18:50 +00:00
end
require "global_id"
GlobalID.app = "ActiveStorageExampleApp"
ActiveRecord::Base.include GlobalID::Identification
class User < ActiveRecord::Base
validates :name, presence: true
has_one_attached :avatar
has_one_attached :cover_photo, dependent: false, service: :local
has_one_attached :avatar_with_variants do |attachable|
attachable.variant :thumb, resize_to_limit: [100, 100]
end
has_many_attached :highlights
has_many_attached :vlogs, dependent: false, service: :local
has_many_attached :highlights_with_variants do |attachable|
attachable.variant :thumb, resize_to_limit: [100, 100]
end
accepts_nested_attributes_for :highlights_attachments, allow_destroy: true
end
class Group < ActiveRecord::Base
has_one_attached :avatar
has_many :users, autosave: true
accepts_nested_attributes_for :users
end
2019-03-24 17:59:28 +00:00
require_relative "../../tools/test_common"