cloudinary 1.9.1 → 1.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -5
- data/.gitignore +1 -0
- data/CHANGELOG.md +32 -0
- data/cloudinary.gemspec +2 -1
- data/lib/cloudinary/api.rb +28 -13
- data/lib/cloudinary/cache.rb +38 -0
- data/lib/cloudinary/cache/breakpoints_cache.rb +31 -0
- data/lib/cloudinary/cache/key_value_cache_adapter.rb +25 -0
- data/lib/cloudinary/cache/rails_cache_adapter.rb +34 -0
- data/lib/cloudinary/cache/storage/rails_cache_storage.rb +5 -0
- data/lib/cloudinary/helper.rb +47 -4
- data/lib/cloudinary/responsive.rb +111 -0
- data/lib/cloudinary/uploader.rb +22 -4
- data/lib/cloudinary/utils.rb +122 -5
- data/lib/cloudinary/version.rb +1 -1
- data/spec/access_control_spec.rb +3 -0
- data/spec/api_spec.rb +19 -13
- data/spec/auth_token_spec.rb +8 -10
- data/spec/cache_spec.rb +109 -0
- data/spec/cloudinary_helper_spec.rb +147 -12
- data/spec/image_spec.rb +107 -0
- data/spec/spec_helper.rb +38 -17
- data/spec/uploader_spec.rb +23 -8
- data/spec/utils_spec.rb +46 -3
- data/spec/video_tag_spec.rb +7 -5
- data/spec/video_url_spec.rb +4 -2
- data/tools/update_version +202 -0
- metadata +83 -30
@@ -3,16 +3,25 @@ require 'spec_helper'
|
|
3
3
|
require 'cloudinary'
|
4
4
|
require 'action_view'
|
5
5
|
require 'cloudinary/helper'
|
6
|
-
|
7
|
-
helper_class = Class.new do
|
8
|
-
include CloudinaryHelper
|
9
|
-
end
|
6
|
+
require 'active_support/core_ext/kernel/reporting'
|
10
7
|
|
11
8
|
RSpec.describe CloudinaryHelper do
|
12
|
-
|
9
|
+
before :all do
|
10
|
+
# Test the helper in the context it runs in in production
|
11
|
+
ActionView::Base.send :include, CloudinaryHelper
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:helper) {
|
15
|
+
ActionView::Base.new
|
16
|
+
}
|
17
|
+
let(:cloud_name) {DUMMY_CLOUD}
|
18
|
+
let(:root_path) {"http://res.cloudinary.com/#{cloud_name}"}
|
19
|
+
let(:upload_path) {"#{root_path}/image/upload"}
|
20
|
+
|
13
21
|
let(:options) { {} }
|
14
22
|
before :each do
|
15
|
-
Cloudinary.
|
23
|
+
Cloudinary.reset_config
|
24
|
+
Cloudinary.config.enhance_image_tag = true
|
16
25
|
end
|
17
26
|
context "#cl_image_upload_tag" do
|
18
27
|
let(:options) {{:multiple => true}}
|
@@ -53,8 +62,9 @@ RSpec.describe CloudinaryHelper do
|
|
53
62
|
end
|
54
63
|
end
|
55
64
|
|
65
|
+
PUBLIC_ID = 'sample.jpg'
|
56
66
|
context "#cl_image_tag" do
|
57
|
-
let(:test_tag) { TestTag.new( helper.cl_image_tag(
|
67
|
+
let(:test_tag) { TestTag.new( helper.cl_image_tag(PUBLIC_ID, options)) }
|
58
68
|
|
59
69
|
context ":responsive_width" do
|
60
70
|
let(:options) { {:responsive_width => true, :cloud_name => "test"} }
|
@@ -118,6 +128,128 @@ RSpec.describe CloudinaryHelper do
|
|
118
128
|
end
|
119
129
|
end
|
120
130
|
end
|
131
|
+
describe "Responsive methods" do
|
132
|
+
let (:options) {{
|
133
|
+
:cloud_name => DUMMY_CLOUD,
|
134
|
+
:width => ResponsiveTest::BREAKPOINTS.last,
|
135
|
+
:height => ResponsiveTest::BREAKPOINTS.last,
|
136
|
+
:crop => :fill}}
|
137
|
+
|
138
|
+
describe "generate_breakpoints" do
|
139
|
+
it "should accept breakpoint" do
|
140
|
+
expect(helper.generate_breakpoints(:breakpoints => [1,2,3])).to eq([1,2,3])
|
141
|
+
end
|
142
|
+
it "should accept min_width, max_width" do
|
143
|
+
expect(helper.generate_breakpoints(:min_width => 100, :max_width => 600, :max_images => 7)).to eq([ 100, 184, 268, 352, 436, 520, 600 ])
|
144
|
+
end
|
145
|
+
end
|
146
|
+
describe "generate_scaled_url" do
|
147
|
+
it "should generate url" do
|
148
|
+
url = helper.generate_scaled_url('sample.jpg', 101, {:width => 200, :crop => "scale"}, options)
|
149
|
+
expect(url).to eq("#{upload_path}/c_scale,w_200/c_scale,w_101/sample.jpg")
|
150
|
+
end
|
151
|
+
it "should generate url without a transformation" do
|
152
|
+
url = helper.generate_scaled_url('sample.jpg', 101, {}, options)
|
153
|
+
expect(url).to eq("#{upload_path}/c_scale,w_101/sample.jpg")
|
154
|
+
end
|
155
|
+
end
|
156
|
+
describe "generate_srcset" do
|
157
|
+
it "should generate a url for each breakpoint" do
|
158
|
+
srcset = helper.generate_srcset_attribute('sample', [1,2,3], {}, options)
|
159
|
+
expect(srcset.split(', ').length).to be(3)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
context "#cl_picture_tag" do
|
165
|
+
let (:options) {{
|
166
|
+
:cloud_name => DUMMY_CLOUD,
|
167
|
+
:width => ResponsiveTest::BREAKPOINTS.last,
|
168
|
+
:height => ResponsiveTest::BREAKPOINTS.last,
|
169
|
+
:crop => :fill}}
|
170
|
+
let (:fill_trans_str) {Cloudinary::Utils.generate_transformation_string(options)}
|
171
|
+
let (:sources) {
|
172
|
+
[
|
173
|
+
{
|
174
|
+
:min_width => ResponsiveTest::BREAKPOINTS.third,
|
175
|
+
:transformation => {:effect => "sepia", :angle => 17, :width => ResponsiveTest::BREAKPOINTS.first, :crop => :scale}
|
176
|
+
},
|
177
|
+
{
|
178
|
+
:min_width => ResponsiveTest::BREAKPOINTS.second,
|
179
|
+
:transformation => {:effect => "colorize", :angle => 18, :width => ResponsiveTest::BREAKPOINTS.second, :crop => :scale}
|
180
|
+
},
|
181
|
+
{
|
182
|
+
:min_width => ResponsiveTest::BREAKPOINTS.first,
|
183
|
+
:transformation => {:effect => "blur", :angle => 19, :width => ResponsiveTest::BREAKPOINTS.first, :crop => :scale}
|
184
|
+
}
|
185
|
+
]
|
186
|
+
}
|
187
|
+
let(:test_tag) {TestTag.new(helper.cl_picture_tag(PUBLIC_ID, options, sources))}
|
188
|
+
def source_url(t)
|
189
|
+
t = Cloudinary::Utils.generate_transformation_string(t)
|
190
|
+
upload_path + '/' + fill_trans_str + '/' + t + "/sample.jpg"
|
191
|
+
end
|
192
|
+
it "should create a picture tag" do
|
193
|
+
expect(test_tag[:attributes]).to be_nil
|
194
|
+
source_tags = test_tag.element.xpath('//source')
|
195
|
+
expect(source_tags.length).to be(3)
|
196
|
+
expect(test_tag.element.xpath('//img').length).to be(1)
|
197
|
+
sources.each_with_index do |source,i|
|
198
|
+
expect(source_tags[i].attribute('srcset').value).to eq(source_url(source[:transformation]))
|
199
|
+
end
|
200
|
+
|
201
|
+
[
|
202
|
+
"(min-width: #{ResponsiveTest::BREAKPOINTS.third}px)",
|
203
|
+
"(min-width: #{ResponsiveTest::BREAKPOINTS.second}px)",
|
204
|
+
"(min-width: #{ResponsiveTest::BREAKPOINTS.first}px)",
|
205
|
+
].each_with_index do |expected, i|
|
206
|
+
expect(source_tags[i].attribute('media').value).to eq(expected)
|
207
|
+
end
|
208
|
+
|
209
|
+
end
|
210
|
+
|
211
|
+
end
|
212
|
+
|
213
|
+
context "#cl_source_tag" do
|
214
|
+
min_width = 100
|
215
|
+
max_width = 399
|
216
|
+
breakpoint_list = [min_width, 200, 300, max_width]
|
217
|
+
common_srcset = {breakpoints: breakpoint_list}
|
218
|
+
fill_transformation = {width: max_width, height: max_width, crop: "fill"}
|
219
|
+
fill_transformation_str = "c_fill,h_#{max_width},w_#{max_width}"
|
220
|
+
let (:options) {{
|
221
|
+
:cloud_name => DUMMY_CLOUD,
|
222
|
+
}}
|
223
|
+
let(:test_tag) {TestTag.new(helper.cl_source_tag(PUBLIC_ID, options))}
|
224
|
+
before(:each) do
|
225
|
+
Cloudinary.config(cloud_name: DUMMY_CLOUD, api_secret: "1234")
|
226
|
+
end
|
227
|
+
|
228
|
+
it "should generate a source tag" do
|
229
|
+
expect(test_tag.name).to eql("source")
|
230
|
+
expect(test_tag['srcset']).to eql("#{upload_path}/sample.jpg")
|
231
|
+
end
|
232
|
+
|
233
|
+
it "should generate source tag with media query" do
|
234
|
+
media = {min_width: min_width, max_width: max_width}
|
235
|
+
tag = helper.cl_source_tag("sample.jpg", media: media)
|
236
|
+
expected_media = "(min-width: #{min_width}px) and (max-width: #{max_width}px)".html_safe
|
237
|
+
expected_tag = "<source srcset=\"#{upload_path}/sample.jpg\" media=\"#{expected_media}\">"
|
238
|
+
expect(tag).to eql(expected_tag)
|
239
|
+
end
|
240
|
+
|
241
|
+
it "should generate source tag with responsive srcset" do
|
242
|
+
tag = helper.cl_source_tag(PUBLIC_ID, srcset: {breakpoints: breakpoint_list})
|
243
|
+
expect(tag).to eql(
|
244
|
+
"<source srcset=\"" +
|
245
|
+
"http://res.cloudinary.com/#{DUMMY_CLOUD}/image/upload/c_scale,w_100/sample.jpg 100w, " +
|
246
|
+
"http://res.cloudinary.com/#{DUMMY_CLOUD}/image/upload/c_scale,w_200/sample.jpg 200w, " +
|
247
|
+
"http://res.cloudinary.com/#{DUMMY_CLOUD}/image/upload/c_scale,w_300/sample.jpg 300w, " +
|
248
|
+
"http://res.cloudinary.com/#{DUMMY_CLOUD}/image/upload/c_scale,w_399/sample.jpg 399w" +
|
249
|
+
"\">")
|
250
|
+
end
|
251
|
+
|
252
|
+
end
|
121
253
|
|
122
254
|
context "#cl_client_hints_meta_tag" do
|
123
255
|
it "should create a meta tag" do
|
@@ -131,12 +263,12 @@ RSpec.describe CloudinaryHelper do
|
|
131
263
|
context "auth_token" do
|
132
264
|
it "should add token to an image tag url" do
|
133
265
|
tag = helper.cl_image_tag "sample.jpg",
|
134
|
-
:cloud_name =>
|
266
|
+
:cloud_name => DUMMY_CLOUD,
|
135
267
|
:sign_url => true,
|
136
268
|
:type => "authenticated",
|
137
269
|
:version => "1486020273",
|
138
270
|
:auth_token => {key: KEY, start_time: 11111111, duration: 300}
|
139
|
-
expect(tag).to match /<img.*src="http:\/\/res.cloudinary.com\/
|
271
|
+
expect(tag).to match /<img.*src="http:\/\/res.cloudinary.com\/#{DUMMY_CLOUD}\/image\/authenticated\/v1486020273\/sample.jpg\?__cld_token__=st=11111111~exp=11111411~hmac=9bd6f41e2a5893da8343dc8eb648de8bf73771993a6d1457d49851250caf3b80.*>/
|
140
272
|
|
141
273
|
end
|
142
274
|
|
@@ -158,12 +290,15 @@ RSpec.describe CloudinaryHelper do
|
|
158
290
|
before :each do
|
159
291
|
@static_support = Cloudinary.config.static_image_support
|
160
292
|
@static_file = Cloudinary::Static::METADATA_FILE
|
293
|
+
Cloudinary.reset_config
|
294
|
+
Cloudinary.config.enhance_image_tag = true
|
161
295
|
Cloudinary::Static.reset_metadata
|
162
296
|
end
|
163
297
|
|
164
298
|
after :each do
|
299
|
+
Cloudinary.reset_config
|
165
300
|
Cloudinary.config.static_image_support = @static_support
|
166
|
-
Kernel::silence_warnings {
|
301
|
+
Kernel::silence_warnings {Cloudinary::Static::METADATA_FILE = @static_file}
|
167
302
|
Cloudinary::Static.reset_metadata
|
168
303
|
end
|
169
304
|
|
@@ -181,8 +316,8 @@ RSpec.describe CloudinaryHelper do
|
|
181
316
|
.to eq("/images/foo.jpg")
|
182
317
|
expect(helper.image_path('some-folder/foo.gif')).to eq("/images/some-folder/foo.gif")
|
183
318
|
Cloudinary.config.static_image_support = true
|
184
|
-
expect(helper.image_path('/images/foo.jpg')).to eq("http://res.cloudinary.com/
|
185
|
-
expect(helper.image_path('foo.jpg')).to eq("http://res.cloudinary.com/
|
319
|
+
expect(helper.image_path('/images/foo.jpg')).to eq("http://res.cloudinary.com/#{Cloudinary.config.cloud_name}/image/asset/images-foo.jpg")
|
320
|
+
expect(helper.image_path('foo.jpg')).to eq("http://res.cloudinary.com/#{Cloudinary.config.cloud_name}/image/asset/images-foo.jpg")
|
186
321
|
expect(helper.image_path('some-folder/foo.gif')).to eq('/images/some-folder/foo.gif')
|
187
322
|
end
|
188
323
|
end
|
data/spec/image_spec.rb
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'cloudinary'
|
3
|
+
require 'action_view'
|
4
|
+
require 'cloudinary/helper'
|
5
|
+
|
6
|
+
COMMON_TRANS = {
|
7
|
+
effect: 'sepia',
|
8
|
+
cloud_name: DUMMY_CLOUD,
|
9
|
+
client_hints: false
|
10
|
+
}
|
11
|
+
COMMON_TRANSFORMATION_STR = 'e_sepia'
|
12
|
+
|
13
|
+
def expected_srcset(public_id, path, common_trans, breakpoints)
|
14
|
+
breakpoints.map {|width| "#{path}/#{common_trans}/c_scale,w_#{width}/#{public_id} #{width}w"}.join(', ')
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'Responsive breakpoints' do
|
18
|
+
|
19
|
+
|
20
|
+
before :all do
|
21
|
+
# Test the helper in the context it runs in in production
|
22
|
+
ActionView::Base.send :include, CloudinaryHelper
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
before :each do
|
27
|
+
Cloudinary.reset_config
|
28
|
+
end
|
29
|
+
|
30
|
+
let(:cloud_name) {COMMON_TRANS[:cloud_name]}
|
31
|
+
let(:root_path) {"http://res.cloudinary.com/#{cloud_name}"}
|
32
|
+
let(:upload_path) {"#{root_path}/image/upload"}
|
33
|
+
|
34
|
+
let(:options) {COMMON_TRANS}
|
35
|
+
# let(:helper) {helper_class.new}
|
36
|
+
let(:helper) {
|
37
|
+
ActionView::Base.new
|
38
|
+
}
|
39
|
+
let(:test_tag) {TestTag.new(helper.cl_image_tag('sample.jpg', options))}
|
40
|
+
describe 'srcset' do
|
41
|
+
it 'Should create srcset attribute with provided breakpoints' do
|
42
|
+
options[:srcset] = {:breakpoints => ResponsiveTest::BREAKPOINTS}
|
43
|
+
srcset = test_tag['srcset'].split(", ")
|
44
|
+
expect(srcset.length).to eq(4)
|
45
|
+
expected_tag = expected_srcset('sample.jpg', upload_path, COMMON_TRANSFORMATION_STR, ResponsiveTest::BREAKPOINTS)
|
46
|
+
expect(test_tag['srcset']).to match(expected_tag)
|
47
|
+
end
|
48
|
+
it "Support srcset attribute defined by min width max width and max images" do
|
49
|
+
options[:srcset] = {:min_width => ResponsiveTest::BREAKPOINTS.first,
|
50
|
+
:max_width => ResponsiveTest::BREAKPOINTS.last,
|
51
|
+
:max_images => ResponsiveTest::BREAKPOINTS.length}
|
52
|
+
|
53
|
+
expected_tag = expected_srcset('sample.jpg', upload_path, COMMON_TRANSFORMATION_STR, ResponsiveTest::BREAKPOINTS)
|
54
|
+
expect(test_tag['srcset']).to match(expected_tag)
|
55
|
+
end
|
56
|
+
it "should generate a single srcset image" do
|
57
|
+
options[:srcset] = {:min_width => ResponsiveTest::BREAKPOINTS.first,
|
58
|
+
:max_width => ResponsiveTest::BREAKPOINTS.last,
|
59
|
+
:max_images => 1}
|
60
|
+
|
61
|
+
expected_tag = expected_srcset('sample.jpg', upload_path, COMMON_TRANSFORMATION_STR, [ResponsiveTest::BREAKPOINTS.last])
|
62
|
+
expect(test_tag['srcset']).to match(expected_tag)
|
63
|
+
end
|
64
|
+
it "Should support custom transformation for srcset items" do
|
65
|
+
options[:srcset] = {
|
66
|
+
:breakpoints => ResponsiveTest::BREAKPOINTS,
|
67
|
+
:transformation => {:crop => 'crop', :width => 10, :height => 20}
|
68
|
+
}
|
69
|
+
|
70
|
+
expected_tag = expected_srcset('sample.jpg', upload_path, 'c_crop,h_20,w_10', ResponsiveTest::BREAKPOINTS)
|
71
|
+
expect(test_tag['srcset']).to match(expected_tag)
|
72
|
+
end
|
73
|
+
it "Should populate sizes attribute" do
|
74
|
+
options[:srcset] = {
|
75
|
+
:breakpoints => ResponsiveTest::BREAKPOINTS,
|
76
|
+
:sizes => true
|
77
|
+
}
|
78
|
+
expected_sizes_attr = '(max-width: 100px) 100px, (max-width: 200px) 200px, ' +
|
79
|
+
'(max-width: 300px) 300px, (max-width: 399px) 399px'
|
80
|
+
expect(test_tag['sizes']).to match(expected_sizes_attr)
|
81
|
+
end
|
82
|
+
it "Should support srcset string value" do
|
83
|
+
raw_src_set = "some srcset data as is"
|
84
|
+
options[:srcset] = raw_src_set
|
85
|
+
|
86
|
+
expect(test_tag['srcset']).to match(raw_src_set)
|
87
|
+
end
|
88
|
+
it "Should remove width and height attributes in case srcset is specified, but passed to transformation" do
|
89
|
+
options.merge!({
|
90
|
+
:srcset => {
|
91
|
+
:breakpoints => ResponsiveTest::BREAKPOINTS,
|
92
|
+
},
|
93
|
+
:width => 500,
|
94
|
+
:height => 500,
|
95
|
+
:crop => 'scale'
|
96
|
+
|
97
|
+
})
|
98
|
+
|
99
|
+
expected_tag = expected_srcset('sample.jpg', upload_path, 'c_scale,e_sepia,h_500,w_500', ResponsiveTest::BREAKPOINTS)
|
100
|
+
expect(test_tag['srcset']).to match(expected_tag)
|
101
|
+
expect(test_tag['width']).to be_nil
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
require 'rspec'
|
2
2
|
require 'rexml/parsers/ultralightparser'
|
3
|
+
require 'nokogiri'
|
3
4
|
require 'rspec/version'
|
4
5
|
require 'rest_client'
|
5
6
|
require 'cloudinary'
|
6
7
|
|
7
8
|
Cloudinary.config.enhance_image_tag = true
|
8
9
|
|
10
|
+
DUMMY_CLOUD = "test123"
|
9
11
|
TEST_IMAGE_URL = "http://cloudinary.com/images/old_logo.png"
|
10
12
|
TEST_IMG = "spec/logo.png"
|
11
13
|
TEST_IMG_W = 241
|
@@ -17,8 +19,15 @@ TIMESTAMP_TAG = "#{TEST_TAG}_#{SUFFIX}_#{RUBY_VERSION}_#{ defined? Rails::versio
|
|
17
19
|
# Auth token
|
18
20
|
KEY = "00112233FF99"
|
19
21
|
ALT_KEY = "CCBB2233FF00"
|
22
|
+
CACHE_KEY = "some_key" + SUFFIX
|
20
23
|
|
24
|
+
module ResponsiveTest
|
25
|
+
TRANSFORMATION = {:angle => 45, :crop => "scale"}
|
26
|
+
FORMAT = "png"
|
27
|
+
IMAGE_BP_VALUES = [206, 50]
|
28
|
+
BREAKPOINTS = [100, 200, 300, 399]
|
21
29
|
|
30
|
+
end
|
22
31
|
Dir[File.join(File.dirname(__FILE__), '/support/**/*.rb')].each {|f| require f}
|
23
32
|
|
24
33
|
module RSpec
|
@@ -41,6 +50,12 @@ RSpec.shared_context "cleanup" do |tag|
|
|
41
50
|
after :all do
|
42
51
|
Cloudinary::Api.delete_resources_by_tag(tag) unless Cloudinary.config.keep_test_products
|
43
52
|
end
|
53
|
+
end
|
54
|
+
|
55
|
+
module Cloudinary
|
56
|
+
def self.reset_config
|
57
|
+
@@config = nil
|
58
|
+
end
|
44
59
|
|
45
60
|
end
|
46
61
|
|
@@ -57,39 +72,45 @@ end
|
|
57
72
|
|
58
73
|
# Represents an HTML tag
|
59
74
|
class TestTag
|
60
|
-
attr_accessor :
|
75
|
+
attr_accessor :element
|
61
76
|
# Creates a new +TestTag+ from a given +element+ string
|
62
77
|
def initialize(element)
|
63
78
|
@html_string = element
|
64
|
-
element = valid_tag(element) unless element.is_a? Array
|
65
|
-
case element[0]
|
66
|
-
when :start_element
|
67
|
-
@name = element[2]
|
68
|
-
@attributes = element[3]
|
69
|
-
@children = (Array(element[4..-1]) || []).map {|c | TestTag.new c}
|
70
|
-
when :text
|
71
|
-
@text = element[1]
|
72
|
-
@name = "text"
|
73
|
-
@attributes = []
|
74
|
-
@children = []
|
75
|
-
end
|
79
|
+
@element = valid_tag(element) unless element.is_a? Array
|
76
80
|
|
77
81
|
end
|
78
82
|
|
83
|
+
def name
|
84
|
+
@element.name
|
85
|
+
end
|
86
|
+
|
87
|
+
def attributes
|
88
|
+
@element.attributes
|
89
|
+
end
|
90
|
+
|
91
|
+
def children
|
92
|
+
@element.children
|
93
|
+
end
|
79
94
|
# Parses a given +tag+ in string format
|
80
95
|
def valid_tag(tag)
|
81
|
-
parser =
|
82
|
-
|
96
|
+
parser = Nokogiri::HTML::Document.parse( tag)
|
97
|
+
# Parsed code will be strctured as either html>body>tag or html>head>tag
|
98
|
+
parser.children[1].children[0].children[0]
|
83
99
|
end
|
84
100
|
|
85
101
|
# Returns attribute named +symbol_or_string+
|
86
102
|
def [](symbol_or_string)
|
87
|
-
|
103
|
+
begin
|
104
|
+
attributes[symbol_or_string.to_s].value
|
105
|
+
rescue
|
106
|
+
nil
|
107
|
+
end
|
88
108
|
end
|
89
109
|
|
90
110
|
def method_missing(symbol, *args)
|
91
111
|
if (m = /children_by_(\w+)/.match(symbol.to_s)) and !args.empty?
|
92
|
-
|
112
|
+
return unless children
|
113
|
+
children.select{ |c| c[m[1]] == args[0]}
|
93
114
|
else
|
94
115
|
super
|
95
116
|
end
|
data/spec/uploader_spec.rb
CHANGED
@@ -184,23 +184,23 @@ describe Cloudinary::Uploader do
|
|
184
184
|
end
|
185
185
|
|
186
186
|
|
187
|
-
describe "context"
|
187
|
+
describe "context" do
|
188
188
|
describe "add_context" do
|
189
|
-
it "should correctly add context"
|
189
|
+
it "should correctly add context" do
|
190
190
|
expected ={
|
191
191
|
:url => /.*\/context/,
|
192
|
-
[:payload, :context] => "key1=value1|key2=
|
192
|
+
[:payload, :context] => "key1=value1|key2=val\\|ue2",
|
193
193
|
[:payload, :public_ids] => ["some_public_id1", "some_public_id2"],
|
194
194
|
[:payload, :command] => "add"
|
195
195
|
}
|
196
196
|
expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
|
197
197
|
|
198
|
-
Cloudinary::Uploader.add_context( {:key1 =>
|
198
|
+
Cloudinary::Uploader.add_context( {:key1 => "value1", :key2 => "val|ue2"}, ["some_public_id1", "some_public_id2"])
|
199
199
|
end
|
200
200
|
end
|
201
201
|
|
202
202
|
describe "remove_all_context" do
|
203
|
-
it "should correctly remove all context"
|
203
|
+
it "should correctly remove all context" do
|
204
204
|
expected ={
|
205
205
|
:url => /.*\/context/,
|
206
206
|
[:payload, :public_ids] => ["some_public_id1", "some_public_id2"],
|
@@ -241,7 +241,7 @@ describe Cloudinary::Uploader do
|
|
241
241
|
|
242
242
|
it "should allow sending face coordinates" do
|
243
243
|
coordinates = [[120, 30, 109, 150], [121, 31, 110, 151]]
|
244
|
-
result_coordinates = [[120, 30, 109, 51], [121, 31, 110, 51]]
|
244
|
+
result_coordinates = [[120, 30, 109, 51], [121, 31, 110, 51]] # actual boundaries fitted by the server
|
245
245
|
result = Cloudinary::Uploader.upload(TEST_IMG, { :face_coordinates => coordinates, :faces => true, :tags => [TEST_TAG, TIMESTAMP_TAG]})
|
246
246
|
expect(result["faces"]).to eq(result_coordinates)
|
247
247
|
|
@@ -263,9 +263,16 @@ describe Cloudinary::Uploader do
|
|
263
263
|
expect(result["moderation"][0]["status"]).to eq("pending")
|
264
264
|
expect(result["moderation"][0]["kind"]).to eq("manual")
|
265
265
|
end
|
266
|
+
|
267
|
+
it "should support requesting ocr anlysis" do
|
268
|
+
expect(RestClient::Request).to receive(:execute) do |options|
|
269
|
+
expect(options[:payload][:ocr]).to eq(:adv_ocr)
|
270
|
+
end
|
271
|
+
Cloudinary::Uploader.upload(TEST_IMG, { :ocr => :adv_ocr, :tags => [TEST_TAG, TIMESTAMP_TAG]})
|
272
|
+
end
|
266
273
|
|
267
274
|
it "should support requesting raw conversion" do
|
268
|
-
expect{Cloudinary::Uploader.upload("spec/docx.docx", {:resource_type => :raw, :raw_convert => :illegal, :tags => [TEST_TAG, TIMESTAMP_TAG]})}.to raise_error(CloudinaryException, /Illegal value|not a valid/)
|
275
|
+
expect{Cloudinary::Uploader.upload("spec/docx.docx", {:resource_type => :raw, :raw_convert => :illegal, :tags => [TEST_TAG, TIMESTAMP_TAG]})}.to raise_error(CloudinaryException, /Illegal value|not a valid|is invalid/)
|
269
276
|
end
|
270
277
|
|
271
278
|
it "should support requesting categorization" do
|
@@ -292,13 +299,21 @@ describe Cloudinary::Uploader do
|
|
292
299
|
expect(result["format"]).to eq("bmp")
|
293
300
|
end
|
294
301
|
|
295
|
-
it "should allow fallback of upload large with remote url to regular upload"
|
302
|
+
it "should allow fallback of upload large with remote url to regular upload" do
|
296
303
|
file = "http://cloudinary.com/images/old_logo.png"
|
297
304
|
result = Cloudinary::Uploader.upload_large(file, :chunk_size => 5243000, :tags => [TEST_TAG, TIMESTAMP_TAG])
|
298
305
|
expect(result).to_not be_nil
|
299
306
|
expect(result["width"]).to eq(TEST_IMG_W)
|
300
307
|
expect(result["height"]).to eq(TEST_IMG_H)
|
301
308
|
end
|
309
|
+
|
310
|
+
it "should include special headers in upload_large" do
|
311
|
+
expect(RestClient::Request).to receive(:execute) do |options|
|
312
|
+
expect(options[:headers]["Content-Range"]).to_not be_empty
|
313
|
+
expect(options[:headers]["X-Unique-Upload-Id"]).to_not be_empty
|
314
|
+
end
|
315
|
+
Cloudinary::Uploader.upload_large(TEST_IMG, { :tags => [TEST_TAG, TIMESTAMP_TAG]})
|
316
|
+
end
|
302
317
|
|
303
318
|
context "unsigned" do
|
304
319
|
after do
|