carrierwave_direct 2.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.
- checksums.yaml +5 -5
- data/.travis.yml +2 -2
- data/Changelog.md +12 -1
- data/README.md +1 -1
- data/carrierwave_direct.gemspec +1 -1
- data/gemfiles/5.2.gemfile +13 -0
- data/lib/carrierwave_direct/form_builder.rb +30 -14
- 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/uploader.rb +41 -76
- data/lib/carrierwave_direct/version.rb +1 -1
- data/spec/form_builder_spec.rb +11 -8
- data/spec/mount_spec.rb +2 -2
- 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 -1
- data/spec/uploader_spec.rb +13 -31
- metadata +15 -10
- data/lib/carrierwave_direct/uploader/direct_url.rb +0 -16
- data/spec/uploader/direct_url_spec.rb +0 -26
data/spec/form_builder_spec.rb
CHANGED
@@ -30,13 +30,14 @@ shared_examples_for 'hidden values form' do
|
|
30
30
|
end
|
31
31
|
|
32
32
|
it "should have a hidden field for '#{name}'" do
|
33
|
+
allow(direct_uploader.send(:signing_policy)).to receive(key).and_return(key.to_s)
|
33
34
|
allow(direct_uploader).to receive(key).and_return(key.to_s)
|
34
35
|
expect(subject).to have_input(
|
35
36
|
:direct_uploader,
|
36
37
|
key,
|
37
38
|
:type => :hidden,
|
38
39
|
:name => name,
|
39
|
-
:value => key,
|
40
|
+
:value => direct_uploader.send(key),
|
40
41
|
:required => false
|
41
42
|
)
|
42
43
|
end
|
@@ -83,7 +84,7 @@ describe CarrierWaveDirect::FormBuilder do
|
|
83
84
|
|
84
85
|
# http://aws.amazon.com/articles/1434?_encoding=UTF8
|
85
86
|
context "form" do
|
86
|
-
|
87
|
+
subject { form_with_default_file_field }
|
87
88
|
it_should_behave_like 'hidden values form'
|
88
89
|
|
89
90
|
default_hidden_fields.each do |input|
|
@@ -95,13 +96,14 @@ describe CarrierWaveDirect::FormBuilder do
|
|
95
96
|
end
|
96
97
|
|
97
98
|
it "should have a hidden field for '#{name}'" do
|
99
|
+
allow(direct_uploader.send(:signing_policy)).to receive(key).and_return(key.to_s)
|
98
100
|
allow(direct_uploader).to receive(key).and_return(key.to_s)
|
99
|
-
expect(
|
101
|
+
expect(subject).to have_input(
|
100
102
|
:direct_uploader,
|
101
103
|
key,
|
102
104
|
:type => :hidden,
|
103
105
|
:name => name,
|
104
|
-
:value => key,
|
106
|
+
:value => direct_uploader.send(key),
|
105
107
|
:required => false
|
106
108
|
)
|
107
109
|
end
|
@@ -116,20 +118,21 @@ describe CarrierWaveDirect::FormBuilder do
|
|
116
118
|
end
|
117
119
|
|
118
120
|
it "should have a hidden field for '#{name}'" do
|
121
|
+
allow(direct_uploader.send(:signing_policy)).to receive(key).and_return(key.to_s)
|
119
122
|
allow(direct_uploader).to receive(key).and_return(key.to_s)
|
120
123
|
expect(form_with_file_field_and_no_redirect).to have_input(
|
121
124
|
:direct_uploader,
|
122
125
|
key,
|
123
126
|
:type => :hidden,
|
124
127
|
:name => name,
|
125
|
-
:value => key,
|
128
|
+
:value => direct_uploader.send(key),
|
126
129
|
:required => false
|
127
130
|
)
|
128
131
|
end
|
129
132
|
end
|
130
133
|
|
131
134
|
it "should have an input for a file to upload" do
|
132
|
-
expect(
|
135
|
+
expect(subject).to have_input(
|
133
136
|
:direct_uploader,
|
134
137
|
:video,
|
135
138
|
:type => :file,
|
@@ -142,7 +145,7 @@ describe CarrierWaveDirect::FormBuilder do
|
|
142
145
|
|
143
146
|
describe "#content_type_select" do
|
144
147
|
context "form" do
|
145
|
-
|
148
|
+
subject do
|
146
149
|
form do |f|
|
147
150
|
f.content_type_select
|
148
151
|
end
|
@@ -178,7 +181,7 @@ describe CarrierWaveDirect::FormBuilder do
|
|
178
181
|
|
179
182
|
describe "#content_type_label" do
|
180
183
|
context "form" do
|
181
|
-
|
184
|
+
subject do
|
182
185
|
form do |f|
|
183
186
|
f.content_type_label
|
184
187
|
end
|
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
|
@@ -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
|
+
|