cloudinary 1.11.1 → 1.18.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +42 -0
  3. data/.github/ISSUE_TEMPLATE/feature_request.md +21 -0
  4. data/.github/pull_request_template.md +24 -0
  5. data/.gitignore +6 -1
  6. data/.travis.yml +15 -5
  7. data/CHANGELOG.md +149 -0
  8. data/Rakefile +3 -45
  9. data/cloudinary.gemspec +20 -4
  10. data/lib/active_storage/blob_key.rb +20 -0
  11. data/lib/active_storage/service/cloudinary_service.rb +229 -0
  12. data/lib/cloudinary.rb +31 -22
  13. data/lib/cloudinary/api.rb +173 -5
  14. data/lib/cloudinary/auth_token.rb +6 -4
  15. data/lib/cloudinary/carrier_wave.rb +3 -1
  16. data/lib/cloudinary/carrier_wave/remote.rb +3 -2
  17. data/lib/cloudinary/carrier_wave/storage.rb +2 -1
  18. data/lib/cloudinary/cloudinary_controller.rb +2 -4
  19. data/lib/cloudinary/helper.rb +30 -3
  20. data/lib/cloudinary/railtie.rb +7 -3
  21. data/lib/cloudinary/uploader.rb +35 -6
  22. data/lib/cloudinary/utils.rb +112 -40
  23. data/lib/cloudinary/version.rb +1 -1
  24. data/lib/cloudinary/video_helper.rb +96 -22
  25. data/lib/tasks/cloudinary/fetch_assets.rake +48 -0
  26. data/lib/tasks/{cloudinary.rake → cloudinary/sync_static.rake} +0 -0
  27. data/tools/allocate_test_cloud.sh +9 -0
  28. data/tools/get_test_cloud.sh +9 -0
  29. data/tools/update_version +29 -11
  30. data/vendor/assets/javascripts/cloudinary/jquery.cloudinary.js +48 -14
  31. data/vendor/assets/javascripts/cloudinary/jquery.fileupload.js +24 -4
  32. data/vendor/assets/javascripts/cloudinary/jquery.ui.widget.js +741 -561
  33. data/vendor/assets/javascripts/cloudinary/load-image.all.min.js +1 -1
  34. metadata +62 -67
  35. data/spec/access_control_spec.rb +0 -102
  36. data/spec/api_spec.rb +0 -567
  37. data/spec/archive_spec.rb +0 -129
  38. data/spec/auth_token_spec.rb +0 -77
  39. data/spec/cache_spec.rb +0 -109
  40. data/spec/cloudinary_helper_spec.rb +0 -325
  41. data/spec/cloudinary_spec.rb +0 -32
  42. data/spec/data/sync_static/app/assets/javascripts/1.coffee +0 -1
  43. data/spec/data/sync_static/app/assets/javascripts/1.js +0 -1
  44. data/spec/data/sync_static/app/assets/stylesheets/1.css +0 -3
  45. data/spec/docx.docx +0 -0
  46. data/spec/favicon.ico +0 -0
  47. data/spec/image_spec.rb +0 -107
  48. data/spec/logo.png +0 -0
  49. data/spec/rake_spec.rb +0 -160
  50. data/spec/sample_asset_file.tsv +0 -4
  51. data/spec/search_spec.rb +0 -109
  52. data/spec/spec_helper.rb +0 -266
  53. data/spec/storage_spec.rb +0 -44
  54. data/spec/streaminig_profiles_api_spec.rb +0 -74
  55. data/spec/support/helpers/temp_file_helpers.rb +0 -22
  56. data/spec/support/shared_contexts/rake.rb +0 -19
  57. data/spec/uploader_spec.rb +0 -392
  58. data/spec/utils_methods_spec.rb +0 -54
  59. data/spec/utils_spec.rb +0 -970
  60. data/spec/video_tag_spec.rb +0 -253
  61. data/spec/video_url_spec.rb +0 -185
@@ -1,32 +0,0 @@
1
- require 'spec_helper'
2
- require 'cloudinary'
3
-
4
- describe Cloudinary do
5
- before :all do
6
- @user_platform = Cloudinary.user_platform
7
- end
8
- after :all do
9
- Cloudinary.user_platform = @user_platform
10
- end
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.]+")
15
-
16
- end
17
-
18
- describe 'config' do
19
- before do
20
- @url_backup = ENV["CLOUDINARY_URL"]
21
- end
22
- after do
23
- ENV["CLOUDINARY_URL"] = @url_backup
24
- Cloudinary::config_from_url @url_backup
25
- end
26
- it "should allow nested values in CLOUDINARY_URL" do
27
- ENV["CLOUDINARY_URL"] = "cloudinary://key:secret@test123?foo[bar]=value"
28
- Cloudinary::config_from_url ENV["CLOUDINARY_URL"]
29
- expect(Cloudinary::config.foo.bar).to eq 'value'
30
- end
31
- end
32
- end
@@ -1 +0,0 @@
1
- coffeescript = true
@@ -1 +0,0 @@
1
- { alert("I am javascript!");}
@@ -1,3 +0,0 @@
1
- p#css {
2
- color: red;
3
- }
Binary file
Binary file
@@ -1,107 +0,0 @@
1
- require 'spec_helper'
2
- require 'cloudinary'
3
- require 'action_view'
4
- require 'cloudinary/helper'
5
-
6
- COMMON_TRANS = {
7
- effect: 'sepia',
8
- cloud_name: DUMMY_CLOUD,
9
- client_hints: false
10
- }
11
- COMMON_TRANSFORMATION_STR = 'e_sepia'
12
-
13
- def expected_srcset(public_id, path, common_trans, breakpoints)
14
- breakpoints.map {|width| "#{path}/#{common_trans}/c_scale,w_#{width}/#{public_id} #{width}w"}.join(', ')
15
- end
16
-
17
- describe 'Responsive breakpoints' do
18
-
19
-
20
- before :all do
21
- # Test the helper in the context it runs in in production
22
- ActionView::Base.send :include, CloudinaryHelper
23
-
24
- end
25
-
26
- before :each do
27
- Cloudinary.reset_config
28
- end
29
-
30
- let(:cloud_name) {COMMON_TRANS[:cloud_name]}
31
- let(:root_path) {"http://res.cloudinary.com/#{cloud_name}"}
32
- let(:upload_path) {"#{root_path}/image/upload"}
33
-
34
- let(:options) {COMMON_TRANS}
35
- # let(:helper) {helper_class.new}
36
- let(:helper) {
37
- ActionView::Base.new
38
- }
39
- let(:test_tag) {TestTag.new(helper.cl_image_tag('sample.jpg', options))}
40
- describe 'srcset' do
41
- it 'Should create srcset attribute with provided breakpoints' do
42
- options[:srcset] = {:breakpoints => ResponsiveTest::BREAKPOINTS}
43
- srcset = test_tag['srcset'].split(", ")
44
- expect(srcset.length).to eq(4)
45
- expected_tag = expected_srcset('sample.jpg', upload_path, COMMON_TRANSFORMATION_STR, ResponsiveTest::BREAKPOINTS)
46
- expect(test_tag['srcset']).to match(expected_tag)
47
- end
48
- it "Support srcset attribute defined by min width max width and max images" do
49
- options[:srcset] = {:min_width => ResponsiveTest::BREAKPOINTS.first,
50
- :max_width => ResponsiveTest::BREAKPOINTS.last,
51
- :max_images => ResponsiveTest::BREAKPOINTS.length}
52
-
53
- expected_tag = expected_srcset('sample.jpg', upload_path, COMMON_TRANSFORMATION_STR, ResponsiveTest::BREAKPOINTS)
54
- expect(test_tag['srcset']).to match(expected_tag)
55
- end
56
- it "should generate a single srcset image" do
57
- options[:srcset] = {:min_width => ResponsiveTest::BREAKPOINTS.first,
58
- :max_width => ResponsiveTest::BREAKPOINTS.last,
59
- :max_images => 1}
60
-
61
- expected_tag = expected_srcset('sample.jpg', upload_path, COMMON_TRANSFORMATION_STR, [ResponsiveTest::BREAKPOINTS.last])
62
- expect(test_tag['srcset']).to match(expected_tag)
63
- end
64
- it "Should support custom transformation for srcset items" do
65
- options[:srcset] = {
66
- :breakpoints => ResponsiveTest::BREAKPOINTS,
67
- :transformation => {:crop => 'crop', :width => 10, :height => 20}
68
- }
69
-
70
- expected_tag = expected_srcset('sample.jpg', upload_path, 'c_crop,h_20,w_10', ResponsiveTest::BREAKPOINTS)
71
- expect(test_tag['srcset']).to match(expected_tag)
72
- end
73
- it "Should populate sizes attribute" do
74
- options[:srcset] = {
75
- :breakpoints => ResponsiveTest::BREAKPOINTS,
76
- :sizes => true
77
- }
78
- expected_sizes_attr = '(max-width: 100px) 100px, (max-width: 200px) 200px, ' +
79
- '(max-width: 300px) 300px, (max-width: 399px) 399px'
80
- expect(test_tag['sizes']).to match(expected_sizes_attr)
81
- end
82
- it "Should support srcset string value" do
83
- raw_src_set = "some srcset data as is"
84
- options[:srcset] = raw_src_set
85
-
86
- expect(test_tag['srcset']).to match(raw_src_set)
87
- end
88
- it "Should remove width and height attributes in case srcset is specified, but passed to transformation" do
89
- options.merge!({
90
- :srcset => {
91
- :breakpoints => ResponsiveTest::BREAKPOINTS,
92
- },
93
- :width => 500,
94
- :height => 500,
95
- :crop => 'scale'
96
-
97
- })
98
-
99
- expected_tag = expected_srcset('sample.jpg', upload_path, 'c_scale,e_sepia,h_500,w_500', ResponsiveTest::BREAKPOINTS)
100
- expect(test_tag['srcset']).to match(expected_tag)
101
- expect(test_tag['width']).to be_nil
102
- end
103
-
104
- end
105
-
106
-
107
- end
Binary file
@@ -1,160 +0,0 @@
1
- require 'spec_helper'
2
- require 'cloudinary'
3
-
4
- require 'tmpdir'
5
- require 'pathname'
6
-
7
- describe 'cloudinary:sync_static' do
8
- include_context 'rake' # context needs to have the exact rake task as name
9
- include Helpers::TempFileHelpers
10
-
11
- before(:all) do
12
- copy_root_to_temp('spec/data/sync_static/')
13
-
14
- # Reuse some existing spec assets so as not to add weight to the project
15
- copy_file_to_temp('spec/logo.png', 'app/assets/images/logo1.png')
16
- copy_file_to_temp('spec/logo.png', 'app/assets/images/logo2.png')
17
- copy_file_to_temp('samples/basic/lake.jpg', 'app/assets/images/lake1.jpg')
18
- copy_file_to_temp('samples/basic/lake.jpg', 'public/images/lake2.jpg')
19
- end
20
-
21
- after(:all) do
22
- clean_up_temp_files!
23
- end
24
-
25
- before (:each) do
26
- allow(Cloudinary).to receive(:app_root).and_return(Pathname.new(temp_root))
27
- Cloudinary::Static.send(:reset_static_file_config!)
28
- end
29
-
30
- after (:each) do
31
- # destroy all uploaded assets
32
- Cloudinary::Static.send(:build_metadata).each do |_, data|
33
- Cloudinary::Uploader.destroy(data['public_id'], {:type => :asset})
34
- end
35
- # delete metadata_file_path
36
- FileUtils.rm_f(Cloudinary::Static.send(:metadata_file_path))
37
- FileUtils.rm_f(Cloudinary::Static.send(:metadata_trash_file_path))
38
- end
39
-
40
- it 'should find correct file when running in default configuration' do
41
- # with default settings, 4 images only will be uploaded
42
- subject.invoke
43
- expect(Cloudinary::Static.send(:build_metadata).size).to eq 4
44
- end
45
-
46
- it 'should respect deprecated static_image_dirs config setting' do
47
- allow(Cloudinary.config).to receive(:static_image_dirs).and_return(['public/images'])
48
- subject.invoke
49
- expect(Cloudinary::Static.send(:build_metadata).size).to eq 1
50
- end
51
-
52
- it 'should allow to specify only dirs in images group, taking the file_mask from default' do
53
- allow(Cloudinary.config).to receive(:static_files).and_return({
54
- 'images' => {
55
- 'dirs' => ['public/images']
56
- }
57
- })
58
- subject.invoke
59
- expect(Cloudinary::Static.send(:build_metadata).size).to eq 1
60
- end
61
-
62
- it 'should allow to specify only file_mask in images group, taking the dirs from default' do
63
- allow(Cloudinary.config).to receive(:static_files).and_return({
64
- 'images' => {
65
- 'file_mask' => 'png'
66
- }
67
- })
68
- subject.invoke
69
- expect(Cloudinary::Static.send(:build_metadata).size).to eq 2
70
- end
71
-
72
- it 'should allow to specify regex expressions in file_mask' do
73
- allow(Cloudinary.config).to receive(:static_files).and_return({
74
- 'images' => {
75
- 'file_mask' => 'p.?g|jp.?'
76
- },
77
- 'javascripts' => {
78
- 'dirs' => ['app/assets/javascripts'],
79
- 'file_mask' => 'js'
80
- },
81
- 'stylesheets' => {
82
- 'dirs' => ['app/assets/stylesheets'],
83
- 'file_mask' => 'css'
84
- }
85
- })
86
- subject.invoke
87
- expect(Cloudinary::Static.send(:build_metadata).size).to eq 6
88
- end
89
-
90
- context 'Cloudinary::Utils.cloudinary_url' do
91
- def all_asset_forms_of(public_id)
92
- [ "/#{public_id}", public_id.split('/').last]
93
- end
94
-
95
- RSpec::Matchers.define :be_asset_mapped_by_cloudinary_url_to do |expected|
96
- match do |actual|
97
- actual = [actual] unless actual.respond_to? :all?
98
- actual.all? do |public_path|
99
- @public_path = public_path
100
- @actual = Cloudinary::Utils.cloudinary_url(public_path, :cloud_name => 'test', :type => 'asset')
101
- @actual == expected
102
- end
103
- end
104
- failure_message do |actual|
105
- "URL for '#{@public_path}' should have been '#{expected}' but was '#{@actual}'.#{ differ.diff_as_string(@actual, expected)}"
106
- end
107
- failure_message_when_negated do |actual|
108
- "URL for '#{@public_path}' should not have been '#{expected}'."
109
- end
110
- def differ
111
- RSpec::Support::Differ.new(
112
- :object_preparer => lambda { |object| RSpec::Matchers::Composable.surface_descriptions_in(object) },
113
- :color => RSpec::Matchers.configuration.color?
114
- )
115
- end
116
-
117
- end
118
-
119
- before(:each) do
120
- allow(Cloudinary.config).to receive(:static_files).and_return({
121
- 'images' => {
122
- 'dirs' => ['app/assets/images'],
123
- 'file_mask' => 'p.?g|jp.?'
124
- },
125
- 'javascripts' => {
126
- 'dirs' => ['app/assets/javascripts'],
127
- 'file_mask' => 'js'
128
- },
129
- 'stylesheets' => {
130
- 'dirs' => ['app/assets/stylesheets'],
131
- 'file_mask' => 'css'
132
- }
133
- })
134
-
135
- end
136
-
137
- it 'should return Cloudinary asset urls for assets when Cloudinary.config.static_file_support is true' do
138
- allow(Cloudinary.config).to receive(:static_file_support).and_return(true)
139
- subject.invoke
140
-
141
- expect(['logo1.png', '/images/logo1.png']).to be_asset_mapped_by_cloudinary_url_to('http://res.cloudinary.com/test/image/asset/logo1-7dc60722d4653261648038b579fdb89e.png')
142
- expect('images/logo1.png').not_to be_asset_mapped_by_cloudinary_url_to('http://res.cloudinary.com/test/image/asset/logo1-7dc60722d4653261648038b579fdb89e.png')
143
- expect('1.js').to be_asset_mapped_by_cloudinary_url_to('http://res.cloudinary.com/test/raw/asset/1-b01de57adb485efdde843154d030644e.js')
144
- expect(['javascripts/1.js', '/javascripts/1.js']).not_to be_asset_mapped_by_cloudinary_url_to('http://res.cloudinary.com/test/raw/asset/1-b01de57adb485efdde843154d030644e.js')
145
- expect('1.css').to be_asset_mapped_by_cloudinary_url_to('http://res.cloudinary.com/test/raw/asset/1-f24cc6123afd401ab86d8596cabc619f.css')
146
- expect(['stylesheets/1.css', '/stylesheets/1.css']).not_to be_asset_mapped_by_cloudinary_url_to('http://res.cloudinary.com/test/raw/asset/1-f24cc6123afd401ab86d8596cabc619f.css')
147
-
148
- # without :type => 'asset'
149
- expect(Cloudinary::Utils.cloudinary_url('logo1.png')).not_to include('7dc60722d4653261648038b579fdb89e')
150
- end
151
-
152
- it 'should return Cloudinary asset urls for assets when Cloudinary.config.static_image_support is true (backwards compatibility)' do
153
- allow(Cloudinary.config).to receive(:static_image_support).and_return(true)
154
- subject.invoke
155
-
156
- expect(['logo1.png', '/images/logo1.png']).to be_asset_mapped_by_cloudinary_url_to('http://res.cloudinary.com/test/image/asset/logo1-7dc60722d4653261648038b579fdb89e.png')
157
- end
158
- end
159
-
160
- end
@@ -1,4 +0,0 @@
1
- public_path public_id upload_time.to_i version width height
2
- stylesheets/foo.css css-foo 123 1 100 100
3
- javascripts/bar.js bar 123 1 100 100
4
- images/foo.jpg images-foo 123 1 100 100
@@ -1,109 +0,0 @@
1
- require 'spec_helper'
2
- require 'cloudinary'
3
-
4
- describe Cloudinary::Search do
5
- context 'unit' do
6
- it 'should create empty json' do
7
- query_hash = Cloudinary::Search.to_h
8
- expect(query_hash).to eq({})
9
- end
10
-
11
- it 'should always return same object in fluent interface' do
12
- instance = Cloudinary::Search.new
13
- %w(expression sort_by max_results next_cursor aggregate with_field).each do |method|
14
- same_instance = instance.send(method, 'emptyarg')
15
- expect(instance).to eq(same_instance)
16
- end
17
- end
18
-
19
- it 'should add expression to query' do
20
- query = Cloudinary::Search.expression('format:jpg').to_h
21
- expect(query).to eq(expression: 'format:jpg')
22
- end
23
-
24
- it 'should add sort_by to query' do
25
- query = Cloudinary::Search.sort_by('created_at', 'asc').sort_by('updated_at', 'desc').to_h
26
- expect(query).to eq(sort_by: [{ 'created_at' => 'asc' }, { 'updated_at' => 'desc' }])
27
- end
28
-
29
- it 'should add max_results to query' do
30
- query = Cloudinary::Search.max_results(10).to_h
31
- expect(query).to eq(max_results: 10)
32
- end
33
-
34
- it 'should add next_cursor to query' do
35
- query = Cloudinary::Search.next_cursor('ASDFIUHASF9832HAFSOF').to_h
36
- expect(query).to eq(next_cursor: 'ASDFIUHASF9832HAFSOF')
37
- end
38
-
39
- it 'should add aggregations arguments as array to query' do
40
- query = Cloudinary::Search.aggregate('format').aggregate('size_category').to_h
41
- expect(query).to eq(aggregate: %w(format size_category))
42
- end
43
-
44
- it 'should add with_field to query' do
45
- query = Cloudinary::Search.with_field('context').with_field('tags').to_h
46
- expect(query).to eq(with_field: %w(context tags))
47
- end
48
- end
49
-
50
- context 'integration' do
51
- SEARCH_TAG = TIMESTAMP_TAG + "_search"
52
- include_context 'cleanup', SEARCH_TAG
53
- prefix = "api_test_#{SUFFIX}"
54
- test_id_1 = "#{prefix}_1"
55
- test_id_2 = "#{prefix}_2"
56
- test_id_3 = "#{prefix}_3"
57
- before(:all) do
58
- Cloudinary::Uploader.upload(TEST_IMG, public_id: test_id_1, tags: [TEST_TAG, TIMESTAMP_TAG, SEARCH_TAG], context: 'stage=in_review')
59
- Cloudinary::Uploader.upload(TEST_IMG, public_id: test_id_2, tags: [TEST_TAG, TIMESTAMP_TAG, SEARCH_TAG], context: 'stage=new')
60
- Cloudinary::Uploader.upload(TEST_IMG, public_id: test_id_3, tags: [TEST_TAG, TIMESTAMP_TAG, SEARCH_TAG], context: 'stage=validated')
61
- sleep(3)
62
- end
63
-
64
- it "should return all images tagged with #{SEARCH_TAG}" do
65
- results = Cloudinary::Search.expression("tags:#{SEARCH_TAG}").execute
66
- expect(results['resources'].count).to eq 3
67
- end
68
-
69
- it "should return resource #{test_id_1}" do
70
- results = Cloudinary::Search.expression("public_id:#{test_id_1}").execute
71
- expect(results['resources'].count).to eq 1
72
- end
73
-
74
- it 'should paginate resources limited by tag and ordered by ascending public_id' do
75
- results = Cloudinary::Search.max_results(1).expression("tags:#{SEARCH_TAG}").sort_by('public_id', 'asc').execute
76
- expect(results['resources'].count).to eq 1
77
- expect(results['resources'][0]['public_id']).to eq test_id_1
78
- expect(results['total_count']).to eq 3
79
-
80
- results = Cloudinary::Search.max_results(1).expression("tags:#{SEARCH_TAG}").sort_by('public_id', 'asc').next_cursor(results['next_cursor']).execute
81
- expect(results['resources'].count).to eq 1
82
- expect(results['resources'][0]['public_id']).to eq test_id_2
83
- expect(results['total_count']).to eq 3
84
-
85
- results = Cloudinary::Search.max_results(1).expression("tags:#{SEARCH_TAG}").sort_by('public_id', 'asc').next_cursor(results['next_cursor']).execute
86
- expect(results['resources'].count).to eq 1
87
- expect(results['resources'][0]['public_id']).to eq test_id_3
88
- expect(results['total_count']).to eq 3
89
- expect(results['next_cursor']).to be_nil
90
- end
91
-
92
- it 'should include context' do
93
- results = Cloudinary::Search.expression("tags:#{SEARCH_TAG}").with_field('context').execute
94
- expect(results['resources'].count).to eq 3
95
- results['resources'].each do |res|
96
- expect(res['context'].keys).to eq ['stage']
97
- end
98
- end
99
- it 'should include context, tags and image_metadata' do
100
- results = Cloudinary::Search.expression("tags:#{SEARCH_TAG}").with_field('context').with_field('tags').with_field('image_metadata').execute
101
- expect(results['resources'].count).to eq 3
102
- results['resources'].each do |res|
103
- expect(res['context'].keys).to eq ['stage']
104
- expect(res.key?('image_metadata')).to eq true
105
- expect(res['tags'].count).to eq 3
106
- end
107
- end
108
- end
109
- end
@@ -1,266 +0,0 @@
1
- require 'rspec'
2
- require 'rexml/parsers/ultralightparser'
3
- require 'nokogiri'
4
- require 'rspec/version'
5
- require 'rest_client'
6
- require 'cloudinary'
7
-
8
- Cloudinary.config.enhance_image_tag = true
9
-
10
- DUMMY_CLOUD = "test123"
11
- TEST_IMAGE_URL = "http://cloudinary.com/images/old_logo.png"
12
- TEST_IMG = "spec/logo.png"
13
- TEST_IMG_W = 241
14
- TEST_IMG_H = 51
15
- SUFFIX = ENV['TRAVIS_JOB_ID'] || rand(999999999).to_s
16
- TEST_TAG = 'cloudinary_gem_test'
17
- TIMESTAMP_TAG = "#{TEST_TAG}_#{SUFFIX}_#{RUBY_VERSION}_#{ defined? Rails::version ? Rails::version : 'no_rails'}"
18
-
19
- # Auth token
20
- KEY = "00112233FF99"
21
- ALT_KEY = "CCBB2233FF00"
22
- CACHE_KEY = "some_key" + SUFFIX
23
-
24
- module ResponsiveTest
25
- TRANSFORMATION = {:angle => 45, :crop => "scale"}
26
- FORMAT = "png"
27
- IMAGE_BP_VALUES = [206, 50]
28
- BREAKPOINTS = [100, 200, 300, 399]
29
-
30
- end
31
- Dir[File.join(File.dirname(__FILE__), '/support/**/*.rb')].each {|f| require f}
32
-
33
- module RSpec
34
- def self.project_root
35
- File.join(File.dirname(__FILE__), '..')
36
- end
37
- end
38
-
39
- # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
40
- RSpec.configure do |config|
41
- unless RSpec::Version::STRING.match( /^3/)
42
- config.treat_symbols_as_metadata_keys_with_true_values = true
43
- end
44
- config.run_all_when_everything_filtered = true
45
- config.filter_run_excluding :delete_all => true
46
- end
47
-
48
- RSpec.shared_context "cleanup" do |tag|
49
- tag ||= TEST_TAG
50
- after :all do
51
- Cloudinary::Api.delete_resources_by_tag(tag) unless Cloudinary.config.keep_test_products
52
- end
53
- end
54
-
55
- module Cloudinary
56
- def self.reset_config
57
- @@config = nil
58
- end
59
-
60
- end
61
-
62
-
63
- CALLS_SERVER_WITH_PARAMETERS = "calls server with parameters"
64
- RSpec.shared_examples CALLS_SERVER_WITH_PARAMETERS do |expected|
65
- expect(RestClient::Request).to receive(:execute).with(deep_hash_value(expected))
66
- end
67
-
68
- # Create a regexp with the given +tag+ name.
69
- def html_tag_matcher( tag)
70
- /<#{tag}([\s]+([-[:word:]]+)[\s]*\=\s*\"([^\"]*)\")*\s*>.*<\s*\/#{tag}\s*>/
71
- end
72
-
73
- # Represents an HTML tag
74
- class TestTag
75
- attr_accessor :element
76
- # Creates a new +TestTag+ from a given +element+ string
77
- def initialize(element)
78
- @html_string = element
79
- @element = valid_tag(element) unless element.is_a? Array
80
-
81
- end
82
-
83
- def name
84
- @element.name
85
- end
86
-
87
- def attributes
88
- @element.attributes
89
- end
90
-
91
- def children
92
- @element.children
93
- end
94
- # Parses a given +tag+ in string format
95
- def valid_tag(tag)
96
- parser = Nokogiri::HTML::Document.parse( tag)
97
- # Parsed code will be strctured as either html>body>tag or html>head>tag
98
- parser.children[1].children[0].children[0]
99
- end
100
-
101
- # Returns attribute named +symbol_or_string+
102
- def [](symbol_or_string)
103
- begin
104
- attributes[symbol_or_string.to_s].value
105
- rescue
106
- nil
107
- end
108
- end
109
-
110
- def method_missing(symbol, *args)
111
- if (m = /children_by_(\w+)/.match(symbol.to_s)) and !args.empty?
112
- return unless children
113
- children.select{ |c| c[m[1]] == args[0]}
114
- else
115
- super
116
- end
117
- end
118
-
119
- def ==(other)
120
- case other
121
- when String
122
- @text == other
123
- else
124
- other.respond_to?( :text) &&
125
- other.respond_to?( :name) &&
126
- other.respond_to?( :attributes) &&
127
- other.respond_to?( :children) &&
128
- @text == other.text &&
129
- @name == other.name &&
130
- @attributes == other.attributes &&
131
- @children == other.children
132
- end
133
- end
134
- end
135
-
136
- RSpec::Matchers.define :produce_url do |expected_url|
137
- match do |params|
138
- public_id, options = params
139
- actual_options = options.clone
140
- @url = Cloudinary::Utils.cloudinary_url(public_id, actual_options)
141
- values_match? expected_url, @url
142
- end
143
- failure_message do |actual|
144
- "expected #{actual} to\nproduce: #{expected_url}\nbut got: #{@url}"
145
- end
146
- end
147
-
148
- RSpec::Matchers.define :mutate_options_to do |expected_options|
149
- match do |params|
150
- public_id, options = params
151
- options = options.clone
152
- Cloudinary::Utils.cloudinary_url(public_id, options)
153
- @actual = options
154
- values_match? expected_options, @actual
155
- end
156
- end
157
-
158
- RSpec::Matchers.define :empty_options do
159
- match do |params|
160
- public_id, options = params
161
- options = options.clone
162
- Cloudinary::Utils.cloudinary_url(public_id, options)
163
- options.empty?
164
- end
165
- end
166
-
167
- # Verify that the given URL can be served by Cloudinary by fetching the resource from the server
168
- RSpec::Matchers.define :be_served_by_cloudinary do
169
- match do |url|
170
- if url.is_a? Array
171
- url, options = url
172
- url = Cloudinary::Utils.cloudinary_url(url, options.clone)
173
- if Cloudinary.config.upload_prefix
174
- res_prefix_uri = URI.parse(Cloudinary.config.upload_prefix)
175
- res_prefix_uri.path = '/res'
176
- url.gsub!(/https?:\/\/res.cloudinary.com/, res_prefix_uri.to_s)
177
- end
178
- end
179
- code = 0
180
- @url = url
181
- RestClient.get @url do |response, request, result|
182
- @result = result
183
- code = response.code
184
- end
185
- values_match? 200, code
186
- end
187
-
188
- failure_message do |actual|
189
- if @result
190
- "Couldn't serve #{actual}. #{@result["status"]}: #{@result["x-cld-error"]}"
191
- else
192
- "Couldn't serve #{actual}."
193
- end
194
- end
195
- failure_message_when_negated do |actual|
196
- if @result
197
- "Expected #{@url} not to be served by cloudinary. #{@result["status"]}: #{@result["x-cld-error"]}"
198
- else
199
- "Expected #{@url} not to be served by cloudinary."
200
- end
201
-
202
- end
203
- end
204
-
205
- def deep_fetch(hash, path)
206
- Array(path).reduce(hash) { |h, key| h && h.fetch(key, nil) }
207
- end
208
-
209
- # Matches deep values in the actual Hash, disregarding other keys and values.
210
- # @example
211
- # expect( {:foo => { :bar => 'foobar'}}).to have_deep_hash_values_of( [:foo, :bar] => 'foobar')
212
- # expect( foo_instance).to receive(:bar_method).with(deep_hash_values_of([:foo, :bar] => 'foobar'))
213
- RSpec::Matchers.define :deep_hash_value do |expected|
214
- match do |actual|
215
- expected.all? do |path, value|
216
- Cloudinary.values_match? value, deep_fetch(actual, path)
217
- end
218
- end
219
- end
220
-
221
- RSpec::Matchers.alias_matcher :have_deep_hash_values_of, :deep_hash_value
222
-
223
- module Cloudinary
224
- # @api private
225
- def self.values_match?(expected, actual)
226
- if Hash === actual
227
- return hashes_match?(expected, actual) if Hash === expected
228
- elsif Array === expected && Enumerable === actual && !(Struct === actual)
229
- return arrays_match?(expected, actual.to_a)
230
- elsif Regexp === expected
231
- return expected.match actual.to_s
232
- end
233
-
234
-
235
- return true if actual == expected
236
-
237
- begin
238
- expected === actual
239
- rescue ArgumentError
240
- # Some objects, like 0-arg lambdas on 1.9+, raise
241
- # ArgumentError for `expected === actual`.
242
- false
243
- end
244
- end
245
-
246
- # @private
247
- def self.arrays_match?(expected_list, actual_list)
248
- return false if expected_list.size != actual_list.size
249
-
250
- expected_list.zip(actual_list).all? do |expected, actual|
251
- values_match?(expected, actual)
252
- end
253
- end
254
-
255
- # @private
256
- def self.hashes_match?(expected_hash, actual_hash)
257
- return false if expected_hash.size != actual_hash.size
258
-
259
- expected_hash.all? do |expected_key, expected_value|
260
- actual_value = actual_hash.fetch(expected_key) { return false }
261
- values_match?(expected_value, actual_value)
262
- end
263
- end
264
-
265
- private_class_method :arrays_match?, :hashes_match?
266
- end