cloudinary 1.8.1 → 1.8.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +5 -0
- data/CHANGELOG.md +12 -0
- data/README.md +19 -18
- data/lib/cloudinary/api.rb +11 -6
- data/lib/cloudinary/carrier_wave.rb +2 -1
- data/lib/cloudinary/carrier_wave/storage.rb +1 -1
- data/lib/cloudinary/utils.rb +17 -5
- data/lib/cloudinary/version.rb +1 -1
- data/lib/tasks/cloudinary.rake +2 -2
- data/spec/api_spec.rb +65 -23
- data/spec/storage_spec.rb +44 -0
- data/spec/utils_spec.rb +11 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8dee4c14d8ddf334a1ff60a96cc7bcb85ef82b25
|
4
|
+
data.tar.gz: 644319b8bdf30ba48b3ab57facc45364aedb3a3d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3af0f955aa2c7a8eeb9f66c2fc92fdc04be4cfeb4a0bc9f6fc203d07ba096e2eaa850d8ca750f402c798b47326c180623e42ddc5d59b258e284ba25a7edef4ff
|
7
|
+
data.tar.gz: f583837bfc36ac1e0db6dd5b5335600fbac2fa7c20cb9a28c0b0578c989e094fb3bacebc22509e9f30944bc0065fcf478e649f4ffbb3f34011b246a3efd1e844
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,16 @@
|
|
1
1
|
|
2
|
+
1.8.2 / 2017-11-22
|
3
|
+
==================
|
4
|
+
|
5
|
+
* Fix URL signature
|
6
|
+
* Use the correct method for updating a column
|
7
|
+
* Add support for `named` parameter in list transformation API
|
8
|
+
* load environment when running sync_static task
|
9
|
+
* Fix the overwritten initializer for hash (#273)
|
10
|
+
* Force TravisCI to install bundler
|
11
|
+
* Fix CloudinaryFile::exists? method. Solves #193 #205
|
12
|
+
* Update Readme to point to HTTPS URLs of cloudinary.com
|
13
|
+
|
2
14
|
1.8.1 / 2017-05-16
|
3
15
|
==================
|
4
16
|
|
data/README.md
CHANGED
@@ -13,7 +13,7 @@ Cloudinary provides URL and HTTP based APIs that can be easily integrated with a
|
|
13
13
|
For Ruby on Rails, Cloudinary provides a GEM for simplifying the integration even further.
|
14
14
|
|
15
15
|
## Getting started guide
|
16
|
-
![More](http://res.cloudinary.com/cloudinary/image/upload/see_more_bullet.png) **Take a look at our [Getting started guide of Ruby on Rails](
|
16
|
+
![More](http://res.cloudinary.com/cloudinary/image/upload/see_more_bullet.png) **Take a look at our [Getting started guide of Ruby on Rails](https://cloudinary.com/documentation/rails_integration#getting_started_guide)**.
|
17
17
|
|
18
18
|
## Setup ######################################################################
|
19
19
|
|
@@ -68,7 +68,7 @@ Converting to a 150x100 PNG with rounded corners of 20 pixels:
|
|
68
68
|
|
69
69
|
![Sample 150x150 Rounded PNG](https://res.cloudinary.com/demo/image/upload/w_150,h_100,c_fill,r_20/sample.png "Sample 150x150 Rounded PNG")
|
70
70
|
|
71
|
-
For plenty more transformation options, see our [image transformations documentation](
|
71
|
+
For plenty more transformation options, see our [image transformations documentation](https://cloudinary.com/documentation/image_transformations).
|
72
72
|
|
73
73
|
Generating a 120x90 thumbnail based on automatic face detection of the Facebook profile picture of Bill Clinton:
|
74
74
|
|
@@ -76,7 +76,7 @@ Generating a 120x90 thumbnail based on automatic face detection of the Facebook
|
|
76
76
|
|
77
77
|
![Facebook 90x120](https://res.cloudinary.com/demo/image/facebook/c_thumb,g_face,h_90,w_120/billclinton.jpg "Facebook 90x200")
|
78
78
|
|
79
|
-
For more details, see our documentation for embedding [Facebook](
|
79
|
+
For more details, see our documentation for embedding [Facebook](https://cloudinary.com/documentation/facebook_profile_pictures) and [Twitter](https://cloudinary.com/documentation/twitter_profile_pictures) profile pictures.
|
80
80
|
|
81
81
|
|
82
82
|
## Usage
|
@@ -84,7 +84,7 @@ For more details, see our documentation for embedding [Facebook](http://cloudina
|
|
84
84
|
### Configuration
|
85
85
|
|
86
86
|
Each request for building a URL of a remote cloud resource must have the `cloud_name` parameter set.
|
87
|
-
Each request to our secure APIs (e.g., image uploads, eager sprite generation) must have the `api_key` and `api_secret` parameters set. See [API, URLs and access identifiers](
|
87
|
+
Each request to our secure APIs (e.g., image uploads, eager sprite generation) must have the `api_key` and `api_secret` parameters set. See [API, URLs and access identifiers](https://cloudinary.com/documentation/api_and_access_identifiers) for more details.
|
88
88
|
|
89
89
|
Setting the `cloud_name`, `api_key` and `api_secret` parameters can be done either directly in each call to a Cloudinary method or by globally setting using a YAML configuration file.
|
90
90
|
|
@@ -130,7 +130,7 @@ Same goes for Twitter:
|
|
130
130
|
|
131
131
|
twitter_name_profile_image_tag("billclinton.jpg")
|
132
132
|
|
133
|
-
![More](http://res.cloudinary.com/cloudinary/image/upload/see_more_bullet.png) **See [our documentation](
|
133
|
+
![More](http://res.cloudinary.com/cloudinary/image/upload/see_more_bullet.png) **See [our documentation](https://cloudinary.com/documentation/rails_image_manipulation) for more information about displaying and transforming images in Rails**.
|
134
134
|
|
135
135
|
|
136
136
|
|
@@ -157,7 +157,7 @@ You can also specify your own public ID:
|
|
157
157
|
http://res.cloudinary.com/demo/image/upload/sample_remote.jpg
|
158
158
|
|
159
159
|
|
160
|
-
![More](http://res.cloudinary.com/cloudinary/image/upload/see_more_bullet.png) **See [our documentation](
|
160
|
+
![More](http://res.cloudinary.com/cloudinary/image/upload/see_more_bullet.png) **See [our documentation](https://cloudinary.com/documentation/rails_image_upload) for plenty more options of uploading to the cloud from your Ruby code or directly from the browser**.
|
161
161
|
|
162
162
|
|
163
163
|
### CarrierWave Integration
|
@@ -172,9 +172,9 @@ Cloudinary's Ruby GEM includes an optional plugin for [CarrierWave](https://gith
|
|
172
172
|
...
|
173
173
|
end
|
174
174
|
|
175
|
-
![More](http://res.cloudinary.com/cloudinary/image/upload/see_more_bullet.png) **For more details on CarrierWave integration see [our documentation](
|
175
|
+
![More](http://res.cloudinary.com/cloudinary/image/upload/see_more_bullet.png) **For more details on CarrierWave integration see [our documentation](https://cloudinary.com/documentation/rails_carrierwave)**.
|
176
176
|
|
177
|
-
We also published an interesting blog post about [Ruby on Rails image uploads with CarrierWave and Cloudinary](
|
177
|
+
We also published an interesting blog post about [Ruby on Rails image uploads with CarrierWave and Cloudinary](https://cloudinary.com/blog/ruby_on_rails_image_uploads_with_carrierwave_and_cloudinary).
|
178
178
|
|
179
179
|
#### Neo4j integration
|
180
180
|
|
@@ -205,7 +205,7 @@ To automatically set-up Cloudinary's configuration, include the following line i
|
|
205
205
|
|
206
206
|
#### Uploading images from the browser
|
207
207
|
|
208
|
-
The Cloudinary JavaScript library utilizes the Blueimp File Upload library to support image uploading from the browser. See the [documentation](
|
208
|
+
The Cloudinary JavaScript library utilizes the Blueimp File Upload library to support image uploading from the browser. See the [documentation](https://cloudinary.com/documentation/jquery_image_upload) for more details.
|
209
209
|
|
210
210
|
|Important|
|
211
211
|
|---------|
|
@@ -233,21 +233,22 @@ Please consult with the [README file](https://github.com/cloudinary/cloudinary_g
|
|
233
233
|
|
234
234
|
Additional resources are available at:
|
235
235
|
|
236
|
-
* [Website](
|
237
|
-
* [
|
238
|
-
* [
|
239
|
-
* [
|
240
|
-
* [Ruby on Rails
|
241
|
-
* [Ruby on Rails image
|
242
|
-
* [
|
236
|
+
* [Website](https://cloudinary.com)
|
237
|
+
* [Interactive demo](https://demo.cloudinary.com/default)
|
238
|
+
* [Documentation](https://cloudinary.com/documentation)
|
239
|
+
* [Knowledge Base](https://support.cloudinary.com/hc/en-us)
|
240
|
+
* [Documentation for Ruby on Rails integration](https://cloudinary.com/documentation/rails_integration)
|
241
|
+
* [Ruby on Rails image upload documentation](https://cloudinary.com/documentation/rails_image_upload)
|
242
|
+
* [Ruby on Rails image manipulation documentation](https://cloudinary.com/documentation/rails_image_manipulation)
|
243
|
+
* [Image transformations documentation](https://cloudinary.com/documentation/image_transformations)
|
243
244
|
|
244
245
|
## Support
|
245
246
|
|
246
247
|
You can [open an issue through GitHub](https://github.com/cloudinary/cloudinary_gem/issues).
|
247
248
|
|
248
|
-
Contact us [
|
249
|
+
Contact us [https://cloudinary.com/contact](https://cloudinary.com/contact)
|
249
250
|
|
250
|
-
Stay tuned for updates, tips and tutorials: [Blog](
|
251
|
+
Stay tuned for updates, tips and tutorials: [Blog](https://cloudinary.com/blog), [Twitter](https://twitter.com/cloudinary), [Facebook](https://www.facebook.com/Cloudinary).
|
251
252
|
|
252
253
|
|
253
254
|
## License #######################################################################
|
data/lib/cloudinary/api.rb
CHANGED
@@ -10,14 +10,19 @@ class Cloudinary::Api
|
|
10
10
|
class BadRequest < Error; end
|
11
11
|
class GeneralError < Error; end
|
12
12
|
class AuthorizationRequired < Error; end
|
13
|
+
|
13
14
|
class Response < Hash
|
14
15
|
attr_reader :rate_limit_reset_at, :rate_limit_remaining, :rate_limit_allowed
|
15
16
|
|
16
|
-
def initialize(response)
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
def initialize(response=nil)
|
18
|
+
if response
|
19
|
+
# This sets the instantiated self as the response Hash
|
20
|
+
update Cloudinary::Api.parse_json_response response
|
21
|
+
|
22
|
+
@rate_limit_allowed = response.headers[:x_featureratelimit_limit].to_i
|
23
|
+
@rate_limit_reset_at = Time.parse(response.headers[:x_featureratelimit_reset])
|
24
|
+
@rate_limit_remaining = response.headers[:x_featureratelimit_remaining].to_i
|
25
|
+
end
|
21
26
|
end
|
22
27
|
end
|
23
28
|
|
@@ -160,7 +165,7 @@ class Cloudinary::Api
|
|
160
165
|
end
|
161
166
|
|
162
167
|
def self.transformations(options={})
|
163
|
-
call_api(:get, "transformations", only(options, :next_cursor, :max_results), options)
|
168
|
+
call_api(:get, "transformations", only(options, :named, :next_cursor, :max_results), options)
|
164
169
|
end
|
165
170
|
|
166
171
|
def self.transformation(transformation, options={})
|
@@ -176,7 +176,8 @@ module Cloudinary::CarrierWave
|
|
176
176
|
end
|
177
177
|
|
178
178
|
def exists?
|
179
|
-
|
179
|
+
public_id = @resource_type == "raw" ? self.filename : self.public_id
|
180
|
+
Cloudinary::Uploader.exists?(public_id, :version=>self.version, :type=>self.storage_type, :resource_type=>self.resource_type)
|
180
181
|
end
|
181
182
|
|
182
183
|
def read(options={})
|
@@ -89,7 +89,7 @@ class Cloudinary::CarrierWave::Storage < ::CarrierWave::Storage::Abstract
|
|
89
89
|
uploader.model.set(column, name)
|
90
90
|
end
|
91
91
|
elsif defined?(Neo4j::VERSION) && Neo4j::VERSION.split(".").first.to_i >= 5
|
92
|
-
uploader.model.
|
92
|
+
uploader.model.write_attribute(column, name)
|
93
93
|
elsif defined?(Sequel::Model) && uploader.model.is_a?(Sequel::Model)
|
94
94
|
# Sequel support
|
95
95
|
uploader.model.this.update(column => name)
|
data/lib/cloudinary/utils.rb
CHANGED
@@ -397,11 +397,7 @@ class Cloudinary::Utils
|
|
397
397
|
transformation = transformation.gsub(%r(([^:])//), '\1/')
|
398
398
|
if sign_url && ( !auth_token || auth_token.empty?)
|
399
399
|
to_sign = [transformation, sign_version && version, source_to_sign].reject(&:blank?).join("/")
|
400
|
-
|
401
|
-
while to_sign != CGI.unescape(to_sign) && i <10
|
402
|
-
to_sign = CGI.unescape(to_sign)
|
403
|
-
i = i + 1
|
404
|
-
end
|
400
|
+
to_sign = fully_unescape(to_sign)
|
405
401
|
signature = 's--' + Base64.urlsafe_encode64(Digest::SHA1.digest(to_sign + secret))[0,8] + '--'
|
406
402
|
end
|
407
403
|
|
@@ -848,8 +844,24 @@ class Cloudinary::Utils
|
|
848
844
|
Cloudinary::AuthToken.generate options
|
849
845
|
|
850
846
|
end
|
847
|
+
|
851
848
|
private
|
852
849
|
|
850
|
+
|
851
|
+
# Repeatedly unescapes the source until no more unescaping is possible or 10 cycles elapsed
|
852
|
+
# @param [String] source - a (possibly) escaped string
|
853
|
+
# @return [String] the fully unescaped string
|
854
|
+
# @private
|
855
|
+
def self.fully_unescape(source)
|
856
|
+
i = 0
|
857
|
+
while source != CGI.unescape(source) && i <10
|
858
|
+
source = CGI.unescape(source.gsub('+', '%2B')) # don't let unescape replace '+' with space
|
859
|
+
i = i + 1
|
860
|
+
end
|
861
|
+
source
|
862
|
+
end
|
863
|
+
private_class_method :fully_unescape
|
864
|
+
|
853
865
|
def self.hash_query_params(hash)
|
854
866
|
if hash.respond_to?("to_query")
|
855
867
|
hash.to_query
|
data/lib/cloudinary/version.rb
CHANGED
data/lib/tasks/cloudinary.rake
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
unless Rake::Task.task_defined?('cloudinary:sync_static') # prevent double-loading/execution
|
2
2
|
namespace :cloudinary do
|
3
3
|
desc "Sync static resources with cloudinary"
|
4
|
-
task :sync_static do
|
4
|
+
task :sync_static => :environment do
|
5
5
|
delete_missing = ENV['DELETE_MISSING'] == 'true' || ENV['DELETE_MISSING'] == '1'
|
6
6
|
Cloudinary::Static.sync(:delete_missing => delete_missing)
|
7
7
|
end
|
8
8
|
end
|
9
|
-
end
|
9
|
+
end
|
data/spec/api_spec.rb
CHANGED
@@ -78,7 +78,7 @@ describe Cloudinary::Api do
|
|
78
78
|
expect(resources.map{|resource| resource["tags"]}.flatten).to include(TEST_TAG, TIMESTAMP_TAG)
|
79
79
|
expect(resources.map{|resource| resource["context"]}).to include({"custom" => {"key" => "value"}})
|
80
80
|
end
|
81
|
-
|
81
|
+
|
82
82
|
it "should allow listing resources by context" do
|
83
83
|
resources = @api.resources_by_context(test_key)["resources"]
|
84
84
|
expect(resources.count).to eq(2)
|
@@ -94,7 +94,7 @@ describe Cloudinary::Api do
|
|
94
94
|
expect(resources.map{|resource| resource["tags"]}.flatten).to include(TEST_TAG, TIMESTAMP_TAG)
|
95
95
|
expect(resources.map{|resource| resource["context"]}).to include({"custom" => {"key" => "value"}})
|
96
96
|
end
|
97
|
-
|
97
|
+
|
98
98
|
it "should allow listing resources by start date", :start_at => true do
|
99
99
|
start_at = Time.now
|
100
100
|
expect(RestClient::Request).to receive(:execute).with(deep_hash_value( {[:payload, :start_at] => start_at, [:payload, :direction] => "asc"}))
|
@@ -129,7 +129,7 @@ describe Cloudinary::Api do
|
|
129
129
|
expect(resource["bytes"]).to eq(3381)
|
130
130
|
expect(resource["derived"].length).to eq(1)
|
131
131
|
end
|
132
|
-
|
132
|
+
|
133
133
|
it "should allow deleting derived resource" do
|
134
134
|
derived_resource_id = "derived_id"
|
135
135
|
expect(RestClient::Request).to receive(:execute).with(deep_hash_value( {[:payload, :derived_resource_ids] => derived_resource_id}))
|
@@ -199,7 +199,7 @@ describe Cloudinary::Api do
|
|
199
199
|
tags = @api.tags(:prefix=>"api_test_no_such_tag")["tags"]
|
200
200
|
expect(tags).to be_blank
|
201
201
|
end
|
202
|
-
|
202
|
+
|
203
203
|
describe 'transformations' do
|
204
204
|
it "should allow listing transformations" do
|
205
205
|
transformation = @api.transformations(max_results: 500)["transformations"].find { |transformation| transformation["name"] == TEST_TRANSFOMATION }
|
@@ -265,6 +265,11 @@ describe Cloudinary::Api do
|
|
265
265
|
@api.update_transformation(public_id, :unsafe_update => { "crop" => "scale", "width" => 103 })
|
266
266
|
end
|
267
267
|
|
268
|
+
it "should allow listing of named transformations" do
|
269
|
+
expect(RestClient::Request).to receive(:execute).with(deep_hash_value( [:payload, :named ]=> true))
|
270
|
+
@api.transformations :named => true
|
271
|
+
end
|
272
|
+
|
268
273
|
end
|
269
274
|
it "should allow deleting implicit transformation" do
|
270
275
|
@api.transformation(TEST_TRANSFOMATION)
|
@@ -272,7 +277,7 @@ describe Cloudinary::Api do
|
|
272
277
|
expect { @api.transformation(TEST_TRANSFOMATION) }.to raise_error(Cloudinary::Api::NotFound)
|
273
278
|
end
|
274
279
|
end
|
275
|
-
|
280
|
+
|
276
281
|
it "should allow creating upload_presets" do
|
277
282
|
expected = {:url => /.*\/upload_presets$/,
|
278
283
|
[:payload, :name] => "new_preset",
|
@@ -305,7 +310,7 @@ describe Cloudinary::Api do
|
|
305
310
|
expect(preset["settings"]["context"]).to eq({"a" => "b", "c" => "d"})
|
306
311
|
expect(preset["settings"]["tags"]).to eq(["a","b","c", TEST_TAG, TIMESTAMP_TAG])
|
307
312
|
end
|
308
|
-
|
313
|
+
|
309
314
|
it "should allow deleting upload_presets", :upload_preset => true do
|
310
315
|
id = "#{prefix}_upload_preset"
|
311
316
|
@api.create_upload_preset(:name => id, :folder => "folder", :tags => [TEST_TAG, TIMESTAMP_TAG])
|
@@ -313,7 +318,7 @@ describe Cloudinary::Api do
|
|
313
318
|
@api.delete_upload_preset(id)
|
314
319
|
expect{preset = @api.upload_preset(id)}.to raise_error(Cloudinary::Api::NotFound)
|
315
320
|
end
|
316
|
-
|
321
|
+
|
317
322
|
it "should allow updating upload_presets", :upload_preset => true do
|
318
323
|
name = @api.create_upload_preset(:folder => "folder", :tags => [TEST_TAG, TIMESTAMP_TAG])["name"]
|
319
324
|
preset = @api.upload_preset(name)
|
@@ -323,7 +328,7 @@ describe Cloudinary::Api do
|
|
323
328
|
expect(preset["unsigned"]).to eq(true)
|
324
329
|
expect(preset["settings"]).to eq({"folder" => "folder", "colors" => true, "disallow_public_id" => true, "tags" => [TEST_TAG, TIMESTAMP_TAG]})
|
325
330
|
end
|
326
|
-
|
331
|
+
|
327
332
|
# this test must be last because it deletes (potentially) all dependent transformations which some tests rely on. Excluded by default.
|
328
333
|
skip "should allow deleting all resources", :delete_all=>true do
|
329
334
|
Cloudinary::Uploader.upload(TEST_IMG, :public_id=>"api_test5", :eager=>[:width=>101,:crop=>:scale], :tags => [TEST_TAG, TIMESTAMP_TAG])
|
@@ -335,7 +340,7 @@ describe Cloudinary::Api do
|
|
335
340
|
expect(resource).not_to be_blank
|
336
341
|
expect(resource["derived"].length).to eq(0)
|
337
342
|
end
|
338
|
-
|
343
|
+
|
339
344
|
it "should support setting manual moderation status" do
|
340
345
|
result = Cloudinary::Uploader.upload(TEST_IMG, {:moderation => :manual, :tags => [TEST_TAG, TIMESTAMP_TAG]})
|
341
346
|
expect(result["moderation"][0]["status"]).to eq("pending")
|
@@ -344,17 +349,17 @@ describe Cloudinary::Api do
|
|
344
349
|
expect(api_result["moderation"][0]["status"]).to eq("approved")
|
345
350
|
expect(api_result["moderation"][0]["kind"]).to eq("manual")
|
346
351
|
end
|
347
|
-
|
352
|
+
|
348
353
|
it "should support requesting raw conversion" do
|
349
354
|
result = Cloudinary::Uploader.upload("spec/docx.docx", :resource_type => :raw, :tags => [TEST_TAG, TIMESTAMP_TAG])
|
350
355
|
expect{Cloudinary::Api.update(result["public_id"], {:resource_type => :raw, :raw_convert => :illegal})}.to raise_error(Cloudinary::Api::BadRequest, /^Illegal value|not a valid/)
|
351
356
|
end
|
352
|
-
|
357
|
+
|
353
358
|
it "should support requesting categorization" do
|
354
359
|
result = Cloudinary::Uploader.upload(TEST_IMG, :tags => [TEST_TAG, TIMESTAMP_TAG])
|
355
360
|
expect{Cloudinary::Api.update(result["public_id"], {:categorization => :illegal})}.to raise_error(Cloudinary::Api::BadRequest, /^Illegal value/)
|
356
361
|
end
|
357
|
-
|
362
|
+
|
358
363
|
it "should support requesting detection with server notification", :focus => true do
|
359
364
|
expected = {
|
360
365
|
[:payload, :detection] => "adv_face",
|
@@ -363,12 +368,12 @@ describe Cloudinary::Api do
|
|
363
368
|
expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
|
364
369
|
Cloudinary::Api.update("public_id", {:detection => "adv_face", :notification_url => "http://example.com"})
|
365
370
|
end
|
366
|
-
|
371
|
+
|
367
372
|
it "should support requesting auto_tagging" do
|
368
373
|
expect(RestClient::Request).to receive(:execute).with(deep_hash_value( [:payload, :auto_tagging] => 0.5))
|
369
374
|
Cloudinary::Api.update("public_id", {:auto_tagging => 0.5})
|
370
375
|
end
|
371
|
-
|
376
|
+
|
372
377
|
it "should support listing by moderation kind and value" do
|
373
378
|
expect(RestClient::Request).to receive(:execute).with(deep_hash_value([:url] => /.*manual\/approved$/, [:payload, :max_results] => 1000))
|
374
379
|
Cloudinary::Api.resources_by_moderation(:manual, :approved, :max_results => 1000)
|
@@ -462,12 +467,12 @@ describe Cloudinary::Api do
|
|
462
467
|
|
463
468
|
expect(result["published"]).to be_an_instance_of(Array)
|
464
469
|
expect(result["published"].length).to eq(1)
|
465
|
-
|
470
|
+
|
466
471
|
resource = result["published"][0]
|
467
|
-
|
472
|
+
|
468
473
|
expect(resource["public_id"]).to eq(publicId)
|
469
474
|
expect(resource["type"]).to eq('upload')
|
470
|
-
|
475
|
+
|
471
476
|
bytes = resource["bytes"]
|
472
477
|
end
|
473
478
|
it "should publish resources by prefix and overwrite" do
|
@@ -475,13 +480,13 @@ describe Cloudinary::Api do
|
|
475
480
|
|
476
481
|
expect(result["published"]).to be_an_instance_of(Array)
|
477
482
|
expect(result["published"].length).to eq(1)
|
478
|
-
|
483
|
+
|
479
484
|
resource = result["published"][0]
|
480
|
-
|
485
|
+
|
481
486
|
expect(resource["public_id"]).to eq(publicId)
|
482
487
|
expect(resource["bytes"]).not_to eq(bytes)
|
483
488
|
expect(resource["type"]).to eq('upload')
|
484
|
-
|
489
|
+
|
485
490
|
bytes = resource["bytes"]
|
486
491
|
end
|
487
492
|
it "should publish resources by tag and overwrite" do
|
@@ -489,15 +494,52 @@ describe Cloudinary::Api do
|
|
489
494
|
|
490
495
|
expect(result["published"]).to be_an_instance_of(Array)
|
491
496
|
expect(result["published"].length).to eq(1)
|
492
|
-
|
497
|
+
|
493
498
|
resource = result["published"][0]
|
494
|
-
|
499
|
+
|
495
500
|
expect(resource["public_id"]).to eq(publicId)
|
496
501
|
expect(resource["bytes"]).not_to eq(bytes)
|
497
502
|
expect(resource["type"]).to eq('upload')
|
498
|
-
|
503
|
+
|
499
504
|
bytes = resource["bytes"]
|
500
505
|
end
|
506
|
+
end
|
507
|
+
end
|
508
|
+
|
509
|
+
describe Cloudinary::Api::Response do
|
510
|
+
let(:api_response) { described_class.new }
|
511
|
+
|
512
|
+
shared_examples 'a Hash' do
|
513
|
+
it 'inherits from Hash' do
|
514
|
+
expect(api_response).to be_a Hash
|
515
|
+
end
|
516
|
+
end
|
517
|
+
|
518
|
+
context 'when there is no argument given on instantiation' do
|
519
|
+
it 'does not raise an error' do
|
520
|
+
expect { api_response }.to_not raise_error
|
521
|
+
end
|
522
|
+
|
523
|
+
it_behaves_like 'a Hash'
|
524
|
+
end
|
525
|
+
|
526
|
+
context 'when the response is nil' do
|
527
|
+
it 'does not raise an error' do
|
528
|
+
expect { described_class.new nil }.to_not raise_error
|
529
|
+
end
|
530
|
+
|
531
|
+
it_behaves_like 'a Hash'
|
532
|
+
end
|
533
|
+
|
534
|
+
context 'when the response is present' do
|
535
|
+
let(:body) { { 'foo' => 'bar' } }
|
536
|
+
let(:http_response) { double code: 200, body: body.to_json, headers: { x_featureratelimit_reset: Time.new.to_s } }
|
537
|
+
let(:api_response) { described_class.new http_response }
|
538
|
+
|
539
|
+
it 'sets the instantiated self as the parsed response which is a Hash' do
|
540
|
+
expect(api_response).to eq body
|
541
|
+
end
|
501
542
|
|
543
|
+
it_behaves_like 'a Hash'
|
502
544
|
end
|
503
545
|
end
|
@@ -0,0 +1,44 @@
|
|
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
|
data/spec/utils_spec.rb
CHANGED
@@ -120,6 +120,17 @@ describe Cloudinary::Utils do
|
|
120
120
|
.and empty_options
|
121
121
|
end
|
122
122
|
|
123
|
+
it "should sign a url" do
|
124
|
+
expected = Cloudinary::Utils.cloudinary_url "some_public_id.jpg",
|
125
|
+
:cloud_name => "test",
|
126
|
+
:api_key => "123456789012345",
|
127
|
+
:api_secret => "AbcdEfghIjklmnopq1234567890",
|
128
|
+
:type => "authenticated",
|
129
|
+
:sign_url => true,
|
130
|
+
:overlay => "text:Helvetica_50:test+text"
|
131
|
+
expect(expected).to eq("http://res.cloudinary.com/test/image/authenticated/s--j5Z1ILxd--/l_text:Helvetica_50:test+text/some_public_id.jpg")
|
132
|
+
end
|
133
|
+
|
123
134
|
it "should not sign the url_suffix" do
|
124
135
|
expected_signture = Cloudinary::Utils.cloudinary_url("test", :format => "jpg", :sign_url => true).match(/s--[0-9A-Za-z_-]{8}--/).to_s
|
125
136
|
expect(["test", { :url_suffix => "hello", :private_cdn => true, :format => "jpg", :sign_url => true }])
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cloudinary
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.8.
|
4
|
+
version: 1.8.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nadav Soferman
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2017-
|
13
|
+
date: 2017-11-22 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: aws_cf_signer
|
@@ -184,6 +184,7 @@ files:
|
|
184
184
|
- spec/sample_asset_file.tsv
|
185
185
|
- spec/search_spec.rb
|
186
186
|
- spec/spec_helper.rb
|
187
|
+
- spec/storage_spec.rb
|
187
188
|
- spec/streaminig_profiles_api_spec.rb
|
188
189
|
- spec/support/helpers/temp_file_helpers.rb
|
189
190
|
- spec/support/shared_contexts/rake.rb
|
@@ -224,7 +225,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
224
225
|
version: '0'
|
225
226
|
requirements: []
|
226
227
|
rubyforge_project: cloudinary
|
227
|
-
rubygems_version: 2.6.
|
228
|
+
rubygems_version: 2.6.12
|
228
229
|
signing_key:
|
229
230
|
specification_version: 4
|
230
231
|
summary: Client library for easily using the Cloudinary service
|
@@ -244,6 +245,7 @@ test_files:
|
|
244
245
|
- spec/sample_asset_file.tsv
|
245
246
|
- spec/search_spec.rb
|
246
247
|
- spec/spec_helper.rb
|
248
|
+
- spec/storage_spec.rb
|
247
249
|
- spec/streaminig_profiles_api_spec.rb
|
248
250
|
- spec/support/helpers/temp_file_helpers.rb
|
249
251
|
- spec/support/shared_contexts/rake.rb
|