test/storage/s3_test.rb in cloudfuji_paperclip-2.4.6 vs test/storage/s3_test.rb in cloudfuji_paperclip-3.0.3

- old
+ new

@@ -86,11 +86,10 @@ context "missing :bucket option" do setup do rebuild_model :storage => :s3, - #:bucket => "testing", # intentionally left out :http_proxy => @proxy_settings, :s3_credentials => {:not => :important} @dummy = Dummy.new @dummy.avatar = StringIO.new(".") @@ -185,12 +184,14 @@ :s3_credentials => { 'access_key_id' => "12345", 'secret_access_key' => "54321" } - @dummy = Dummy.new - @dummy.avatar = File.new(fixture_file('5k.png'), 'rb') + File.open(fixture_file('5k.png'), 'rb') do |file| + @dummy = Dummy.new + @dummy.avatar = file + end end should "return a url containing the correct original file mime type" do assert_match /.+\/5k.png/, @dummy.avatar.url end @@ -216,20 +217,48 @@ :s3_credentials => { 'access_key_id' => "12345", 'secret_access_key' => "54321" } + File.open(fixture_file('spaced file.png'), 'rb') do |file| + @dummy = Dummy.new + @dummy.avatar = file + end + end + + should "return a replaced version for path" do + assert_match /.+\/spaced_file\.png/, @dummy.avatar.path + end + + should "return a replaced version for url" do + assert_match /.+\/spaced_file\.png/, @dummy.avatar.url + end + end + + context "An attachment that uses S3 for storage and has a question mark in file name" do + setup do + rebuild_model :styles => { :large => ['500x500#', :jpg] }, + :storage => :s3, + :bucket => "bucket", + :s3_credentials => { + 'access_key_id' => "12345", + 'secret_access_key' => "54321" + } + + file = Paperclip.io_adapters.for(StringIO.new(".")) + file.original_filename = "question?mark.png" @dummy = Dummy.new - @dummy.avatar = File.new(fixture_file('spaced file.png'), 'rb') + @dummy.avatar = file + @dummy.save end - should "return an unescaped version for path" do - assert_match /.+\/spaced file\.png/, @dummy.avatar.path + should "return a replaced version for path" do + assert_match /.+\/question_mark\.png/, @dummy.avatar.path end - should "return an escaped version for url" do - assert_match /.+\/spaced%20file\.png/, @dummy.avatar.url + should "return a replaced version for url" do + assert_match /.+\/question_mark\.png/, @dummy.avatar.url end end context "" do setup do @@ -307,24 +336,35 @@ end should "return a relative URL for Rails to calculate assets host" do assert_match %r{^avatars/stringio\.txt}, @dummy.avatar.url end + end context "Generating a secure url with an expiration" do setup do - rebuild_model :storage => :s3, - :s3_credentials => { - :production => { :bucket => "prod_bucket" }, - :development => { :bucket => "dev_bucket" } - }, - :s3_host_alias => "something.something.com", - :s3_permissions => "private", - :path => ":attachment/:basename.:extension", - :url => ":s3_alias_url" + @build_model_with_options = lambda {|options| + base_options = { + :storage => :s3, + :s3_credentials => { + :production => { :bucket => "prod_bucket" }, + :development => { :bucket => "dev_bucket" } + }, + :s3_host_alias => "something.something.com", + :s3_permissions => "private", + :path => ":attachment/:basename.:extension", + :url => ":s3_alias_url" + } + rebuild_model base_options.merge(options) + } + end + + should "use default options" do + @build_model_with_options[{}] + rails_env("production") @dummy = Dummy.new @dummy.avatar = StringIO.new(".") @@ -333,13 +373,45 @@ object.expects(:url_for).with(:read, :expires => 3600, :secure => true) @dummy.avatar.expiring_url end - should "should succeed" do - assert true + should "allow overriding s3_url_options" do + @build_model_with_options[:s3_url_options => { :response_content_disposition => "inline" }] + + rails_env("production") + + @dummy = Dummy.new + @dummy.avatar = StringIO.new(".") + + object = stub + @dummy.avatar.stubs(:s3_object).returns(object) + object.expects(:url_for).with(:read, :expires => 3600, :secure => true, :response_content_disposition => "inline") + + @dummy.avatar.expiring_url end + + should "allow overriding s3_object options with a proc" do + @build_model_with_options[:s3_url_options => lambda {|attachment| { :response_content_type => attachment.avatar_content_type } }] + + rails_env("production") + + @dummy = Dummy.new + + @file = StringIO.new(".") + @file.stubs(:original_filename).returns("5k.png\n\n") + @file.stubs(:content_type).returns("image/png\n\n") + @file.stubs(:to_tempfile).returns(@file) + + @dummy.avatar = @file + + object = stub + @dummy.avatar.stubs(:s3_object).returns(object) + object.expects(:url_for).with(:read, :expires => 3600, :secure => true, :response_content_type => "image/png") + + @dummy.avatar.expiring_url + end end context "Generating a url with an expiration for each style" do setup do rebuild_model :storage => :s3, @@ -473,18 +545,10 @@ should "succeed" do assert true end end - should "delete tempfiles" do - File.stubs(:exist?).returns(true) - Paperclip::Tempfile.any_instance.expects(:close).at_least_once() - Paperclip::Tempfile.any_instance.expects(:unlink).at_least_once() - - @dummy.save! - end - context "and saved without a bucket" do setup do AWS::S3::BucketCollection.any_instance.expects(:create).with("testing") AWS::S3::S3Object.any_instance.stubs(:write). raises(AWS::S3::Errors::NoSuchBucket.new(stub, @@ -508,10 +572,20 @@ should "succeed" do assert true end end + + context 'that the file were missing' do + setup do + AWS::S3::S3Object.any_instance.stubs(:exists?).raises(AWS::Errors::Base) + end + + should 'return false on exists?' do + assert !@dummy.avatar.exists? + end + end end end context "An attachment with S3 storage and bucket defined as a Proc" do setup do @@ -526,10 +600,25 @@ assert "bucket_b", Dummy.new(:other => 'b').avatar.bucket_name assert "bucket_b", Dummy.new(:other => 'b').avatar.s3_bucket.name end end + context "An attachment with S3 storage and S3 credentials defined as a Proc" do + setup do + rebuild_model :storage => :s3, + :bucket => {:not => :important}, + :s3_credentials => lambda { |attachment| + Hash['access_key_id' => "access#{attachment.instance.other}", 'secret_access_key' => "secret#{attachment.instance.other}"] + } + end + + should "get the right credentials" do + assert "access1234", Dummy.new(:other => '1234').avatar.s3_credentials[:access_key_id] + assert "secret1234", Dummy.new(:other => '1234').avatar.s3_credentials[:secret_access_key] + end + end + context "An attachment with S3 storage and specific s3 headers set" do setup do rebuild_model :storage => :s3, :bucket => "testing", :path => ":attachment/:style/:basename.:extension", @@ -682,10 +771,49 @@ end end end end + context "An attachment with S3 storage and using AES256 encryption" do + setup do + rebuild_model :storage => :s3, + :bucket => "testing", + :path => ":attachment/:style/:basename.:extension", + :s3_credentials => { + 'access_key_id' => "12345", + 'secret_access_key' => "54321" + }, + :s3_server_side_encryption => :aes256 + end + + context "when assigned" do + setup do + @file = File.new(File.join(File.dirname(__FILE__), '..', 'fixtures', '5k.png'), 'rb') + @dummy = Dummy.new + @dummy.avatar = @file + end + + teardown { @file.close } + + context "and saved" do + setup do + object = stub + @dummy.avatar.stubs(:s3_object).returns(object) + object.expects(:write).with(anything, + :content_type => "image/png", + :acl => :public_read, + :server_side_encryption => :aes256) + @dummy.save + end + + should "succeed" do + assert true + end + end + end + end + context "An attachment with S3 storage and storage class set using the :storage_class option" do setup do rebuild_model :storage => :s3, :bucket => "testing", :path => ":attachment/:style/:basename.:extension", @@ -919,25 +1047,67 @@ teardown { @file.close } context "and saved" do setup do - [:thumb, :original].each do |style| - object = stub - @dummy.avatar.stubs(:s3_object).with(style).returns(object) - object.expects(:write).with(anything, - :content_type => "image/png", - :acl => style == :thumb ? :public_read : :private) - end @dummy.save end should "succeed" do assert @dummy.avatar.url().include? "https://" assert @dummy.avatar.url(:thumb).include? "http://" end end end + end + end + + context "An attachment with S3 storage and metadata set using a proc as headers" do + setup do + rebuild_model( + :storage => :s3, + :bucket => "testing", + :path => ":attachment/:style/:basename.:extension", + :styles => { + :thumb => "80x80>" + }, + :s3_credentials => { + 'access_key_id' => "12345", + 'secret_access_key' => "54321" + }, + :s3_headers => lambda {|attachment| + {'Content-Disposition' => "attachment; filename=\"#{attachment.name}\""} + } + ) + end + + context "when assigned" do + setup do + @file = File.new(fixture_file('5k.png'), 'rb') + @dummy = Dummy.new + @dummy.stubs(:name => 'Custom Avatar Name.png') + @dummy.avatar = @file + end + + teardown { @file.close } + + context "and saved" do + setup do + [:thumb, :original].each do |style| + object = stub + @dummy.avatar.stubs(:s3_object).with(style).returns(object) + object.expects(:write).with(anything, + :content_type => "image/png", + :acl => :public_read, + :content_disposition => 'attachment; filename="Custom Avatar Name.png"') + end + @dummy.save + end + + should "succeed" do + assert true + end + end end end end