cloudinary 1.13.0 → 1.13.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/cloudinary.gemspec +1 -2
  4. data/lib/active_storage/service/cloudinary_service.rb +0 -1
  5. data/lib/cloudinary/utils.rb +1 -1
  6. data/lib/cloudinary/version.rb +1 -1
  7. metadata +3 -185
  8. data/spec/access_control_spec.rb +0 -102
  9. data/spec/active_storage/Gemfile +0 -12
  10. data/spec/active_storage/application_system_test_case.rb +0 -5
  11. data/spec/active_storage/database/create_users_migration.rb +0 -9
  12. data/spec/active_storage/database/setup.rb +0 -7
  13. data/spec/active_storage/dummy/Rakefile +0 -5
  14. data/spec/active_storage/dummy/app/assets/config/manifest.js +0 -3
  15. data/spec/active_storage/dummy/app/assets/javascripts/application.js +0 -13
  16. data/spec/active_storage/dummy/app/assets/stylesheets/application.css +0 -15
  17. data/spec/active_storage/dummy/app/controllers/application_controller.rb +0 -5
  18. data/spec/active_storage/dummy/app/helpers/application_helper.rb +0 -4
  19. data/spec/active_storage/dummy/app/jobs/application_job.rb +0 -4
  20. data/spec/active_storage/dummy/app/models/application_record.rb +0 -5
  21. data/spec/active_storage/dummy/app/views/layouts/application.html.erb +0 -14
  22. data/spec/active_storage/dummy/bin/bundle +0 -5
  23. data/spec/active_storage/dummy/bin/rails +0 -6
  24. data/spec/active_storage/dummy/bin/rake +0 -6
  25. data/spec/active_storage/dummy/bin/yarn +0 -11
  26. data/spec/active_storage/dummy/config.ru +0 -7
  27. data/spec/active_storage/dummy/config/application.rb +0 -22
  28. data/spec/active_storage/dummy/config/boot.rb +0 -7
  29. data/spec/active_storage/dummy/config/database.yml +0 -25
  30. data/spec/active_storage/dummy/config/environment.rb +0 -7
  31. data/spec/active_storage/dummy/config/environments/development.rb +0 -52
  32. data/spec/active_storage/dummy/config/environments/production.rb +0 -83
  33. data/spec/active_storage/dummy/config/environments/test.rb +0 -38
  34. data/spec/active_storage/dummy/config/initializers/application_controller_renderer.rb +0 -7
  35. data/spec/active_storage/dummy/config/initializers/assets.rb +0 -16
  36. data/spec/active_storage/dummy/config/initializers/backtrace_silencers.rb +0 -8
  37. data/spec/active_storage/dummy/config/initializers/cookies_serializer.rb +0 -7
  38. data/spec/active_storage/dummy/config/initializers/filter_parameter_logging.rb +0 -6
  39. data/spec/active_storage/dummy/config/initializers/inflections.rb +0 -17
  40. data/spec/active_storage/dummy/config/initializers/mime_types.rb +0 -5
  41. data/spec/active_storage/dummy/config/initializers/wrap_parameters.rb +0 -16
  42. data/spec/active_storage/dummy/config/routes.rb +0 -4
  43. data/spec/active_storage/dummy/config/secrets.yml +0 -32
  44. data/spec/active_storage/dummy/config/spring.rb +0 -8
  45. data/spec/active_storage/dummy/config/storage.yml +0 -3
  46. data/spec/active_storage/dummy/config/webpacker.yml +0 -72
  47. data/spec/active_storage/dummy/package.json +0 -5
  48. data/spec/active_storage/dummy/public/404.html +0 -67
  49. data/spec/active_storage/dummy/public/422.html +0 -67
  50. data/spec/active_storage/dummy/public/500.html +0 -66
  51. data/spec/active_storage/dummy/public/apple-touch-icon-precomposed.png +0 -0
  52. data/spec/active_storage/dummy/public/apple-touch-icon.png +0 -0
  53. data/spec/active_storage/dummy/public/favicon.ico +0 -0
  54. data/spec/active_storage/fixtures/files/colors.bmp +0 -0
  55. data/spec/active_storage/fixtures/files/empty_file.txt +0 -0
  56. data/spec/active_storage/fixtures/files/favicon.ico +0 -0
  57. data/spec/active_storage/fixtures/files/icon.psd +0 -0
  58. data/spec/active_storage/fixtures/files/icon.svg +0 -13
  59. data/spec/active_storage/fixtures/files/image.gif +0 -0
  60. data/spec/active_storage/fixtures/files/racecar.jpg +0 -0
  61. data/spec/active_storage/fixtures/files/racecar.tif +0 -0
  62. data/spec/active_storage/fixtures/files/racecar_rotated.jpg +0 -0
  63. data/spec/active_storage/fixtures/files/report.pdf +0 -0
  64. data/spec/active_storage/fixtures/files/rotated_video.mp4 +0 -0
  65. data/spec/active_storage/fixtures/files/video.mp4 +0 -0
  66. data/spec/active_storage/fixtures/files/video_with_rectangular_samples.mp4 +0 -0
  67. data/spec/active_storage/fixtures/files/video_with_undefined_display_aspect_ratio.mp4 +0 -0
  68. data/spec/active_storage/fixtures/files/video_without_video_stream.mp4 +0 -0
  69. data/spec/active_storage/service/cloudinary_service_spec.rb +0 -107
  70. data/spec/active_storage/service/configurations.yml +0 -4
  71. data/spec/active_storage/test_helper.rb +0 -43
  72. data/spec/api_spec.rb +0 -623
  73. data/spec/archive_spec.rb +0 -145
  74. data/spec/auth_token_spec.rb +0 -77
  75. data/spec/cache_spec.rb +0 -109
  76. data/spec/cloudinary_helper_spec.rb +0 -327
  77. data/spec/cloudinary_spec.rb +0 -56
  78. data/spec/data/sync_static/app/assets/javascripts/1.coffee +0 -1
  79. data/spec/data/sync_static/app/assets/javascripts/1.js +0 -1
  80. data/spec/data/sync_static/app/assets/stylesheets/1.css +0 -3
  81. data/spec/docx.docx +0 -0
  82. data/spec/favicon.ico +0 -0
  83. data/spec/image_spec.rb +0 -107
  84. data/spec/logo.png +0 -0
  85. data/spec/movie.mp4 +0 -0
  86. data/spec/rake_spec.rb +0 -160
  87. data/spec/sample_asset_file.tsv +0 -4
  88. data/spec/search_spec.rb +0 -109
  89. data/spec/spec_helper.rb +0 -273
  90. data/spec/storage_spec.rb +0 -44
  91. data/spec/streaminig_profiles_api_spec.rb +0 -74
  92. data/spec/support/helpers/temp_file_helpers.rb +0 -22
  93. data/spec/support/shared_contexts/rake.rb +0 -19
  94. data/spec/uploader_spec.rb +0 -409
  95. data/spec/utils_methods_spec.rb +0 -81
  96. data/spec/utils_spec.rb +0 -1052
  97. data/spec/video_tag_spec.rb +0 -253
  98. data/spec/video_url_spec.rb +0 -185
data/spec/spec_helper.rb DELETED
@@ -1,273 +0,0 @@
1
- SUFFIX = ENV['TRAVIS_JOB_ID'] || rand(999999999).to_s
2
-
3
- require 'rspec'
4
- require 'rexml/parsers/ultralightparser'
5
- require 'nokogiri'
6
- require 'rspec/version'
7
- require 'rest_client'
8
- require 'active_storage/test_helper' if RUBY_VERSION >= '2.2.2'
9
- require 'cloudinary'
10
-
11
- Cloudinary.config.enhance_image_tag = true
12
-
13
- DUMMY_CLOUD = "test123"
14
- TEST_IMAGE_URL = "http://cloudinary.com/images/old_logo.png"
15
- TEST_IMG = "spec/logo.png"
16
- TEST_VIDEO = "spec/movie.mp4"
17
- TEST_RAW = "spec/docx.docx"
18
- TEST_IMG_W = 241
19
- TEST_IMG_H = 51
20
- TEST_TAG = 'cloudinary_gem_test'
21
- TIMESTAMP_TAG = "#{TEST_TAG}_#{SUFFIX}_#{RUBY_VERSION}_#{ defined? Rails::version ? Rails::version : 'no_rails'}"
22
- UNIQUE_TEST_FOLDER = "#{TEST_TAG}_#{SUFFIX}_folder"
23
- NEXT_CURSOR = "db27cfb02b3f69cb39049969c23ca430c6d33d5a3a7c3ad1d870c54e1a54ee0faa5acdd9f6d288666986001711759d10"
24
- GENERIC_FOLDER_NAME = "some_folder"
25
-
26
- # Auth token
27
- KEY = "00112233FF99"
28
- ALT_KEY = "CCBB2233FF00"
29
- CACHE_KEY = "some_key" + SUFFIX
30
-
31
- module ResponsiveTest
32
- TRANSFORMATION = {:angle => 45, :crop => "scale"}
33
- FORMAT = "png"
34
- IMAGE_BP_VALUES = [206, 50]
35
- BREAKPOINTS = [100, 200, 300, 399]
36
-
37
- end
38
- Dir[File.join(File.dirname(__FILE__), '/support/**/*.rb')].each {|f| require f}
39
-
40
- module RSpec
41
- def self.project_root
42
- File.join(File.dirname(__FILE__), '..')
43
- end
44
- end
45
-
46
- # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
47
- RSpec.configure do |config|
48
- unless RSpec::Version::STRING.match( /^3/)
49
- config.treat_symbols_as_metadata_keys_with_true_values = true
50
- end
51
- config.run_all_when_everything_filtered = true
52
- config.filter_run_excluding :delete_all => true
53
- end
54
-
55
- RSpec.shared_context "cleanup" do |tag|
56
- tag ||= TEST_TAG
57
- after :all do
58
- Cloudinary::Api.delete_resources_by_tag(tag) unless Cloudinary.config.keep_test_products
59
- end
60
- end
61
-
62
- module Cloudinary
63
- def self.reset_config
64
- @@config = nil
65
- end
66
-
67
- end
68
-
69
-
70
- CALLS_SERVER_WITH_PARAMETERS = "calls server with parameters"
71
- RSpec.shared_examples CALLS_SERVER_WITH_PARAMETERS do |expected|
72
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
73
- end
74
-
75
- # Create a regexp with the given +tag+ name.
76
- def html_tag_matcher( tag)
77
- /<#{tag}([\s]+([-[:word:]]+)[\s]*\=\s*\"([^\"]*)\")*\s*>.*<\s*\/#{tag}\s*>/
78
- end
79
-
80
- # Represents an HTML tag
81
- class TestTag
82
- attr_accessor :element
83
- # Creates a new +TestTag+ from a given +element+ string
84
- def initialize(element)
85
- @html_string = element
86
- @element = valid_tag(element) unless element.is_a? Array
87
-
88
- end
89
-
90
- def name
91
- @element.name
92
- end
93
-
94
- def attributes
95
- @element.attributes
96
- end
97
-
98
- def children
99
- @element.children
100
- end
101
- # Parses a given +tag+ in string format
102
- def valid_tag(tag)
103
- parser = Nokogiri::HTML::Document.parse( tag)
104
- # Parsed code will be strctured as either html>body>tag or html>head>tag
105
- parser.children[1].children[0].children[0]
106
- end
107
-
108
- # Returns attribute named +symbol_or_string+
109
- def [](symbol_or_string)
110
- begin
111
- attributes[symbol_or_string.to_s].value
112
- rescue
113
- nil
114
- end
115
- end
116
-
117
- def method_missing(symbol, *args)
118
- if (m = /children_by_(\w+)/.match(symbol.to_s)) and !args.empty?
119
- return unless children
120
- children.select{ |c| c[m[1]] == args[0]}
121
- else
122
- super
123
- end
124
- end
125
-
126
- def ==(other)
127
- case other
128
- when String
129
- @text == other
130
- else
131
- other.respond_to?( :text) &&
132
- other.respond_to?( :name) &&
133
- other.respond_to?( :attributes) &&
134
- other.respond_to?( :children) &&
135
- @text == other.text &&
136
- @name == other.name &&
137
- @attributes == other.attributes &&
138
- @children == other.children
139
- end
140
- end
141
- end
142
-
143
- RSpec::Matchers.define :produce_url do |expected_url|
144
- match do |params|
145
- public_id, options = params
146
- actual_options = options.clone
147
- @url = Cloudinary::Utils.cloudinary_url(public_id, actual_options)
148
- values_match? expected_url, @url
149
- end
150
- failure_message do |actual|
151
- "expected #{actual} to\nproduce: #{expected_url}\nbut got: #{@url}"
152
- end
153
- end
154
-
155
- RSpec::Matchers.define :mutate_options_to do |expected_options|
156
- match do |params|
157
- public_id, options = params
158
- options = options.clone
159
- Cloudinary::Utils.cloudinary_url(public_id, options)
160
- @actual = options
161
- values_match? expected_options, @actual
162
- end
163
- end
164
-
165
- RSpec::Matchers.define :empty_options do
166
- match do |params|
167
- public_id, options = params
168
- options = options.clone
169
- Cloudinary::Utils.cloudinary_url(public_id, options)
170
- options.empty?
171
- end
172
- end
173
-
174
- # Verify that the given URL can be served by Cloudinary by fetching the resource from the server
175
- RSpec::Matchers.define :be_served_by_cloudinary do
176
- match do |url|
177
- if url.is_a? Array
178
- url, options = url
179
- url = Cloudinary::Utils.cloudinary_url(url, options.clone)
180
- if Cloudinary.config.upload_prefix
181
- res_prefix_uri = URI.parse(Cloudinary.config.upload_prefix)
182
- res_prefix_uri.path = '/res'
183
- url.gsub!(/https?:\/\/res.cloudinary.com/, res_prefix_uri.to_s)
184
- end
185
- end
186
- code = 0
187
- @url = url
188
- RestClient.get @url do |response, request, result|
189
- @result = result
190
- code = response.code
191
- end
192
- values_match? 200, code
193
- end
194
-
195
- failure_message do |actual|
196
- if @result
197
- "Couldn't serve #{actual}. #{@result["status"]}: #{@result["x-cld-error"]}"
198
- else
199
- "Couldn't serve #{actual}."
200
- end
201
- end
202
- failure_message_when_negated do |actual|
203
- if @result
204
- "Expected #{@url} not to be served by cloudinary. #{@result["status"]}: #{@result["x-cld-error"]}"
205
- else
206
- "Expected #{@url} not to be served by cloudinary."
207
- end
208
-
209
- end
210
- end
211
-
212
- def deep_fetch(hash, path)
213
- Array(path).reduce(hash) { |h, key| h && h.fetch(key, nil) }
214
- end
215
-
216
- # Matches deep values in the actual Hash, disregarding other keys and values.
217
- # @example
218
- # expect( {:foo => { :bar => 'foobar'}}).to have_deep_hash_values_of( [:foo, :bar] => 'foobar')
219
- # expect( foo_instance).to receive(:bar_method).with(deep_hash_values_of([:foo, :bar] => 'foobar'))
220
- RSpec::Matchers.define :deep_hash_value do |expected|
221
- match do |actual|
222
- expected.all? do |path, value|
223
- Cloudinary.values_match? value, deep_fetch(actual, path)
224
- end
225
- end
226
- end
227
-
228
- RSpec::Matchers.alias_matcher :have_deep_hash_values_of, :deep_hash_value
229
-
230
- module Cloudinary
231
- # @api private
232
- def self.values_match?(expected, actual)
233
- if Hash === actual
234
- return hashes_match?(expected, actual) if Hash === expected
235
- elsif Array === expected && Enumerable === actual && !(Struct === actual)
236
- return arrays_match?(expected, actual.to_a)
237
- elsif Regexp === expected
238
- return expected.match actual.to_s
239
- end
240
-
241
-
242
- return true if actual == expected
243
-
244
- begin
245
- expected === actual
246
- rescue ArgumentError
247
- # Some objects, like 0-arg lambdas on 1.9+, raise
248
- # ArgumentError for `expected === actual`.
249
- false
250
- end
251
- end
252
-
253
- # @private
254
- def self.arrays_match?(expected_list, actual_list)
255
- return false if expected_list.size != actual_list.size
256
-
257
- expected_list.zip(actual_list).all? do |expected, actual|
258
- values_match?(expected, actual)
259
- end
260
- end
261
-
262
- # @private
263
- def self.hashes_match?(expected_hash, actual_hash)
264
- return false if expected_hash.size != actual_hash.size
265
-
266
- expected_hash.all? do |expected_key, expected_value|
267
- actual_value = actual_hash.fetch(expected_key) { return false }
268
- values_match?(expected_value, actual_value)
269
- end
270
- end
271
-
272
- private_class_method :arrays_match?, :hashes_match?
273
- end
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,409 +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
- it "should support the cinemagraph_analysis parameter for upload" do
53
- expected = {
54
- [:payload, :cinemagraph_analysis] => 1,
55
- [:method] => :post
56
- }
57
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
58
- Cloudinary::Uploader.upload(Pathname.new(TEST_IMG), :cinemagraph_analysis => true, :tags => [TEST_TAG, TIMESTAMP_TAG])
59
- end
60
-
61
- it "should support the cinemagraph_analysis parameter for explicit" do
62
- expected = {
63
- [:payload, :cinemagraph_analysis] => 1,
64
- [:method] => :post
65
- }
66
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
67
- Cloudinary::Uploader.explicit('sample', :type => "upload", :cinemagraph_analysis => true, :tags => [TEST_TAG, TIMESTAMP_TAG])
68
- end
69
-
70
- describe '.rename' do
71
- before(:all) do
72
- @result = Cloudinary::Uploader.upload(TEST_IMG, :tags => [TEST_TAG, TIMESTAMP_TAG])
73
- @resource_1_id = @result["public_id"]
74
- @resource_1_type = @result["type"]
75
- result = Cloudinary::Uploader.upload("spec/favicon.ico", :tags => [TEST_TAG, TIMESTAMP_TAG])
76
- @resource_2_id = result["public_id"]
77
- end
78
-
79
- it 'should rename a resource' do
80
- Cloudinary::Uploader.rename(@resource_1_id, @resource_1_id+"2")
81
- expect(Cloudinary::Api.resource(@resource_1_id+"2")).not_to be_nil
82
- @resource_1_id = @resource_1_id+"2" # will not update if expect fails
83
- end
84
- it 'should not allow renaming to an existing ID' do
85
- id = @resource_2_id
86
- @resource_2_id = @resource_1_id+"2" # if rename doesn't fail, this is the new ID
87
- expect { Cloudinary::Uploader.rename(id, @resource_1_id+"2") }.to raise_error(CloudinaryException)
88
- @resource_2_id = id
89
- end
90
- it 'should allow changing type of an uploaded resource' do
91
- id = @resource_2_id
92
- from_type = @resource_1_type
93
- to_type = "private"
94
- Cloudinary::Uploader.rename(id, id, :type => from_type, :to_type => to_type)
95
- expect(Cloudinary::Api.resource(id, type: to_type)).to_not be_empty
96
- Cloudinary::Uploader.rename(id, id, :type => to_type, :to_type => from_type)
97
- end
98
- context ':overwrite => true' do
99
- it 'should rename to an existing ID' do
100
- new_id = Cloudinary::Uploader.upload(TEST_IMG, :tags => [TEST_TAG, TIMESTAMP_TAG])["public_id"]
101
- Cloudinary::Uploader.rename(@resource_2_id, new_id, :overwrite => true)
102
- expect(Cloudinary::Api.resource(new_id)["format"]).to eq("ico")
103
- @resource_2_id = new_id # will not update if expect fails
104
- end
105
- end
106
- context ':invalidate => true' do
107
- it 'should notify the server to invalidate the resource in the CDN' do
108
- # Can't test the result, so we just verify the parameter is send to the server
109
- expected ={
110
- :url => /.*\/rename$/,
111
- [:payload, :invalidate] => 1,
112
- [:payload, :from_public_id] => @resource_2_id,
113
- [:payload, :to_public_id] => @resource_2_id+"2"
114
- }
115
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
116
- Cloudinary::Uploader.rename(@resource_2_id, @resource_2_id+"2", :invalidate => true) # will not affect the server
117
- end
118
-
119
- end
120
- end
121
-
122
- it "should support explicit" do
123
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value( [:payload, :public_id] => "sample", [:payload, :eager] => "c_scale,w_2.0"))
124
- result = Cloudinary::Uploader.explicit("sample", :type=>"upload", :eager=>[{:crop=>"scale", :width=>"2.0"}])
125
- end
126
-
127
- it "should support eager" do
128
- result = Cloudinary::Uploader.upload(TEST_IMG, :eager =>[{ :crop =>"scale", :width =>"2.0"}], :tags => [TEST_TAG, TIMESTAMP_TAG])
129
- expect(result["eager"].length).to be(1)
130
- expect(result).to have_deep_hash_values_of(["eager", 0, "transformation"] => "c_scale,w_2.0")
131
- result = Cloudinary::Uploader.upload(TEST_IMG, :eager =>"c_scale,w_2.0", :tags => [TEST_TAG, TIMESTAMP_TAG])
132
- expect(result["eager"].length).to be(1)
133
- expect(result).to have_deep_hash_values_of(["eager", 0, "transformation"] => "c_scale,w_2.0")
134
- result = Cloudinary::Uploader.upload(TEST_IMG, :eager =>[
135
- "c_scale,w_2.0",
136
- { :crop =>"crop", :width =>"0.5", :format => "tiff"},
137
- [[{:crop =>"crop", :width =>"0.5"},{:angle =>90}]],
138
- [[{:crop =>"crop", :width =>"0.5"},{:angle =>90}],"tiff"]
139
- ], :tags => [TEST_TAG, TIMESTAMP_TAG])
140
- expect(result["eager"].length).to be(4)
141
- expect(result).to have_deep_hash_values_of(
142
- ["eager", 0, "transformation"] => "c_scale,w_2.0",
143
- ["eager", 1, "transformation"] => "c_crop,w_0.5/tiff",
144
- ["eager", 2, "transformation"] => "c_crop,w_0.5/a_90",
145
- ["eager", 3, "transformation"] => "c_crop,w_0.5/a_90/tiff"
146
- )
147
- end
148
-
149
- it "should support headers" do
150
- Cloudinary::Uploader.upload(TEST_IMG, :headers =>["Link: 1"], :tags => [TEST_TAG, TIMESTAMP_TAG])
151
- Cloudinary::Uploader.upload(TEST_IMG, :headers =>{ "Link" => "1"}, :tags => [TEST_TAG, TIMESTAMP_TAG])
152
- end
153
-
154
- it "should successfully generate text image" do
155
- result = Cloudinary::Uploader.text("hello world", :tags => [TEST_TAG, TIMESTAMP_TAG])
156
- expect(result["width"]).to be > 1
157
- expect(result["height"]).to be > 1
158
- end
159
-
160
- describe "tag" do
161
- describe "add_tag" do
162
- it "should correctly add tags" do
163
- expected ={
164
- :url => /.*\/tags/,
165
- [:payload, :tag] => "new_tag",
166
- [:payload, :public_ids] => ["some_public_id1", "some_public_id2"],
167
- [:payload, :command] => "add"
168
- }
169
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
170
-
171
- Cloudinary::Uploader.add_tag( "new_tag", ["some_public_id1", "some_public_id2"])
172
- end
173
- end
174
-
175
- describe "remove_tag" do
176
- it "should correctly remove tag" do
177
- expected ={
178
- :url => /.*\/tags/,
179
- [:payload, :tag] => "tag",
180
- [:payload, :public_ids] => ["some_public_id1", "some_public_id2"],
181
- [:payload, :command] => "remove"
182
- }
183
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
184
-
185
- Cloudinary::Uploader.remove_tag("tag", ["some_public_id1", "some_public_id2"])
186
- end
187
- end
188
-
189
- describe "replace_tag" do
190
- it "should correctly replace tag" do
191
- expected ={
192
- :url => /.*\/tags/,
193
- [:payload, :tag] => "tag",
194
- [:payload, :public_ids] => ["some_public_id1", "some_public_id2"],
195
- [:payload, :command] => "replace"
196
- }
197
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
198
-
199
- Cloudinary::Uploader.replace_tag("tag", ["some_public_id1", "some_public_id2"])
200
- end
201
- end
202
-
203
- describe "remove_all_tags" do
204
- it "should correctly remove all tags" do
205
- expected ={
206
- :url => /.*\/tags/,
207
- [:payload, :public_ids] => ["some_public_id1", "some_public_id2"],
208
- [:payload, :command] => "remove_all"
209
- }
210
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
211
-
212
- Cloudinary::Uploader.remove_all_tags(["some_public_id1", "some_public_id2"])
213
- end
214
- end
215
-
216
- end
217
-
218
-
219
- describe "context" do
220
- describe "add_context" do
221
- it "should correctly add context" do
222
- expected ={
223
- :url => /.*\/context/,
224
- [:payload, :context] => "key1=value1|key2=val\\|ue2",
225
- [:payload, :public_ids] => ["some_public_id1", "some_public_id2"],
226
- [:payload, :command] => "add"
227
- }
228
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
229
-
230
- Cloudinary::Uploader.add_context( {:key1 => "value1", :key2 => "val|ue2"}, ["some_public_id1", "some_public_id2"])
231
- end
232
- end
233
-
234
- describe "remove_all_context" do
235
- it "should correctly remove all context" do
236
- expected ={
237
- :url => /.*\/context/,
238
- [:payload, :public_ids] => ["some_public_id1", "some_public_id2"],
239
- [:payload, :command] => "remove_all",
240
- [:payload, :type] => "private"
241
-
242
- }
243
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
244
-
245
- Cloudinary::Uploader.remove_all_context(["some_public_id1", "some_public_id2"], :type => "private")
246
- end
247
- end
248
-
249
- end
250
-
251
-
252
-
253
- it "should correctly handle unique_filename" do
254
- result = Cloudinary::Uploader.upload(TEST_IMG, :use_filename => true, :tags => [TEST_TAG, TIMESTAMP_TAG])
255
- expect(result["public_id"]).to match(/logo_[a-zA-Z0-9]{6}/)
256
- result = Cloudinary::Uploader.upload(TEST_IMG, :use_filename => true, :unique_filename => false, :tags => [TEST_TAG, TIMESTAMP_TAG])
257
- expect(result["public_id"]).to eq("logo")
258
- end
259
-
260
- it "should allow whitelisted formats if allowed_formats", :allowed=>true do
261
- result = Cloudinary::Uploader.upload(TEST_IMG, :allowed_formats => ["png"], :tags => [TEST_TAG, TIMESTAMP_TAG])
262
- expect(result["format"]).to eq("png")
263
- end
264
-
265
- it "should prevent non whitelisted formats from being uploaded if allowed_formats is specified", :allowed=>true do
266
- expect{Cloudinary::Uploader.upload(TEST_IMG, :allowed_formats => ["jpg"], :tags => [TEST_TAG, TIMESTAMP_TAG])}.to raise_error(CloudinaryException)
267
- end
268
-
269
- it "should allow non whitelisted formats if type is specified and convert to that type", :allowed=>true do
270
- result = Cloudinary::Uploader.upload(TEST_IMG, :allowed_formats => ["jpg"], :format => "jpg", :tags => [TEST_TAG, TIMESTAMP_TAG])
271
- expect(result["format"]).to eq("jpg")
272
- end
273
-
274
- it "should allow sending face coordinates" do
275
- coordinates = [[120, 30, 109, 150], [121, 31, 110, 151]]
276
- result_coordinates = [[120, 30, 109, 51], [121, 31, 110, 51]] # actual boundaries fitted by the server
277
- result = Cloudinary::Uploader.upload(TEST_IMG, { :face_coordinates => coordinates, :faces => true, :tags => [TEST_TAG, TIMESTAMP_TAG]})
278
- expect(result["faces"]).to eq(result_coordinates)
279
-
280
- different_coordinates = [[122, 32, 111, 152]]
281
- Cloudinary::Uploader.explicit(result["public_id"], {:face_coordinates => different_coordinates, :faces => true, :type => "upload", :tags => [TEST_TAG, TIMESTAMP_TAG]})
282
- info = Cloudinary::Api.resource(result["public_id"], {:faces => true})
283
- expect(info["faces"]).to eq(different_coordinates)
284
- end
285
-
286
- it "should allow sending context" do
287
- context = {"key1"=>'value1', "key2" => 'valu\e2', "key3" => 'val=u|e3', "key4" => 'val\=ue'}
288
- result = Cloudinary::Uploader.upload(TEST_IMG, { :context => context, :tags => [TEST_TAG, TIMESTAMP_TAG]})
289
- info = Cloudinary::Api.resource(result["public_id"], {:context => true})
290
- expect(info["context"]).to eq({"custom" => context})
291
- end
292
-
293
- it "should support requesting manual moderation" do
294
- result = Cloudinary::Uploader.upload(TEST_IMG, { :moderation => :manual, :tags => [TEST_TAG, TIMESTAMP_TAG]})
295
- expect(result["moderation"][0]["status"]).to eq("pending")
296
- expect(result["moderation"][0]["kind"]).to eq("manual")
297
- end
298
-
299
- it "should support requesting ocr anlysis" do
300
- expect(RestClient::Request).to receive(:execute) do |options|
301
- expect(options[:payload][:ocr]).to eq(:adv_ocr)
302
- end
303
- Cloudinary::Uploader.upload(TEST_IMG, { :ocr => :adv_ocr, :tags => [TEST_TAG, TIMESTAMP_TAG]})
304
- end
305
-
306
- it "should support requesting raw conversion" do
307
- expect{Cloudinary::Uploader.upload(TEST_RAW, {:resource_type => :raw, :raw_convert => :illegal, :tags => [TEST_TAG, TIMESTAMP_TAG]})}.to raise_error(CloudinaryException, /Illegal value|not a valid|is invalid/)
308
- end
309
-
310
- it "should support requesting categorization" do
311
- 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/)
312
- end
313
-
314
- it "should support requesting detection" do
315
- expect{Cloudinary::Uploader.upload(TEST_IMG, { :detection => :illegal, :tags => [TEST_TAG, TIMESTAMP_TAG]})}.to raise_error(CloudinaryException, /Detection is invalid/)
316
- end
317
-
318
- it "should support upload_large", :large => true do
319
- io = StringIO.new
320
- 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"
321
- io.puts(header)
322
- 5880000.times{ io.write("\xFF") }
323
- io.rewind
324
- result = Cloudinary::Uploader.upload_large(io, :chunk_size => 5243000, :tags => [TEST_TAG, TIMESTAMP_TAG])
325
- expect(result["resource_type"]).to eq('raw')
326
- io.rewind
327
- result = Cloudinary::Uploader.upload_large(io, :resource_type => 'image', :chunk_size => 5243000, :tags => [TEST_TAG, TIMESTAMP_TAG])
328
- expect(result["resource_type"]).to eq('image')
329
- expect(result["width"]).to eq(1400)
330
- expect(result["height"]).to eq(1400)
331
- expect(result["format"]).to eq("bmp")
332
- end
333
-
334
- it "should allow fallback of upload large with remote url to regular upload" do
335
- file = "http://cloudinary.com/images/old_logo.png"
336
- result = Cloudinary::Uploader.upload_large(file, :chunk_size => 5243000, :tags => [TEST_TAG, TIMESTAMP_TAG])
337
- expect(result).to_not be_nil
338
- expect(result["width"]).to eq(TEST_IMG_W)
339
- expect(result["height"]).to eq(TEST_IMG_H)
340
- end
341
-
342
- it "should include special headers in upload_large" do
343
- expect(RestClient::Request).to receive(:execute) do |options|
344
- expect(options[:headers]["Content-Range"]).to_not be_empty
345
- expect(options[:headers]["X-Unique-Upload-Id"]).to_not be_empty
346
- end
347
- Cloudinary::Uploader.upload_large(TEST_IMG, { :tags => [TEST_TAG, TIMESTAMP_TAG]})
348
- end
349
-
350
- context "unsigned" do
351
- after do
352
- Cloudinary.class_variable_set(:@@config, nil)
353
- end
354
-
355
- it "should support unsigned uploading using presets", :upload_preset => true do
356
- preset = Cloudinary::Api.create_upload_preset(:folder => "test_folder_upload", :unsigned => true, :tags => [TEST_TAG, TIMESTAMP_TAG])
357
-
358
- Cloudinary.config.api_key = nil
359
- Cloudinary.config.api_secret = nil
360
-
361
- result = Cloudinary::Uploader.unsigned_upload(TEST_IMG, preset["name"], :tags => [TEST_TAG, TIMESTAMP_TAG])
362
- expect(result["public_id"]).to match(/^test_folder_upload\/[a-z0-9]+$/)
363
-
364
- Cloudinary.class_variable_set(:@@config, nil)
365
-
366
- end
367
- end
368
-
369
- describe ":timeout" do
370
- before do
371
- @timeout = Cloudinary.config.timeout
372
- Cloudinary.config.timeout = 0.01
373
- end
374
- after do
375
- Cloudinary.config.timeout = @timeout
376
- end
377
-
378
- it "should fail if timeout is reached" do
379
- expect{Cloudinary::Uploader.upload(Pathname.new(TEST_IMG), :tags => [TEST_TAG, TIMESTAMP_TAG])}.to raise_error(RestClient::RequestTimeout)
380
- end
381
- end
382
-
383
- context ":responsive_breakpoints" do
384
- context ":create_derived with transformation and format conversion" do
385
- expected ={
386
- :url => /.*\/upload$/,
387
- [:payload, :responsive_breakpoints] => %r("transformation":"e_sepia/jpg"),
388
- [:payload, :responsive_breakpoints] => %r("transformation":"gif"),
389
- [:payload, :responsive_breakpoints] => %r("create_derived":true)
390
- }
391
- it 'should return a proper responsive_breakpoints hash in the response' do
392
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
393
- 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])
394
- end
395
- end
396
- end
397
-
398
-
399
-
400
- describe 'explicit' do
401
- context ":invalidate" do
402
- it 'should pass the invalidate value to the server' do
403
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value( [:payload, :invalidate] => 1))
404
- Cloudinary::Uploader.explicit("cloudinary", :type=>"twitter_name", :eager=>[{:crop=>"scale", :width=>"2.0"}], :invalidate => true, :tags => [TEST_TAG, TIMESTAMP_TAG])
405
- end
406
- end
407
- end
408
- end
409
-