From 6468b7d98d00cb1129e4f43d272e13d5141e9540 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 3 Feb 2022 11:25:16 +1100 Subject: [PATCH 1/2] Spec image upload The use of AWS S3 was untested before and it failed after upgrading to Ruby 3. --- spec/models/spree/image_spec.rb | 74 +++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 spec/models/spree/image_spec.rb diff --git a/spec/models/spree/image_spec.rb b/spec/models/spree/image_spec.rb new file mode 100644 index 0000000000..75096792a8 --- /dev/null +++ b/spec/models/spree/image_spec.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: false + +require 'spec_helper' + +module Spree + describe Image do + include FileHelper + + let(:file) { Rack::Test::UploadedFile.new(black_logo_file, 'image/png') } + let(:product) { create(:product) } + + describe "using local storage" do + it "stores a new image" do + image = Spree::Image.create!( + attachment: file, + viewable: product.master, + ) + + attachment = image.attachment + expect(attachment.exists?).to eq true + expect(attachment.file?).to eq true + expect(attachment.url).to match /logo-black\.png\?[0-9]+$/ + end + end + + describe "using AWS S3" do + let(:s3_config) { + { + url: ":s3_alias_url", + storage: :s3, + s3_credentials: { + access_key_id: "A...A", + secret_access_key: "H...H", + }, + s3_headers: { "Cache-Control" => "max-age=31557600" }, + bucket: "ofn", + s3_protocol: "https", + s3_host_alias: "ofn.s3.us-east-1.amazonaws.com", + + # This is for easier testing: + path: "/:id/:style/:basename.:extension", + } + } + around do |example| + original_config = Spree::Image.attachment_definitions + test_config = original_config.dup + test_config[:attachment].merge!(s3_config) + Spree::Image.attachment_definitions = test_config + + example.run + + Spree::Image.attachment_definitions = original_config + end + + it "saves a new image when none is present" do + pending "patch for aws-sdk to encode URIs" + + stub_request(:put, %r"https://ofn.s3.amazonaws.com/[0-9]+/(original|mini|small|product|large)/logo-black.png"). + to_return(status: 200, body: "", headers: {}) + stub_request(:head, %r"https://ofn.s3.amazonaws.com/[0-9]+/product/logo-black.png"). + to_return(status: 200, body: "", headers: {}) + image = Spree::Image.create!( + attachment: file, + viewable: product.master, + ) + + attachment = image.attachment + expect(attachment.exists?).to eq true + expect(attachment.file?).to eq true + expect(attachment.url).to match /logo-black\.png\?[0-9]+$/ + end + end + end +end From 2e6d8c12161d918940d02c8800b0ac41757b2a47 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 3 Feb 2022 11:26:34 +1100 Subject: [PATCH 2/2] Provide aws-sdk with working URI.encode method The S3 class is calling URI.encode which is removed in Ruby 3. By providing a URI module within the S3 class makes the S3 code call that module instead. --- config/initializers/aws_sdk.rb | 20 ++++++++++++++++++++ spec/models/spree/image_spec.rb | 28 +++++++++++++--------------- 2 files changed, 33 insertions(+), 15 deletions(-) create mode 100644 config/initializers/aws_sdk.rb diff --git a/config/initializers/aws_sdk.rb b/config/initializers/aws_sdk.rb new file mode 100644 index 0000000000..cf49dc9bb5 --- /dev/null +++ b/config/initializers/aws_sdk.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: false + +if AWS::VERSION == "1.67.0" + module AWS + module Core + module Signers + # @api private + class S3 + module URI + def self.escape(string) + ::URI::RFC2396_Parser.new.escape(string) + end + end + end + end + end + end +else + Rails.logger.warn "The aws-sdk patch needs updating or removing." +end diff --git a/spec/models/spree/image_spec.rb b/spec/models/spree/image_spec.rb index 75096792a8..eba817048b 100644 --- a/spec/models/spree/image_spec.rb +++ b/spec/models/spree/image_spec.rb @@ -19,7 +19,7 @@ module Spree attachment = image.attachment expect(attachment.exists?).to eq true expect(attachment.file?).to eq true - expect(attachment.url).to match /logo-black\.png\?[0-9]+$/ + expect(attachment.url).to match %r"^/spree/products/[0-9]+/product/logo-black\.png\?[0-9]+$" end end @@ -41,24 +41,22 @@ module Spree path: "/:id/:style/:basename.:extension", } } - around do |example| - original_config = Spree::Image.attachment_definitions - test_config = original_config.dup - test_config[:attachment].merge!(s3_config) - Spree::Image.attachment_definitions = test_config - example.run - - Spree::Image.attachment_definitions = original_config + before do + attachment_definition = Spree::Image.attachment_definitions[:attachment] + allow(Spree::Image).to receive(:attachment_definitions).and_return( + attachment: attachment_definition.merge(s3_config) + ) end it "saves a new image when none is present" do - pending "patch for aws-sdk to encode URIs" + 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]+$" + + stub_request(:put, upload_pattern).to_return(status: 200, body: "", headers: {}) + stub_request(:head, download_pattern).to_return(status: 200, body: "", headers: {}) - stub_request(:put, %r"https://ofn.s3.amazonaws.com/[0-9]+/(original|mini|small|product|large)/logo-black.png"). - to_return(status: 200, body: "", headers: {}) - stub_request(:head, %r"https://ofn.s3.amazonaws.com/[0-9]+/product/logo-black.png"). - to_return(status: 200, body: "", headers: {}) image = Spree::Image.create!( attachment: file, viewable: product.master, @@ -67,7 +65,7 @@ module Spree attachment = image.attachment expect(attachment.exists?).to eq true expect(attachment.file?).to eq true - expect(attachment.url).to match /logo-black\.png\?[0-9]+$/ + expect(attachment.url).to match public_url_pattern end end end