cloudinary 1.1.6 → 1.1.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 58c3479c59e20893f65ba55c52498183ebce293a
4
- data.tar.gz: 45b5a9f416a2522b820ebd2f5229024bb5e055a2
3
+ metadata.gz: 8c21572d5ca0363eb07c0a226e92498d90d9f2b9
4
+ data.tar.gz: ab8a7a05057dbf409296897576f69745d9516a8a
5
5
  SHA512:
6
- metadata.gz: fd74bfe3c3f91408cfdb0de65add6249c51c8828d61ea3bb3831efcb02219551ccabbf67b99e3a47c6cbfc8d1540974f75aa8e40aad67b51c33177b1bb58954f
7
- data.tar.gz: 36ff909b5ef5903ef1ffec3ba61ec21f7807d27f0e933ca0b807bb653551f858ded73a9f3ad8d7f49f2e3f6c95e9767f38ce0652b37fe576417de9a48b0d0f09
6
+ metadata.gz: d609e1b2f396d259645df469f7ec94769f31bae9e49571b77530aa73521bbece7dcdff545309db03f8486ff4c566a68179b26f3d3473a7db444554fd1cdddcca
7
+ data.tar.gz: 3496b66de2e36abdde1e9b28e30c392807f784295ed4de76f4f0e87e5362fb9be2202e625cd6ffe85c6e8b4c8d01a70127c6c29ff5a4c6b278e8c0999be7412c
@@ -0,0 +1,7 @@
1
+ rvm:
2
+ - 1.9.3
3
+ - 2.2.3
4
+ env:
5
+ matrix:
6
+ secure: OTtg+CpNgfqJYqJk4rRZRvljss2p6nLTgBLrdUt/4hpSFLFueo0m7Jdu2zeEDPLEzMKo6zZlBp1/BPjCHtnjda7qpOQpMutEzD5EG60BG5LiMDsoAHL6apiL4zNUy8Sjcp/QslpKRozcYzogHjCnxM8RtSnW9wqiCehM5yivlj4JwU/e2x7XZGRbwW2jj4kr/BAdylYYftAaVOrl/3vqngE2tciq6YRL5GFR6o1L5ty435jsyDwEWAPs6vTLwJuEmPLJ4pEOVPOI08zOgVWKHyAWiCc7WYyBxKDmDUU9Xth922ko7nhptQUJeJuxh2dTvrPuTkibNzX1QLugX8RwzJ7pXG9iuhx14lmFbfZZtl+g2SEh5Hem5GFCVOlxpULuxZUKDcNwYURWwuoeBYpGOrOu7xn70o6cF3bNfenUJEl/ts1YgAZ/pcHmbeW95ovb+vTHj8uPk1J17FKOtXjbgblzYLwrl68ika1QfWJEYq1DcI7BT7AwsEeThPmvQ03y+lH8DrYQVprzTpjGICvMyMQSZdA8woXMeEFV0CzKew1+Q0JgjLpYDTQ6U51HEvzCZFTNoN2ZDdsdMRtkxmjBwgEQAY5+SA5icI6/uxAvloScl+7SnNiAhqyPaA2YlwZ/xhI8plvydkmK805Z1uZztGUNu0yn47FzGDC286RF/rI=
7
+ script: bundle exec rspec
@@ -1,4 +1,35 @@
1
1
 
2
+ 1.1.7 / 2016-06-06
3
+ ==================
4
+
5
+ New functionality and features
6
+ ------------------------------
7
+ * Add TravisCI configuration and label
8
+ * Add `keyframe_interval` and `streaming_profile` transformation parameters
9
+ * Add `expires_at` parameter to `Utils#download_archive_url`
10
+ * Add `CONTRIBUTING.md`
11
+ * Add `next_cursor` to `transformation()`
12
+ * Update Readme with information on the Cloudinary JavaScript library. Related to #199
13
+
14
+ Other Changes
15
+ -------------
16
+
17
+ * Ensuring rails environment is loaded as a dependency of running sync_static rake task, so anything initializer that sets up Cloudinary.config takes affect
18
+ * Refactor tests to allow parallel runs.
19
+ * Fix `deep_hash_values` matcher.
20
+ * Mock heavy tests
21
+ * Remove upload_presets created during the tests
22
+ * Merge pull request #177 from Buyapowa/fix-rake-task-config-loading
23
+ * Merge pull request #185 from gunterja/patch-1
24
+ * Merge pull request #186 from gunterja/patch-2
25
+ * Merge pull request #187 from gunterja/patch-3
26
+ * Merge pull request #189 from gunterja/patch-5
27
+ * Merge branch 'task/add-next-cursor-to-transformation'
28
+ * adding tests for next_cursor with transformation
29
+ * Merge pull request #192 from thedrow/patch-1
30
+ * exists? must return booleans
31
+ * `File.exists?` is deprecated in favor of `File.exist?`
32
+
2
33
  1.1.6 / 2016-04-20
3
34
  ==================
4
35
 
@@ -0,0 +1,136 @@
1
+ # Contributing to Cloudinary GEM
2
+
3
+ Contributions are welcome and greatly appreciated!
4
+
5
+ ## Reporting a bug
6
+
7
+ - Ensure that the bug was not already reported by searching in GitHub under [Issues](https://github.com/cloudinary/cloudinary_gem) and the Cloudinary [Support forms](https://support.cloudinary.com).
8
+ - If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/cloudinary/cloudinary_gem/issues/new).
9
+ Be sure to include a **title and clear description**, as much relevant information as possible, and a **code sample** or an **executable test case** demonstrating the expected behavior that is not occurring.
10
+ - If you require assistance in the implementation of cloudinary_gem please [submit a request](https://support.cloudinary.com/hc/en-us/requests/new) in the Cloudinary web site.
11
+
12
+ ## Requesting a feature
13
+
14
+ We would love to hear your requests!
15
+ Please be aware that the GEM is used in a wide variety of environments and that some features may not be applicable to all users.
16
+
17
+ - Open a GitHub [issue](https://github.com/cloudinary/cloudinary_gem) describing the benefits (and possible drawbacks) of the requested feature
18
+
19
+ ## Fixing a bug / Implementing a new feature
20
+
21
+ - Follow the instructions detailed in [Code contribution](#code-contribution)
22
+ - Open a new GitHub pull request
23
+ - Ensure the PR description clearly describes the bug / feature. Include the relevant issue number if applicable.
24
+ - Provide test code that covers the new code
25
+ - Make sure that your code works both with and without Rails
26
+ - The code should support:
27
+ - Ruby >= 1.8
28
+ - Rails >= 3.0
29
+
30
+ ## Code contribution
31
+
32
+ When contributing code, either to fix a bug or to implement a new feature, please follow these guidelines:
33
+
34
+ #### Fork the Project
35
+
36
+ Fork [project on Github](https://github.com/cloudinary/cloudinary_gem) and check out your copy.
37
+
38
+ ```
39
+ git clone https://github.com/contributor/cloudinary_gem.git
40
+ cd cloudinary_gem
41
+ git remote add upstream https://github.com/cloudinary/cloudinary_gem.git
42
+ ```
43
+
44
+ #### Create a Topic Branch
45
+
46
+ Make sure your fork is up-to-date and create a topic branch for your feature or bug fix.
47
+
48
+ ```
49
+ git checkout master
50
+ git pull upstream master
51
+ git checkout -b my-feature-branch
52
+ ```
53
+ #### Rebase
54
+
55
+ If you've been working on a change for a while, rebase with upstream/master.
56
+
57
+ ```
58
+ git fetch upstream
59
+ git rebase upstream/master
60
+ git push origin my-feature-branch -f
61
+ ```
62
+
63
+
64
+ #### Write Tests
65
+
66
+ Try to write a test that reproduces the problem you're trying to fix or describes a feature that you want to build. Add to [test](test).
67
+
68
+ We definitely appreciate pull requests that highlight or reproduce a problem, even without a fix.
69
+
70
+ #### Write Code
71
+
72
+ Implement your feature or bug fix.
73
+ Follow the following [style guide](https://github.com/styleguide/ruby).
74
+ Make sure that your code works both with and without Rails
75
+ The code should support:
76
+
77
+ - Ruby >= 1.8
78
+ - Rails >= 3.0
79
+
80
+ Make sure that `bundle exec rake test` completes without errors.
81
+
82
+ #### Write Documentation
83
+
84
+ Document any external behavior in the [README](README.md).
85
+
86
+ #### Commit Changes
87
+
88
+ Make sure git knows your name and email address:
89
+
90
+ ```
91
+ git config --global user.name "Your Name"
92
+ git config --global user.email "contributor@example.com"
93
+ ```
94
+
95
+ Writing good commit logs is important. A commit log should describe what changed and why.
96
+
97
+ ```
98
+ git add ...
99
+ git commit
100
+ ```
101
+
102
+
103
+ > Please squash your commits into a single commit when appropriate. This simplifies future cherry picks and keeps the git log clean.
104
+
105
+ #### Push
106
+
107
+ ```
108
+ git push origin my-feature-branch
109
+ ```
110
+
111
+ #### Make a Pull Request
112
+
113
+ Go to https://github.com/contributor/cloudinary_gem and select your feature branch. Click the 'Pull Request' button and fill out the form. Pull requests are usually reviewed within a few days.
114
+ Ensure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable.
115
+
116
+ #### Rebase
117
+
118
+ If you've been working on a change for a while, rebase with upstream/master.
119
+
120
+ ```
121
+ git fetch upstream
122
+ git rebase upstream/master
123
+ git push origin my-feature-branch -f
124
+ ```
125
+
126
+ #### Check on Your Pull Request
127
+
128
+ Go back to your pull request after a few minutes and see whether it passed muster with Travis-CI. Everything should look green, otherwise fix issues and amend your commit as described above.
129
+
130
+ #### Be Patient
131
+
132
+ It's likely that your change will not be merged and that the nitpicky maintainers will ask you to do more, or fix seemingly benign problems. Hang on there!
133
+
134
+ #### Thank You
135
+
136
+ Please do know that we really appreciate and value your time and work. We love you, really.
data/README.md CHANGED
@@ -1,3 +1,4 @@
1
+ [![Build Status](https://travis-ci.org/cloudinary/cloudinary_gem.svg?branch=master)](https://travis-ci.org/cloudinary/cloudinary_gem)
1
2
  Cloudinary
2
3
  ==========
3
4
 
@@ -175,10 +176,54 @@ Cloudinary's Ruby GEM includes an optional plugin for [CarrierWave](https://gith
175
176
 
176
177
  We also published an interesting blog post about [Ruby on Rails image uploads with CarrierWave and Cloudinary](http://cloudinary.com/blog/ruby_on_rails_image_uploads_with_carrierwave_and_cloudinary).
177
178
 
178
- ## Neo4j integration
179
+ #### Neo4j integration
179
180
 
180
181
  Starting from version 1.1.1 Cloudinary's Ruby GEM supports the use of carrierwave with Neo4j.
181
182
 
183
+ ### JavaScript support library
184
+
185
+ During the installation or update of the Cloudinary GEM, the latest Cloudinary JavaScript library is automatically fetched and bundled with the GEM.
186
+
187
+ To use the JavaScript files you need to include them in your application, for example:
188
+
189
+ ```
190
+ <%= javascript_include_tag("jquery.ui.widget", "jquery.iframe-transport",
191
+ "jquery.fileupload", "jquery.cloudinary") %>
192
+ ```
193
+
194
+ Alternatively, if you use Asset Pipeline, simply edit your application.js file and add the following line:
195
+
196
+ ```
197
+ //= require cloudinary
198
+ ```
199
+
200
+ To automatically set-up Cloudinary's configuration, include the following line in your view or layout:
201
+
202
+ ```
203
+ <%= cloudinary_js_config %>
204
+ ```
205
+
206
+ #### Uploading images from the browser
207
+
208
+ The Cloudinary JavaScript library utilizes the Blueimp File Upload library to support image uploading from the browser. See the [documentation](http://cloudinary.com/documentation/jquery_image_upload) for more details.
209
+
210
+ |Important|
211
+ |---------|
212
+ |Starting with version 2.0 of the Cloudinary JavaScript library, the Cloudinary extension to the Blueimp File Upload library is no longer initialized automatically. Instead you need to explicitly set it up as described below.|
213
+
214
+ To initialize the File Upload library with Cloudinary include the following code in your page:
215
+
216
+ ```javascript
217
+ $(function() {
218
+ if($.fn.cloudinary_fileupload !== undefined) {
219
+ $("input.cloudinary-fileupload[type=file]").cloudinary_fileupload();
220
+ }
221
+ });
222
+ ```
223
+
224
+
225
+ (`cloudinary_fileupload()` internally calls Blueimp's `fileupload()` so there's no need to call both.)
226
+
182
227
  ### Samples
183
228
 
184
229
  You can find our simple and ready-to-use samples projects, along with documentation in the [samples folder](https://github.com/cloudinary/cloudinary_gem/tree/master/samples).
data/Rakefile CHANGED
@@ -16,7 +16,8 @@ namespace :cloudinary do
16
16
  task :fetch_assets do
17
17
  index_files = %w[jquery.ui.widget.js jquery.iframe-transport.js jquery.fileupload.js jquery.cloudinary.js]
18
18
  processing_files = %w[canvas-to-blob.min.js load-image.all.min.js jquery.fileupload-process.js jquery.fileupload-image.js jquery.fileupload-validate.js]
19
- files = index_files + processing_files
19
+ other_files = %w[jquery.cloudinary.coffee jquery.cloudinary.js.map]
20
+ files = index_files + processing_files + other_files
20
21
 
21
22
  release = JSON(RestClient.get("https://api.github.com/repos/cloudinary/cloudinary_js/releases/latest"))
22
23
 
@@ -137,7 +137,7 @@ class Cloudinary::Api
137
137
  end
138
138
 
139
139
  def self.transformation(transformation, options={})
140
- call_api(:get, "transformations/#{transformation_string(transformation)}", only(options, :max_results), options)
140
+ call_api(:get, "transformations/#{transformation_string(transformation)}", only(options, :max_results, :next_cursor), options)
141
141
  end
142
142
 
143
143
  def self.delete_transformation(transformation, options={})
@@ -6,7 +6,7 @@ module Cloudinary::CarrierWave
6
6
 
7
7
  def process_all_versions(*args)
8
8
  @all_versions ||= Class.new(self)
9
- @all_versions.process *args
9
+ @all_versions.process(*args)
10
10
  end
11
11
 
12
12
  def eager
@@ -164,7 +164,7 @@ class Cloudinary::Migrator
164
164
  def update_row(row, values)
165
165
  values.merge!("updated_at"=>Time.now.to_i)
166
166
  query = ["update queue set #{values.keys.map{|key| "#{key}=?"}.join(",")} where id=?"] + values.values + [row["id"]]
167
- result = @db.execute(*query)
167
+ @db.execute(*query)
168
168
  values.each{|key, value| row[key.to_s] = value}
169
169
  row
170
170
  end
@@ -149,7 +149,8 @@ class Cloudinary::Uploader
149
149
  def self.exists?(public_id, options={})
150
150
  cloudinary_url = Cloudinary::Utils.cloudinary_url(public_id, options)
151
151
  begin
152
- RestClient::Request.execute(:method => :head, :url => cloudinary_url, :timeout => 5).code.to_s =~ /2\d{2}/
152
+ code = RestClient::Request.execute(:method => :head, :url => cloudinary_url, :timeout => 5).code
153
+ code >= 200 && code < 300
153
154
  rescue RestClient::ResourceNotFound
154
155
  return false
155
156
  end
@@ -121,6 +121,7 @@ class Cloudinary::Utils
121
121
  :eo => :end_offset,
122
122
  :f => :fetch_format,
123
123
  :g => :gravity,
124
+ :ki => :keyframe_interval,
124
125
  :o => :opacity,
125
126
  :p => :prefix,
126
127
  :pg => :page,
@@ -128,6 +129,7 @@ class Cloudinary::Utils
128
129
  :r => :radius,
129
130
  :af => :audio_frequency,
130
131
  :so => :start_offset,
132
+ :sp => :streaming_profile,
131
133
  :vc => :video_codec,
132
134
  :vs => :video_sampling,
133
135
  :x => :x,
@@ -741,6 +743,7 @@ class Cloudinary::Utils
741
743
  :tags=>options[:tags] && Cloudinary::Utils.build_array(options[:tags]),
742
744
  :public_ids=>options[:public_ids] && Cloudinary::Utils.build_array(options[:public_ids]),
743
745
  :prefixes=>options[:prefixes] && Cloudinary::Utils.build_array(options[:prefixes]),
746
+ :expires_at=>options[:expires_at],
744
747
  :transformations => build_eager(options[:transformations])
745
748
  }
746
749
  end
@@ -1,4 +1,4 @@
1
1
  # Copyright Cloudinary
2
2
  module Cloudinary
3
- VERSION = "1.1.6"
3
+ VERSION = "1.1.7"
4
4
  end
@@ -1,7 +1,7 @@
1
1
  namespace :cloudinary do
2
2
  desc "Sync static resources with cloudinary"
3
- task :sync_static do
3
+ task :sync_static => :environment do
4
4
  delete_missing = ENV["DELETE_MISSING"] == 'true' || ENV["DELETE_MISSING"] == '1'
5
5
  Cloudinary::Static.sync(:delete_missing=>delete_missing)
6
6
  end
7
- end
7
+ end
@@ -3,16 +3,32 @@ require 'cloudinary'
3
3
 
4
4
  describe Cloudinary::Api do
5
5
  break puts("Please setup environment for api test to run") if Cloudinary.config.api_secret.blank?
6
- include_context "cleanup"
6
+ include_context "cleanup", TIMESTAMP_TAG
7
7
 
8
8
  prefix = "api_test_#{Time.now.to_i}"
9
9
  test_id_1 = "#{prefix}_1"
10
10
  test_id_2 = "#{prefix}_2"
11
+ test_id_3 = "#{prefix}_3"
11
12
  before(:all) do
12
- @timestamp_tag = "api_test_tag_#{Time.now.to_i}"
13
+
13
14
  @api = Cloudinary::Api
14
- Cloudinary::Uploader.upload("spec/logo.png", :public_id => test_id_1, :tags => [TEST_TAG, @timestamp_tag], :context => "key=value", :eager =>[:width =>100, :crop =>:scale])
15
- Cloudinary::Uploader.upload("spec/logo.png", :public_id => test_id_2, :tags => [TEST_TAG, @timestamp_tag], :context => "key=value", :eager =>[:width =>100, :crop =>:scale])
15
+ Cloudinary::Uploader.upload("spec/logo.png", :public_id => test_id_1, :tags => [TEST_TAG, TIMESTAMP_TAG], :context => "key=value", :eager =>[:width =>100, :crop =>:scale])
16
+ Cloudinary::Uploader.upload("spec/logo.png", :public_id => test_id_2, :tags => [TEST_TAG, TIMESTAMP_TAG], :context => "key=value", :eager =>[:width =>100, :crop =>:scale])
17
+ Cloudinary::Uploader.upload("spec/logo.png", :public_id => test_id_3, :tags => [TEST_TAG, TIMESTAMP_TAG], :context => "key=value", :eager =>[:width =>100, :crop =>:scale])
18
+ end
19
+
20
+ after(:all) do
21
+ # in addition to "cleanup" context
22
+ unless Cloudinary.config.keep_test_products
23
+ up = Cloudinary::Api.upload_presets max_results: 500
24
+ up["presets"].each do |u|
25
+ tags = u["settings"]["tags"]
26
+ name = u["name"]
27
+ if tags =~ /.*#{TIMESTAMP_TAG}.*/
28
+ Cloudinary::Api.delete_upload_preset(name)
29
+ end
30
+ end
31
+ end
16
32
  end
17
33
 
18
34
  it "should allow listing resource_types" do
@@ -37,18 +53,17 @@ describe Cloudinary::Api do
37
53
  expect(result2["resources"][0]["public_id"]).not_to eq(result["resources"][0]["public_id"] )
38
54
  end
39
55
 
40
-
41
56
  it "should allow listing resources by type" do
42
57
  resource = @api.resources(:type=>"upload", :tags=>true)["resources"].find{|resource| resource["public_id"] == test_id_1
43
58
  }
44
59
  expect(resource).not_to be_blank
45
- expect(resource["tags"]).to match_array([TEST_TAG, @timestamp_tag])
60
+ expect(resource["tags"]).to match_array([TEST_TAG, TIMESTAMP_TAG])
46
61
  end
47
62
 
48
63
  it "should allow listing resources by prefix" do
49
64
  resources = @api.resources(:type =>"upload", :prefix => prefix, :tags => true, :context => true)["resources"]
50
65
  expect(resources.map{|resource| resource["public_id"]}).to include(test_id_1, test_id_2)
51
- expect(resources.map{|resource| resource["tags"]}.flatten).to include(TEST_TAG, @timestamp_tag)
66
+ expect(resources.map{|resource| resource["tags"]}.flatten).to include(TEST_TAG, TIMESTAMP_TAG)
52
67
  expect(resources.map{|resource| resource["context"]}).to include({"custom" => {"key" => "value"}})
53
68
  end
54
69
 
@@ -56,7 +71,7 @@ describe Cloudinary::Api do
56
71
  resources = @api.resources_by_tag(TEST_TAG, :tags => true, :context => true)["resources"]
57
72
  expect(resources.find{|resource| resource["public_id"] == test_id_1
58
73
  }).not_to be_blank
59
- expect(resources.map{|resource| resource["tags"]}.flatten).to include(TEST_TAG, @timestamp_tag)
74
+ expect(resources.map{|resource| resource["tags"]}.flatten).to include(TEST_TAG, TIMESTAMP_TAG)
60
75
  expect(resources.map{|resource| resource["context"]}).to include({"custom" => {"key" => "value"}})
61
76
  end
62
77
 
@@ -65,29 +80,35 @@ describe Cloudinary::Api do
65
80
  expect(resources.length).to eq(2)
66
81
  expect(resources.find{|resource| resource["public_id"] == test_id_1
67
82
  }).not_to be_blank
68
- expect(resources.map{|resource| resource["tags"]}.flatten).to include(TEST_TAG, @timestamp_tag)
83
+ expect(resources.map{|resource| resource["tags"]}.flatten).to include(TEST_TAG, TIMESTAMP_TAG)
69
84
  expect(resources.map{|resource| resource["context"]}).to include({"custom" => {"key" => "value"}})
70
85
  end
71
86
 
72
87
  it "should allow listing resources by start date", :start_at => true do
73
- sleep(1)
74
- response = Cloudinary::Uploader.upload("spec/logo.png", :tags => TEST_TAG)
75
- start_at = Time.parse( response["created_at"]) - 0.5
76
- resources = @api.resources(:type=>"upload", :start_at=>start_at, :direction => "asc")["resources"]
77
- expect(resources.map{|resource| resource["public_id"]}).to eq([response["public_id"]])
88
+ start_at = Time.now
89
+ expect(RestClient::Request).to receive(:execute).with(deep_hash_value( {[:payload, :start_at] => start_at, [:payload, :direction] => "asc"}))
90
+ @api.resources(:type=>"upload", :start_at=>start_at, :direction => "asc")
78
91
  end
79
-
80
- it "should allow listing resources in both directions" do
81
- asc_resources = @api.resources_by_tag(@timestamp_tag, :type=>"upload", :direction => "asc")["resources"]
82
- desc_resources = @api.resources_by_tag(@timestamp_tag, :type=>"upload", :direction => "desc")["resources"]
83
- # NOTE: this assumes the full list fits in a page which is the case unless resources with 'api_test' prefix were
84
- # uploaded to the account against which this test runs
85
- expect(asc_resources.reverse).to eq(desc_resources)
86
- asc_resources_alt = @api.resources_by_tag(@timestamp_tag, :type=>"upload", :direction => 1)["resources"]
87
- desc_resources_alt = @api.resources_by_tag(@timestamp_tag, :type=>"upload", :direction => -1)["resources"]
88
- expect(asc_resources_alt.reverse).to eq(desc_resources_alt)
89
- expect(asc_resources).to eq(asc_resources_alt)
90
- expect{@api.resources_by_tag(@timestamp_tag, :type=>"upload", :direction => "anythingelse")["resources"]}.to raise_error(Cloudinary::Api::BadRequest)
92
+
93
+ describe ":direction" do
94
+
95
+ it "should accept a string 'desc' and 'asc'" do
96
+ expected = {
97
+ :url => /.*\/resources\/image\/tags\/#{TIMESTAMP_TAG}/,
98
+ [:payload, :direction] => "asc"
99
+ }
100
+ expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
101
+
102
+ @api.resources_by_tag(TIMESTAMP_TAG, :type=>"upload", :direction => "asc")
103
+ end
104
+ it "should accept an integer of '1' or '-1'" do
105
+ expected = {
106
+ :url => /.*\/resources\/image\/tags\/#{TIMESTAMP_TAG}/,
107
+ [:payload, :direction] => "-1"
108
+ }
109
+ expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
110
+ @api.resources_by_tag(TIMESTAMP_TAG, :type=>"upload", :direction => "-1")
111
+ end
91
112
  end
92
113
 
93
114
  it "should allow get resource metadata" do
@@ -99,39 +120,24 @@ describe Cloudinary::Api do
99
120
  end
100
121
 
101
122
  it "should allow deleting derived resource" do
102
- Cloudinary::Uploader.upload("spec/logo.png", :public_id=>"api_test3", :eager=>[:width=>101,:crop=>:scale])
103
- resource = @api.resource("api_test3")
104
- expect(resource).not_to be_blank
105
- expect(resource["derived"].length).to eq(1)
106
- derived_resource_id = resource["derived"][0]["id"]
123
+ derived_resource_id = "derived_id"
124
+ expect(RestClient::Request).to receive(:execute).with(deep_hash_value( {[:payload, :derived_resource_ids] => derived_resource_id}))
107
125
  @api.delete_derived_resources(derived_resource_id)
108
- resource = @api.resource("api_test3")
109
- expect(resource).not_to be_blank
110
- expect(resource["derived"].length).to eq(0)
111
126
  end
112
127
 
113
128
  it "should allow deleting resources" do
114
- Cloudinary::Uploader.upload("spec/logo.png", :public_id=>"api_test3")
115
- resource = @api.resource("api_test3")
116
- expect(resource).not_to be_blank
117
- @api.delete_resources(["apit_test", test_id_2, "api_test3"])
118
- expect{@api.resource("api_test3")}.to raise_error(Cloudinary::Api::NotFound)
129
+ expect(RestClient::Request).to receive(:execute).with(deep_hash_value( {[:payload, :public_ids] => ["apit_test", "test_id_2", "api_test3"]}))
130
+ @api.delete_resources(["apit_test", "test_id_2", "api_test3"])
119
131
  end
120
132
 
121
133
  it "should allow deleting resources by prefix" do
122
- Cloudinary::Uploader.upload("spec/logo.png", :public_id=>"api_test_by_prefix")
123
- resource = @api.resource("api_test_by_prefix")
124
- expect(resource).not_to be_blank
134
+ expect(RestClient::Request).to receive(:execute).with(deep_hash_value( {[:payload, :prefix] => "api_test_by"}))
125
135
  @api.delete_resources_by_prefix("api_test_by")
126
- expect{@api.resource("api_test_by_prefix")}.to raise_error(Cloudinary::Api::NotFound)
127
136
  end
128
137
 
129
138
  it "should allow deleting resources by tags" do
130
- Cloudinary::Uploader.upload("spec/logo.png", :public_id=>"api_test4", :tags=>[TEST_TAG, "api_test_tag_for_delete"])
131
- resource = @api.resource("api_test4")
132
- expect(resource).not_to be_blank
139
+ expect(RestClient::Request).to receive(:execute).with(hash_including( :url => /.*\/tags\/api_test_tag_for_delete$/))
133
140
  @api.delete_resources_by_tag("api_test_tag_for_delete")
134
- expect{@api.resource("api_test4")}.to raise_error(Cloudinary::Api::NotFound)
135
141
  end
136
142
 
137
143
  it "should allow listing tags" do
@@ -140,8 +146,8 @@ describe Cloudinary::Api do
140
146
  end
141
147
 
142
148
  it "should allow listing tag by prefix" do
143
- tags = @api.tags(:prefix=> "api_test_tag")["tags"]
144
- expect(tags).to include(@timestamp_tag)
149
+ tags = @api.tags(:prefix=> TEST_TAG)["tags"]
150
+ expect(tags).to include(TIMESTAMP_TAG)
145
151
  tags = @api.tags(:prefix=>"api_test_no_such_tag")["tags"]
146
152
  expect(tags).to be_blank
147
153
  end
@@ -173,10 +179,21 @@ describe Cloudinary::Api do
173
179
  expect(transformation["allowed_for_strict"]).to eq(false)
174
180
  end
175
181
 
182
+ it "should fetch two different derived images using next_cursor" do
183
+ result = @api.transformation("c_scale,w_100", :max_results=>1)
184
+ expect(result["derived"]).not_to be_blank
185
+ expect(result["derived"].length).to eq(1)
186
+ expect(result["next_cursor"]).not_to be_blank
187
+ result2 = @api.transformation("c_scale,w_100", :max_results=>1, :next_cursor=>result["next_cursor"])
188
+ expect(result2["derived"]).not_to be_blank
189
+ expect(result2["derived"].length).to eq(1)
190
+ expect(result2["derived"][0]["id"]).not_to eq(result["derived"][0]["id"] )
191
+ end
192
+
176
193
  describe "named transformations" do
177
194
  it "should allow creating named transformation" do
178
195
  public_id = "api_test_transformation_#{Time.now.to_i}"
179
- @api.create_transformation(public_id, "crop" => "scale", "width" => 102, :tags => TEST_TAG)
196
+ @api.create_transformation(public_id, "crop" => "scale", "width" => 102)
180
197
  transformation = @api.transformation(public_id)
181
198
  expect(transformation).not_to be_blank
182
199
  expect(transformation["allowed_for_strict"]).to eq(true)
@@ -186,20 +203,18 @@ describe Cloudinary::Api do
186
203
 
187
204
  it "should allow deleting named transformation" do
188
205
  public_id = "api_test_transformation_#{Time.now.to_i}"
189
- @api.create_transformation(public_id, "crop" => "scale", "width" => 103, :tags => TEST_TAG)
190
- @api.transformation(public_id)
206
+ expect(RestClient::Request).to receive(:execute).with(deep_hash_value( :url => /.*\/transformations\/#{public_id}/, :method => :delete))
191
207
  @api.delete_transformation(public_id)
192
- expect { @api.transformation(public_id) }.to raise_error(Cloudinary::Api::NotFound)
193
208
  end
194
209
 
195
210
  it "should allow unsafe update of named transformation" do
196
211
  public_id = "api_test_transformation_#{Time.now.to_i}"
197
- @api.create_transformation(public_id, "crop" => "scale", "width" => 102, :tags => TEST_TAG)
212
+ expected = {
213
+ :url => /.*\/transformations\/#{public_id}$/,
214
+ :method => :put,
215
+ [:payload, :unsafe_update] => "c_scale,w_103"}
216
+ expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
198
217
  @api.update_transformation(public_id, :unsafe_update => { "crop" => "scale", "width" => 103 })
199
- transformation = @api.transformation(public_id)
200
- expect(transformation).not_to be_blank
201
- expect(transformation["info"]).to eq(["crop" => "scale", "width" => 103])
202
- expect(transformation["used"]).to eq(false)
203
218
  end
204
219
 
205
220
  end
@@ -210,17 +225,29 @@ describe Cloudinary::Api do
210
225
  end
211
226
  end
212
227
 
213
- it "should allow creating and listing upload_presets", :upload_preset => true do
214
- name = []
215
- 3.times { |i| name.push( "api_test_#{Time.now.to_i}_#{i}")}
216
- @api.create_upload_preset(:name => name[0], :folder => "folder", :tags => TEST_TAG)
217
- @api.create_upload_preset(:name => name[1], :folder => "folder2", :tags => TEST_TAG)
218
- @api.create_upload_preset(:name => name[2], :folder => "folder3", :tags => TEST_TAG)
219
- expect(@api.upload_presets["presets"].first(3).map{|p| p["name"]}).to match_array(name)
228
+ it "should allow creating upload_presets" do
229
+ expected = {:url => /.*\/upload_presets$/,
230
+ [:payload, :name] => "new_preset",
231
+ [:payload, :folder] => "some_folder"}
232
+ expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
233
+
234
+ @api.create_upload_preset(:name => "new_preset", :folder => "some_folder", :tags => [TEST_TAG, TIMESTAMP_TAG])
235
+ end
236
+
237
+ describe "upload_presets" do
238
+ it 'should not accept parameters' do
239
+ expected = {
240
+ :url => /.*\/upload_presets/,
241
+ [:payload, :next_cursor] => 1234567,
242
+ [:payload, :max_results] => 10
243
+ }
244
+ expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
245
+ @api.upload_presets :next_cursor => 1234567, :max_results => 10
246
+
247
+ end
220
248
  end
221
-
222
249
  it "should allow getting a single upload_preset", :upload_preset => true do
223
- result = @api.create_upload_preset(:unsigned => true, :folder => "folder", :width => 100, :crop => :scale, :tags => ["a","b","c", TEST_TAG], :context => {:a => "b", :c => "d"})
250
+ result = @api.create_upload_preset(:unsigned => true, :folder => "folder", :width => 100, :crop => :scale, :tags => ["a","b","c", TEST_TAG, TIMESTAMP_TAG], :context => {:a => "b", :c => "d"})
224
251
  name = result["name"]
225
252
  preset = @api.upload_preset(name)
226
253
  expect(preset["name"]).to eq(name)
@@ -228,29 +255,29 @@ describe Cloudinary::Api do
228
255
  expect(preset["settings"]["folder"]).to eq("folder")
229
256
  expect(preset["settings"]["transformation"]).to eq([{"width" => 100, "crop" => "scale"}])
230
257
  expect(preset["settings"]["context"]).to eq({"a" => "b", "c" => "d"})
231
- expect(preset["settings"]["tags"]).to eq(["a","b","c", TEST_TAG])
258
+ expect(preset["settings"]["tags"]).to eq(["a","b","c", TEST_TAG, TIMESTAMP_TAG])
232
259
  end
233
260
 
234
261
  it "should allow deleting upload_presets", :upload_preset => true do
235
- @api.create_upload_preset(:name => "api_test_upload_preset4", :folder => "folder", :tags => TEST_TAG)
262
+ @api.create_upload_preset(:name => "api_test_upload_preset4", :folder => "folder", :tags => [TEST_TAG, TIMESTAMP_TAG])
236
263
  preset = @api.upload_preset("api_test_upload_preset4")
237
264
  @api.delete_upload_preset("api_test_upload_preset4")
238
265
  expect{preset = @api.upload_preset("api_test_upload_preset4")}.to raise_error
239
266
  end
240
267
 
241
268
  it "should allow updating upload_presets", :upload_preset => true do
242
- name = @api.create_upload_preset(:folder => "folder", :tags => TEST_TAG)["name"]
269
+ name = @api.create_upload_preset(:folder => "folder", :tags => [TEST_TAG, TIMESTAMP_TAG])["name"]
243
270
  preset = @api.upload_preset(name)
244
271
  @api.update_upload_preset(name, preset["settings"].merge(:colors => true, :unsigned => true, :disallow_public_id => true))
245
272
  preset = @api.upload_preset(name)
246
273
  expect(preset["name"]).to eq(name)
247
274
  expect(preset["unsigned"]).to eq(true)
248
- expect(preset["settings"]).to eq({"folder" => "folder", "colors" => true, "disallow_public_id" => true, "tags" => [TEST_TAG]})
275
+ expect(preset["settings"]).to eq({"folder" => "folder", "colors" => true, "disallow_public_id" => true, "tags" => [TEST_TAG, TIMESTAMP_TAG]})
249
276
  end
250
277
 
251
278
  # this test must be last because it deletes (potentially) all dependent transformations which some tests rely on. Excluded by default.
252
279
  skip "should allow deleting all resources", :delete_all=>true do
253
- Cloudinary::Uploader.upload("spec/logo.png", :public_id=>"api_test5", :eager=>[:width=>101,:crop=>:scale], :tags => TEST_TAG)
280
+ Cloudinary::Uploader.upload("spec/logo.png", :public_id=>"api_test5", :eager=>[:width=>101,:crop=>:scale], :tags => [TEST_TAG, TIMESTAMP_TAG])
254
281
  resource = @api.resource("api_test5")
255
282
  expect(resource).not_to be_blank
256
283
  expect(resource["derived"].length).to eq(1)
@@ -261,7 +288,7 @@ describe Cloudinary::Api do
261
288
  end
262
289
 
263
290
  it "should support setting manual moderation status" do
264
- result = Cloudinary::Uploader.upload("spec/logo.png", {:moderation => :manual, :tags => TEST_TAG})
291
+ result = Cloudinary::Uploader.upload("spec/logo.png", {:moderation => :manual, :tags => [TEST_TAG, TIMESTAMP_TAG]})
265
292
  expect(result["moderation"][0]["status"]).to eq("pending")
266
293
  expect(result["moderation"][0]["kind"]).to eq("manual")
267
294
  api_result = Cloudinary::Api.update(result["public_id"], {:moderation_status => :approved})
@@ -270,111 +297,53 @@ describe Cloudinary::Api do
270
297
  end
271
298
 
272
299
  it "should support requesting raw conversion" do
273
- result = Cloudinary::Uploader.upload("spec/docx.docx", :resource_type => :raw, :tags => TEST_TAG)
300
+ result = Cloudinary::Uploader.upload("spec/docx.docx", :resource_type => :raw, :tags => [TEST_TAG, TIMESTAMP_TAG])
274
301
  expect{Cloudinary::Api.update(result["public_id"], {:resource_type => :raw, :raw_convert => :illegal})}.to raise_error(Cloudinary::Api::BadRequest, /^Illegal value|not a valid/)
275
302
  end
276
303
 
277
304
  it "should support requesting categorization" do
278
- result = Cloudinary::Uploader.upload("spec/logo.png", :tags => TEST_TAG)
305
+ result = Cloudinary::Uploader.upload("spec/logo.png", :tags => [TEST_TAG, TIMESTAMP_TAG])
279
306
  expect{Cloudinary::Api.update(result["public_id"], {:categorization => :illegal})}.to raise_error(Cloudinary::Api::BadRequest, /^Illegal value/)
280
307
  end
281
308
 
282
309
  it "should support requesting detection" do
283
- result = Cloudinary::Uploader.upload("spec/logo.png", :tags => TEST_TAG)
284
- expect{Cloudinary::Api.update(result["public_id"], {:detection => :illegal})}.to raise_error(Cloudinary::Api::BadRequest, /^Illegal value/)
310
+ expect(RestClient::Request).to receive(:execute).with(deep_hash_value( [:payload, :detection] => "adv_face"))
311
+ Cloudinary::Api.update("public_id", {:detection => "adv_face"})
285
312
  end
286
313
 
287
314
  it "should support requesting auto_tagging" do
288
- result = Cloudinary::Uploader.upload("spec/logo.png", :tags => TEST_TAG)
289
- expect{Cloudinary::Api.update(result["public_id"], {:auto_tagging => 0.5})}.to raise_error(Cloudinary::Api::BadRequest, /^Must use/)
315
+ expect(RestClient::Request).to receive(:execute).with(deep_hash_value( [:payload, :auto_tagging] => 0.5))
316
+ Cloudinary::Api.update("public_id", {:auto_tagging => 0.5})
290
317
  end
291
318
 
292
319
  it "should support listing by moderation kind and value" do
293
- result1 = Cloudinary::Uploader.upload("spec/logo.png", { :moderation => :manual, :tags => TEST_TAG})
294
- result2 = Cloudinary::Uploader.upload("spec/logo.png", { :moderation => :manual, :tags => TEST_TAG})
295
- result3 = Cloudinary::Uploader.upload("spec/logo.png", { :moderation => :manual, :tags => TEST_TAG})
296
- Cloudinary::Api.update(result1["public_id"], {:moderation_status => :approved})
297
- Cloudinary::Api.update(result2["public_id"], {:moderation_status => :rejected})
298
- approved = Cloudinary::Api.resources_by_moderation(:manual, :approved, :max_results => 1000)["resources"].map{|r| r["public_id"]}
299
- expect(approved).to include(result1["public_id"])
300
- expect(approved).not_to include(result2["public_id"])
301
- expect(approved).not_to include(result3["public_id"])
302
- rejected = Cloudinary::Api.resources_by_moderation(:manual, :rejected, :max_results => 1000)["resources"].map{|r| r["public_id"]}
303
- expect(rejected).to include(result2["public_id"])
304
- expect(rejected).not_to include(result1["public_id"])
305
- expect(rejected).not_to include(result3["public_id"])
306
- pending = Cloudinary::Api.resources_by_moderation(:manual, :pending, :max_results => 1000)["resources"].map{|r| r["public_id"]}
307
- expect(pending).to include(result3["public_id"])
308
- expect(pending).not_to include(result1["public_id"])
309
- expect(pending).not_to include(result2["public_id"])
320
+ expect(RestClient::Request).to receive(:execute).with(deep_hash_value([:url] => /.*manual\/approved$/, [:payload, :max_results] => 1000))
321
+ Cloudinary::Api.resources_by_moderation(:manual, :approved, :max_results => 1000)
310
322
  end
311
323
 
312
324
  it "should support listing folders" do
313
- # pending("For this test to work, 'Auto-create folders' should be enabled in the Upload Settings, " +
314
- # "and the account should be empty of folders. " +
315
- # "Comment out this line if you really want to test it.")
316
- Cloudinary::Uploader.upload("spec/logo.png", {:public_id => "test_folder1/item", :tags => TEST_TAG})
317
- Cloudinary::Uploader.upload("spec/logo.png", {:public_id => "test_folder2/item", :tags => TEST_TAG})
318
- Cloudinary::Uploader.upload("spec/logo.png", {:public_id => "test_folder1/test_subfolder1/item", :tags => TEST_TAG})
319
- Cloudinary::Uploader.upload("spec/logo.png", {:public_id => "test_folder1/test_subfolder2/item", :tags => TEST_TAG})
320
- result = Cloudinary::Api.root_folders
321
- expect(result["folders"]).not_to be_empty, "Folders should have been created. Make sure that 'Auto-create folders' is enabled for this cloud"
322
- names = result["folders"].map{|f| f["name"]}
323
- expect(names).to include("test_folder1")
324
- expect(names).to include("test_folder2")
325
- result = Cloudinary::Api.subfolders("test_folder1")
326
-
327
- paths = result["folders"].map{|f| f["path"]}
328
- expect(paths).to include("test_folder1/test_subfolder1")
329
- expect(paths).to include("test_folder1/test_subfolder2")
330
- expect{Cloudinary::Api.subfolders("test_folder")}.to raise_error(Cloudinary::Api::NotFound)
325
+ expect(RestClient::Request).to receive(:execute).with(deep_hash_value( [:url] => /.*\/folders$/, [:method] => :get))
326
+ Cloudinary::Api.root_folders
327
+ expect(RestClient::Request).to receive(:execute).with(deep_hash_value( [:url] => /.*\/folders\/test_folder1$/, [:method] => :get))
328
+ Cloudinary::Api.subfolders("test_folder1")
331
329
  end
332
330
 
333
331
  describe '.restore' do
334
- before :each do
335
- Cloudinary::Uploader.upload("spec/logo.png", :public_id => "api_test_restore", :backup => true, :tags => TEST_TAG)
336
- resource = Cloudinary::Api.resource("api_test_restore")
337
- expect(resource).not_to be_nil
338
- expect(resource["bytes"]).to eq(3381)
339
- Cloudinary::Api.delete_resources("api_test_restore")
340
- resource = Cloudinary::Api.resource("api_test_restore")
341
- expect(resource).not_to be_nil
342
- expect(resource["bytes"]).to eq(0)
343
- expect(resource["placeholder"]).to eq(true)
344
- end
345
332
  it 'should restore a deleted resource' do
346
- response = Cloudinary::Api.restore("api_test_restore")
347
- info = response["api_test_restore"]
348
- expect(info).not_to be_nil
349
- expect(info["bytes"]).to eq(3381)
350
- resource = Cloudinary::Api.resource("api_test_restore")
351
- expect(resource).not_to be_nil
352
- expect(resource["bytes"]).to eq(3381)
333
+ expect(RestClient::Request).to receive(:execute).with(deep_hash_value( [:payload, :public_ids] => "api_test_restore", [:url] => /.*\/restore$/))
334
+ Cloudinary::Api.restore("api_test_restore")
353
335
  end
354
336
  end
355
337
 
356
- describe 'mapping' do
338
+ describe 'create_upload_mapping' do
357
339
  mapping = "api_test_upload_mapping#{rand(100000)}"
358
- after :all do
359
- begin
360
- Cloudinary::Api.delete_upload_mapping(mapping)
361
- rescue
362
- puts "Could not delete #{mapping}"
363
- end
364
- end
365
-
366
340
  it 'should create mapping' do
367
- result = Cloudinary::Api.create_upload_mapping(mapping, :template =>"http://cloudinary.com")
368
- result = Cloudinary::Api.upload_mapping(mapping)
369
- expect(result['template']).to eq("http://cloudinary.com")
341
+ expect(RestClient::Request).to receive(:execute).with(deep_hash_value( [:payload, :template] => "http://cloudinary.com"))
342
+ Cloudinary::Api.create_upload_mapping(mapping, :template =>"http://cloudinary.com")
343
+ expect(RestClient::Request).to receive(:execute).with(deep_hash_value( [:payload, :template] => "http://res.cloudinary.com"))
370
344
  Cloudinary::Api.update_upload_mapping(mapping, "template" =>"http://res.cloudinary.com")
371
- result = Cloudinary::Api.upload_mapping(mapping)
372
- expect(result["template"]).to eq("http://res.cloudinary.com")
373
- result = Cloudinary::Api.upload_mappings
374
- expect(result["mappings"]).to include("folder" => mapping, "template" =>"http://res.cloudinary.com" )
375
- Cloudinary::Api.delete_upload_mapping(mapping)
376
- result = Cloudinary::Api.upload_mappings()
377
- expect(result["mappings"]).not_to include("folder" => mapping )
378
345
  end
346
+
347
+
379
348
  end
380
349
  end