carrierwave_direct 1.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,229 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+ require 'data/sample_data'
4
+
5
+ describe CarrierWaveDirect::Policies::AwsBase64Sha1 do
6
+ let(:subject) { described_class.new(uploader) }
7
+ let(:uploader) { DirectUploader.new }
8
+ let(:mounted_model) { MountedClass.new }
9
+ let(:mounted_subject) { DirectUploader.new(mounted_model, sample(:mounted_as)) }
10
+
11
+ describe "#direct_fog_hash" do
12
+ it "should return the policy hash" do
13
+ expect(subject.direct_fog_hash.keys).to eq([:key, :AWSAccessKeyId, :acl, :policy, :signature, :uri])
14
+ expect(subject.direct_fog_hash[:acl]).to eq 'public-read'
15
+ expect(subject.direct_fog_hash[:key]).to match /\$\{filename\}/
16
+ expect(subject.direct_fog_hash[:uri]).to eq "https://s3.amazonaws.com/AWS_FOG_DIRECTORY/"
17
+ end
18
+ end
19
+
20
+ describe "#policy" do
21
+ def decoded_policy(options = {}, &block)
22
+ instance = options.delete(:subject) || subject
23
+ JSON.parse(Base64.decode64(instance.policy(options, &block)))
24
+ end
25
+
26
+ context "policy is given a block" do
27
+ it "should yield the options to the block" do
28
+ number = 0
29
+ subject.policy do |conditions|
30
+ number+=1
31
+ end
32
+ expect(number).to eq 1
33
+ end
34
+ it "should include new options in the conditions" do
35
+ policy = subject.policy do |conditions|
36
+ conditions << {"x-aws-storage-class" => "STANDARD"}
37
+ end
38
+ decoded = JSON.parse(Base64.decode64(policy))
39
+ expect(decoded['conditions'].last['x-aws-storage-class']).to eq "STANDARD"
40
+ end
41
+ end
42
+
43
+ it "should return Base64-encoded JSON" do
44
+ expect(decoded_policy).to be_a(Hash)
45
+ end
46
+
47
+ it "should not contain any new lines" do
48
+ expect(subject.policy).to_not include("\n")
49
+ end
50
+
51
+ it "should be cached" do
52
+ Timecop.freeze(Time.now) do
53
+ @policy_now = subject.policy
54
+ end
55
+ Timecop.freeze(1.second.from_now) do
56
+ @policy_later = subject.policy
57
+ end
58
+ expect(@policy_later).to eql @policy_now
59
+ end
60
+
61
+ context "expiration" do
62
+ def expiration(options = {})
63
+ decoded_policy(options)["expiration"]
64
+ end
65
+
66
+ # JSON times have no seconds, so accept upto one second inaccuracy
67
+ def have_expiration(expires_in = DirectUploader.upload_expiration)
68
+ be_within(1.second).of (Time.now + expires_in)
69
+ end
70
+
71
+ it "should be valid ISO8601 and not use default Time#to_json" do
72
+ Time.any_instance.stub(:to_json) { '"Invalid time"' } # JSON gem
73
+ Time.any_instance.stub(:as_json) { '"Invalid time"' } # Active Support
74
+ expect { Time.iso8601(expiration) }.to_not raise_error
75
+ end
76
+
77
+ it "should be #{DirectUploader.upload_expiration / 3600} hours from now" do
78
+ Timecop.freeze(Time.now) do
79
+ expect(Time.parse(expiration)).to have_expiration
80
+ end
81
+ end
82
+
83
+ it "should be encoded as a utc time" do
84
+ expect(Time.parse(expiration)).to be_utc
85
+ end
86
+
87
+ it "should be #{sample(:expiration) / 60 } minutes from now when passing {:expiration => #{sample(:expiration)}}" do
88
+ Timecop.freeze(Time.now) do
89
+ expect(Time.parse(expiration(:expiration => sample(:expiration)))).to have_expiration(sample(:expiration))
90
+ end
91
+ end
92
+ end
93
+
94
+ context "conditions" do
95
+ def conditions(options = {})
96
+ decoded_policy(options)["conditions"]
97
+ end
98
+
99
+ def have_condition(field, value = nil)
100
+ field.is_a?(Hash) ? include(field) : include(["starts-with", "$#{field}", value.to_s])
101
+ end
102
+
103
+ context "should include" do
104
+ it "'utf8' if enforce_ut8 is set" do
105
+ expect(conditions(enforce_utf8: true)).to have_condition(:utf8)
106
+ end
107
+
108
+ it "'utf8' if enforce_ut8 is set" do
109
+ expect(conditions).to_not have_condition(:utf8)
110
+ end
111
+
112
+ # S3 conditions
113
+ it "'key'" do
114
+ allow(mounted_subject).to receive(:key).and_return(sample(:s3_key))
115
+ expect(conditions(
116
+ :subject => mounted_subject
117
+ )).to have_condition(:key, sample(:s3_key))
118
+ end
119
+
120
+ it "'key' without FILENAME_WILDCARD" do
121
+ expect(conditions(
122
+ :subject => mounted_subject
123
+ )).to have_condition(:key, mounted_subject.key.sub("${filename}", ""))
124
+ end
125
+
126
+ it "'bucket'" do
127
+ expect(conditions).to have_condition("bucket" => uploader.fog_directory)
128
+ end
129
+
130
+ it "'acl'" do
131
+ expect(conditions).to have_condition("acl" => uploader.acl)
132
+ end
133
+
134
+ it "'success_action_redirect'" do
135
+ uploader.success_action_redirect = "http://example.com/some_url"
136
+ expect(conditions).to have_condition("success_action_redirect" => "http://example.com/some_url")
137
+ end
138
+
139
+ it "does not have 'content-type' when will_include_content_type is false" do
140
+ allow(uploader.class).to receive(:will_include_content_type).and_return(false)
141
+ expect(conditions).to_not have_condition('Content-Type')
142
+ end
143
+
144
+ it "has 'content-type' when will_include_content_type is true" do
145
+ allow(uploader.class).to receive(:will_include_content_type).and_return(true)
146
+ expect(conditions).to have_condition('Content-Type')
147
+ end
148
+
149
+ context 'when use_action_status is true' do
150
+ before(:all) do
151
+ DirectUploader.use_action_status = true
152
+ end
153
+
154
+ after(:all) do
155
+ DirectUploader.use_action_status = false
156
+ end
157
+
158
+ it "'success_action_status'" do
159
+ uploader.success_action_status = '200'
160
+ expect(conditions).to have_condition("success_action_status" => "200")
161
+ end
162
+
163
+ it "does not have 'success_action_redirect'" do
164
+ uploader.success_action_redirect = "http://example.com/some_url"
165
+ expect(conditions).to_not have_condition("success_action_redirect" => "http://example.com/some_url")
166
+ end
167
+ end
168
+
169
+ context "'content-length-range of'" do
170
+ def have_content_length_range(options = {})
171
+ include([
172
+ "content-length-range",
173
+ options[:min_file_size] || DirectUploader.min_file_size,
174
+ options[:max_file_size] || DirectUploader.max_file_size,
175
+ ])
176
+ end
177
+
178
+ it "#{DirectUploader.min_file_size} bytes" do
179
+ expect(conditions).to have_content_length_range
180
+ end
181
+
182
+ it "#{DirectUploader.max_file_size} bytes" do
183
+ expect(conditions).to have_content_length_range
184
+ end
185
+
186
+ it "#{sample(:min_file_size)} bytes when passing {:min_file_size => #{sample(:min_file_size)}}" do
187
+ expect(conditions(
188
+ :min_file_size => sample(:min_file_size)
189
+ )).to have_content_length_range(:min_file_size => sample(:min_file_size))
190
+ end
191
+
192
+ it "#{sample(:max_file_size)} bytes when passing {:max_file_size => #{sample(:max_file_size)}}" do
193
+ expect(conditions(
194
+ :max_file_size => sample(:max_file_size)
195
+ )).to have_content_length_range(:max_file_size => sample(:max_file_size))
196
+ end
197
+ end
198
+ end
199
+ end
200
+ end
201
+
202
+ describe "clear!" do
203
+ it "should reset the cached policy string" do
204
+ Timecop.freeze(Time.now) do
205
+ @policy_now = subject.policy
206
+ end
207
+ subject.clear!
208
+
209
+ Timecop.freeze(1.second.from_now) do
210
+ @policy_after_reset = subject.policy
211
+ end
212
+ expect(@policy_after_reset).not_to eql @policy_now
213
+ end
214
+ end
215
+
216
+ describe "#signature" do
217
+ it "should not contain any new lines" do
218
+ expect(subject.signature).to_not include("\n")
219
+ end
220
+
221
+ it "should return a base64 encoded 'sha1' hash of the secret key and policy document" do
222
+ expect(Base64.decode64(subject.signature)).to eq OpenSSL::HMAC.digest(
223
+ OpenSSL::Digest.new('sha1'),
224
+ uploader.aws_secret_access_key, subject.policy
225
+ )
226
+ end
227
+ end
228
+ end
229
+
data/spec/spec_helper.rb CHANGED
@@ -3,6 +3,11 @@
3
3
  require 'carrierwave_direct'
4
4
  require 'json'
5
5
  require 'timecop'
6
+ begin
7
+ require 'byebug'
8
+ rescue LoadError
9
+ puts "Byebug not installed"
10
+ end
6
11
 
7
12
  require File.dirname(__FILE__) << '/support/view_helpers' # Catch dependency order
8
13
 
@@ -1,6 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  CarrierWave.configure do |config|
4
+ config.fog_provider = 'fog/aws'
4
5
  config.fog_credentials = {
5
6
  :provider => 'AWS',
6
7
  :aws_access_key_id => 'AWS_ACCESS_KEY_ID',
@@ -19,7 +19,7 @@ describe CarrierWaveDirect::Test::Helpers do
19
19
 
20
20
  context "['exe', 'bmp']" do
21
21
  before do
22
- allow(direct_uploader).to receive(:extension_white_list).and_return(%w{exe bmp})
22
+ allow(direct_uploader).to receive(:extension_whitelist).and_return(%w{exe bmp})
23
23
  end
24
24
 
25
25
  it "should return '*/guid/filename.exe'" do
@@ -29,7 +29,7 @@ describe CarrierWaveDirect::Test::Helpers do
29
29
 
30
30
  context "[]" do
31
31
  before do
32
- allow(direct_uploader).to receive(:extension_white_list).and_return([])
32
+ allow(direct_uploader).to receive(:extension_whitelist).and_return([])
33
33
  end
34
34
 
35
35
  it_should_behave_like "returning the default extension"
@@ -37,7 +37,7 @@ describe CarrierWaveDirect::Test::Helpers do
37
37
 
38
38
  context "nil" do
39
39
  before do
40
- allow(direct_uploader).to receive(:extension_white_list).and_return(nil)
40
+ allow(direct_uploader).to receive(:extension_whitelist).and_return(nil)
41
41
  end
42
42
 
43
43
  it_should_behave_like "returning the default extension"
@@ -7,10 +7,8 @@ describe CarrierWaveDirect::Uploader do
7
7
  include ModelHelpers
8
8
 
9
9
  let(:subject) { DirectUploader.new }
10
- let(:mounted_model) { double(sample(:mounted_model_name), video_identifier: sample(:stored_filename)) }
10
+ let(:mounted_model) { MountedClass.new }
11
11
  let(:mounted_subject) { DirectUploader.new(mounted_model, sample(:mounted_as)) }
12
- let(:direct_subject) { DirectUploader.new }
13
-
14
12
 
15
13
  DirectUploader.fog_credentials.keys.each do |key|
16
14
  describe "##{key}" do
@@ -74,8 +72,9 @@ describe CarrierWaveDirect::Uploader do
74
72
  context "but the uploaders url is '#{sample(:s3_file_url)}'" do
75
73
  before do
76
74
  allow(mounted_subject).to receive(:store_dir).and_return(sample(:store_dir))
77
- allow(mounted_subject).to receive(:url).and_return(sample(:s3_file_url))
78
75
  allow(mounted_subject).to receive(:present?).and_return(true)
76
+ allow(mounted_model).to receive(:video_identifier).and_return(sample(:stored_filename))
77
+ mounted_model.remote_video_url = sample(:s3_file_url)
79
78
  end
80
79
 
81
80
  it "should return '#{sample(:s3_key)}'" do
@@ -104,6 +103,14 @@ describe CarrierWaveDirect::Uploader do
104
103
  end
105
104
  end
106
105
 
106
+ describe "#direct_fog_url" do
107
+ it "should return the result from CarrierWave::Storage::Fog::File#public_url" do
108
+ expect(subject.direct_fog_url).to eq CarrierWave::Storage::Fog::File.new(
109
+ subject, nil, nil
110
+ ).public_url
111
+ end
112
+ end
113
+
107
114
  describe "#key_regexp" do
108
115
  it "should return a regexp" do
109
116
  expect(subject.key_regexp).to be_a(Regexp)
@@ -138,26 +145,26 @@ describe CarrierWaveDirect::Uploader do
138
145
  expect(subject.extension_regexp).to be_a(String)
139
146
  end
140
147
 
141
- context "where #extension_white_list returns nil" do
148
+ context "where #extension_whitelist returns nil" do
142
149
  before do
143
- allow(subject).to receive(:extension_white_list).and_return(nil)
150
+ allow(subject).to receive(:extension_whitelist).and_return(nil)
144
151
  end
145
152
 
146
153
  it_should_behave_like "a globally allowed file extension"
147
154
  end
148
155
 
149
- context "where #extension_white_list returns []" do
156
+ context "where #extension_whitelist returns []" do
150
157
  before do
151
- allow(subject).to receive(:extension_white_list).and_return([])
158
+ allow(subject).to receive(:extension_whitelist).and_return([])
152
159
  end
153
160
 
154
161
  it_should_behave_like "a globally allowed file extension"
155
162
  end
156
163
 
157
- context "where #extension_white_list returns ['exe', 'bmp']" do
164
+ context "where #extension_whitelist returns ['exe', 'bmp']" do
158
165
 
159
166
  before do
160
- allow(subject).to receive(:extension_white_list).and_return(%w{exe bmp})
167
+ allow(subject).to receive(:extension_whitelist).and_return(%w{exe bmp})
161
168
  end
162
169
 
163
170
  it "should return '(exe|bmp)'" do
@@ -474,42 +481,17 @@ describe CarrierWaveDirect::Uploader do
474
481
  end
475
482
  end
476
483
 
477
- describe "#signature" do
478
- it "should not contain any new lines" do
479
- expect(subject.signature).to_not include("\n")
480
- end
481
-
482
- it "should return a HMAC hexdigest encoded 'sha256' hash of the secret key and policy document" do
483
- expect(subject.signature).to eq OpenSSL::HMAC.hexdigest(
484
- OpenSSL::Digest.new('sha256'),
485
- subject.send(:signing_key), subject.policy
486
- )
487
- end
488
- end
489
- #http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-UsingHTTPPOST.html
490
- describe "#signature_key" do
491
- it "should include correct signature_key elements" do
492
- kDate = OpenSSL::HMAC.digest('sha256', "AWS4" + subject.aws_secret_access_key, Time.now.utc.strftime("%Y%m%d"))
493
- kRegion = OpenSSL::HMAC.digest('sha256', kDate, subject.region)
494
- kService = OpenSSL::HMAC.digest('sha256', kRegion, 's3')
495
- kSigning = OpenSSL::HMAC.digest('sha256', kService, "aws4_request")
496
-
497
- expect(subject.send(:signing_key)).to eq (kSigning)
498
- end
499
- end
500
-
501
-
502
484
  # note that 'video' is hardcoded into the MountedClass support file
503
485
  # so changing the sample will cause the tests to fail
504
486
  context "a class has a '#{sample(:mounted_as)}' mounted" do
505
487
  describe "#{sample(:mounted_as).to_s.capitalize}Uploader" do
506
488
  describe "##{sample(:mounted_as)}" do
507
489
  it "should be defined" do
508
- expect(direct_subject).to be_respond_to(sample(:mounted_as))
490
+ expect(subject).to be_respond_to(sample(:mounted_as))
509
491
  end
510
492
 
511
493
  it "should return itself" do
512
- expect(direct_subject.send(sample(:mounted_as))).to eq direct_subject
494
+ expect(subject.send(sample(:mounted_as))).to eq subject
513
495
  end
514
496
  end
515
497
 
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: carrierwave_direct
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Wilkie
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-07-02 00:00:00.000000000 Z
11
+ date: 2018-10-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: carrierwave
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '0.11'
19
+ version: 1.0.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '0.11'
26
+ version: 1.0.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: fog-aws
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -42,16 +42,16 @@ dependencies:
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: '3.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: '3.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: timecop
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: byebug
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
111
125
  description: Process your uploads in the background by uploading directly to S3
112
126
  email:
113
127
  - dwilkie@gmail.com
@@ -125,6 +139,7 @@ files:
125
139
  - carrierwave_direct.gemspec
126
140
  - gemfiles/4.2.gemfile
127
141
  - gemfiles/5.1.gemfile
142
+ - gemfiles/5.2.gemfile
128
143
  - lib/carrierwave_direct.rb
129
144
  - lib/carrierwave_direct/action_view_extensions/form_helper.rb
130
145
  - lib/carrierwave_direct/form_builder.rb
@@ -132,12 +147,14 @@ files:
132
147
  - lib/carrierwave_direct/locale/nl.yml
133
148
  - lib/carrierwave_direct/mount.rb
134
149
  - lib/carrierwave_direct/orm/activerecord.rb
150
+ - lib/carrierwave_direct/policies/aws4_hmac_sha256.rb
151
+ - lib/carrierwave_direct/policies/aws_base64_sha1.rb
152
+ - lib/carrierwave_direct/policies/base.rb
135
153
  - lib/carrierwave_direct/test/capybara_helpers.rb
136
154
  - lib/carrierwave_direct/test/helpers.rb
137
155
  - lib/carrierwave_direct/uploader.rb
138
156
  - lib/carrierwave_direct/uploader/configuration.rb
139
157
  - lib/carrierwave_direct/uploader/content_type.rb
140
- - lib/carrierwave_direct/uploader/direct_url.rb
141
158
  - lib/carrierwave_direct/validations/active_model.rb
142
159
  - lib/carrierwave_direct/version.rb
143
160
  - spec/action_view_extensions/form_helper_spec.rb
@@ -146,6 +163,8 @@ files:
146
163
  - spec/mount_spec.rb
147
164
  - spec/orm/activerecord_spec.rb
148
165
  - spec/orm/indirect_activerecord_spec.rb
166
+ - spec/policies/aws4_hmac_sha256_spec.rb
167
+ - spec/policies/aws_base64_sha1_spec.rb
149
168
  - spec/spec_helper.rb
150
169
  - spec/support/carrier_wave_config.rb
151
170
  - spec/support/direct_uploader.rb
@@ -159,7 +178,6 @@ files:
159
178
  - spec/test/helpers_spec.rb
160
179
  - spec/uploader/configuration_spec.rb
161
180
  - spec/uploader/content_type_spec.rb
162
- - spec/uploader/direct_url_spec.rb
163
181
  - spec/uploader_spec.rb
164
182
  homepage: https://github.com/dwilkie/carrierwave_direct
165
183
  licenses: []
@@ -180,7 +198,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
180
198
  version: '0'
181
199
  requirements: []
182
200
  rubyforge_project: carrierwave_direct
183
- rubygems_version: 2.5.2.3
201
+ rubygems_version: 2.7.6
184
202
  signing_key:
185
203
  specification_version: 4
186
204
  summary: Upload direct to S3 using CarrierWave
@@ -191,6 +209,8 @@ test_files:
191
209
  - spec/mount_spec.rb
192
210
  - spec/orm/activerecord_spec.rb
193
211
  - spec/orm/indirect_activerecord_spec.rb
212
+ - spec/policies/aws4_hmac_sha256_spec.rb
213
+ - spec/policies/aws_base64_sha1_spec.rb
194
214
  - spec/spec_helper.rb
195
215
  - spec/support/carrier_wave_config.rb
196
216
  - spec/support/direct_uploader.rb
@@ -204,5 +224,4 @@ test_files:
204
224
  - spec/test/helpers_spec.rb
205
225
  - spec/uploader/configuration_spec.rb
206
226
  - spec/uploader/content_type_spec.rb
207
- - spec/uploader/direct_url_spec.rb
208
227
  - spec/uploader_spec.rb