cloudinary 1.11.1 → 1.18.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +42 -0
  3. data/.github/ISSUE_TEMPLATE/feature_request.md +21 -0
  4. data/.github/pull_request_template.md +24 -0
  5. data/.gitignore +6 -1
  6. data/.travis.yml +15 -5
  7. data/CHANGELOG.md +149 -0
  8. data/Rakefile +3 -45
  9. data/cloudinary.gemspec +20 -4
  10. data/lib/active_storage/blob_key.rb +20 -0
  11. data/lib/active_storage/service/cloudinary_service.rb +229 -0
  12. data/lib/cloudinary.rb +31 -22
  13. data/lib/cloudinary/api.rb +173 -5
  14. data/lib/cloudinary/auth_token.rb +6 -4
  15. data/lib/cloudinary/carrier_wave.rb +3 -1
  16. data/lib/cloudinary/carrier_wave/remote.rb +3 -2
  17. data/lib/cloudinary/carrier_wave/storage.rb +2 -1
  18. data/lib/cloudinary/cloudinary_controller.rb +2 -4
  19. data/lib/cloudinary/helper.rb +30 -3
  20. data/lib/cloudinary/railtie.rb +7 -3
  21. data/lib/cloudinary/uploader.rb +35 -6
  22. data/lib/cloudinary/utils.rb +112 -40
  23. data/lib/cloudinary/version.rb +1 -1
  24. data/lib/cloudinary/video_helper.rb +96 -22
  25. data/lib/tasks/cloudinary/fetch_assets.rake +48 -0
  26. data/lib/tasks/{cloudinary.rake → cloudinary/sync_static.rake} +0 -0
  27. data/tools/allocate_test_cloud.sh +9 -0
  28. data/tools/get_test_cloud.sh +9 -0
  29. data/tools/update_version +29 -11
  30. data/vendor/assets/javascripts/cloudinary/jquery.cloudinary.js +48 -14
  31. data/vendor/assets/javascripts/cloudinary/jquery.fileupload.js +24 -4
  32. data/vendor/assets/javascripts/cloudinary/jquery.ui.widget.js +741 -561
  33. data/vendor/assets/javascripts/cloudinary/load-image.all.min.js +1 -1
  34. metadata +62 -67
  35. data/spec/access_control_spec.rb +0 -102
  36. data/spec/api_spec.rb +0 -567
  37. data/spec/archive_spec.rb +0 -129
  38. data/spec/auth_token_spec.rb +0 -77
  39. data/spec/cache_spec.rb +0 -109
  40. data/spec/cloudinary_helper_spec.rb +0 -325
  41. data/spec/cloudinary_spec.rb +0 -32
  42. data/spec/data/sync_static/app/assets/javascripts/1.coffee +0 -1
  43. data/spec/data/sync_static/app/assets/javascripts/1.js +0 -1
  44. data/spec/data/sync_static/app/assets/stylesheets/1.css +0 -3
  45. data/spec/docx.docx +0 -0
  46. data/spec/favicon.ico +0 -0
  47. data/spec/image_spec.rb +0 -107
  48. data/spec/logo.png +0 -0
  49. data/spec/rake_spec.rb +0 -160
  50. data/spec/sample_asset_file.tsv +0 -4
  51. data/spec/search_spec.rb +0 -109
  52. data/spec/spec_helper.rb +0 -266
  53. data/spec/storage_spec.rb +0 -44
  54. data/spec/streaminig_profiles_api_spec.rb +0 -74
  55. data/spec/support/helpers/temp_file_helpers.rb +0 -22
  56. data/spec/support/shared_contexts/rake.rb +0 -19
  57. data/spec/uploader_spec.rb +0 -392
  58. data/spec/utils_methods_spec.rb +0 -54
  59. data/spec/utils_spec.rb +0 -970
  60. data/spec/video_tag_spec.rb +0 -253
  61. data/spec/video_url_spec.rb +0 -185
@@ -1,44 +0,0 @@
1
- require 'spec_helper'
2
- require 'cloudinary'
3
-
4
- module CarrierWave
5
- module Storage
6
- class Abstract
7
- def initialize(uploader)
8
- @uploader = uploader
9
- end
10
-
11
- attr_accessor :uploader
12
- end
13
- end
14
- class SanitizedFile; end
15
- end
16
-
17
- RSpec.describe Cloudinary::CarrierWave::Storage do
18
- describe '#store_cloudinary_identifier' do
19
- let(:column) { 'example_field' }
20
- let(:model) { double :model, _mounter: mount, write_attribute: true }
21
- let(:mount) { double :mount, serialization_column: column }
22
- let(:storage) { Cloudinary::CarrierWave::Storage.new(uploader) }
23
- let(:store_identifier) { storage.store_cloudinary_identifier('1', 'test.png') }
24
- let(:uploader) { double :uploader, model: model, mounted_as: :example, use_extended_identifier?: false }
25
-
26
- describe 'when the ORM is Neo4j 5 and above' do
27
- before { stub_const('Neo4j::VERSION', '5.0') }
28
-
29
- subject! { store_identifier }
30
-
31
- it 'writes the name to the datastore without triggering validations' do
32
- expect(model).to have_received(:write_attribute).with(column, 'v1/test.png')
33
- end
34
- end
35
-
36
- describe 'when the ORM is Neo4j 4' do
37
- before { stub_const('Neo4j::VERSION', '4.0') }
38
-
39
- it 'raises an unsupported exception' do
40
- expect { store_identifier }.to raise_error(CloudinaryException)
41
- end
42
- end
43
- end
44
- end
@@ -1,74 +0,0 @@
1
- require 'spec_helper'
2
- require 'cloudinary'
3
-
4
- describe Cloudinary::Api do
5
- PREDEFINED_PROFILES = %w(4k full_hd hd sd full_hd_wifi full_hd_lean hd_lean)
6
- break puts('Please setup environment for api test to run') if Cloudinary.config.api_secret.blank?
7
- include_context 'cleanup', TIMESTAMP_TAG
8
-
9
- prefix = TEST_TAG + "_#{Time.now.to_i}"
10
- test_id_1 = "#{prefix}_1"
11
- test_id_2 = "#{prefix}_2"
12
- test_id_3 = "#{prefix}_3"
13
- before(:all) do
14
-
15
- @api = Cloudinary::Api
16
- end
17
-
18
- describe 'create_streaming_profile' do
19
- it 'should create a streaming profile with representations' do
20
- result = @api.create_streaming_profile test_id_1, :representations =>
21
- [{:transformation => {:crop => 'scale', :width => '1200', :height => '1200', :bit_rate => '5m'}}]
22
- expect(result).not_to be_blank
23
- end
24
- it 'should create a streaming profile with an array of transformation' do
25
- result = @api.create_streaming_profile test_id_1 + 'a', :representations =>
26
- [{:transformation => [{:crop => 'scale', :width => '1200', :height => '1200', :bit_rate => '5m'}]}]
27
- expect(result).not_to be_blank
28
- end
29
- end
30
-
31
- describe 'list_streaming_profile' do
32
- it 'should list streaming profile' do
33
- result = @api.list_streaming_profiles
34
- expect(result).to have_key('data')
35
- expect(result['data'].map{|p| p['name']}).to include(*PREDEFINED_PROFILES)
36
- end
37
- end
38
-
39
- describe 'delete_streaming_profile' do
40
- it 'should delete a streaming profile' do
41
- result = @api.create_streaming_profile test_id_2, :representations =>
42
- [{:transformation => {:crop => 'scale', :width => '1200', :height => '1200', :bit_rate => '5m'}}]
43
- expect(result).not_to be_blank
44
- result = @api.delete_streaming_profile test_id_2
45
- expect(result).to have_key('message')
46
- expect(result['message']).to eq('deleted')
47
- result = @api.list_streaming_profiles
48
- expect(result['data'].map{|p| p['name']}).not_to include(test_id_2)
49
- end
50
- end
51
-
52
- describe 'get_streaming_profile' do
53
- it 'should get a specific streaming profile' do
54
- result = @api.get_streaming_profile(PREDEFINED_PROFILES[1])
55
- expect(result['data'].keys).to include('name', 'display_name', 'representations')
56
- end
57
- end
58
-
59
- describe 'update_streaming_profile' do
60
- it 'should create a streaming profile with representations' do
61
- result = @api.create_streaming_profile test_id_3, :representations =>
62
- [{:transformation => {:crop => 'scale', :width => '1200', :height => '1200', :bit_rate => '5m'}}]
63
- expect(result).not_to be_blank
64
- result = @api.update_streaming_profile test_id_3, :representations =>
65
- [{:transformation => {:crop => 'scale', :width => '1000', :height => '1000', :bit_rate => '4m'}}]
66
- expect(result).not_to be_blank
67
- result = @api.get_streaming_profile(test_id_3)
68
- result = result['data']
69
- expect(result['representations'].length).to eq(1)
70
- # Notice transformation is always returned as an array; numeric values represented as numbers, not strings
71
- expect(result['representations'][0]).to eq({'transformation' => ['crop' => 'scale', 'width' => 1000, 'height' => 1000, 'bit_rate' => '4m']})
72
- end
73
- end
74
- end
@@ -1,22 +0,0 @@
1
- module Helpers
2
- module TempFileHelpers
3
- def clean_up_temp_files!
4
- FileUtils.remove_entry temp_root
5
- end
6
-
7
- def temp_root
8
- @temp_root ||= Dir.mktmpdir 'test_root'
9
- end
10
-
11
- def copy_root_to_temp(source)
12
- source = File.join(RSpec.project_root, source) unless Pathname.new(source).directory?
13
- FileUtils.copy_entry source, temp_root
14
- end
15
-
16
- def copy_file_to_temp(source, dest)
17
- dest_path = File.join(temp_root, dest)
18
- FileUtils.mkdir_p(File.dirname(dest_path))
19
- FileUtils.copy_entry(File.join(RSpec.project_root, source), dest_path)
20
- end
21
- end
22
- end
@@ -1,19 +0,0 @@
1
- require "rake"
2
-
3
- # From https://robots.thoughtbot.com/test-rake-tasks-like-a-boss
4
- shared_context "rake" do
5
- let(:rake) { Rake::Application.new }
6
- let(:task_name) { self.class.top_level_description }
7
- let(:task_path) { "lib/tasks/#{task_name.split(":").first}" }
8
- subject { rake[task_name] }
9
-
10
- def loaded_files_excluding_current_rake_file
11
- $".reject {|file| file == Pathname.new(RSpec.project_root).join("#{task_path}.rake").to_s }
12
- end
13
-
14
- before do
15
- Rake.application = rake
16
- Rake.application.rake_require(task_path, [RSpec.project_root], loaded_files_excluding_current_rake_file)
17
- Rake::Task.define_task(:environment)
18
- end
19
- end
@@ -1,392 +0,0 @@
1
- require 'spec_helper'
2
- require 'cloudinary'
3
-
4
- RSpec.configure do |c|
5
- c.filter_run_excluding :large => true
6
- end
7
-
8
- describe Cloudinary::Uploader do
9
- break puts("Please setup environment for api test to run") if Cloudinary.config.api_secret.blank?
10
- include_context "cleanup", TIMESTAMP_TAG
11
-
12
- it "should successfully upload file" do
13
- result = Cloudinary::Uploader.upload(TEST_IMG, :tags => [TEST_TAG, TIMESTAMP_TAG])
14
- expect(result["width"]).to eq(TEST_IMG_W)
15
- expect(result["height"]).to eq(TEST_IMG_H)
16
- expected_signature = Cloudinary::Utils.api_sign_request({:public_id=>result["public_id"], :version=>result["version"]}, Cloudinary.config.api_secret)
17
- expect(result["signature"]).to eq(expected_signature)
18
- end
19
-
20
- it "should successfully upload a file from pathname", :pathname => true do
21
- result = Cloudinary::Uploader.upload(Pathname.new(TEST_IMG), :tags => [TEST_TAG, TIMESTAMP_TAG])
22
- expect(result["width"]).to eq(TEST_IMG_W)
23
- end
24
-
25
- it "should successfully upload file by url" do
26
- result = Cloudinary::Uploader.upload("http://cloudinary.com/images/old_logo.png", :tags => [TEST_TAG, TIMESTAMP_TAG])
27
- expect(result["width"]).to eq(TEST_IMG_W)
28
- expect(result["height"]).to eq(TEST_IMG_H)
29
- expected_signature = Cloudinary::Utils.api_sign_request({:public_id=>result["public_id"], :version=>result["version"]}, Cloudinary.config.api_secret)
30
- expect(result["signature"]).to eq(expected_signature)
31
- end
32
-
33
- it "should successfully upload file asynchronously" do
34
- result = Cloudinary::Uploader.upload(Pathname.new(TEST_IMG), :async => true)
35
- expect(result["status"]).to eq("pending")
36
- end
37
-
38
- it "should support the quality_analysis parameter" do
39
- result = Cloudinary::Uploader.upload(Pathname.new(TEST_IMG), :quality_analysis => true, :tags => [TEST_TAG, TIMESTAMP_TAG])
40
- expect(result).to have_key("quality_analysis")
41
- expect(result["quality_analysis"]).to have_key("focus")
42
- end
43
-
44
- it "should support the quality_override parameter" do
45
- ['auto:advanced', 'auto:best', '80:420', 'none'].each do |q|
46
- expected = {[:payload, :quality_override] => q}
47
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
48
- Cloudinary::Uploader.upload Pathname.new(TEST_IMG), :quality_override => q
49
- end
50
- end
51
-
52
- describe '.rename' do
53
- before(:all) do
54
- @result = Cloudinary::Uploader.upload(TEST_IMG, :tags => [TEST_TAG, TIMESTAMP_TAG])
55
- @resource_1_id = @result["public_id"]
56
- @resource_1_type = @result["type"]
57
- result = Cloudinary::Uploader.upload("spec/favicon.ico", :tags => [TEST_TAG, TIMESTAMP_TAG])
58
- @resource_2_id = result["public_id"]
59
- end
60
-
61
- it 'should rename a resource' do
62
- Cloudinary::Uploader.rename(@resource_1_id, @resource_1_id+"2")
63
- expect(Cloudinary::Api.resource(@resource_1_id+"2")).not_to be_nil
64
- @resource_1_id = @resource_1_id+"2" # will not update if expect fails
65
- end
66
- it 'should not allow renaming to an existing ID' do
67
- id = @resource_2_id
68
- @resource_2_id = @resource_1_id+"2" # if rename doesn't fail, this is the new ID
69
- expect { Cloudinary::Uploader.rename(id, @resource_1_id+"2") }.to raise_error(CloudinaryException)
70
- @resource_2_id = id
71
- end
72
- it 'should allow changing type of an uploaded resource' do
73
- id = @resource_2_id
74
- from_type = @resource_1_type
75
- to_type = "private"
76
- Cloudinary::Uploader.rename(id, id, :type => from_type, :to_type => to_type)
77
- expect(Cloudinary::Api.resource(id, type: to_type)).to_not be_empty
78
- Cloudinary::Uploader.rename(id, id, :type => to_type, :to_type => from_type)
79
- end
80
- context ':overwrite => true' do
81
- it 'should rename to an existing ID' do
82
- new_id = Cloudinary::Uploader.upload(TEST_IMG, :tags => [TEST_TAG, TIMESTAMP_TAG])["public_id"]
83
- Cloudinary::Uploader.rename(@resource_2_id, new_id, :overwrite => true)
84
- expect(Cloudinary::Api.resource(new_id)["format"]).to eq("ico")
85
- @resource_2_id = new_id # will not update if expect fails
86
- end
87
- end
88
- context ':invalidate => true' do
89
- it 'should notify the server to invalidate the resource in the CDN' do
90
- # Can't test the result, so we just verify the parameter is send to the server
91
- expected ={
92
- :url => /.*\/rename$/,
93
- [:payload, :invalidate] => 1,
94
- [:payload, :from_public_id] => @resource_2_id,
95
- [:payload, :to_public_id] => @resource_2_id+"2"
96
- }
97
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
98
- Cloudinary::Uploader.rename(@resource_2_id, @resource_2_id+"2", :invalidate => true) # will not affect the server
99
- end
100
-
101
- end
102
- end
103
-
104
- it "should support explicit" do
105
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value( [:payload, :public_id] => "sample", [:payload, :eager] => "c_scale,w_2.0"))
106
- result = Cloudinary::Uploader.explicit("sample", :type=>"upload", :eager=>[{:crop=>"scale", :width=>"2.0"}])
107
- end
108
-
109
- it "should support eager" do
110
- result = Cloudinary::Uploader.upload(TEST_IMG, :eager =>[{ :crop =>"scale", :width =>"2.0"}], :tags => [TEST_TAG, TIMESTAMP_TAG])
111
- expect(result["eager"].length).to be(1)
112
- expect(result).to have_deep_hash_values_of(["eager", 0, "transformation"] => "c_scale,w_2.0")
113
- result = Cloudinary::Uploader.upload(TEST_IMG, :eager =>"c_scale,w_2.0", :tags => [TEST_TAG, TIMESTAMP_TAG])
114
- expect(result["eager"].length).to be(1)
115
- expect(result).to have_deep_hash_values_of(["eager", 0, "transformation"] => "c_scale,w_2.0")
116
- result = Cloudinary::Uploader.upload(TEST_IMG, :eager =>[
117
- "c_scale,w_2.0",
118
- { :crop =>"crop", :width =>"0.5", :format => "tiff"},
119
- [[{:crop =>"crop", :width =>"0.5"},{:angle =>90}]],
120
- [[{:crop =>"crop", :width =>"0.5"},{:angle =>90}],"tiff"]
121
- ], :tags => [TEST_TAG, TIMESTAMP_TAG])
122
- expect(result["eager"].length).to be(4)
123
- expect(result).to have_deep_hash_values_of(
124
- ["eager", 0, "transformation"] => "c_scale,w_2.0",
125
- ["eager", 1, "transformation"] => "c_crop,w_0.5/tiff",
126
- ["eager", 2, "transformation"] => "c_crop,w_0.5/a_90",
127
- ["eager", 3, "transformation"] => "c_crop,w_0.5/a_90/tiff"
128
- )
129
- end
130
-
131
- it "should support headers" do
132
- Cloudinary::Uploader.upload(TEST_IMG, :headers =>["Link: 1"], :tags => [TEST_TAG, TIMESTAMP_TAG])
133
- Cloudinary::Uploader.upload(TEST_IMG, :headers =>{ "Link" => "1"}, :tags => [TEST_TAG, TIMESTAMP_TAG])
134
- end
135
-
136
- it "should successfully generate text image" do
137
- result = Cloudinary::Uploader.text("hello world", :tags => [TEST_TAG, TIMESTAMP_TAG])
138
- expect(result["width"]).to be > 1
139
- expect(result["height"]).to be > 1
140
- end
141
-
142
- describe "tag" do
143
- describe "add_tag" do
144
- it "should correctly add tags" do
145
- expected ={
146
- :url => /.*\/tags/,
147
- [:payload, :tag] => "new_tag",
148
- [:payload, :public_ids] => ["some_public_id1", "some_public_id2"],
149
- [:payload, :command] => "add"
150
- }
151
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
152
-
153
- Cloudinary::Uploader.add_tag( "new_tag", ["some_public_id1", "some_public_id2"])
154
- end
155
- end
156
-
157
- describe "remove_tag" do
158
- it "should correctly remove tag" do
159
- expected ={
160
- :url => /.*\/tags/,
161
- [:payload, :tag] => "tag",
162
- [:payload, :public_ids] => ["some_public_id1", "some_public_id2"],
163
- [:payload, :command] => "remove"
164
- }
165
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
166
-
167
- Cloudinary::Uploader.remove_tag("tag", ["some_public_id1", "some_public_id2"])
168
- end
169
- end
170
-
171
- describe "replace_tag" do
172
- it "should correctly replace tag" do
173
- expected ={
174
- :url => /.*\/tags/,
175
- [:payload, :tag] => "tag",
176
- [:payload, :public_ids] => ["some_public_id1", "some_public_id2"],
177
- [:payload, :command] => "replace"
178
- }
179
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
180
-
181
- Cloudinary::Uploader.replace_tag("tag", ["some_public_id1", "some_public_id2"])
182
- end
183
- end
184
-
185
- describe "remove_all_tags" do
186
- it "should correctly remove all tags" do
187
- expected ={
188
- :url => /.*\/tags/,
189
- [:payload, :public_ids] => ["some_public_id1", "some_public_id2"],
190
- [:payload, :command] => "remove_all"
191
- }
192
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
193
-
194
- Cloudinary::Uploader.remove_all_tags(["some_public_id1", "some_public_id2"])
195
- end
196
- end
197
-
198
- end
199
-
200
-
201
- describe "context" do
202
- describe "add_context" do
203
- it "should correctly add context" do
204
- expected ={
205
- :url => /.*\/context/,
206
- [:payload, :context] => "key1=value1|key2=val\\|ue2",
207
- [:payload, :public_ids] => ["some_public_id1", "some_public_id2"],
208
- [:payload, :command] => "add"
209
- }
210
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
211
-
212
- Cloudinary::Uploader.add_context( {:key1 => "value1", :key2 => "val|ue2"}, ["some_public_id1", "some_public_id2"])
213
- end
214
- end
215
-
216
- describe "remove_all_context" do
217
- it "should correctly remove all context" do
218
- expected ={
219
- :url => /.*\/context/,
220
- [:payload, :public_ids] => ["some_public_id1", "some_public_id2"],
221
- [:payload, :command] => "remove_all",
222
- [:payload, :type] => "private"
223
-
224
- }
225
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
226
-
227
- Cloudinary::Uploader.remove_all_context(["some_public_id1", "some_public_id2"], :type => "private")
228
- end
229
- end
230
-
231
- end
232
-
233
-
234
-
235
- it "should correctly handle unique_filename" do
236
- result = Cloudinary::Uploader.upload(TEST_IMG, :use_filename => true, :tags => [TEST_TAG, TIMESTAMP_TAG])
237
- expect(result["public_id"]).to match(/logo_[a-zA-Z0-9]{6}/)
238
- result = Cloudinary::Uploader.upload(TEST_IMG, :use_filename => true, :unique_filename => false, :tags => [TEST_TAG, TIMESTAMP_TAG])
239
- expect(result["public_id"]).to eq("logo")
240
- end
241
-
242
- it "should allow whitelisted formats if allowed_formats", :allowed=>true do
243
- result = Cloudinary::Uploader.upload(TEST_IMG, :allowed_formats => ["png"], :tags => [TEST_TAG, TIMESTAMP_TAG])
244
- expect(result["format"]).to eq("png")
245
- end
246
-
247
- it "should prevent non whitelisted formats from being uploaded if allowed_formats is specified", :allowed=>true do
248
- expect{Cloudinary::Uploader.upload(TEST_IMG, :allowed_formats => ["jpg"], :tags => [TEST_TAG, TIMESTAMP_TAG])}.to raise_error(CloudinaryException)
249
- end
250
-
251
- it "should allow non whitelisted formats if type is specified and convert to that type", :allowed=>true do
252
- result = Cloudinary::Uploader.upload(TEST_IMG, :allowed_formats => ["jpg"], :format => "jpg", :tags => [TEST_TAG, TIMESTAMP_TAG])
253
- expect(result["format"]).to eq("jpg")
254
- end
255
-
256
- it "should allow sending face coordinates" do
257
- coordinates = [[120, 30, 109, 150], [121, 31, 110, 151]]
258
- result_coordinates = [[120, 30, 109, 51], [121, 31, 110, 51]] # actual boundaries fitted by the server
259
- result = Cloudinary::Uploader.upload(TEST_IMG, { :face_coordinates => coordinates, :faces => true, :tags => [TEST_TAG, TIMESTAMP_TAG]})
260
- expect(result["faces"]).to eq(result_coordinates)
261
-
262
- different_coordinates = [[122, 32, 111, 152]]
263
- Cloudinary::Uploader.explicit(result["public_id"], {:face_coordinates => different_coordinates, :faces => true, :type => "upload", :tags => [TEST_TAG, TIMESTAMP_TAG]})
264
- info = Cloudinary::Api.resource(result["public_id"], {:faces => true})
265
- expect(info["faces"]).to eq(different_coordinates)
266
- end
267
-
268
- it "should allow sending context" do
269
- context = {"key1"=>'value1', "key2" => 'valu\e2', "key3" => 'val=u|e3', "key4" => 'val\=ue'}
270
- result = Cloudinary::Uploader.upload(TEST_IMG, { :context => context, :tags => [TEST_TAG, TIMESTAMP_TAG]})
271
- info = Cloudinary::Api.resource(result["public_id"], {:context => true})
272
- expect(info["context"]).to eq({"custom" => context})
273
- end
274
-
275
- it "should support requesting manual moderation" do
276
- result = Cloudinary::Uploader.upload(TEST_IMG, { :moderation => :manual, :tags => [TEST_TAG, TIMESTAMP_TAG]})
277
- expect(result["moderation"][0]["status"]).to eq("pending")
278
- expect(result["moderation"][0]["kind"]).to eq("manual")
279
- end
280
-
281
- it "should support requesting ocr anlysis" do
282
- expect(RestClient::Request).to receive(:execute) do |options|
283
- expect(options[:payload][:ocr]).to eq(:adv_ocr)
284
- end
285
- Cloudinary::Uploader.upload(TEST_IMG, { :ocr => :adv_ocr, :tags => [TEST_TAG, TIMESTAMP_TAG]})
286
- end
287
-
288
- it "should support requesting raw conversion" do
289
- 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/)
290
- end
291
-
292
- it "should support requesting categorization" do
293
- expect{Cloudinary::Uploader.upload(TEST_IMG, { :categorization => :illegal, :tags => [TEST_TAG, TIMESTAMP_TAG]})}.to raise_error(CloudinaryException, /Illegal value|not a valid|is not valid/)
294
- end
295
-
296
- it "should support requesting detection" do
297
- expect{Cloudinary::Uploader.upload(TEST_IMG, { :detection => :illegal, :tags => [TEST_TAG, TIMESTAMP_TAG]})}.to raise_error(CloudinaryException, /Detection is invalid/)
298
- end
299
-
300
- it "should support upload_large", :large => true do
301
- io = StringIO.new
302
- header = "BMJ\xB9Y\x00\x00\x00\x00\x00\x8A\x00\x00\x00|\x00\x00\x00x\x05\x00\x00x\x05\x00\x00\x01\x00\x18\x00\x00\x00\x00\x00\xC0\xB8Y\x00a\x0F\x00\x00a\x0F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\xFFBGRs\x00\x00\x00\x00\x00\x00\x00\x00T\xB8\x1E\xFC\x00\x00\x00\x00\x00\x00\x00\x00fff\xFC\x00\x00\x00\x00\x00\x00\x00\x00\xC4\xF5(\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
303
- io.puts(header)
304
- 5880000.times{ io.write("\xFF") }
305
- io.rewind
306
- result = Cloudinary::Uploader.upload_large(io, :chunk_size => 5243000, :tags => [TEST_TAG, TIMESTAMP_TAG])
307
- expect(result["resource_type"]).to eq('raw')
308
- io.rewind
309
- result = Cloudinary::Uploader.upload_large(io, :resource_type => 'image', :chunk_size => 5243000, :tags => [TEST_TAG, TIMESTAMP_TAG])
310
- expect(result["resource_type"]).to eq('image')
311
- expect(result["width"]).to eq(1400)
312
- expect(result["height"]).to eq(1400)
313
- expect(result["format"]).to eq("bmp")
314
- end
315
-
316
- it "should allow fallback of upload large with remote url to regular upload" do
317
- file = "http://cloudinary.com/images/old_logo.png"
318
- result = Cloudinary::Uploader.upload_large(file, :chunk_size => 5243000, :tags => [TEST_TAG, TIMESTAMP_TAG])
319
- expect(result).to_not be_nil
320
- expect(result["width"]).to eq(TEST_IMG_W)
321
- expect(result["height"]).to eq(TEST_IMG_H)
322
- end
323
-
324
- it "should include special headers in upload_large" do
325
- expect(RestClient::Request).to receive(:execute) do |options|
326
- expect(options[:headers]["Content-Range"]).to_not be_empty
327
- expect(options[:headers]["X-Unique-Upload-Id"]).to_not be_empty
328
- end
329
- Cloudinary::Uploader.upload_large(TEST_IMG, { :tags => [TEST_TAG, TIMESTAMP_TAG]})
330
- end
331
-
332
- context "unsigned" do
333
- after do
334
- Cloudinary.class_variable_set(:@@config, nil)
335
- end
336
-
337
- it "should support unsigned uploading using presets", :upload_preset => true do
338
- preset = Cloudinary::Api.create_upload_preset(:folder => "test_folder_upload", :unsigned => true, :tags => [TEST_TAG, TIMESTAMP_TAG])
339
-
340
- Cloudinary.config.api_key = nil
341
- Cloudinary.config.api_secret = nil
342
-
343
- result = Cloudinary::Uploader.unsigned_upload(TEST_IMG, preset["name"], :tags => [TEST_TAG, TIMESTAMP_TAG])
344
- expect(result["public_id"]).to match(/^test_folder_upload\/[a-z0-9]+$/)
345
-
346
- Cloudinary.class_variable_set(:@@config, nil)
347
-
348
- end
349
- end
350
-
351
- describe ":timeout" do
352
- before do
353
- @timeout = Cloudinary.config.timeout
354
- Cloudinary.config.timeout = 0.01
355
- end
356
- after do
357
- Cloudinary.config.timeout = @timeout
358
- end
359
-
360
- it "should fail if timeout is reached" do
361
- expect{Cloudinary::Uploader.upload(Pathname.new(TEST_IMG), :tags => [TEST_TAG, TIMESTAMP_TAG])}.to raise_error(RestClient::RequestTimeout)
362
- end
363
- end
364
-
365
- context ":responsive_breakpoints" do
366
- context ":create_derived with transformation and format conversion" do
367
- expected ={
368
- :url => /.*\/upload$/,
369
- [:payload, :responsive_breakpoints] => %r("transformation":"e_sepia/jpg"),
370
- [:payload, :responsive_breakpoints] => %r("transformation":"gif"),
371
- [:payload, :responsive_breakpoints] => %r("create_derived":true)
372
- }
373
- it 'should return a proper responsive_breakpoints hash in the response' do
374
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
375
- Cloudinary::Uploader.upload(TEST_IMG, responsive_breakpoints:[{transformation:{effect: "sepia"}, format:"jpg", bytes_step:20000, create_derived: true, :min_width => 200, :max_width => 1000, :max_images => 20},{format:"gif", create_derived:true, bytes_step:20000, :min_width => 200, :max_width => 1000, :max_images => 20}], :tags => [TEST_TAG, TIMESTAMP_TAG])
376
- end
377
- end
378
- end
379
-
380
-
381
-
382
- describe 'explicit' do
383
-
384
- context ":invalidate" do
385
- it 'should pass the invalidate value to the server' do
386
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value( [:payload, :invalidate] => 1))
387
- Cloudinary::Uploader.explicit("cloudinary", :type=>"twitter_name", :eager=>[{:crop=>"scale", :width=>"2.0"}], :invalidate => true, :tags => [TEST_TAG, TIMESTAMP_TAG])
388
- end
389
- end
390
- end
391
- end
392
-