carrierwave_direct 0.0.16 → 3.0.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.
- checksums.yaml +5 -5
- data/.travis.yml +14 -9
- data/Changelog.md +45 -1
- data/README.md +37 -23
- data/carrierwave_direct.gemspec +4 -3
- data/gemfiles/{3.2.gemfile → 5.1.gemfile} +3 -3
- data/gemfiles/{4.0.gemfile → 5.2.gemfile} +3 -3
- data/gemfiles/{4.1.gemfile → 6.0.gemfile} +3 -3
- data/gemfiles/6.1.gemfile +13 -0
- data/lib/carrierwave_direct/action_view_extensions/form_helper.rb +1 -1
- data/lib/carrierwave_direct/form_builder.rb +30 -12
- data/lib/carrierwave_direct/mount.rb +1 -11
- data/lib/carrierwave_direct/policies/aws4_hmac_sha256.rb +93 -0
- data/lib/carrierwave_direct/policies/aws_base64_sha1.rb +57 -0
- data/lib/carrierwave_direct/policies/base.rb +21 -0
- data/lib/carrierwave_direct/test/capybara_helpers.rb +3 -3
- data/lib/carrierwave_direct/test/helpers.rb +1 -1
- data/lib/carrierwave_direct/uploader.rb +55 -56
- data/lib/carrierwave_direct/validations/active_model.rb +2 -2
- data/lib/carrierwave_direct/version.rb +1 -1
- data/spec/form_builder_spec.rb +24 -15
- data/spec/mount_spec.rb +2 -2
- data/spec/orm/activerecord_spec.rb +11 -7
- data/spec/orm/indirect_activerecord_spec.rb +7 -1
- data/spec/policies/aws4_hmac_sha256_spec.rb +243 -0
- data/spec/policies/aws_base64_sha1_spec.rb +229 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/support/carrier_wave_config.rb +1 -0
- data/spec/test/capybara_helpers_spec.rb +4 -4
- data/spec/test/helpers_spec.rb +3 -3
- data/spec/uploader_spec.rb +20 -26
- metadata +36 -18
- data/lib/carrierwave_direct/uploader/direct_url.rb +0 -15
- data/spec/uploader/direct_url_spec.rb +0 -26
data/spec/mount_spec.rb
CHANGED
@@ -18,12 +18,12 @@ describe CarrierWaveDirect::Mount do
|
|
18
18
|
|
19
19
|
describe "#has_video_upload?" do
|
20
20
|
it "returns false when video does not have a key" do
|
21
|
-
|
21
|
+
subject.video.key = nil
|
22
22
|
expect(subject).to_not have_video_upload
|
23
23
|
end
|
24
24
|
|
25
25
|
it "returns true when video has a key" do
|
26
|
-
|
26
|
+
subject.video.key = sample(:s3_key)
|
27
27
|
expect(subject).to have_video_upload
|
28
28
|
end
|
29
29
|
end
|
@@ -9,8 +9,12 @@ describe CarrierWaveDirect::ActiveRecord do
|
|
9
9
|
:adapter => 'sqlite3',
|
10
10
|
:database => ':memory:'
|
11
11
|
}
|
12
|
-
|
13
|
-
|
12
|
+
if ActiveRecord::VERSION::MAJOR >= 5
|
13
|
+
migration_class = ::ActiveRecord::Migration[5.0]
|
14
|
+
else
|
15
|
+
migration_class = ::ActiveRecord::Migration
|
16
|
+
end
|
17
|
+
class TestMigration < migration_class
|
14
18
|
def self.up
|
15
19
|
create_table :parties, :force => true do |t|
|
16
20
|
t.column :video, :string
|
@@ -100,8 +104,8 @@ describe CarrierWaveDirect::ActiveRecord do
|
|
100
104
|
messages = I18n.t("errors.messages.carrierwave_direct_filename_invalid")
|
101
105
|
|
102
106
|
if i18n_options
|
103
|
-
if i18n_options[:
|
104
|
-
extensions = i18n_options[:
|
107
|
+
if i18n_options[:extension_allowlist]
|
108
|
+
extensions = i18n_options[:extension_allowlist].to_sentence
|
105
109
|
messages += I18n.t("errors.messages.carrierwave_direct_allowed_extensions", :extensions => extensions)
|
106
110
|
end
|
107
111
|
|
@@ -240,7 +244,7 @@ describe CarrierWaveDirect::ActiveRecord do
|
|
240
244
|
|
241
245
|
context "where the uploader has an extension white list" do
|
242
246
|
before do
|
243
|
-
subject.video.stub(:
|
247
|
+
subject.video.stub(:extension_allowlist).and_return(%w{avi mp4})
|
244
248
|
end
|
245
249
|
|
246
250
|
context "and the uploaded file's extension is included in the list" do
|
@@ -298,7 +302,7 @@ describe CarrierWaveDirect::ActiveRecord do
|
|
298
302
|
context "on create" do
|
299
303
|
context "where the uploader has an extension white list" do
|
300
304
|
before do
|
301
|
-
subject.video.stub(:
|
305
|
+
subject.video.stub(:extension_allowlist).and_return(%w{avi mp4})
|
302
306
|
end
|
303
307
|
|
304
308
|
context "and the url's extension is included in the list" do
|
@@ -321,7 +325,7 @@ describe CarrierWaveDirect::ActiveRecord do
|
|
321
325
|
end
|
322
326
|
|
323
327
|
it_should_behave_like "a remote net url i18n error message" do
|
324
|
-
let(:i18n_options) { {:
|
328
|
+
let(:i18n_options) { {:extension_allowlist => %w{avi mp4} } }
|
325
329
|
end
|
326
330
|
|
327
331
|
it "should include the white listed extensions in the error message" do
|
@@ -10,7 +10,13 @@ describe CarrierWave::ActiveRecord do
|
|
10
10
|
:database => ':memory:'
|
11
11
|
}
|
12
12
|
|
13
|
-
|
13
|
+
if ActiveRecord::VERSION::MAJOR >= 5
|
14
|
+
migration_class = ::ActiveRecord::Migration[5.0]
|
15
|
+
else
|
16
|
+
migration_class = ::ActiveRecord::Migration
|
17
|
+
end
|
18
|
+
|
19
|
+
class OtherTestMigration < migration_class
|
14
20
|
def self.up
|
15
21
|
create_table :other_parties, :force => true do |t|
|
16
22
|
t.column :video, :string
|
@@ -0,0 +1,243 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'data/sample_data'
|
4
|
+
|
5
|
+
describe CarrierWaveDirect::Policies::Aws4HmacSha256 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, :acl, :policy, :"X-Amz-Signature", :"X-Amz-Credential", :"X-Amz-Algorithm", :"X-Amz-Date", :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[:"X-Amz-Algorithm"]).to eq "AWS4-HMAC-SHA256"
|
17
|
+
expect(subject.direct_fog_hash[:uri]).to eq "https://s3.amazonaws.com/AWS_FOG_DIRECTORY/"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# http://aws.amazon.com/articles/1434?_encoding=UTF8
|
22
|
+
#http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-UsingHTTPPOST.html
|
23
|
+
describe "#policy" do
|
24
|
+
def decoded_policy(options = {}, &block)
|
25
|
+
instance = options.delete(:subject) || subject
|
26
|
+
JSON.parse(Base64.decode64(instance.policy(options, &block)))
|
27
|
+
end
|
28
|
+
|
29
|
+
context "policy is given a block" do
|
30
|
+
it "should yield the options to the block" do
|
31
|
+
number = 0
|
32
|
+
subject.policy do |conditions|
|
33
|
+
number+=1
|
34
|
+
end
|
35
|
+
expect(number).to eq 1
|
36
|
+
end
|
37
|
+
it "should include new options in the conditions" do
|
38
|
+
policy = subject.policy do |conditions|
|
39
|
+
conditions << {"x-aws-storage-class" => "STANDARD"}
|
40
|
+
end
|
41
|
+
decoded = JSON.parse(Base64.decode64(policy))
|
42
|
+
expect(decoded['conditions'].last['x-aws-storage-class']).to eq "STANDARD"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should return Base64-encoded JSON" do
|
47
|
+
expect(decoded_policy).to be_a(Hash)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should not contain any new lines" do
|
51
|
+
expect(subject.policy).to_not include("\n")
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should be cached" do
|
55
|
+
Timecop.freeze(Time.now) do
|
56
|
+
@policy_now = subject.policy
|
57
|
+
end
|
58
|
+
Timecop.freeze(1.second.from_now) do
|
59
|
+
@policy_later = subject.policy
|
60
|
+
end
|
61
|
+
expect(@policy_later).to eql @policy_now
|
62
|
+
end
|
63
|
+
|
64
|
+
context "expiration" do
|
65
|
+
def expiration(options = {})
|
66
|
+
decoded_policy(options)["expiration"]
|
67
|
+
end
|
68
|
+
|
69
|
+
# JSON times have no seconds, so accept upto one second inaccuracy
|
70
|
+
def have_expiration(expires_in = DirectUploader.upload_expiration)
|
71
|
+
be_within(1.second).of (Time.now + expires_in)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should be valid ISO8601 and not use default Time#to_json" do
|
75
|
+
Time.any_instance.stub(:to_json) { '"Invalid time"' } # JSON gem
|
76
|
+
Time.any_instance.stub(:as_json) { '"Invalid time"' } # Active Support
|
77
|
+
expect { Time.iso8601(expiration) }.to_not raise_error
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should be #{DirectUploader.upload_expiration / 3600} hours from now" do
|
81
|
+
Timecop.freeze(Time.now) do
|
82
|
+
expect(Time.parse(expiration)).to have_expiration
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should be encoded as a utc time" do
|
87
|
+
expect(Time.parse(expiration)).to be_utc
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should be #{sample(:expiration) / 60 } minutes from now when passing {:expiration => #{sample(:expiration)}}" do
|
91
|
+
Timecop.freeze(Time.now) do
|
92
|
+
expect(Time.parse(expiration(:expiration => sample(:expiration)))).to have_expiration(sample(:expiration))
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context "conditions" do
|
98
|
+
def conditions(options = {})
|
99
|
+
decoded_policy(options)["conditions"]
|
100
|
+
end
|
101
|
+
|
102
|
+
def have_condition(field, value = nil)
|
103
|
+
field.is_a?(Hash) ? include(field) : include(["starts-with", "$#{field}", value.to_s])
|
104
|
+
end
|
105
|
+
|
106
|
+
context "should include" do
|
107
|
+
it "'utf8' if enforce_ut8 is set" do
|
108
|
+
expect(conditions(enforce_utf8: true)).to have_condition(:utf8)
|
109
|
+
end
|
110
|
+
|
111
|
+
it "'utf8' if enforce_ut8 is set" do
|
112
|
+
expect(conditions).to_not have_condition(:utf8)
|
113
|
+
end
|
114
|
+
|
115
|
+
# S3 conditions
|
116
|
+
it "'key'" do
|
117
|
+
allow(mounted_subject).to receive(:key).and_return(sample(:s3_key))
|
118
|
+
expect(conditions(
|
119
|
+
:subject => mounted_subject
|
120
|
+
)).to have_condition(:key, sample(:s3_key))
|
121
|
+
end
|
122
|
+
|
123
|
+
it "'key' without FILENAME_WILDCARD" do
|
124
|
+
expect(conditions(
|
125
|
+
:subject => mounted_subject
|
126
|
+
)).to have_condition(:key, mounted_subject.key.sub("${filename}", ""))
|
127
|
+
end
|
128
|
+
|
129
|
+
it "'bucket'" do
|
130
|
+
expect(conditions).to have_condition("bucket" => uploader.fog_directory)
|
131
|
+
end
|
132
|
+
|
133
|
+
it "'acl'" do
|
134
|
+
expect(conditions).to have_condition("acl" => uploader.acl)
|
135
|
+
end
|
136
|
+
|
137
|
+
it "'success_action_redirect'" do
|
138
|
+
uploader.success_action_redirect = "http://example.com/some_url"
|
139
|
+
expect(conditions).to have_condition("success_action_redirect" => "http://example.com/some_url")
|
140
|
+
end
|
141
|
+
|
142
|
+
it "does not have 'content-type' when will_include_content_type is false" do
|
143
|
+
allow(uploader.class).to receive(:will_include_content_type).and_return(false)
|
144
|
+
expect(conditions).to_not have_condition('Content-Type')
|
145
|
+
end
|
146
|
+
|
147
|
+
it "has 'content-type' when will_include_content_type is true" do
|
148
|
+
allow(uploader.class).to receive(:will_include_content_type).and_return(true)
|
149
|
+
expect(conditions).to have_condition('Content-Type')
|
150
|
+
end
|
151
|
+
|
152
|
+
context 'when use_action_status is true' do
|
153
|
+
before(:all) do
|
154
|
+
DirectUploader.use_action_status = true
|
155
|
+
end
|
156
|
+
|
157
|
+
after(:all) do
|
158
|
+
DirectUploader.use_action_status = false
|
159
|
+
end
|
160
|
+
|
161
|
+
it "'success_action_status'" do
|
162
|
+
uploader.success_action_status = '200'
|
163
|
+
expect(conditions).to have_condition("success_action_status" => "200")
|
164
|
+
end
|
165
|
+
|
166
|
+
it "does not have 'success_action_redirect'" do
|
167
|
+
uploader.success_action_redirect = "http://example.com/some_url"
|
168
|
+
expect(conditions).to_not have_condition("success_action_redirect" => "http://example.com/some_url")
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
context "'content-length-range of'" do
|
173
|
+
def have_content_length_range(options = {})
|
174
|
+
include([
|
175
|
+
"content-length-range",
|
176
|
+
options[:min_file_size] || DirectUploader.min_file_size,
|
177
|
+
options[:max_file_size] || DirectUploader.max_file_size,
|
178
|
+
])
|
179
|
+
end
|
180
|
+
|
181
|
+
it "#{DirectUploader.min_file_size} bytes" do
|
182
|
+
expect(conditions).to have_content_length_range
|
183
|
+
end
|
184
|
+
|
185
|
+
it "#{DirectUploader.max_file_size} bytes" do
|
186
|
+
expect(conditions).to have_content_length_range
|
187
|
+
end
|
188
|
+
|
189
|
+
it "#{sample(:min_file_size)} bytes when passing {:min_file_size => #{sample(:min_file_size)}}" do
|
190
|
+
expect(conditions(
|
191
|
+
:min_file_size => sample(:min_file_size)
|
192
|
+
)).to have_content_length_range(:min_file_size => sample(:min_file_size))
|
193
|
+
end
|
194
|
+
|
195
|
+
it "#{sample(:max_file_size)} bytes when passing {:max_file_size => #{sample(:max_file_size)}}" do
|
196
|
+
expect(conditions(
|
197
|
+
:max_file_size => sample(:max_file_size)
|
198
|
+
)).to have_content_length_range(:max_file_size => sample(:max_file_size))
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
describe "clear!" do
|
206
|
+
it "should reset the cached policy string" do
|
207
|
+
Timecop.freeze(Time.now) do
|
208
|
+
@policy_now = subject.policy
|
209
|
+
end
|
210
|
+
subject.clear!
|
211
|
+
|
212
|
+
Timecop.freeze(1.second.from_now) do
|
213
|
+
@policy_after_reset = subject.policy
|
214
|
+
end
|
215
|
+
expect(@policy_after_reset).not_to eql @policy_now
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
describe "#signature" do
|
220
|
+
it "should not contain any new lines" do
|
221
|
+
expect(subject.signature).to_not include("\n")
|
222
|
+
end
|
223
|
+
|
224
|
+
it "should return a HMAC hexdigest encoded 'sha256' hash of the secret key and policy document" do
|
225
|
+
expect(subject.signature).to eq OpenSSL::HMAC.hexdigest(
|
226
|
+
OpenSSL::Digest.new('sha256'),
|
227
|
+
subject.signing_key, subject.policy
|
228
|
+
)
|
229
|
+
end
|
230
|
+
end
|
231
|
+
#http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-UsingHTTPPOST.html
|
232
|
+
describe "#signature_key" do
|
233
|
+
it "should include correct signature_key elements" do
|
234
|
+
kDate = OpenSSL::HMAC.digest('sha256', "AWS4" + uploader.aws_secret_access_key, Time.now.utc.strftime("%Y%m%d"))
|
235
|
+
kRegion = OpenSSL::HMAC.digest('sha256', kDate, uploader.region)
|
236
|
+
kService = OpenSSL::HMAC.digest('sha256', kRegion, 's3')
|
237
|
+
kSigning = OpenSSL::HMAC.digest('sha256', kService, "aws4_request")
|
238
|
+
|
239
|
+
expect(subject.signing_key).to eq (kSigning)
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
@@ -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
|
+
|