cloudinary 1.9.1 → 1.10.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.
@@ -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
- let(:helper) { helper_class.new }
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.config({})
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('sample.jpg', options)) }
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 => 'test123',
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\/test123\/image\/authenticated\/v1486020273\/sample.jpg\?__cld_token__=st=11111111~exp=11111411~hmac=9bd6f41e2a5893da8343dc8eb648de8bf73771993a6d1457d49851250caf3b80.*>/
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 { Cloudinary::Static::METADATA_FILE = @static_file }
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/sdk-test/image/asset/images-foo.jpg")
185
- expect(helper.image_path('foo.jpg')).to eq("http://res.cloudinary.com/sdk-test/image/asset/images-foo.jpg")
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
@@ -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
@@ -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 :name, :attributes, :children, :text, :html_string
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 = REXML::Parsers::UltraLightParser.new( tag)
82
- parser.parse[0]
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
- attributes[symbol_or_string.to_s]
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
- @children.select{ |c| c[m[1]] == args[0]}
112
+ return unless children
113
+ children.select{ |c| c[m[1]] == args[0]}
93
114
  else
94
115
  super
95
116
  end
@@ -184,23 +184,23 @@ describe Cloudinary::Uploader do
184
184
  end
185
185
 
186
186
 
187
- describe "context", :focus => true do
187
+ describe "context" do
188
188
  describe "add_context" do
189
- it "should correctly add context", :focus => true do
189
+ it "should correctly add context" do
190
190
  expected ={
191
191
  :url => /.*\/context/,
192
- [:payload, :context] => "key1=value1|key2=value2",
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 => :value1, :key2 => :value2}, ["some_public_id1", "some_public_id2"])
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", :focus => true do
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", :focus => true do
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