cloudinary 1.11.1 → 1.18.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.
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
-