diff --git a/.gitignore b/.gitignore index 3743258d..93305a5f 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ gemfiles/*.lock .ruby-version coverage/ log/ +test/tmp diff --git a/Appraisals b/Appraisals index 6b0c351d..d9368cb8 100644 --- a/Appraisals +++ b/Appraisals @@ -1,7 +1,9 @@ # frozen_string_literal: true appraise "active_record_61" do + gem "activejob", "~> 6.1.0", require: "active_job" gem "activerecord", "~> 6.1.0", require: "active_record" + gem "activestorage", "~> 6.1.0" gem "activesupport", "~> 6.1.0", require: "active_support" group :development do @@ -10,7 +12,9 @@ appraise "active_record_61" do end appraise "active_record_70" do + gem "activejob", "~> 7.0.0", require: "active_job" gem "activerecord", "~> 7.0.0", require: "active_record" + gem "activestorage", "~> 7.0.0" gem "activesupport", "~> 7.0.0", require: "active_support" group :development do @@ -19,7 +23,9 @@ appraise "active_record_70" do end appraise "active_record_71" do + gem "activejob", "~> 7.1.0", require: "active_job" gem "activerecord", "~> 7.1.0", require: "active_record" + gem "activestorage", "~> 7.1.0" gem "activesupport", "~> 7.1.0", require: "active_support" group :development do diff --git a/gemfiles/active_record_61.gemfile b/gemfiles/active_record_61.gemfile index 2360820e..90651ce0 100644 --- a/gemfiles/active_record_61.gemfile +++ b/gemfiles/active_record_61.gemfile @@ -4,7 +4,9 @@ source "https://rubygems.org" +gem "activejob", "~> 6.1.0", require: "active_job" gem "activerecord", "~> 6.1.0", require: "active_record" +gem "activestorage", "~> 6.1.0" gem "activesupport", "~> 6.1.0", require: "active_support" group :development do diff --git a/gemfiles/active_record_70.gemfile b/gemfiles/active_record_70.gemfile index a34c9137..99f4a3c5 100644 --- a/gemfiles/active_record_70.gemfile +++ b/gemfiles/active_record_70.gemfile @@ -4,7 +4,9 @@ source "https://rubygems.org" +gem "activejob", "~> 7.0.0", require: "active_job" gem "activerecord", "~> 7.0.0", require: "active_record" +gem "activestorage", "~> 7.0.0" gem "activesupport", "~> 7.0.0", require: "active_support" group :development do diff --git a/gemfiles/active_record_71.gemfile b/gemfiles/active_record_71.gemfile index e55e3086..a5984b0c 100644 --- a/gemfiles/active_record_71.gemfile +++ b/gemfiles/active_record_71.gemfile @@ -4,7 +4,9 @@ source "https://rubygems.org" +gem "activejob", "~> 7.1.0", require: "active_job" gem "activerecord", "~> 7.1.0", require: "active_record" +gem "activestorage", "~> 7.1.0" gem "activesupport", "~> 7.1.0", require: "active_support" group :development do diff --git a/test/fixtures/hello.txt b/test/fixtures/hello.txt new file mode 100644 index 00000000..5dd01c17 --- /dev/null +++ b/test/fixtures/hello.txt @@ -0,0 +1 @@ +Hello, world! \ No newline at end of file diff --git a/test/test_active_storage.rb b/test/test_active_storage.rb new file mode 100644 index 00000000..370d756f --- /dev/null +++ b/test/test_active_storage.rb @@ -0,0 +1,148 @@ +# frozen_string_literal: true + +require "test_helper" + +# load ActiveStorage +require "global_id" +ActiveRecord::Base.include(GlobalID::Identification) +GlobalID.app = "ActsAsParanoid" + +require "active_job" +ActiveJob::Base.queue_adapter = :test + +require "active_support/cache" + +require "active_storage" +require "active_storage/attached" +require "active_storage/service/disk_service" +if ActiveRecord::VERSION::MAJOR >= 6 + require "active_storage/reflection" + ActiveRecord::Base.include(ActiveStorage::Reflection::ActiveRecordExtensions) + ActiveRecord::Reflection.singleton_class.prepend(ActiveStorage::Reflection::ReflectionExtension) + ActiveRecord::Base.include(ActiveStorage::Attached::Model) + + if ActiveRecord::VERSION::MAJOR == 6 && ActiveRecord::VERSION::MINOR.zero? + module Rails + def self.autoloaders + Object.new.tap do |o| + def o.zeitwerk_enabled? + false + end + end + end + end + else + require "#{Gem.loaded_specs['activestorage'].full_gem_path}/app/models/active_storage/record" + module ActiveStorage + class Blob < Record + end + end + Dir.glob("#{Gem.loaded_specs['activestorage'].full_gem_path}/app/models/active_storage/blob/*").sort.each do |f| + require f + end + end +else + ActiveRecord::Base.extend(ActiveStorage::Attached::Macros) +end +$LOAD_PATH << "#{Gem.loaded_specs['activestorage'].full_gem_path}/app/models/" +Dir.glob("#{Gem.loaded_specs['activestorage'].full_gem_path}/app/models/active_storage/*").sort.each do |f| + require f +end +if ActiveStorage::Blob.respond_to?(:services=) + require "active_storage/service/disk_service" + ActiveStorage::Blob.services = { + "test" => ActiveStorage::Service::DiskService.build(name: "test", configurator: nil, root: "test/tmp") + } +end +if File.exist?("#{Gem.loaded_specs['activestorage'].full_gem_path}/app/jobs/active_storage/base_job.rb") + require "#{Gem.loaded_specs['activestorage'].full_gem_path}/app/jobs/active_storage/base_job" +end +Dir.glob("#{Gem.loaded_specs['activestorage'].full_gem_path}/app/jobs/active_storage/*").sort.each do |f| + require f +end +ActiveStorage::Blob.service = ActiveStorage::Service::DiskService.new(root: "test/tmp") + +class ParanoidActiveStorageTest < ActiveSupport::TestCase + self.file_fixture_path = "test/fixtures" + + class ParanoidActiveStorage < ActiveRecord::Base + acts_as_paranoid + + has_one_attached :main_file + has_many_attached :files + has_one_attached :undependent_main_file, dependent: false + has_many_attached :undependent_files, dependent: false + end + + def setup_db + ActiveRecord::Schema.define(version: 1) do + create_table :active_storage_blobs do |t| + t.string :key, null: false + t.string :filename, null: false + t.string :content_type + t.text :metadata + t.string :service_name + t.bigint :byte_size, null: false + t.string :checksum, null: false + t.datetime :created_at, null: false + t.index [:key], name: "index_active_storage_blobs_on_key", unique: true + end + + create_table :active_storage_attachments do |t| + t.string :name, null: false + t.references :record, null: false, polymorphic: true, index: false + t.references :blob, null: false + t.datetime :created_at, null: false + t.index [:record_type, :record_id, :name, :blob_id], name: "index_active_storage_attachments_uniqueness", unique: true + end + + create_table :active_storage_variant_records do |t| + t.belongs_to :blob, null: false, index: false + t.string :variation_digest, null: false + t.index [:blob_id, :variation_digest], name: "index_active_storage_variant_records_uniqueness", unique: true + end + + create_table :paranoid_active_storages do |t| + t.datetime :deleted_at + timestamps t + end + end + end + + def clean_active_storage_attachments + Dir.glob("test/tmp/*").each do |f| + FileUtils.rm_r(f) + end + end + + def create_file_blob(filename: "hello.txt", content_type: "text/plain", metadata: nil) + args = { io: file_fixture(filename).open, filename: filename, content_type: content_type, metadata: metadata } + if ActiveRecord::VERSION::MAJOR > 6 || (ActiveRecord::VERSION::MAJOR == 6 && ActiveRecord::VERSION::MINOR >= 1) + args[:service_name] = "test" + end + if ActiveStorage::Blob.respond_to?(:create_and_upload!) + ActiveStorage::Blob.create_and_upload!(**args) + else + ActiveStorage::Blob.create_after_upload!(**args) + end + end + + def setup + setup_db + end + + def teardown + super + clean_active_storage_attachments + end + + def test_paranoid_active_storage + pt = ParanoidActiveStorage.create({ + main_file: create_file_blob, + files: [create_file_blob, create_file_blob], + undependent_main_file: create_file_blob, + undependent_files: [create_file_blob, create_file_blob] + }) + pt.destroy + end +end