diff options
Diffstat (limited to 'activestorage')
33 files changed, 131 insertions, 222 deletions
diff --git a/activestorage/CHANGELOG.md b/activestorage/CHANGELOG.md index 0c7e0426ae..957591ec0a 100644 --- a/activestorage/CHANGELOG.md +++ b/activestorage/CHANGELOG.md @@ -1,165 +1,3 @@ -## Rails 6.0.0.beta1 (January 18, 2019) ## -* [Rename npm package](https://github.com/rails/rails/pull/34905) from - [`activestorage`](https://www.npmjs.com/package/activestorage) to - [`@rails/activestorage`](https://www.npmjs.com/package/@rails/activestorage). - *Javan Makhmali* - -* Replace `config.active_storage.queue` with two options that indicate which - queues analysis and purge jobs should use, respectively: - - * `config.active_storage.queues.analysis` - * `config.active_storage.queues.purge` - - `config.active_storage.queue` is preferred over the new options when it's - set, but it is deprecated and will be removed in Rails 6.1. - - *George Claghorn* - -* Permit generating variants of TIFF images. - - *Luciano Sousa* - -* Use base36 (all lowercase) for all new Blob keys to prevent - collisions and undefined behavior with case-insensitive filesystems and - database indices. - - *Julik Tarkhanov* - -* It doesn’t include an `X-CSRF-Token` header if a meta tag is not found on - the page. It previously included one with a value of `undefined`. - - *Cameron Bothner* - -* Fix `ArgumentError` when uploading to amazon s3 - - *Hiroki Sanpei* - -* Add progressive JPG to default list of variable content types - - *Maurice Kühlborn* - -* Add `ActiveStorage.routes_prefix` for configuring generated routes. - - *Chris Bisnett* - -* `ActiveStorage::Service::AzureStorageService` only handles specifically - relevant types of `Azure::Core::Http::HTTPError`. It previously obscured - other types of `HTTPError`, which is the azure-storage gem’s catch-all - exception class. - - *Cameron Bothner* - -* `ActiveStorage::DiskController#show` generates a 404 Not Found response when - the requested file is missing from the disk service. It previously raised - `Errno::ENOENT`. - - *Cameron Bothner* - -* `ActiveStorage::Blob#download` and `ActiveStorage::Blob#open` raise - `ActiveStorage::FileNotFoundError` when the corresponding file is missing - from the storage service. Services translate service-specific missing object - exceptions (e.g. `Google::Cloud::NotFoundError` for the GCS service and - `Errno::ENOENT` for the disk service) into - `ActiveStorage::FileNotFoundError`. - - *Cameron Bothner* - -* Added the `ActiveStorage::SetCurrent` concern for custom Active Storage - controllers that can't inherit from `ActiveStorage::BaseController`. - - *George Claghorn* - -* Active Storage error classes like `ActiveStorage::IntegrityError` and - `ActiveStorage::UnrepresentableError` now inherit from `ActiveStorage::Error` - instead of `StandardError`. This permits rescuing `ActiveStorage::Error` to - handle all Active Storage errors. - - *Andrei Makarov*, *George Claghorn* - -* Uploaded files assigned to a record are persisted to storage when the record - is saved instead of immediately. - - In Rails 5.2, the following causes an uploaded file in `params[:avatar]` to - be stored: - - ```ruby - @user.avatar = params[:avatar] - ``` - - In Rails 6, the uploaded file is stored when `@user` is successfully saved. - - *George Claghorn* - -* Add the ability to reflect on defined attachments using the existing - ActiveRecord reflection mechanism. - - *Kevin Deisz* - -* Variant arguments of `false` or `nil` will no longer be passed to the - processor. For example, the following will not have the monochrome - variation applied: - - ```ruby - avatar.variant(monochrome: false) - ``` - - *Jacob Smith* - -* Generated attachment getter and setter methods are created - within the model's `GeneratedAssociationMethods` module to - allow overriding and composition using `super`. - - *Josh Susser*, *Jamon Douglas* - -* Add `ActiveStorage::Blob#open`, which downloads a blob to a tempfile on disk - and yields the tempfile. Deprecate `ActiveStorage::Downloading`. - - *David Robertson*, *George Claghorn* - -* Pass in `identify: false` as an argument when providing a `content_type` for - `ActiveStorage::Attached::{One,Many}#attach` to bypass automatic content - type inference. For example: - - ```ruby - @message.image.attach( - io: File.open('/path/to/file'), - filename: 'file.pdf', - content_type: 'application/pdf', - identify: false - ) - ``` - - *Ryan Davidson* - -* The Google Cloud Storage service properly supports streaming downloads. - It now requires version 1.11 or newer of the google-cloud-storage gem. - - *George Claghorn* - -* Use the [ImageProcessing](https://github.com/janko-m/image_processing) gem - for Active Storage variants, and deprecate the MiniMagick backend. - - This means that variants are now automatically oriented if the original - image was rotated. Also, in addition to the existing ImageMagick - operations, variants can now use `:resize_to_fit`, `:resize_to_fill`, and - other ImageProcessing macros. These are now recommended over raw `:resize`, - as they also sharpen the thumbnail after resizing. - - The ImageProcessing gem also comes with a backend implemented on - [libvips](http://jcupitt.github.io/libvips/), an alternative to - ImageMagick which has significantly better performance than - ImageMagick in most cases, both in terms of speed and memory usage. In - Active Storage it's now possible to switch to the libvips backend by - changing `Rails.application.config.active_storage.variant_processor` to - `:vips`. - - *Janko Marohnić* - -* Rails 6 requires Ruby 2.5.0 or newer. - - *Jeremy Daer*, *Kasper Timm Hansen* - - -Please check [5-2-stable](https://github.com/rails/rails/blob/5-2-stable/activestorage/CHANGELOG.md) for previous changes. +Please check [6-0-stable](https://github.com/rails/rails/blob/6-0-stable/activestorage/CHANGELOG.md) for previous changes. diff --git a/activestorage/README.md b/activestorage/README.md index 2886169ca7..7a437d4014 100644 --- a/activestorage/README.md +++ b/activestorage/README.md @@ -4,7 +4,9 @@ Active Storage makes it simple to upload and reference files in cloud services l Files can be uploaded from the server to the cloud or directly from the client to the cloud. -Image files can furthermore be transformed using on-demand variants for quality, aspect ratio, size, or any other [MiniMagick](https://github.com/minimagick/minimagick) or [Vips](http://www.rubydoc.info/gems/ruby-vips/Vips/Image) supported transformation. +Image files can furthermore be transformed using on-demand variants for quality, aspect ratio, size, or any other [MiniMagick](https://github.com/minimagick/minimagick) or [Vips](https://www.rubydoc.info/gems/ruby-vips/Vips/Image) supported transformation. + +You can read more about Active Storage in the [Active Storage Overview](https://edgeguides.rubyonrails.org/active_storage_overview.html) guide. ## Compared to other storage solutions @@ -149,7 +151,7 @@ Active Storage is released under the [MIT License](https://opensource.org/licens API documentation is at: -* http://api.rubyonrails.org +* https://api.rubyonrails.org Bug reports for the Ruby on Rails project can be filed here: diff --git a/activestorage/Rakefile b/activestorage/Rakefile index 2e86d3d860..0b246564bc 100644 --- a/activestorage/Rakefile +++ b/activestorage/Rakefile @@ -12,6 +12,14 @@ Rake::TestTask.new do |t| t.warning = true end +if ENV["encrypted_0fb9444d0374_key"] && ENV["encrypted_0fb9444d0374_iv"] + file "test/service/configurations.yml" do + system "openssl aes-256-cbc -K $encrypted_0fb9444d0374_key -iv $encrypted_0fb9444d0374_iv -in test/service/configurations.yml.enc -out test/service/configurations.yml -d" + end + + task test: "test/service/configurations.yml" +end + task :package task default: :test diff --git a/activestorage/activestorage.gemspec b/activestorage/activestorage.gemspec index dfada7054a..0ae2dcdd3e 100644 --- a/activestorage/activestorage.gemspec +++ b/activestorage/activestorage.gemspec @@ -15,7 +15,7 @@ Gem::Specification.new do |s| s.author = "David Heinemeier Hansson" s.email = "david@loudthinking.com" - s.homepage = "http://rubyonrails.org" + s.homepage = "https://rubyonrails.org" s.files = Dir["CHANGELOG.md", "MIT-LICENSE", "README.md", "lib/**/*", "app/**/*", "config/**/*", "db/**/*"] s.require_path = "lib" @@ -28,7 +28,8 @@ Gem::Specification.new do |s| # NOTE: Please read our dependency guidelines before updating versions: # https://edgeguides.rubyonrails.org/security.html#dependency-management-and-cves - s.add_dependency "actionpack", version + s.add_dependency "actionpack", version + s.add_dependency "activejob", version s.add_dependency "activerecord", version s.add_dependency "marcel", "~> 0.3.1" diff --git a/activestorage/app/controllers/active_storage/disk_controller.rb b/activestorage/app/controllers/active_storage/disk_controller.rb index df8d73cc91..df3116afd7 100644 --- a/activestorage/app/controllers/active_storage/disk_controller.rb +++ b/activestorage/app/controllers/active_storage/disk_controller.rb @@ -3,7 +3,7 @@ # Serves files stored with the disk service in the same way that the cloud services do. # This means using expiring, signed URLs that are meant for immediate access, not permanent linking. # Always go through the BlobsController, or your own authenticated controller, rather than directly -# to the service url. +# to the service URL. class ActiveStorage::DiskController < ActiveStorage::BaseController skip_forgery_protection diff --git a/activestorage/app/models/active_storage/attachment.rb b/activestorage/app/models/active_storage/attachment.rb index 13758d9179..874ba80ca8 100644 --- a/activestorage/app/models/active_storage/attachment.rb +++ b/activestorage/app/models/active_storage/attachment.rb @@ -46,3 +46,5 @@ class ActiveStorage::Attachment < ActiveRecord::Base record.attachment_reflections[name]&.options[:dependent] end end + +ActiveSupport.run_load_hooks :active_storage_attachment, ActiveStorage::Attachment diff --git a/activestorage/app/models/active_storage/blob.rb b/activestorage/app/models/active_storage/blob.rb index 6ca7d49bc1..c9fbafad1f 100644 --- a/activestorage/app/models/active_storage/blob.rb +++ b/activestorage/app/models/active_storage/blob.rb @@ -193,17 +193,18 @@ class ActiveStorage::Blob < ActiveRecord::Base # # The tempfile's name is prefixed with +ActiveStorage-+ and the blob's ID. Its extension matches that of the blob. # - # By default, the tempfile is created in <tt>Dir.tmpdir</tt>. Pass +tempdir:+ to create it in a different directory: + # By default, the tempfile is created in <tt>Dir.tmpdir</tt>. Pass +tmpdir:+ to create it in a different directory: # - # blob.open(tempdir: "/path/to/tmp") do |file| + # blob.open(tmpdir: "/path/to/tmp") do |file| # # ... # end # # The tempfile is automatically closed and unlinked after the given block is executed. # # Raises ActiveStorage::IntegrityError if the downloaded data does not match the blob's checksum. - def open(tempdir: nil, &block) - ActiveStorage::Downloader.new(self, tempdir: tempdir).download_blob_to_tempfile(&block) + def open(tmpdir: nil, &block) + service.open key, checksum: checksum, + name: [ "ActiveStorage-#{id}-", filename.extension_with_delimiter ], tmpdir: tmpdir, &block end @@ -272,6 +273,6 @@ class ActiveStorage::Blob < ActiveRecord::Base { content_type: content_type } end end - - ActiveSupport.run_load_hooks(:active_storage_blob, self) end + +ActiveSupport.run_load_hooks :active_storage_blob, ActiveStorage::Blob diff --git a/activestorage/app/models/active_storage/variation.rb b/activestorage/app/models/active_storage/variation.rb index 67568772da..45ae71e0ca 100644 --- a/activestorage/app/models/active_storage/variation.rb +++ b/activestorage/app/models/active_storage/variation.rb @@ -40,7 +40,7 @@ class ActiveStorage::Variation end def initialize(transformations) - @transformations = transformations + @transformations = transformations.deep_symbolize_keys end # Accepts a File object, performs the +transformations+ against it, and @@ -64,7 +64,7 @@ class ActiveStorage::Variation begin require "image_processing" rescue LoadError - ActiveSupport::Deprecation.warn <<~WARNING + ActiveSupport::Deprecation.warn <<~WARNING.squish Generating image variants will require the image_processing gem in Rails 6.1. Please add `gem 'image_processing', '~> 1.2'` to your Gemfile. WARNING diff --git a/activestorage/db/update_migrate/20180723000244_add_foreign_key_constraint_to_active_storage_attachments_for_blob_id.rb b/activestorage/db/update_migrate/20180723000244_add_foreign_key_constraint_to_active_storage_attachments_for_blob_id.rb index 6830203cd6..5472e3c87b 100644 --- a/activestorage/db/update_migrate/20180723000244_add_foreign_key_constraint_to_active_storage_attachments_for_blob_id.rb +++ b/activestorage/db/update_migrate/20180723000244_add_foreign_key_constraint_to_active_storage_attachments_for_blob_id.rb @@ -1,6 +1,8 @@ class AddForeignKeyConstraintToActiveStorageAttachmentsForBlobId < ActiveRecord::Migration[6.0] def up - unless foreign_key_exists?(:active_storage_attachments, column: :blob_id) + return if foreign_key_exists?(:active_storage_attachments, column: :blob_id) + + if table_exists?(:active_storage_blobs) add_foreign_key :active_storage_attachments, :active_storage_blobs, column: :blob_id end end diff --git a/activestorage/lib/active_storage.rb b/activestorage/lib/active_storage.rb index e542c4b2ca..5c5da551ae 100644 --- a/activestorage/lib/active_storage.rb +++ b/activestorage/lib/active_storage.rb @@ -26,6 +26,7 @@ require "active_record" require "active_support" require "active_support/rails" +require "active_support/core_ext/numeric/time" require "active_storage/version" require "active_storage/errors" diff --git a/activestorage/lib/active_storage/analyzer.rb b/activestorage/lib/active_storage/analyzer.rb index caa25418a5..26414ffbc2 100644 --- a/activestorage/lib/active_storage/analyzer.rb +++ b/activestorage/lib/active_storage/analyzer.rb @@ -24,14 +24,14 @@ module ActiveStorage private # Downloads the blob to a tempfile on disk. Yields the tempfile. def download_blob_to_tempfile(&block) #:doc: - blob.open tempdir: tempdir, &block + blob.open tmpdir: tmpdir, &block end def logger #:doc: ActiveStorage.logger end - def tempdir #:doc: + def tmpdir #:doc: Dir.tmpdir end end diff --git a/activestorage/lib/active_storage/analyzer/image_analyzer.rb b/activestorage/lib/active_storage/analyzer/image_analyzer.rb index 3b39de91be..c8bc8fe953 100644 --- a/activestorage/lib/active_storage/analyzer/image_analyzer.rb +++ b/activestorage/lib/active_storage/analyzer/image_analyzer.rb @@ -25,17 +25,24 @@ module ActiveStorage { width: image.width, height: image.height } end end - rescue LoadError - logger.info "Skipping image analysis because the mini_magick gem isn't installed" - {} end private def read_image download_blob_to_tempfile do |file| require "mini_magick" - yield MiniMagick::Image.new(file.path) + image = MiniMagick::Image.new(file.path) + + if image.valid? + yield image + else + logger.info "Skipping image analysis because ImageMagick doesn't support the file" + {} + end end + rescue LoadError + logger.info "Skipping image analysis because the mini_magick gem isn't installed" + {} end def rotated_image?(image) diff --git a/activestorage/lib/active_storage/attached/changes/create_one.rb b/activestorage/lib/active_storage/attached/changes/create_one.rb index 5812fd2b08..89cccfb58a 100644 --- a/activestorage/lib/active_storage/attached/changes/create_one.rb +++ b/activestorage/lib/active_storage/attached/changes/create_one.rb @@ -30,6 +30,7 @@ module ActiveStorage def save record.public_send("#{name}_attachment=", attachment) + record.public_send("#{name}_blob=", blob) end private diff --git a/activestorage/lib/active_storage/downloader.rb b/activestorage/lib/active_storage/downloader.rb index 87be6efb05..4d7e832af5 100644 --- a/activestorage/lib/active_storage/downloader.rb +++ b/activestorage/lib/active_storage/downloader.rb @@ -2,24 +2,23 @@ module ActiveStorage class Downloader #:nodoc: - def initialize(blob, tempdir: nil) - @blob = blob - @tempdir = tempdir + attr_reader :service + + def initialize(service) + @service = service end - def download_blob_to_tempfile - open_tempfile do |file| - download_blob_to file - verify_integrity_of file + def open(key, checksum:, name: "ActiveStorage-", tmpdir: nil) + open_tempfile(name, tmpdir) do |file| + download key, file + verify_integrity_of file, checksum: checksum yield file end end private - attr_reader :blob, :tempdir - - def open_tempfile - file = Tempfile.open([ "ActiveStorage-#{blob.id}-", blob.filename.extension_with_delimiter ], tempdir) + def open_tempfile(name, tmpdir = nil) + file = Tempfile.open(name, tmpdir) begin yield file @@ -28,15 +27,15 @@ module ActiveStorage end end - def download_blob_to(file) + def download(key, file) file.binmode - blob.download { |chunk| file.write(chunk) } + service.download(key) { |chunk| file.write(chunk) } file.flush file.rewind end - def verify_integrity_of(file) - unless Digest::MD5.file(file).base64digest == blob.checksum + def verify_integrity_of(file, checksum:) + unless Digest::MD5.file(file).base64digest == checksum raise ActiveStorage::IntegrityError end end diff --git a/activestorage/lib/active_storage/engine.rb b/activestorage/lib/active_storage/engine.rb index 384e6ebfa6..cbb205627e 100644 --- a/activestorage/lib/active_storage/engine.rb +++ b/activestorage/lib/active_storage/engine.rb @@ -1,6 +1,10 @@ # frozen_string_literal: true require "rails" +require "action_controller/railtie" +require "active_job/railtie" +require "active_record/railtie" + require "active_storage" require "active_storage/previewer/poppler_pdf_previewer" @@ -29,6 +33,7 @@ module ActiveStorage image/jpeg image/pjpeg image/tiff + image/bmp image/vnd.adobe.photoshop image/vnd.microsoft.icon ) @@ -52,6 +57,7 @@ module ActiveStorage image/jpg image/jpeg image/tiff + image/bmp image/vnd.adobe.photoshop image/vnd.microsoft.icon application/pdf diff --git a/activestorage/lib/active_storage/gem_version.rb b/activestorage/lib/active_storage/gem_version.rb index c4c7bf5677..5ef5d09f28 100644 --- a/activestorage/lib/active_storage/gem_version.rb +++ b/activestorage/lib/active_storage/gem_version.rb @@ -8,9 +8,9 @@ module ActiveStorage module VERSION MAJOR = 6 - MINOR = 0 + MINOR = 1 TINY = 0 - PRE = "beta1" + PRE = "alpha" STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".") end diff --git a/activestorage/lib/active_storage/previewer.rb b/activestorage/lib/active_storage/previewer.rb index 95a041fd16..af6bcadd4c 100644 --- a/activestorage/lib/active_storage/previewer.rb +++ b/activestorage/lib/active_storage/previewer.rb @@ -26,7 +26,7 @@ module ActiveStorage private # Downloads the blob to a tempfile on disk. Yields the tempfile. def download_blob_to_tempfile(&block) #:doc: - blob.open tempdir: tempdir, &block + blob.open tmpdir: tmpdir, &block end # Executes a system command, capturing its binary output in a tempfile. Yields the tempfile. @@ -42,7 +42,7 @@ module ActiveStorage # end # end # - # The output tempfile is opened in the directory returned by #tempdir. + # The output tempfile is opened in the directory returned by #tmpdir. def draw(*argv) #:doc: open_tempfile do |file| instrument :preview, key: blob.key do @@ -54,7 +54,7 @@ module ActiveStorage end def open_tempfile - tempfile = Tempfile.open("ActiveStorage-", tempdir) + tempfile = Tempfile.open("ActiveStorage-", tmpdir) begin yield tempfile @@ -77,7 +77,7 @@ module ActiveStorage ActiveStorage.logger end - def tempdir #:doc: + def tmpdir #:doc: Dir.tmpdir end end diff --git a/activestorage/lib/active_storage/service.rb b/activestorage/lib/active_storage/service.rb index c18fccbb1d..aac1e62e7f 100644 --- a/activestorage/lib/active_storage/service.rb +++ b/activestorage/lib/active_storage/service.rb @@ -82,6 +82,10 @@ module ActiveStorage raise NotImplementedError end + def open(*args, &block) + ActiveStorage::Downloader.new(self).open(*args, &block) + end + # Delete the file at the +key+. def delete(key) raise NotImplementedError diff --git a/activestorage/lib/active_storage/service/gcs_service.rb b/activestorage/lib/active_storage/service/gcs_service.rb index 9c20ed1d10..09abc613f3 100644 --- a/activestorage/lib/active_storage/service/gcs_service.rb +++ b/activestorage/lib/active_storage/service/gcs_service.rb @@ -131,7 +131,7 @@ module ActiveStorage end def bucket - @bucket ||= client.bucket(config.fetch(:bucket)) + @bucket ||= client.bucket(config.fetch(:bucket), skip_lookup: true) end def client diff --git a/activestorage/lib/active_storage/service/mirror_service.rb b/activestorage/lib/active_storage/service/mirror_service.rb index 75274f81b3..aa41df304e 100644 --- a/activestorage/lib/active_storage/service/mirror_service.rb +++ b/activestorage/lib/active_storage/service/mirror_service.rb @@ -9,7 +9,7 @@ module ActiveStorage class Service::MirrorService < Service attr_reader :primary, :mirrors - delegate :download, :download_chunk, :exist?, :url, to: :primary + delegate :download, :download_chunk, :exist?, :url, :path_for, to: :primary # Stitch together from named services. def self.build(primary:, mirrors:, configurator:, **options) #:nodoc: diff --git a/activestorage/lib/active_storage/service/s3_service.rb b/activestorage/lib/active_storage/service/s3_service.rb index bf94f3f49e..c7e4ec96a2 100644 --- a/activestorage/lib/active_storage/service/s3_service.rb +++ b/activestorage/lib/active_storage/service/s3_service.rb @@ -40,7 +40,7 @@ module ActiveStorage def download_chunk(key, range) instrument :download_chunk, key: key, range: range do - object_for(key).get(range: "bytes=#{range.begin}-#{range.exclude_end? ? range.end - 1 : range.end}").body.read.force_encoding(Encoding::BINARY) + object_for(key).get(range: "bytes=#{range.begin}-#{range.exclude_end? ? range.end - 1 : range.end}").body.string.force_encoding(Encoding::BINARY) rescue Aws::S3::Errors::NoSuchKey raise ActiveStorage::FileNotFoundError end @@ -108,7 +108,7 @@ module ActiveStorage raise ActiveStorage::FileNotFoundError unless object.exists? while offset < object.content_length - yield object.get(range: "bytes=#{offset}-#{offset + chunk_size - 1}").body.read.force_encoding(Encoding::BINARY) + yield object.get(range: "bytes=#{offset}-#{offset + chunk_size - 1}").body.string.force_encoding(Encoding::BINARY) offset += chunk_size end end diff --git a/activestorage/lib/active_storage/transformers/image_processing_transformer.rb b/activestorage/lib/active_storage/transformers/image_processing_transformer.rb index 7f8685b72d..506150576c 100644 --- a/activestorage/lib/active_storage/transformers/image_processing_transformer.rb +++ b/activestorage/lib/active_storage/transformers/image_processing_transformer.rb @@ -22,7 +22,7 @@ module ActiveStorage def operations transformations.each_with_object([]) do |(name, argument), list| if name.to_s == "combine_options" - ActiveSupport::Deprecation.warn <<~WARNING + ActiveSupport::Deprecation.warn <<~WARNING.squish Active Storage's ImageProcessing transformer doesn't support :combine_options, as it always generates a single ImageMagick command. Passing :combine_options will not be supported in Rails 6.1. diff --git a/activestorage/package.json b/activestorage/package.json index f7b896b5ee..39a1ea1383 100644 --- a/activestorage/package.json +++ b/activestorage/package.json @@ -1,6 +1,6 @@ { "name": "@rails/activestorage", - "version": "6.0.0-beta1", + "version": "6.1.0-alpha", "description": "Attach cloud and local files in Rails applications", "main": "app/assets/javascripts/activestorage.js", "files": [ diff --git a/activestorage/test/analyzer/image_analyzer_test.rb b/activestorage/test/analyzer/image_analyzer_test.rb index 55bb5e7280..73438c15ab 100644 --- a/activestorage/test/analyzer/image_analyzer_test.rb +++ b/activestorage/test/analyzer/image_analyzer_test.rb @@ -29,4 +29,12 @@ class ActiveStorage::Analyzer::ImageAnalyzerTest < ActiveSupport::TestCase assert_equal 792, metadata[:width] assert_equal 584, metadata[:height] end + + test "analyzing an unsupported image type" do + blob = create_blob(data: "bad", filename: "bad_file.bad", content_type: "image/bad_type") + metadata = extract_metadata_from(blob) + + assert_nil metadata[:width] + assert_nil metadata[:heigh] + end end diff --git a/activestorage/test/fixtures/files/colors.bmp b/activestorage/test/fixtures/files/colors.bmp Binary files differnew file mode 100644 index 0000000000..3cc1e8764d --- /dev/null +++ b/activestorage/test/fixtures/files/colors.bmp diff --git a/activestorage/test/models/attached/many_test.rb b/activestorage/test/models/attached/many_test.rb index 8fede0e682..e826109874 100644 --- a/activestorage/test/models/attached/many_test.rb +++ b/activestorage/test/models/attached/many_test.rb @@ -16,6 +16,9 @@ class ActiveStorage::ManyAttachedTest < ActiveSupport::TestCase @user.highlights.attach create_blob(filename: "funky.jpg"), create_blob(filename: "town.jpg") assert_equal "funky.jpg", @user.highlights.first.filename.to_s assert_equal "town.jpg", @user.highlights.second.filename.to_s + + assert_not_empty @user.highlights_attachments + assert_equal @user.highlights_blobs.count, 2 end test "attaching existing blobs from signed IDs to an existing record" do diff --git a/activestorage/test/models/attached/one_test.rb b/activestorage/test/models/attached/one_test.rb index 7fb3262781..ac08d324bb 100644 --- a/activestorage/test/models/attached/one_test.rb +++ b/activestorage/test/models/attached/one_test.rb @@ -15,6 +15,9 @@ class ActiveStorage::OneAttachedTest < ActiveSupport::TestCase test "attaching an existing blob to an existing record" do @user.avatar.attach create_blob(filename: "funky.jpg") assert_equal "funky.jpg", @user.avatar.filename.to_s + + assert_not_nil @user.avatar_attachment + assert_not_nil @user.avatar_blob end test "attaching an existing blob from a signed ID to an existing record" do diff --git a/activestorage/test/models/blob_test.rb b/activestorage/test/models/blob_test.rb index 54cf9e2b8a..9fd75a1b4a 100644 --- a/activestorage/test/models/blob_test.rb +++ b/activestorage/test/models/blob_test.rb @@ -104,19 +104,17 @@ class ActiveStorage::BlobTest < ActiveSupport::TestCase end end - test "open in a custom tempdir" do - tempdir = Dir.mktmpdir - - create_file_blob(filename: "racecar.jpg").open(tempdir: tempdir) do |file| + test "open in a custom tmpdir" do + create_file_blob(filename: "racecar.jpg").open(tmpdir: tmpdir = Dir.mktmpdir) do |file| assert file.binmode? assert_equal 0, file.pos assert_match(/\.jpg\z/, file.path) - assert file.path.starts_with?(tempdir) + assert file.path.starts_with?(tmpdir) assert_equal file_fixture("racecar.jpg").binread, file.read, "Expected downloaded file to match fixture file" end end - test "urls expiring in 5 minutes" do + test "URLs expiring in 5 minutes" do blob = create_blob freeze_time do @@ -125,7 +123,7 @@ class ActiveStorage::BlobTest < ActiveSupport::TestCase end end - test "urls force content_type to binary and attachment as content disposition for content types served as binary" do + test "URLs force content_type to binary and attachment as content disposition for content types served as binary" do blob = create_blob(content_type: "text/html") freeze_time do @@ -134,7 +132,7 @@ class ActiveStorage::BlobTest < ActiveSupport::TestCase end end - test "urls force attachment as content disposition when the content type is not allowed inline" do + test "URLs force attachment as content disposition when the content type is not allowed inline" do blob = create_blob(content_type: "application/zip") freeze_time do @@ -143,7 +141,7 @@ class ActiveStorage::BlobTest < ActiveSupport::TestCase end end - test "urls allow for custom filename" do + test "URLs allow for custom filename" do blob = create_blob(filename: "original.txt") new_filename = ActiveStorage::Filename.new("new.txt") @@ -155,7 +153,7 @@ class ActiveStorage::BlobTest < ActiveSupport::TestCase end end - test "urls allow for custom options" do + test "URLs allow for custom options" do blob = create_blob(filename: "original.txt") arguments = [ diff --git a/activestorage/test/models/variant_test.rb b/activestorage/test/models/variant_test.rb index d98935eb9f..6b43923159 100644 --- a/activestorage/test/models/variant_test.rb +++ b/activestorage/test/models/variant_test.rb @@ -4,6 +4,14 @@ require "test_helper" require "database/setup" class ActiveStorage::VariantTest < ActiveSupport::TestCase + test "variations have the same key for different types of the same transformation" do + blob = create_file_blob(filename: "racecar.jpg") + variant_a = blob.variant(resize: "100x100") + variant_b = blob.variant("resize" => "100x100") + + assert_equal variant_a.key, variant_b.key + end + test "resized variation of JPEG blob" do blob = create_file_blob(filename: "racecar.jpg") variant = blob.variant(resize: "100x100").processed @@ -144,6 +152,17 @@ class ActiveStorage::VariantTest < ActiveSupport::TestCase assert_equal 33, image.height end + test "resized variation of BMP blob" do + blob = create_file_blob(filename: "colors.bmp") + variant = blob.variant(resize: "15x15").processed + assert_match(/colors\.bmp/, variant.service_url) + + image = read_image(variant) + assert_equal "BMP", image.type + assert_equal 15, image.width + assert_equal 8, image.height + end + test "optimized variation of GIF blob" do blob = create_file_blob(filename: "image.gif", content_type: "image/gif") diff --git a/activestorage/test/service/disk_service_test.rb b/activestorage/test/service/disk_service_test.rb index a0218bff1c..f3c4dd26bd 100644 --- a/activestorage/test/service/disk_service_test.rb +++ b/activestorage/test/service/disk_service_test.rb @@ -7,7 +7,7 @@ class ActiveStorage::Service::DiskServiceTest < ActiveSupport::TestCase include ActiveStorage::Service::SharedServiceTests - test "url generation" do + test "URL generation" do assert_match(/^https:\/\/example.com\/rails\/active_storage\/disk\/.*\/avatar\.png\?content_type=image%2Fpng&disposition=inline/, @service.url(@key, expires_in: 5.minutes, disposition: :inline, filename: ActiveStorage::Filename.new("avatar.png"), content_type: "image/png")) end diff --git a/activestorage/test/service/mirror_service_test.rb b/activestorage/test/service/mirror_service_test.rb index 94c751a4ff..249a5652fb 100644 --- a/activestorage/test/service/mirror_service_test.rb +++ b/activestorage/test/service/mirror_service_test.rb @@ -61,4 +61,8 @@ class ActiveStorage::Service::MirrorServiceTest < ActiveSupport::TestCase @service.url(@key, expires_in: 2.minutes, disposition: :inline, filename: filename, content_type: "text/plain") end end + + test "path for file in primary service" do + assert_equal @service.primary.path_for(@key), @service.path_for(@key) + end end diff --git a/activestorage/test/template/image_tag_test.rb b/activestorage/test/template/image_tag_test.rb index f0b166c225..258cf702ad 100644 --- a/activestorage/test/template/image_tag_test.rb +++ b/activestorage/test/template/image_tag_test.rb @@ -37,7 +37,7 @@ class ActiveStorage::ImageTagTest < ActionView::TestCase assert_raises(ArgumentError) { image_tag(@user.avatar) } end - test "error when object can't be resolved into url" do + test "error when object can't be resolved into URL" do unresolvable_object = ActionView::Helpers::AssetTagHelper assert_raises(ArgumentError) { image_tag(unresolvable_object) } end diff --git a/activestorage/test/test_helper.rb b/activestorage/test/test_helper.rb index 144c224421..b34d0d64bb 100644 --- a/activestorage/test/test_helper.rb +++ b/activestorage/test/test_helper.rb @@ -101,3 +101,5 @@ end class Group < ActiveRecord::Base has_one_attached :avatar end + +require_relative "../../tools/test_common" |