diff --git a/app/models/spree/image.rb b/app/models/spree/image.rb index e508395729..3d835de7b2 100644 --- a/app/models/spree/image.rb +++ b/app/models/spree/image.rb @@ -7,6 +7,17 @@ module Spree validates_attachment_presence :attachment validate :no_attachment_errors + # Active Storage declaration + has_one_attached :attachment + + # Backup Active Storage methods before they get overridden by Paperclip. + alias_method :active_storage_attachment, :attachment + alias_method :active_storage_attachment=, :attachment= + + # Paperclip declaration + # + # This will define the `name` and `name=` methods as well. + # # This is where the styles are used in the app: # - mini: used in the BackOffice: Bulk Product Edit page and Order Cycle edit page # - small: used in the FrontOffice: Product List page @@ -21,6 +32,18 @@ module Spree path: ':rails_root/public/spree/products/:id/:style/:basename.:extension', convert_options: { all: '-strip -auto-orient -colorspace sRGB' } + after_post_process do + if attachment.errors.blank? + attachable = { + io: File.open(local_filename_of_original), + filename: attachment_file_name, + content_type: attachment_content_type, + identify: false, + } + self.active_storage_attachment = attachable + end + end + # save the w,h of the original image (from which others can be calculated) # we need to look at the write-queue for images which have not been saved yet after_post_process :find_dimensions diff --git a/config/storage.yml b/config/storage.yml index fbac2cd79c..255c8298d9 100644 --- a/config/storage.yml +++ b/config/storage.yml @@ -6,6 +6,13 @@ test: service: Disk root: <%= Rails.root.join("tmp/storage") %> +test_amazon: + service: S3 + access_key_id: "A...A" + secret_access_key: "H...H" + bucket: "ofn" + region: "us-east-1" + amazon: service: S3 access_key_id: <%= ENV["S3_ACCESS_KEY"] %> diff --git a/spec/models/spree/image_spec.rb b/spec/models/spree/image_spec.rb index eba817048b..06de9c955b 100644 --- a/spec/models/spree/image_spec.rb +++ b/spec/models/spree/image_spec.rb @@ -21,6 +21,18 @@ module Spree expect(attachment.file?).to eq true expect(attachment.url).to match %r"^/spree/products/[0-9]+/product/logo-black\.png\?[0-9]+$" end + + it "duplicates the image with Active Storage" do + image = Spree::Image.create!( + attachment: file, + viewable: product.master, + ) + + attachment = image.active_storage_attachment + url = Rails.application.routes.url_helpers.url_for(attachment) + + expect(url).to match %r|^http://test\.host/rails/active_storage/blobs/redirect/[[:alnum:]-]+/logo-black\.png$| + end end describe "using AWS S3" do @@ -47,9 +59,12 @@ module Spree allow(Spree::Image).to receive(:attachment_definitions).and_return( attachment: attachment_definition.merge(s3_config) ) + allow(Rails.application.config.active_storage). + to receive(:service).and_return(:test_amazon) end it "saves a new image when none is present" do + # Paperclip requests upload_pattern = %r"^https://ofn.s3.amazonaws.com/[0-9]+/(original|mini|small|product|large)/logo-black.png$" download_pattern = %r"^https://ofn.s3.amazonaws.com/[0-9]+/product/logo-black.png$" public_url_pattern = %r"^https://ofn.s3.us-east-1.amazonaws.com/[0-9]+/product/logo-black.png\?[0-9]+$" @@ -57,15 +72,27 @@ module Spree stub_request(:put, upload_pattern).to_return(status: 200, body: "", headers: {}) stub_request(:head, download_pattern).to_return(status: 200, body: "", headers: {}) + # Active Storage requests + as_upload_pattern = %r"^https://ofn.s3.amazonaws.com/[[:alnum:]]+$" + + stub_request(:put, as_upload_pattern).to_return(status: 200, body: "", headers: {}) + image = Spree::Image.create!( attachment: file, viewable: product.master, ) + # Paperclip attachment = image.attachment expect(attachment.exists?).to eq true expect(attachment.file?).to eq true expect(attachment.url).to match public_url_pattern + + # Active Storage + attachment = image.active_storage_attachment + expect(attachment).to be_attached + expect(Rails.application.routes.url_helpers.url_for(attachment)). + to match %r"^http://test\.host/rails/active_storage/blobs/redirect/[[:alnum:]-]+/logo-black\.png" end end end