cloudinary 1.8.1 → 1.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
-
 **Take a look at our [Getting started guide of Ruby on Rails](
|
16
|
+
 **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
|

|
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
|

|
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
|
-
 **See [our documentation](
|
133
|
+
 **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
|
-
 **See [our documentation](
|
160
|
+
 **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
|
-
 **For more details on CarrierWave integration see [our documentation](
|
175
|
+
 **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
|