cloudinary 1.9.1 → 1.20.0

Sign up to get free protection for your applications and to get access to all the features.
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
-