cloudinary 1.9.1 → 1.20.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 (72) hide show
  1. checksums.yaml +5 -5
  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 +7 -1
  6. data/.travis.yml +15 -8
  7. data/CHANGELOG.md +261 -0
  8. data/README.md +3 -0
  9. data/Rakefile +3 -45
  10. data/cloudinary.gemspec +27 -20
  11. data/lib/active_storage/blob_key.rb +20 -0
  12. data/lib/active_storage/service/cloudinary_service.rb +249 -0
  13. data/lib/cloudinary.rb +53 -63
  14. data/lib/cloudinary/account_api.rb +231 -0
  15. data/lib/cloudinary/account_config.rb +30 -0
  16. data/lib/cloudinary/api.rb +228 -71
  17. data/lib/cloudinary/auth_token.rb +10 -4
  18. data/lib/cloudinary/base_api.rb +79 -0
  19. data/lib/cloudinary/base_config.rb +70 -0
  20. data/lib/cloudinary/cache.rb +38 -0
  21. data/lib/cloudinary/cache/breakpoints_cache.rb +31 -0
  22. data/lib/cloudinary/cache/key_value_cache_adapter.rb +25 -0
  23. data/lib/cloudinary/cache/rails_cache_adapter.rb +34 -0
  24. data/lib/cloudinary/cache/storage/rails_cache_storage.rb +5 -0
  25. data/lib/cloudinary/carrier_wave.rb +4 -2
  26. data/lib/cloudinary/carrier_wave/remote.rb +3 -2
  27. data/lib/cloudinary/carrier_wave/storage.rb +2 -1
  28. data/lib/cloudinary/{controller.rb → cloudinary_controller.rb} +3 -5
  29. data/lib/cloudinary/config.rb +43 -0
  30. data/lib/cloudinary/helper.rb +77 -7
  31. data/lib/cloudinary/migrator.rb +3 -1
  32. data/lib/cloudinary/railtie.rb +7 -3
  33. data/lib/cloudinary/responsive.rb +111 -0
  34. data/lib/cloudinary/uploader.rb +67 -15
  35. data/lib/cloudinary/utils.rb +324 -54
  36. data/lib/cloudinary/version.rb +1 -1
  37. data/lib/cloudinary/video_helper.rb +96 -22
  38. data/lib/tasks/cloudinary/fetch_assets.rake +48 -0
  39. data/lib/tasks/{cloudinary.rake → cloudinary/sync_static.rake} +0 -0
  40. data/tools/allocate_test_cloud.sh +9 -0
  41. data/tools/get_test_cloud.sh +9 -0
  42. data/tools/update_version +220 -0
  43. data/vendor/assets/javascripts/cloudinary/jquery.cloudinary.js +51 -13
  44. data/vendor/assets/javascripts/cloudinary/jquery.fileupload.js +24 -4
  45. data/vendor/assets/javascripts/cloudinary/jquery.ui.widget.js +741 -561
  46. data/vendor/assets/javascripts/cloudinary/load-image.all.min.js +1 -1
  47. metadata +92 -67
  48. data/spec/access_control_spec.rb +0 -99
  49. data/spec/api_spec.rb +0 -545
  50. data/spec/archive_spec.rb +0 -129
  51. data/spec/auth_token_spec.rb +0 -79
  52. data/spec/cloudinary_helper_spec.rb +0 -190
  53. data/spec/cloudinary_spec.rb +0 -32
  54. data/spec/data/sync_static/app/assets/javascripts/1.coffee +0 -1
  55. data/spec/data/sync_static/app/assets/javascripts/1.js +0 -1
  56. data/spec/data/sync_static/app/assets/stylesheets/1.css +0 -3
  57. data/spec/docx.docx +0 -0
  58. data/spec/favicon.ico +0 -0
  59. data/spec/logo.png +0 -0
  60. data/spec/rake_spec.rb +0 -160
  61. data/spec/sample_asset_file.tsv +0 -4
  62. data/spec/search_spec.rb +0 -109
  63. data/spec/spec_helper.rb +0 -245
  64. data/spec/storage_spec.rb +0 -44
  65. data/spec/streaminig_profiles_api_spec.rb +0 -74
  66. data/spec/support/helpers/temp_file_helpers.rb +0 -22
  67. data/spec/support/shared_contexts/rake.rb +0 -19
  68. data/spec/uploader_spec.rb +0 -363
  69. data/spec/utils_methods_spec.rb +0 -54
  70. data/spec/utils_spec.rb +0 -906
  71. data/spec/video_tag_spec.rb +0 -251
  72. data/spec/video_url_spec.rb +0 -164
data/spec/storage_spec.rb DELETED
@@ -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,363 +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
- describe '.rename' do
39
- before(:all) do
40
- @result = Cloudinary::Uploader.upload(TEST_IMG, :tags => [TEST_TAG, TIMESTAMP_TAG])
41
- @resource_1_id = @result["public_id"]
42
- @resource_1_type = @result["type"]
43
- result = Cloudinary::Uploader.upload("spec/favicon.ico", :tags => [TEST_TAG, TIMESTAMP_TAG])
44
- @resource_2_id = result["public_id"]
45
- end
46
-
47
- it 'should rename a resource' do
48
- Cloudinary::Uploader.rename(@resource_1_id, @resource_1_id+"2")
49
- expect(Cloudinary::Api.resource(@resource_1_id+"2")).not_to be_nil
50
- @resource_1_id = @resource_1_id+"2" # will not update if expect fails
51
- end
52
- it 'should not allow renaming to an existing ID' do
53
- id = @resource_2_id
54
- @resource_2_id = @resource_1_id+"2" # if rename doesn't fail, this is the new ID
55
- expect { Cloudinary::Uploader.rename(id, @resource_1_id+"2") }.to raise_error(CloudinaryException)
56
- @resource_2_id = id
57
- end
58
- it 'should allow changing type of an uploaded resource' do
59
- id = @resource_2_id
60
- from_type = @resource_1_type
61
- to_type = "private"
62
- Cloudinary::Uploader.rename(id, id, :type => from_type, :to_type => to_type)
63
- expect(Cloudinary::Api.resource(id, type: to_type)).to_not be_empty
64
- Cloudinary::Uploader.rename(id, id, :type => to_type, :to_type => from_type)
65
- end
66
- context ':overwrite => true' do
67
- it 'should rename to an existing ID' do
68
- new_id = Cloudinary::Uploader.upload(TEST_IMG, :tags => [TEST_TAG, TIMESTAMP_TAG])["public_id"]
69
- Cloudinary::Uploader.rename(@resource_2_id, new_id, :overwrite => true)
70
- expect(Cloudinary::Api.resource(new_id)["format"]).to eq("ico")
71
- @resource_2_id = new_id # will not update if expect fails
72
- end
73
- end
74
- context ':invalidate => true' do
75
- it 'should notify the server to invalidate the resource in the CDN' do
76
- # Can't test the result, so we just verify the parameter is send to the server
77
- expected ={
78
- :url => /.*\/rename$/,
79
- [:payload, :invalidate] => 1,
80
- [:payload, :from_public_id] => @resource_2_id,
81
- [:payload, :to_public_id] => @resource_2_id+"2"
82
- }
83
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
84
- Cloudinary::Uploader.rename(@resource_2_id, @resource_2_id+"2", :invalidate => true) # will not affect the server
85
- end
86
-
87
- end
88
- end
89
-
90
- it "should support explicit" do
91
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value( [:payload, :public_id] => "sample", [:payload, :eager] => "c_scale,w_2.0"))
92
- result = Cloudinary::Uploader.explicit("sample", :type=>"upload", :eager=>[{:crop=>"scale", :width=>"2.0"}])
93
- end
94
-
95
- it "should support eager" do
96
- result = Cloudinary::Uploader.upload(TEST_IMG, :eager =>[{ :crop =>"scale", :width =>"2.0"}], :tags => [TEST_TAG, TIMESTAMP_TAG])
97
- expect(result["eager"].length).to be(1)
98
- expect(result).to have_deep_hash_values_of(["eager", 0, "transformation"] => "c_scale,w_2.0")
99
- result = Cloudinary::Uploader.upload(TEST_IMG, :eager =>"c_scale,w_2.0", :tags => [TEST_TAG, TIMESTAMP_TAG])
100
- expect(result["eager"].length).to be(1)
101
- expect(result).to have_deep_hash_values_of(["eager", 0, "transformation"] => "c_scale,w_2.0")
102
- result = Cloudinary::Uploader.upload(TEST_IMG, :eager =>[
103
- "c_scale,w_2.0",
104
- { :crop =>"crop", :width =>"0.5", :format => "tiff"},
105
- [[{:crop =>"crop", :width =>"0.5"},{:angle =>90}]],
106
- [[{:crop =>"crop", :width =>"0.5"},{:angle =>90}],"tiff"]
107
- ], :tags => [TEST_TAG, TIMESTAMP_TAG])
108
- expect(result["eager"].length).to be(4)
109
- expect(result).to have_deep_hash_values_of(
110
- ["eager", 0, "transformation"] => "c_scale,w_2.0",
111
- ["eager", 1, "transformation"] => "c_crop,w_0.5/tiff",
112
- ["eager", 2, "transformation"] => "c_crop,w_0.5/a_90",
113
- ["eager", 3, "transformation"] => "c_crop,w_0.5/a_90/tiff"
114
- )
115
- end
116
-
117
- it "should support headers" do
118
- Cloudinary::Uploader.upload(TEST_IMG, :headers =>["Link: 1"], :tags => [TEST_TAG, TIMESTAMP_TAG])
119
- Cloudinary::Uploader.upload(TEST_IMG, :headers =>{ "Link" => "1"}, :tags => [TEST_TAG, TIMESTAMP_TAG])
120
- end
121
-
122
- it "should successfully generate text image" do
123
- result = Cloudinary::Uploader.text("hello world", :tags => [TEST_TAG, TIMESTAMP_TAG])
124
- expect(result["width"]).to be > 1
125
- expect(result["height"]).to be > 1
126
- end
127
-
128
- describe "tag" do
129
- describe "add_tag" do
130
- it "should correctly add tags" do
131
- expected ={
132
- :url => /.*\/tags/,
133
- [:payload, :tag] => "new_tag",
134
- [:payload, :public_ids] => ["some_public_id1", "some_public_id2"],
135
- [:payload, :command] => "add"
136
- }
137
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
138
-
139
- Cloudinary::Uploader.add_tag( "new_tag", ["some_public_id1", "some_public_id2"])
140
- end
141
- end
142
-
143
- describe "remove_tag" do
144
- it "should correctly remove tag" do
145
- expected ={
146
- :url => /.*\/tags/,
147
- [:payload, :tag] => "tag",
148
- [:payload, :public_ids] => ["some_public_id1", "some_public_id2"],
149
- [:payload, :command] => "remove"
150
- }
151
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
152
-
153
- Cloudinary::Uploader.remove_tag("tag", ["some_public_id1", "some_public_id2"])
154
- end
155
- end
156
-
157
- describe "replace_tag" do
158
- it "should correctly replace tag" do
159
- expected ={
160
- :url => /.*\/tags/,
161
- [:payload, :tag] => "tag",
162
- [:payload, :public_ids] => ["some_public_id1", "some_public_id2"],
163
- [:payload, :command] => "replace"
164
- }
165
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
166
-
167
- Cloudinary::Uploader.replace_tag("tag", ["some_public_id1", "some_public_id2"])
168
- end
169
- end
170
-
171
- describe "remove_all_tags" do
172
- it "should correctly remove all tags" do
173
- expected ={
174
- :url => /.*\/tags/,
175
- [:payload, :public_ids] => ["some_public_id1", "some_public_id2"],
176
- [:payload, :command] => "remove_all"
177
- }
178
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
179
-
180
- Cloudinary::Uploader.remove_all_tags(["some_public_id1", "some_public_id2"])
181
- end
182
- end
183
-
184
- end
185
-
186
-
187
- describe "context", :focus => true do
188
- describe "add_context" do
189
- it "should correctly add context", :focus => true do
190
- expected ={
191
- :url => /.*\/context/,
192
- [:payload, :context] => "key1=value1|key2=value2",
193
- [:payload, :public_ids] => ["some_public_id1", "some_public_id2"],
194
- [:payload, :command] => "add"
195
- }
196
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
197
-
198
- Cloudinary::Uploader.add_context( {:key1 => :value1, :key2 => :value2}, ["some_public_id1", "some_public_id2"])
199
- end
200
- end
201
-
202
- describe "remove_all_context" do
203
- it "should correctly remove all context", :focus => true do
204
- expected ={
205
- :url => /.*\/context/,
206
- [:payload, :public_ids] => ["some_public_id1", "some_public_id2"],
207
- [:payload, :command] => "remove_all",
208
- [:payload, :type] => "private"
209
-
210
- }
211
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
212
-
213
- Cloudinary::Uploader.remove_all_context(["some_public_id1", "some_public_id2"], :type => "private")
214
- end
215
- end
216
-
217
- end
218
-
219
-
220
-
221
- it "should correctly handle unique_filename" do
222
- result = Cloudinary::Uploader.upload(TEST_IMG, :use_filename => true, :tags => [TEST_TAG, TIMESTAMP_TAG])
223
- expect(result["public_id"]).to match(/logo_[a-zA-Z0-9]{6}/)
224
- result = Cloudinary::Uploader.upload(TEST_IMG, :use_filename => true, :unique_filename => false, :tags => [TEST_TAG, TIMESTAMP_TAG])
225
- expect(result["public_id"]).to eq("logo")
226
- end
227
-
228
- it "should allow whitelisted formats if allowed_formats", :allowed=>true do
229
- result = Cloudinary::Uploader.upload(TEST_IMG, :allowed_formats => ["png"], :tags => [TEST_TAG, TIMESTAMP_TAG])
230
- expect(result["format"]).to eq("png")
231
- end
232
-
233
- it "should prevent non whitelisted formats from being uploaded if allowed_formats is specified", :allowed=>true do
234
- expect{Cloudinary::Uploader.upload(TEST_IMG, :allowed_formats => ["jpg"], :tags => [TEST_TAG, TIMESTAMP_TAG])}.to raise_error(CloudinaryException)
235
- end
236
-
237
- it "should allow non whitelisted formats if type is specified and convert to that type", :allowed=>true do
238
- result = Cloudinary::Uploader.upload(TEST_IMG, :allowed_formats => ["jpg"], :format => "jpg", :tags => [TEST_TAG, TIMESTAMP_TAG])
239
- expect(result["format"]).to eq("jpg")
240
- end
241
-
242
- it "should allow sending face coordinates" do
243
- coordinates = [[120, 30, 109, 150], [121, 31, 110, 151]]
244
- result_coordinates = [[120, 30, 109, 51], [121, 31, 110, 51]]
245
- result = Cloudinary::Uploader.upload(TEST_IMG, { :face_coordinates => coordinates, :faces => true, :tags => [TEST_TAG, TIMESTAMP_TAG]})
246
- expect(result["faces"]).to eq(result_coordinates)
247
-
248
- different_coordinates = [[122, 32, 111, 152]]
249
- Cloudinary::Uploader.explicit(result["public_id"], {:face_coordinates => different_coordinates, :faces => true, :type => "upload", :tags => [TEST_TAG, TIMESTAMP_TAG]})
250
- info = Cloudinary::Api.resource(result["public_id"], {:faces => true})
251
- expect(info["faces"]).to eq(different_coordinates)
252
- end
253
-
254
- it "should allow sending context" do
255
- context = {"key1"=>'value1', "key2" => 'valu\e2', "key3" => 'val=u|e3', "key4" => 'val\=ue'}
256
- result = Cloudinary::Uploader.upload(TEST_IMG, { :context => context, :tags => [TEST_TAG, TIMESTAMP_TAG]})
257
- info = Cloudinary::Api.resource(result["public_id"], {:context => true})
258
- expect(info["context"]).to eq({"custom" => context})
259
- end
260
-
261
- it "should support requesting manual moderation" do
262
- result = Cloudinary::Uploader.upload(TEST_IMG, { :moderation => :manual, :tags => [TEST_TAG, TIMESTAMP_TAG]})
263
- expect(result["moderation"][0]["status"]).to eq("pending")
264
- expect(result["moderation"][0]["kind"]).to eq("manual")
265
- end
266
-
267
- 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/)
269
- end
270
-
271
- it "should support requesting categorization" do
272
- 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/)
273
- end
274
-
275
- it "should support requesting detection" do
276
- expect{Cloudinary::Uploader.upload(TEST_IMG, { :detection => :illegal, :tags => [TEST_TAG, TIMESTAMP_TAG]})}.to raise_error(CloudinaryException, /Illegal value|not a valid/)
277
- end
278
-
279
- it "should support upload_large", :large => true do
280
- io = StringIO.new
281
- 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"
282
- io.puts(header)
283
- 5880000.times{ io.write("\xFF") }
284
- io.rewind
285
- result = Cloudinary::Uploader.upload_large(io, :chunk_size => 5243000, :tags => [TEST_TAG, TIMESTAMP_TAG])
286
- expect(result["resource_type"]).to eq('raw')
287
- io.rewind
288
- result = Cloudinary::Uploader.upload_large(io, :resource_type => 'image', :chunk_size => 5243000, :tags => [TEST_TAG, TIMESTAMP_TAG])
289
- expect(result["resource_type"]).to eq('image')
290
- expect(result["width"]).to eq(1400)
291
- expect(result["height"]).to eq(1400)
292
- expect(result["format"]).to eq("bmp")
293
- end
294
-
295
- it "should allow fallback of upload large with remote url to regular upload", :focus => true do
296
- file = "http://cloudinary.com/images/old_logo.png"
297
- result = Cloudinary::Uploader.upload_large(file, :chunk_size => 5243000, :tags => [TEST_TAG, TIMESTAMP_TAG])
298
- expect(result).to_not be_nil
299
- expect(result["width"]).to eq(TEST_IMG_W)
300
- expect(result["height"]).to eq(TEST_IMG_H)
301
- end
302
-
303
- context "unsigned" do
304
- after do
305
- Cloudinary.class_variable_set(:@@config, nil)
306
- end
307
-
308
- it "should support unsigned uploading using presets", :upload_preset => true do
309
- preset = Cloudinary::Api.create_upload_preset(:folder => "test_folder_upload", :unsigned => true, :tags => [TEST_TAG, TIMESTAMP_TAG])
310
-
311
- Cloudinary.config.api_key = nil
312
- Cloudinary.config.api_secret = nil
313
-
314
- result = Cloudinary::Uploader.unsigned_upload(TEST_IMG, preset["name"], :tags => [TEST_TAG, TIMESTAMP_TAG])
315
- expect(result["public_id"]).to match(/^test_folder_upload\/[a-z0-9]+$/)
316
-
317
- Cloudinary.class_variable_set(:@@config, nil)
318
-
319
- end
320
- end
321
-
322
- describe ":timeout" do
323
- before do
324
- @timeout = Cloudinary.config.timeout
325
- Cloudinary.config.timeout = 0.01
326
- end
327
- after do
328
- Cloudinary.config.timeout = @timeout
329
- end
330
-
331
- it "should fail if timeout is reached" do
332
- expect{Cloudinary::Uploader.upload(Pathname.new(TEST_IMG), :tags => [TEST_TAG, TIMESTAMP_TAG])}.to raise_error(RestClient::RequestTimeout)
333
- end
334
- end
335
-
336
- context ":responsive_breakpoints" do
337
- context ":create_derived with transformation and format conversion" do
338
- expected ={
339
- :url => /.*\/upload$/,
340
- [:payload, :responsive_breakpoints] => %r("transformation":"e_sepia/jpg"),
341
- [:payload, :responsive_breakpoints] => %r("transformation":"gif"),
342
- [:payload, :responsive_breakpoints] => %r("create_derived":true)
343
- }
344
- it 'should return a proper responsive_breakpoints hash in the response' do
345
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
346
- 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])
347
- end
348
- end
349
- end
350
-
351
-
352
-
353
- describe 'explicit' do
354
-
355
- context ":invalidate" do
356
- it 'should pass the invalidate value to the server' do
357
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value( [:payload, :invalidate] => 1))
358
- Cloudinary::Uploader.explicit("cloudinary", :type=>"twitter_name", :eager=>[{:crop=>"scale", :width=>"2.0"}], :invalidate => true, :tags => [TEST_TAG, TIMESTAMP_TAG])
359
- end
360
- end
361
- end
362
- end
363
-