carrierwave_direct 1.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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