cloudinary 1.11.1 → 1.12.0

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.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +6 -1
  3. data/.travis.yml +12 -6
  4. data/CHANGELOG.md +30 -0
  5. data/cloudinary.gemspec +2 -0
  6. data/lib/active_storage/blob_key.rb +20 -0
  7. data/lib/active_storage/service/cloudinary_service.rb +181 -0
  8. data/lib/cloudinary.rb +9 -4
  9. data/lib/cloudinary/api.rb +17 -4
  10. data/lib/cloudinary/auth_token.rb +6 -4
  11. data/lib/cloudinary/uploader.rb +4 -4
  12. data/lib/cloudinary/utils.rb +62 -29
  13. data/lib/cloudinary/version.rb +1 -1
  14. data/spec/active_storage/Gemfile +12 -0
  15. data/spec/active_storage/application_system_test_case.rb +5 -0
  16. data/spec/active_storage/database/create_users_migration.rb +9 -0
  17. data/spec/active_storage/database/setup.rb +7 -0
  18. data/spec/active_storage/dummy/Rakefile +5 -0
  19. data/spec/active_storage/dummy/app/assets/config/manifest.js +3 -0
  20. data/spec/active_storage/dummy/app/assets/javascripts/application.js +13 -0
  21. data/spec/active_storage/dummy/app/assets/stylesheets/application.css +15 -0
  22. data/spec/active_storage/dummy/app/controllers/application_controller.rb +5 -0
  23. data/spec/active_storage/dummy/app/helpers/application_helper.rb +4 -0
  24. data/spec/active_storage/dummy/app/jobs/application_job.rb +4 -0
  25. data/spec/active_storage/dummy/app/models/application_record.rb +5 -0
  26. data/spec/active_storage/dummy/app/views/layouts/application.html.erb +14 -0
  27. data/spec/active_storage/dummy/bin/bundle +5 -0
  28. data/spec/active_storage/dummy/bin/rails +6 -0
  29. data/spec/active_storage/dummy/bin/rake +6 -0
  30. data/spec/active_storage/dummy/bin/yarn +11 -0
  31. data/spec/active_storage/dummy/config.ru +7 -0
  32. data/spec/active_storage/dummy/config/application.rb +22 -0
  33. data/spec/active_storage/dummy/config/boot.rb +7 -0
  34. data/spec/active_storage/dummy/config/database.yml +25 -0
  35. data/spec/active_storage/dummy/config/environment.rb +7 -0
  36. data/spec/active_storage/dummy/config/environments/development.rb +52 -0
  37. data/spec/active_storage/dummy/config/environments/production.rb +83 -0
  38. data/spec/active_storage/dummy/config/environments/test.rb +38 -0
  39. data/spec/active_storage/dummy/config/initializers/application_controller_renderer.rb +7 -0
  40. data/spec/active_storage/dummy/config/initializers/assets.rb +16 -0
  41. data/spec/active_storage/dummy/config/initializers/backtrace_silencers.rb +8 -0
  42. data/spec/active_storage/dummy/config/initializers/cookies_serializer.rb +7 -0
  43. data/spec/active_storage/dummy/config/initializers/filter_parameter_logging.rb +6 -0
  44. data/spec/active_storage/dummy/config/initializers/inflections.rb +17 -0
  45. data/spec/active_storage/dummy/config/initializers/mime_types.rb +5 -0
  46. data/spec/active_storage/dummy/config/initializers/wrap_parameters.rb +16 -0
  47. data/spec/active_storage/dummy/config/routes.rb +4 -0
  48. data/spec/active_storage/dummy/config/secrets.yml +32 -0
  49. data/spec/active_storage/dummy/config/spring.rb +8 -0
  50. data/spec/active_storage/dummy/config/storage.yml +3 -0
  51. data/spec/active_storage/dummy/config/webpacker.yml +72 -0
  52. data/spec/active_storage/dummy/package.json +5 -0
  53. data/spec/active_storage/dummy/public/404.html +67 -0
  54. data/spec/active_storage/dummy/public/422.html +67 -0
  55. data/spec/active_storage/dummy/public/500.html +66 -0
  56. data/spec/active_storage/dummy/public/apple-touch-icon-precomposed.png +0 -0
  57. data/spec/active_storage/dummy/public/apple-touch-icon.png +0 -0
  58. data/spec/active_storage/dummy/public/favicon.ico +0 -0
  59. data/spec/active_storage/fixtures/files/colors.bmp +0 -0
  60. data/spec/active_storage/fixtures/files/empty_file.txt +0 -0
  61. data/spec/active_storage/fixtures/files/favicon.ico +0 -0
  62. data/spec/active_storage/fixtures/files/icon.psd +0 -0
  63. data/spec/active_storage/fixtures/files/icon.svg +13 -0
  64. data/spec/active_storage/fixtures/files/image.gif +0 -0
  65. data/spec/active_storage/fixtures/files/racecar.jpg +0 -0
  66. data/spec/active_storage/fixtures/files/racecar.tif +0 -0
  67. data/spec/active_storage/fixtures/files/racecar_rotated.jpg +0 -0
  68. data/spec/active_storage/fixtures/files/report.pdf +0 -0
  69. data/spec/active_storage/fixtures/files/rotated_video.mp4 +0 -0
  70. data/spec/active_storage/fixtures/files/video.mp4 +0 -0
  71. data/spec/active_storage/fixtures/files/video_with_rectangular_samples.mp4 +0 -0
  72. data/spec/active_storage/fixtures/files/video_with_undefined_display_aspect_ratio.mp4 +0 -0
  73. data/spec/active_storage/fixtures/files/video_without_video_stream.mp4 +0 -0
  74. data/spec/active_storage/service/cloudinary_service_spec.rb +92 -0
  75. data/spec/active_storage/service/configurations.yml +4 -0
  76. data/spec/active_storage/test_helper.rb +43 -0
  77. data/spec/api_spec.rb +68 -12
  78. data/spec/archive_spec.rb +17 -1
  79. data/spec/cloudinary_helper_spec.rb +2 -0
  80. data/spec/cloudinary_spec.rb +30 -6
  81. data/spec/movie.mp4 +0 -0
  82. data/spec/spec_helper.rb +9 -2
  83. data/spec/uploader_spec.rb +20 -3
  84. data/spec/utils_methods_spec.rb +29 -2
  85. data/spec/utils_spec.rb +93 -11
  86. data/vendor/assets/javascripts/cloudinary/jquery.cloudinary.js +31 -1
  87. data/vendor/assets/javascripts/cloudinary/jquery.fileupload.js +24 -4
  88. data/vendor/assets/javascripts/cloudinary/jquery.ui.widget.js +741 -561
  89. data/vendor/assets/javascripts/cloudinary/load-image.all.min.js +1 -1
  90. metadata +161 -3
@@ -0,0 +1,66 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>We're sorry, but something went wrong (500)</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <style>
7
+ .rails-default-error-page {
8
+ background-color: #EFEFEF;
9
+ color: #2E2F30;
10
+ text-align: center;
11
+ font-family: arial, sans-serif;
12
+ margin: 0;
13
+ }
14
+
15
+ .rails-default-error-page div.dialog {
16
+ width: 95%;
17
+ max-width: 33em;
18
+ margin: 4em auto 0;
19
+ }
20
+
21
+ .rails-default-error-page div.dialog > div {
22
+ border: 1px solid #CCC;
23
+ border-right-color: #999;
24
+ border-left-color: #999;
25
+ border-bottom-color: #BBB;
26
+ border-top: #B00100 solid 4px;
27
+ border-top-left-radius: 9px;
28
+ border-top-right-radius: 9px;
29
+ background-color: white;
30
+ padding: 7px 12% 0;
31
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
+ }
33
+
34
+ .rails-default-error-page h1 {
35
+ font-size: 100%;
36
+ color: #730E15;
37
+ line-height: 1.5em;
38
+ }
39
+
40
+ .rails-default-error-page div.dialog > p {
41
+ margin: 0 0 1em;
42
+ padding: 1em;
43
+ background-color: #F7F7F7;
44
+ border: 1px solid #CCC;
45
+ border-right-color: #999;
46
+ border-left-color: #999;
47
+ border-bottom-color: #999;
48
+ border-bottom-left-radius: 4px;
49
+ border-bottom-right-radius: 4px;
50
+ border-top-color: #DADADA;
51
+ color: #666;
52
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
53
+ }
54
+ </style>
55
+ </head>
56
+
57
+ <body class="rails-default-error-page">
58
+ <!-- This file lives in public/500.html -->
59
+ <div class="dialog">
60
+ <div>
61
+ <h1>We're sorry, but something went wrong.</h1>
62
+ </div>
63
+ <p>If you are the application owner check the logs for more information.</p>
64
+ </div>
65
+ </body>
66
+ </html>
@@ -0,0 +1,13 @@
1
+ <!-- The XML declaration is intentionally omitted. -->
2
+ <svg width="792px" height="584px" viewBox="0 0 792 584" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <path d="M9.51802657,28.724593 C9.51802657,18.2155955 18.1343454,9.60822622 28.6542694,9.60822622 L763.245541,9.60822622 C773.765465,9.60822622 782.381784,18.2155955 782.381784,28.724593 L782.381784,584 L792,584 L792,28.724593 C792,12.911054 779.075522,0 763.245541,0 L28.7544592,0 C12.9244782,0 0,12.911054 0,28.724593 L0,584 L9.61821632,584 C9.51802657,584 9.51802657,28.724593 9.51802657,28.724593 L9.51802657,28.724593 Z" id="Shape" opacity="0.3" fill="#CCCCCC"></path>
4
+ <circle id="Oval" fill="#FFCC33" cx="119.1" cy="147.2" r="33"></circle>
5
+ <circle id="Oval" fill="#3399FF" cx="119.1" cy="281.1" r="33"></circle>
6
+ <circle id="Oval" fill="#FF3333" cx="676.1" cy="376.8" r="33"></circle>
7
+ <circle id="Oval" fill="#FFCC33" cx="119.1" cy="477.2" r="33"></circle>
8
+ <rect id="Rectangle-path" opacity="0.75" fill="#CCCCCC" x="176.5" y="130.5" width="442.1" height="33.5"></rect>
9
+ <rect id="Rectangle-path" opacity="0.75" fill="#CCCCCC" x="176.5" y="183.1" width="442.1" height="33.5"></rect>
10
+ <rect id="Rectangle-path" opacity="0.75" fill="#CCCCCC" x="176.5" y="265.8" width="442.1" height="33.5"></rect>
11
+ <rect id="Rectangle-path" opacity="0.75" fill="#CCCCCC" x="176.5" y="363.4" width="442.1" height="33.5"></rect>
12
+ <rect id="Rectangle-path" opacity="0.75" fill="#CCCCCC" x="176.5" y="465.3" width="442.1" height="33.5"></rect>
13
+ </svg>
@@ -0,0 +1,92 @@
1
+ if RUBY_VERSION > '2.2.2'
2
+ require 'spec_helper'
3
+
4
+ AS_TAG = "active_storage_" + SUFFIX
5
+ BASENAME = File.basename(TEST_IMG, '.*')
6
+
7
+ CONFIGURATION_PATH = Pathname.new(File.expand_path("service/configurations.yml", __dir__))
8
+ SERVICE = ActiveStorage::Service.configure(:cloudinary, SERVICE_CONFIGURATIONS)
9
+
10
+ describe 'active_storage' do
11
+ let(:key) {ActiveStorage::BlobKey.new({key: SecureRandom.base58(24), filename: BASENAME})}
12
+
13
+ before :all do
14
+ @key = ActiveStorage::BlobKey.new key: SecureRandom.base58(24), filename: BASENAME
15
+ @service = self.class.const_get(:SERVICE)
16
+ @service.upload @key, TEST_IMG, tags: [TEST_TAG, TIMESTAMP_TAG, AS_TAG]
17
+ end
18
+
19
+ after :all do
20
+ Cloudinary::Api.delete_resources_by_tag AS_TAG
21
+ end
22
+
23
+ describe :url_for_direct_upload do
24
+ it "should use the key" do
25
+ key = SecureRandom.base58(24)
26
+ url = @service.url_for_direct_upload(key)
27
+ expect(url).not_to include(BASENAME)
28
+ expect(url).to include("public_id=#{key}")
29
+ end
30
+ it "should include the key in a context field" do
31
+ key = SecureRandom.base58(24)
32
+ url = @service.url_for_direct_upload(key)
33
+ expect(url).to include("context=active_storage_key%3D#{key}")
34
+ end
35
+ end
36
+
37
+ it "should support uploading to Cloudinary" do
38
+ url = @service.url_for_direct_upload(key, tags: [TEST_TAG, TIMESTAMP_TAG, AS_TAG])
39
+ uri = URI.parse url
40
+ request = Net::HTTP::Put.new uri.request_uri
41
+ file = File.open(TEST_IMG)
42
+ request.body_stream = file
43
+ request['content-length'] = file.size
44
+ request['content-type'] = 'image/png'
45
+ response = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
46
+ http.request request
47
+ end
48
+ result = Cloudinary::Utils.json_decode(response.body)
49
+ expect(result['error']).not_to be_truthy
50
+ #Same test as uploader_spec "should successfully upload file"
51
+ expect(result["width"]).to eq(TEST_IMG_W)
52
+ expect(result["height"]).to eq(TEST_IMG_H)
53
+ expected_signature = Cloudinary::Utils.api_sign_request({:public_id => result["public_id"], :version => result["version"]}, Cloudinary.config.api_secret)
54
+ expect(result["signature"]).to eq(expected_signature)
55
+ end
56
+
57
+ it "should check if resource exists" do
58
+ expect(@service.exist?(@key)).to be_truthy
59
+ expect(@service.exist?(@key + "nonsense")).to be_falsey
60
+ end
61
+
62
+ it "should delete a resource" do
63
+ @service.delete @key
64
+ expect(@service.exist?(@key)).to be_falsey
65
+ end
66
+
67
+ it "should fail to delete nonexistent key" do
68
+ expect {@service.delete SecureRandom.base58(24)}.not_to raise_error
69
+ end
70
+
71
+ it "should support transformations" do
72
+ url = @service.url(@key, crop: 'scale', width: 100)
73
+ expect(url).to match(/c_scale,w_100/)
74
+ end
75
+
76
+ it "should use global configuration options" do
77
+ tags = SERVICE_CONFIGURATIONS[:cloudinary][:tags]
78
+ expect(tags).not_to be_empty, "Please set a tags value under cloudinary in #{CONFIGURATION_PATH}"
79
+ expect(Cloudinary::Uploader).to receive(:upload).with(TEST_IMG, hash_including(tags: tags))
80
+ @service.upload(key, TEST_IMG, tags: tags)
81
+ end
82
+
83
+ it "should accept options that override global configuration" do
84
+ tags = SERVICE_CONFIGURATIONS[:cloudinary][:tags]
85
+ expect(tags).not_to be_empty, "Please set a tags value under cloudinary in #{CONFIGURATION_PATH}"
86
+ override_tags = [TEST_TAG, TIMESTAMP_TAG, AS_TAG]
87
+ expect(override_tags).not_to eql(tags), "Overriding tags should be different from configuration"
88
+ expect(Cloudinary::Uploader).to receive(:upload).with(TEST_IMG, hash_including(tags: override_tags))
89
+ @service.upload(key, TEST_IMG, tags: override_tags)
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,4 @@
1
+ cloudinary:
2
+ service: Cloudinary
3
+ tags:
4
+ - ActiveStorageTestTag
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+ ENV['RAILS_ENV'] ||= 'test'
3
+ require_relative './dummy/config/environment'
4
+
5
+ require "bundler/setup"
6
+ require "active_support"
7
+ require "rails"
8
+ require "active_model/railtie"
9
+ require "active_job/railtie"
10
+ require "active_record/railtie"
11
+ require "action_controller/railtie"
12
+ require "action_view/railtie"
13
+ require "active_storage/engine"
14
+ require "net/http"
15
+ require "active_support/core_ext/securerandom"
16
+ require "active_storage/database/setup"
17
+
18
+ begin
19
+ require "byebug"
20
+ rescue LoadError
21
+ end
22
+
23
+ require "active_job"
24
+ ActiveJob::Base.queue_adapter = :test
25
+ ActiveJob::Base.logger = ActiveSupport::Logger.new(nil)
26
+
27
+
28
+ require "yaml"
29
+ SERVICE_CONFIGURATIONS = begin
30
+ erb = ERB.new(Pathname.new(File.expand_path("service/configurations.yml", __dir__)).read)
31
+ configuration = YAML.load(erb.result) || {}
32
+ configuration.deep_symbolize_keys
33
+ rescue Errno::ENOENT
34
+ puts "Missing service configuration file in test/service/configurations.yml"
35
+ {}
36
+ end
37
+
38
+ ActiveStorage.logger = ActiveSupport::Logger.new(nil)
39
+ ActiveStorage.verifier = ActiveSupport::MessageVerifier.new("Testing")
40
+
41
+ require "global_id"
42
+ GlobalID.app = "ActiveStorageExampleApp"
43
+ ActiveRecord::Base.send :include, GlobalID::Identification
@@ -35,6 +35,14 @@ describe Cloudinary::Api do
35
35
  end
36
36
  end
37
37
 
38
+ it "should allow using derived_next_cursor when listing details of a single resource" do
39
+ expected = {
40
+ [:payload, :derived_next_cursor] => "b16b8bd80426df43a107f26b0348"
41
+ }
42
+ expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
43
+ @api.resource("test", {"derived_next_cursor" => "b16b8bd80426df43a107f26b0348"})
44
+ end
45
+
38
46
  it "should allow listing resource_types" do
39
47
  expect(@api.resource_types()["resource_types"]).to include("image")
40
48
  end
@@ -137,6 +145,15 @@ describe Cloudinary::Api do
137
145
  expect(resource["quality_analysis"]).to have_key("focus")
138
146
  end
139
147
 
148
+ it "should support the cinemagraph_analysis parameter" do
149
+ expected = {
150
+ [:payload, :cinemagraph_analysis] => true,
151
+ [:method] => :get
152
+ }
153
+ expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
154
+ @api.resource(test_id_1, :cinemagraph_analysis => true)
155
+ end
156
+
140
157
  it "should allow deleting derived resource" do
141
158
  derived_resource_id = "derived_id"
142
159
  expect(RestClient::Request).to receive(:execute).with(deep_hash_value( {[:payload, :derived_resource_ids] => derived_resource_id}))
@@ -359,7 +376,7 @@ describe Cloudinary::Api do
359
376
  end
360
377
 
361
378
  it "should support requesting raw conversion" do
362
- result = Cloudinary::Uploader.upload("spec/docx.docx", :resource_type => :raw, :tags => [TEST_TAG, TIMESTAMP_TAG])
379
+ result = Cloudinary::Uploader.upload(TEST_RAW, :resource_type => :raw, :tags => [TEST_TAG, TIMESTAMP_TAG])
363
380
  expect{Cloudinary::Api.update(result["public_id"], {:resource_type => :raw, :raw_convert => :illegal})}.to raise_error(Cloudinary::Api::BadRequest, /^Illegal value|not a valid/)
364
381
  end
365
382
 
@@ -395,15 +412,55 @@ describe Cloudinary::Api do
395
412
  Cloudinary::Api.resources_by_moderation(:manual, :approved, :max_results => 1000)
396
413
  end
397
414
 
398
- it "should support listing folders" do
399
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value( [:url] => /.*\/folders$/, [:method] => :get))
400
- Cloudinary::Api.root_folders
401
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value( [:url] => /.*\/folders\/test_folder1$/, [:method] => :get))
402
- Cloudinary::Api.subfolders("test_folder1")
403
- end
404
-
405
- it "should throw if folder is missing" do
406
- expect{Cloudinary::Api.subfolders("I_do_not_exist")}.to raise_error(Cloudinary::Api::NotFound)
415
+ describe 'folders' do
416
+ it 'should create folder' do
417
+ expected = {
418
+ [:url] => /.*\/folders\/#{UNIQUE_TEST_FOLDER}$/,
419
+ [:method] => :post
420
+ }
421
+ expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
422
+ @api.create_folder(UNIQUE_TEST_FOLDER)
423
+ end
424
+ it "should support listing folders" do
425
+ expect(RestClient::Request).to receive(:execute).with(deep_hash_value( [:url] => /.*\/folders$/, [:method] => :get))
426
+ Cloudinary::Api.root_folders
427
+ expect(RestClient::Request).to receive(:execute).with(deep_hash_value( [:url] => /.*\/folders\/test_folder1$/, [:method] => :get))
428
+ Cloudinary::Api.subfolders("test_folder1")
429
+ end
430
+ it "should URL escape the folder name" do
431
+ expected = {
432
+ [:url] => %r".*\/folders\/sub%5Efolder%20test$"
433
+ }
434
+ expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
435
+ Cloudinary::Api.subfolders("sub^folder test")
436
+ end
437
+ it "should throw if folder is missing" do
438
+ expect{Cloudinary::Api.subfolders("I_do_not_exist")}.to raise_error(Cloudinary::Api::NotFound)
439
+ end
440
+ it 'should include max_results and next_cursor for root_folders call' do
441
+ expected = {
442
+ [:payload, :max_results] => 3,
443
+ [:payload, :next_cursor] => NEXT_CURSOR,
444
+ }
445
+ expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
446
+ @api.root_folders :max_results => 3, :next_cursor => NEXT_CURSOR
447
+ end
448
+ it 'should include max_results and next_cursor for subfolders call' do
449
+ expected = {
450
+ [:payload, :max_results] => 3,
451
+ [:payload, :next_cursor] => NEXT_CURSOR,
452
+ }
453
+ expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
454
+ @api.subfolders GENERIC_FOLDER_NAME, :max_results => 3, :next_cursor => NEXT_CURSOR
455
+ end
456
+ it "should support deleting a folder" do
457
+ expected = {
458
+ :url => %r"/folders/#{GENERIC_FOLDER_NAME}$",
459
+ :method => :delete
460
+ }
461
+ expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
462
+ @api.delete_folder(GENERIC_FOLDER_NAME)
463
+ end
407
464
  end
408
465
 
409
466
  describe '.restore' do
@@ -421,9 +478,8 @@ describe Cloudinary::Api do
421
478
  expect(RestClient::Request).to receive(:execute).with(deep_hash_value( [:payload, :template] => "http://res.cloudinary.com"))
422
479
  Cloudinary::Api.update_upload_mapping(mapping, "template" =>"http://res.cloudinary.com")
423
480
  end
424
-
425
-
426
481
  end
482
+
427
483
  describe "access_mode" do
428
484
  i = 0
429
485
 
@@ -126,4 +126,20 @@ describe Cloudinary::Uploader do
126
126
  Cloudinary::Uploader.create_zip({ :tags => TEST_TAG })
127
127
  end
128
128
  end
129
- end
129
+ describe '.create_archive based on fully_qualified_public_ids' do
130
+ it 'should allow you to generate an archive by specifying multiple resource_types' do
131
+ test_ids = %W(image/upload/#{TEST_IMG} video/upload/#{TEST_VIDEO} raw/upload/#{TEST_RAW})
132
+ expected = {
133
+ [:payload, :fully_qualified_public_ids] => test_ids,
134
+ [:url] => %r"/auto/generate_archive$"
135
+ }
136
+ expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
137
+ Cloudinary::Uploader.create_archive(
138
+ {
139
+ :resource_type => :auto,
140
+ :fully_qualified_public_ids => test_ids
141
+ }
142
+ )
143
+ end
144
+ end
145
+ end
@@ -307,6 +307,8 @@ RSpec.describe CloudinaryHelper do
307
307
  expect(helper.image_path('/bar')).to eq('/bar')
308
308
  end
309
309
  it "should not transform images staring with /images unless asset is found and static_support is true" do
310
+ skip if RUBY_VERSION >= '2.2.2'
311
+
310
312
  Cloudinary.config.static_image_support = false
311
313
  expect(helper.image_path('/images/foo.jpg')).to eq('/images/foo.jpg')
312
314
  expect(helper.image_path('some-folder/foo.gif')).to eq("/images/some-folder/foo.gif")
@@ -2,17 +2,24 @@ require 'spec_helper'
2
2
  require 'cloudinary'
3
3
 
4
4
  describe Cloudinary do
5
- before :all do
5
+ before :each do
6
6
  @user_platform = Cloudinary.user_platform
7
7
  end
8
- after :all do
8
+ after :each do
9
9
  Cloudinary.user_platform = @user_platform
10
10
  end
11
11
 
12
- it 'should add a user platform to USER_AGENT' do
13
- Cloudinary.user_platform = "Spec/1.0 (Test)"
14
- expect(Cloudinary.USER_AGENT).to match( %r"Spec\/1.0 \(Test\) CloudinaryRuby/[\d.]+")
12
+ CLOUDINARY_USER_AGENT_REGEXP = %r"^CloudinaryRuby\/[\d.]+ \(Ruby [\d\.]+-p\d+\)$"
13
+ CLOUDINARY_USER_PLATFORM_REGEXP = %r"^Rails\/[\d.]+ CloudinaryRuby\/[\d.]+ \(Ruby [\d\.]+-p\d+\)$"
14
+
15
+ it "should return the USER_AGENT without user_platform if there's no Rails or set to empty" do
16
+ Cloudinary.user_platform = ""
17
+ expect(Cloudinary.USER_AGENT).to match(CLOUDINARY_USER_AGENT_REGEXP)
18
+ end
15
19
 
20
+ it 'should add a user platform to USER_AGENT' do
21
+ Cloudinary.user_platform = "Rails/5.6.7"
22
+ expect(Cloudinary.USER_AGENT).to match(CLOUDINARY_USER_PLATFORM_REGEXP)
16
23
  end
17
24
 
18
25
  describe 'config' do
@@ -28,5 +35,22 @@ describe Cloudinary do
28
35
  Cloudinary::config_from_url ENV["CLOUDINARY_URL"]
29
36
  expect(Cloudinary::config.foo.bar).to eq 'value'
30
37
  end
38
+
39
+ it "should set accept a CLOUDINARY_URL with the correct scheme (cloudinary)" do
40
+ valid_cloudinary_url = "cloudinary://123456789012345:ALKJdjklLJAjhkKJ45hBK92baj3@test"
41
+ expect{Cloudinary::config_from_url valid_cloudinary_url}.not_to raise_error
42
+ end
43
+ it "should raise an exception if the CLOUDINARY_URL doesn't start with 'cloudinary://'" do
44
+ invalid_cloudinary_urls = [
45
+ "CLOUDINARY_URL=cloudinary://123456789012345:ALKJdjklLJAjhkKJ45hBK92baj3@test",
46
+ "https://123456789012345:ALKJdjklLJAjhkKJ45hBK92baj3@test",
47
+ "://123456789012345:ALKJdjklLJAjhkKJ45hBK92baj3@test",
48
+ " "
49
+ ]
50
+ invalid_cloudinary_urls.each do |cloudinary_url|
51
+ expect{Cloudinary::config_from_url cloudinary_url}
52
+ .to raise_error(/bad URI|Invalid CLOUDINARY_URL/)
53
+ end
54
+ end
31
55
  end
32
- end
56
+ end