link_thumbnailer 3.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.rspec +2 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +5 -0
  6. data/CHANGELOG.md +334 -0
  7. data/Gemfile +12 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +210 -0
  10. data/Rakefile +9 -0
  11. data/lib/generators/link_thumbnailer/install_generator.rb +17 -0
  12. data/lib/generators/templates/initializer.rb +89 -0
  13. data/lib/link_thumbnailer.rb +38 -0
  14. data/lib/link_thumbnailer/configuration.rb +72 -0
  15. data/lib/link_thumbnailer/exceptions.rb +11 -0
  16. data/lib/link_thumbnailer/grader.rb +43 -0
  17. data/lib/link_thumbnailer/graders/base.rb +39 -0
  18. data/lib/link_thumbnailer/graders/html_attribute.rb +48 -0
  19. data/lib/link_thumbnailer/graders/length.rb +37 -0
  20. data/lib/link_thumbnailer/graders/link_density.rb +20 -0
  21. data/lib/link_thumbnailer/graders/position.rb +13 -0
  22. data/lib/link_thumbnailer/image_comparator.rb +26 -0
  23. data/lib/link_thumbnailer/image_comparators/base.rb +19 -0
  24. data/lib/link_thumbnailer/image_comparators/size.rb +13 -0
  25. data/lib/link_thumbnailer/image_parser.rb +62 -0
  26. data/lib/link_thumbnailer/image_validator.rb +32 -0
  27. data/lib/link_thumbnailer/model.rb +20 -0
  28. data/lib/link_thumbnailer/models/description.rb +37 -0
  29. data/lib/link_thumbnailer/models/favicon.rb +27 -0
  30. data/lib/link_thumbnailer/models/image.rb +56 -0
  31. data/lib/link_thumbnailer/models/title.rb +22 -0
  32. data/lib/link_thumbnailer/models/video.rb +44 -0
  33. data/lib/link_thumbnailer/models/website.rb +54 -0
  34. data/lib/link_thumbnailer/page.rb +43 -0
  35. data/lib/link_thumbnailer/parser.rb +15 -0
  36. data/lib/link_thumbnailer/processor.rb +128 -0
  37. data/lib/link_thumbnailer/railtie.rb +6 -0
  38. data/lib/link_thumbnailer/response.rb +39 -0
  39. data/lib/link_thumbnailer/scraper.rb +62 -0
  40. data/lib/link_thumbnailer/scrapers/base.rb +69 -0
  41. data/lib/link_thumbnailer/scrapers/default/base.rb +12 -0
  42. data/lib/link_thumbnailer/scrapers/default/description.rb +49 -0
  43. data/lib/link_thumbnailer/scrapers/default/favicon.rb +38 -0
  44. data/lib/link_thumbnailer/scrapers/default/images.rb +78 -0
  45. data/lib/link_thumbnailer/scrapers/default/title.rb +27 -0
  46. data/lib/link_thumbnailer/scrapers/default/videos.rb +18 -0
  47. data/lib/link_thumbnailer/scrapers/opengraph/base.rb +45 -0
  48. data/lib/link_thumbnailer/scrapers/opengraph/description.rb +12 -0
  49. data/lib/link_thumbnailer/scrapers/opengraph/favicon.rb +17 -0
  50. data/lib/link_thumbnailer/scrapers/opengraph/image.rb +107 -0
  51. data/lib/link_thumbnailer/scrapers/opengraph/images.rb +18 -0
  52. data/lib/link_thumbnailer/scrapers/opengraph/title.rb +12 -0
  53. data/lib/link_thumbnailer/scrapers/opengraph/video.rb +115 -0
  54. data/lib/link_thumbnailer/scrapers/opengraph/videos.rb +18 -0
  55. data/lib/link_thumbnailer/uri.rb +20 -0
  56. data/lib/link_thumbnailer/version.rb +5 -0
  57. data/lib/link_thumbnailer/video_parser.rb +47 -0
  58. data/link_thumbnailer.gemspec +29 -0
  59. data/spec/configuration_spec.rb +61 -0
  60. data/spec/fixture_spec.rb +114 -0
  61. data/spec/fixtures/bar.png +2907 -0
  62. data/spec/fixtures/default_from_body.html +13 -0
  63. data/spec/fixtures/default_from_meta.html +12 -0
  64. data/spec/fixtures/foo.png +0 -0
  65. data/spec/fixtures/google_shift_jis.html +6 -0
  66. data/spec/fixtures/google_utf8.html +6 -0
  67. data/spec/fixtures/og_not_valid_example.html +12 -0
  68. data/spec/fixtures/og_valid_example.html +18 -0
  69. data/spec/fixtures/og_valid_multi_image_example.html +13 -0
  70. data/spec/fixtures/og_valid_multi_video_example.html +13 -0
  71. data/spec/grader_spec.rb +27 -0
  72. data/spec/graders/base_spec.rb +14 -0
  73. data/spec/graders/html_attribute_spec.rb +50 -0
  74. data/spec/graders/length_spec.rb +93 -0
  75. data/spec/graders/link_density_spec.rb +52 -0
  76. data/spec/graders/position_spec.rb +49 -0
  77. data/spec/image_comparators/size_spec.rb +58 -0
  78. data/spec/image_validator_spec.rb +37 -0
  79. data/spec/model_spec.rb +27 -0
  80. data/spec/models/description_spec.rb +66 -0
  81. data/spec/models/favicon_spec.rb +12 -0
  82. data/spec/models/image_spec.rb +95 -0
  83. data/spec/models/title_spec.rb +26 -0
  84. data/spec/models/video_spec.rb +49 -0
  85. data/spec/models/website_spec.rb +51 -0
  86. data/spec/page_spec.rb +28 -0
  87. data/spec/processor_spec.rb +410 -0
  88. data/spec/response_spec.rb +62 -0
  89. data/spec/scraper_spec.rb +70 -0
  90. data/spec/scrapers/base_spec.rb +69 -0
  91. data/spec/scrapers/opengraph/base_spec.rb +96 -0
  92. data/spec/spec_helper.rb +11 -0
  93. data/spec/uri_spec.rb +44 -0
  94. data/spec/video_parser_spec.rb +148 -0
  95. metadata +271 -0
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe LinkThumbnailer::ImageValidator do
6
+
7
+ let(:src) { 'http://foo.com' }
8
+ let(:image) { double(src: src) }
9
+ let(:instance) { described_class.new(image) }
10
+
11
+ describe '#call' do
12
+
13
+ let(:action) { instance.call }
14
+
15
+ before do
16
+ allow(instance).to receive(:blacklist_urls).and_return(blacklist_urls)
17
+ end
18
+
19
+ context 'when image url is blacklisted' do
20
+
21
+ let(:blacklist_urls) { [src] }
22
+
23
+ it { expect(action).to be_falsey }
24
+
25
+ end
26
+
27
+ context 'when image url is not blacklisted' do
28
+
29
+ let(:blacklist_urls) { [] }
30
+
31
+ it { expect(action).to be_truthy }
32
+
33
+ end
34
+
35
+ end
36
+
37
+ end
@@ -0,0 +1,27 @@
1
+ # -*- encoding : utf-8 -*-
2
+ # frozen_string_literal: true
3
+
4
+ require 'spec_helper'
5
+
6
+ describe LinkThumbnailer::Model do
7
+
8
+ let(:instance) { described_class.new }
9
+
10
+ describe '#sanitize' do
11
+
12
+ let(:str) { "foo\r\n" }
13
+ let(:result) { "foo" }
14
+ let(:action) { instance.send(:sanitize, str) }
15
+
16
+ it { expect(action).to eq(result) }
17
+
18
+ context "when string includes utf-8 characters" do
19
+ let(:str) { "中文" }
20
+
21
+ it "should keeps those characters" do
22
+ expect(instance.send(:sanitize, str)).to eq(str)
23
+ end
24
+ end
25
+ end
26
+
27
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe LinkThumbnailer::Models::Description do
6
+
7
+ let(:text) { 'bar' }
8
+ let(:grader) { double(call: 0) }
9
+ let(:node) { double(text: 'bar') }
10
+ let(:instance) { described_class.new(node, text) }
11
+
12
+ before do
13
+ expect(LinkThumbnailer::Grader).to receive(:new).at_least(1).times.and_return(grader)
14
+ end
15
+
16
+ describe '#to_s' do
17
+
18
+ let(:action) { instance.to_s }
19
+
20
+ it { expect(action).to eq(text) }
21
+
22
+ end
23
+
24
+ describe '#<=>' do
25
+
26
+ let(:another_instance) { described_class.new(node, text) }
27
+ let(:probability) { 0.5 }
28
+ let(:action) { instance <=> another_instance }
29
+
30
+ before do
31
+ another_instance.probability = probability
32
+ end
33
+
34
+ context 'when instance probability is lower' do
35
+
36
+ before do
37
+ instance.probability = probability - 0.5
38
+ end
39
+
40
+ it { expect(action).to eq(-1) }
41
+
42
+ end
43
+
44
+ context 'when instance probability is equal' do
45
+
46
+ before do
47
+ instance.probability = probability
48
+ end
49
+
50
+ it { expect(action).to eq(0) }
51
+
52
+ end
53
+
54
+ context 'when instance probability is greater' do
55
+
56
+ before do
57
+ instance.probability = probability + 0.5
58
+ end
59
+
60
+ it { expect(action).to eq(1) }
61
+
62
+ end
63
+
64
+ end
65
+
66
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe LinkThumbnailer::Models::Favicon do
6
+
7
+ let(:uri) { URI.parse('http://foo.com') }
8
+ let(:instance) { described_class.new(uri) }
9
+
10
+ it { expect(instance.to_s).to eq('http://foo.com') }
11
+
12
+ end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe LinkThumbnailer::Models::Image do
6
+
7
+ let(:src) { 'http://foo.com' }
8
+ let(:instance) { described_class.new(src) }
9
+
10
+ before do
11
+ stub_request(:get, src).to_return(status: 200, body: '', headers: {})
12
+ end
13
+
14
+ describe '#to_s' do
15
+
16
+ let(:action) { instance.to_s }
17
+
18
+ it { expect(action).to eq(src) }
19
+
20
+ end
21
+
22
+ describe '#<=>' do
23
+
24
+ let(:other) { double(size: other_size) }
25
+ let(:action) { instance <=> other }
26
+
27
+ before do
28
+ allow(instance).to receive(:size).and_return([20, 20])
29
+ end
30
+
31
+ context 'when other has a smaller image' do
32
+
33
+ let(:other_size) { [10, 10] }
34
+
35
+ it { expect(action).to eq(-1) }
36
+
37
+ end
38
+
39
+ context 'when other as identical image size' do
40
+
41
+ let(:other_size) { [20, 20] }
42
+
43
+ it { expect(action).to eq(0) }
44
+
45
+ end
46
+
47
+ context 'when other as a bigger image' do
48
+
49
+ let(:other_size) { [30, 30] }
50
+
51
+ it { expect(action).to eq(1) }
52
+
53
+ end
54
+
55
+ end
56
+
57
+ describe '#valid?' do
58
+
59
+ let(:validator) { double }
60
+ let(:action) { instance.valid? }
61
+
62
+ before do
63
+ allow(instance).to receive(:validator).and_return(validator)
64
+ end
65
+
66
+ it 'calls validator public method' do
67
+ expect(validator).to receive(:call)
68
+ action
69
+ end
70
+
71
+ end
72
+
73
+ describe '#as_json' do
74
+
75
+ let(:action) { instance.as_json }
76
+ let(:size) { [1, 1] }
77
+ let(:type) { 'foo' }
78
+ let(:result) {
79
+ {
80
+ src: src,
81
+ size: size,
82
+ type: type
83
+ }
84
+ }
85
+
86
+ before do
87
+ allow(instance).to receive(:size).and_return(size)
88
+ allow(instance).to receive(:type).and_return(type)
89
+ end
90
+
91
+ it { expect(action).to eq(result) }
92
+
93
+ end
94
+
95
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe LinkThumbnailer::Models::Title do
6
+
7
+ let(:node) { double(text: 'bar') }
8
+ let(:instance) { described_class.new(node, text) }
9
+
10
+ context 'when text provided' do
11
+
12
+ let(:text) { 'foo' }
13
+
14
+ it { expect(instance.to_s).to eq(text) }
15
+
16
+ end
17
+
18
+ context 'when text not provided' do
19
+
20
+ let(:text) { nil }
21
+
22
+ it { expect(instance.to_s).to eq(node.text) }
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe LinkThumbnailer::Models::Video do
6
+
7
+ let(:src) { 'http://foo.com/foo.swf' }
8
+ let(:instance) { described_class.new(src) }
9
+
10
+ describe '#to_s' do
11
+
12
+ let(:action) { instance.to_s }
13
+
14
+ it { expect(action).to eq(src) }
15
+
16
+ end
17
+
18
+ describe '#as_json' do
19
+
20
+ let(:action) { instance.as_json }
21
+ let(:id) { 1 }
22
+ let(:size) { [1, 1] }
23
+ let(:duration) { 10 }
24
+ let(:provider) { 'foo' }
25
+ let(:embed_code) { 'bar' }
26
+ let(:result) {
27
+ {
28
+ id: id,
29
+ src: src,
30
+ size: size,
31
+ duration: duration,
32
+ provider: provider,
33
+ embed_code: embed_code
34
+ }
35
+ }
36
+
37
+ before do
38
+ allow(instance).to receive(:id).and_return(id)
39
+ allow(instance).to receive(:size).and_return(size)
40
+ allow(instance).to receive(:duration).and_return(duration)
41
+ allow(instance).to receive(:provider).and_return(provider)
42
+ allow(instance).to receive(:embed_code).and_return(embed_code)
43
+ end
44
+
45
+ it { expect(action).to eq(result) }
46
+
47
+ end
48
+
49
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe LinkThumbnailer::Models::Website do
6
+
7
+ let(:instance) { described_class.new }
8
+
9
+ it { expect(instance.images).to be_empty }
10
+
11
+ describe '#image=' do
12
+
13
+ let(:image) { double }
14
+ let(:action) { instance.image = image }
15
+
16
+ before do
17
+ allow(image).to receive(:valid?).and_return(true)
18
+ end
19
+
20
+ it { expect { action }.to change { instance.images.size }.by(1) }
21
+
22
+ end
23
+
24
+ describe '#images=' do
25
+
26
+ let(:image) { double }
27
+ let(:action) { instance.images = image }
28
+
29
+ context 'when image is valid' do
30
+
31
+ before do
32
+ allow(image).to receive(:valid?).and_return(true)
33
+ end
34
+
35
+ it { expect { action }.to change { instance.images.size }.by(1) }
36
+
37
+ end
38
+
39
+ context 'when image is not valid' do
40
+
41
+ before do
42
+ allow(image).to receive(:valid?).and_return(false)
43
+ end
44
+
45
+ it { expect { action }.to_not change { instance.images.size } }
46
+
47
+ end
48
+
49
+ end
50
+
51
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe LinkThumbnailer::Page do
6
+
7
+ let(:url) { 'http://foo.com' }
8
+ let(:instance) { described_class.new(url, options) }
9
+
10
+ context 'with inline options' do
11
+
12
+ let(:options) { { image_limit: 2 } }
13
+
14
+ it { expect(instance.config.image_limit).to eq(2) }
15
+ it { expect(instance.config.user_agent).to eq(LinkThumbnailer.config.user_agent) }
16
+
17
+ end
18
+
19
+ context 'without inline options' do
20
+
21
+ let(:options) { {} }
22
+
23
+ it { expect(instance.config.image_limit).to eq(LinkThumbnailer.config.image_limit) }
24
+ it { expect(instance.config.user_agent).to eq(LinkThumbnailer.config.user_agent) }
25
+
26
+ end
27
+
28
+ end
@@ -0,0 +1,410 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe LinkThumbnailer::Processor do
6
+
7
+ let(:page) { ::LinkThumbnailer::Page.new(url, {}) }
8
+ let(:instance) { described_class.new }
9
+ let(:url) { 'http://foo.com' }
10
+
11
+ before do
12
+ allow(LinkThumbnailer).to receive(:page).and_return(page)
13
+ end
14
+
15
+ describe '#call' do
16
+
17
+ let(:action) { instance.call(url) }
18
+
19
+ context 'when redirect_count is greater than config' do
20
+
21
+ it { expect { instance.call(url, 10) } .to raise_error(LinkThumbnailer::RedirectLimit) }
22
+
23
+ end
24
+
25
+ context 'on no http error' do
26
+
27
+ let(:body) { 'foo' }
28
+
29
+ before do
30
+ stub_request(:get, url).to_return(status: 200, body: body, headers: {})
31
+ end
32
+
33
+ it { expect(action).to eq(body) }
34
+
35
+ end
36
+
37
+ context 'on http error' do
38
+
39
+ before do
40
+ stub_request(:get, url).to_return(status: 500, body: '', headers: {})
41
+ end
42
+
43
+ it { expect { action }.to raise_error(LinkThumbnailer::HTTPError) }
44
+
45
+ end
46
+
47
+ context 'on http redirection' do
48
+
49
+ let(:body) { 'foo' }
50
+
51
+ context 'with relative uri' do
52
+
53
+ let(:another_url) { '/bar' }
54
+
55
+ before do
56
+ stub_request(:get, url).to_return(status: 300, body: '', headers: { 'Location' => another_url })
57
+ stub_request(:get, url + another_url).to_return(status: 200, body: body, headers: {})
58
+ end
59
+
60
+ it { expect(action).to eq(body) }
61
+
62
+ end
63
+
64
+ context 'with absolute uri' do
65
+
66
+ let(:another_url) { 'http://bar.com' }
67
+
68
+ before do
69
+ stub_request(:get, url).to_return(status: 300, body: '', headers: { 'Location' => another_url })
70
+ stub_request(:get, another_url).to_return(status: 200, body: body, headers: {})
71
+ end
72
+
73
+ it { expect(action).to eq(body) }
74
+
75
+ end
76
+
77
+ end
78
+
79
+ end
80
+
81
+ describe '#with_valid_url' do
82
+
83
+ context 'when valid' do
84
+
85
+ before do
86
+ allow(instance).to receive(:valid_url_format?).and_return(true)
87
+ end
88
+
89
+ it 'yields' do
90
+ expect(instance).to receive(:with_valid_url).and_yield
91
+ instance.send(:with_valid_url) {}
92
+ end
93
+
94
+ end
95
+
96
+ context 'when not valid' do
97
+
98
+ before do
99
+ allow(instance).to receive(:valid_url_format?).and_return(false)
100
+ end
101
+
102
+ it { expect { instance.send(:with_valid_url) }.to raise_error(LinkThumbnailer::BadUriFormat) }
103
+
104
+ end
105
+
106
+ end
107
+
108
+ describe '#set_http_headers' do
109
+
110
+ let(:user_agent) { 'foo' }
111
+ let(:headers) { instance.send(:http).override_headers }
112
+ let(:action) { instance.send(:set_http_headers) }
113
+
114
+ before do
115
+ allow(instance).to receive(:user_agent).and_return(user_agent)
116
+ action
117
+ end
118
+
119
+ it { expect(headers['User-Agent']).to eq(user_agent) }
120
+
121
+ end
122
+
123
+ describe '#set_http_options' do
124
+
125
+ let(:http) { instance.send(:http) }
126
+ let(:action) { instance.send(:set_http_options) }
127
+
128
+ describe 'verify_mode' do
129
+
130
+ context 'when verify_ssl is true' do
131
+
132
+ before do
133
+ allow(instance).to receive(:ssl_required?).and_return(true)
134
+ action
135
+ end
136
+
137
+ it { expect(http.verify_mode).to_not eq(::OpenSSL::SSL::VERIFY_NONE) }
138
+
139
+ end
140
+
141
+ context 'when verify_ssl is not true' do
142
+
143
+ before do
144
+ allow(instance).to receive(:ssl_required?).and_return(false)
145
+ action
146
+ end
147
+
148
+ it { expect(http.verify_mode).to eq(::OpenSSL::SSL::VERIFY_NONE) }
149
+
150
+ end
151
+
152
+ end
153
+
154
+ describe 'open_timeout' do
155
+
156
+ let(:http_open_timeout) { 1 }
157
+
158
+ before do
159
+ allow(instance).to receive(:http_open_timeout).and_return(http_open_timeout)
160
+ action
161
+ end
162
+
163
+ it { expect(http.open_timeout).to eq(http_open_timeout) }
164
+
165
+ end
166
+
167
+ describe 'read_timeout' do
168
+
169
+ let(:http_read_timeout) { 1 }
170
+
171
+ before do
172
+ allow(instance).to receive(:http_read_timeout).and_return(http_read_timeout)
173
+ action
174
+ end
175
+
176
+ it { expect(http.read_timeout).to eq(http_read_timeout) }
177
+
178
+ end
179
+ end
180
+
181
+ describe '#perform_request' do
182
+
183
+ let(:action) { instance.send(:perform_request) }
184
+ let(:http) { double }
185
+
186
+ before do
187
+ allow(instance).to receive(:http).and_return(http)
188
+ allow(http).to receive(:request).and_return(response)
189
+ end
190
+
191
+ context 'when http success' do
192
+
193
+ let(:code) { 200 }
194
+ let(:body) { 'body' }
195
+ let(:response) { ::Net::HTTPSuccess.new('', code, body) }
196
+
197
+ before do
198
+ allow(response).to receive(:body).and_return(body)
199
+ end
200
+
201
+ it { expect(action).to eq(body) }
202
+
203
+ end
204
+
205
+ context 'when access non-utf8-encoding website' do
206
+ let(:code) { 200 }
207
+ let(:body_shift_jis) do
208
+ File.read(File.expand_path('fixtures/google_shift_jis.html', File.dirname(__FILE__)))
209
+ end
210
+ let(:body_utf8) do
211
+ File.read(File.expand_path('fixtures/google_utf8.html', File.dirname(__FILE__)))
212
+ end
213
+ let(:response) do
214
+ r = ::Net::HTTPSuccess.new('', code, body_shift_jis)
215
+ r['Content-Type'] = 'text/html'
216
+ r.body = body_shift_jis
217
+ r.instance_variable_set(:@read, true)
218
+ r
219
+ end
220
+
221
+ context 'when http success with valid charset provided in Content-Type' do
222
+ before { response['Content-Type'] = 'text/html; charset=Shift_JIS' }
223
+ it { expect(action).to eq body_utf8 }
224
+ end
225
+
226
+ context 'when http success with invalid charset provided in Content-Type' do
227
+ before { response['Content-Type'] = 'text/html; charset=Shift-JIS' }
228
+ it { expect(action).to eq body_shift_jis }
229
+ end
230
+ end
231
+
232
+ context 'when http redirection' do
233
+
234
+ let(:code) { 200 }
235
+ let(:body) { 'body' }
236
+ let(:response) { ::Net::HTTPRedirection.new('', code, body) }
237
+ let(:new_url) { 'http://foo.com/bar' }
238
+
239
+ before do
240
+ allow(instance).to receive(:redirect_count).and_return(0)
241
+ allow(instance).to receive(:resolve_relative_url).and_return(new_url)
242
+ end
243
+
244
+ it 'calls call method' do
245
+ expect(instance).to receive(:resolve_relative_url)
246
+ expect(instance).to receive(:call).with(new_url, instance.redirect_count + 1, {})
247
+ action
248
+ end
249
+
250
+ end
251
+
252
+ end
253
+
254
+ describe '#build_absolute_url_for' do
255
+
256
+ let(:scheme) { 'https' }
257
+ let(:host) { 'foo.com' }
258
+ let(:url) { URI("#{scheme}://#{host}") }
259
+ let(:relative_url) { '/bar' }
260
+ let(:action) { instance.send(:build_absolute_url_for, relative_url).to_s }
261
+
262
+ before do
263
+ allow(instance).to receive(:url).and_return(url)
264
+ end
265
+
266
+ it { expect(action).to eq("#{scheme}://#{host}#{relative_url}") }
267
+
268
+ end
269
+
270
+ describe '#redirect_limit' do
271
+
272
+ let(:redirect_limit) { 1 }
273
+ let(:action) { instance.send(:redirect_limit) }
274
+
275
+ before do
276
+ instance.config.redirect_limit = redirect_limit
277
+ end
278
+
279
+ it { expect(action).to eq(redirect_limit) }
280
+
281
+ end
282
+
283
+ describe '#user_agent' do
284
+
285
+ let(:user_agent) { 'foo' }
286
+ let(:action) { instance.send(:user_agent) }
287
+
288
+ before do
289
+ instance.config.user_agent = user_agent
290
+ end
291
+
292
+ it { expect(action).to eq(user_agent) }
293
+
294
+ end
295
+
296
+ describe '#http_open_timeout' do
297
+
298
+ let(:http_open_timeout) { 1 }
299
+ let(:action) { instance.send(:http_open_timeout) }
300
+
301
+ before do
302
+ instance.config.http_open_timeout = http_open_timeout
303
+ end
304
+
305
+ it { expect(action).to eq(http_open_timeout) }
306
+
307
+ end
308
+
309
+ describe '#http_read_timeout' do
310
+
311
+ let(:http_read_timeout) { 1 }
312
+ let(:action) { instance.send(:http_read_timeout) }
313
+
314
+ before do
315
+ instance.config.http_read_timeout = http_read_timeout
316
+ end
317
+
318
+ it { expect(action).to eq(http_read_timeout) }
319
+
320
+ end
321
+
322
+ describe '#ssl_required?' do
323
+
324
+ let(:verify_ssl) { true }
325
+ let(:action) { instance.send(:ssl_required?) }
326
+
327
+ before do
328
+ instance.config.verify_ssl = verify_ssl
329
+ end
330
+
331
+ it { expect(action).to eq(verify_ssl) }
332
+
333
+ end
334
+
335
+ describe '#valid_url_format?' do
336
+
337
+ let(:action) { instance.send(:valid_url_format?) }
338
+
339
+ context 'when bad format' do
340
+
341
+ before do
342
+ allow(instance).to receive(:url).and_return("http://foo.com")
343
+ end
344
+
345
+ it { expect(action).to be_falsey }
346
+
347
+ end
348
+
349
+ context 'when valid format' do
350
+
351
+ before do
352
+ allow(instance).to receive(:url).and_return(URI("http://foo.com"))
353
+ end
354
+
355
+ it { expect(action).to be_truthy }
356
+
357
+ end
358
+
359
+ end
360
+
361
+ describe '#too_many_redirections?' do
362
+
363
+ let(:action) { instance.send(:too_many_redirections?) }
364
+
365
+ context 'when redirect count is greater than redirect limit' do
366
+
367
+ before do
368
+ allow(instance).to receive(:redirect_count).and_return(5)
369
+ allow(instance).to receive(:redirect_limit).and_return(4)
370
+ end
371
+
372
+ it { expect(action).to be_truthy }
373
+
374
+ end
375
+
376
+ context 'when redirect count is less than redirect limit' do
377
+
378
+ before do
379
+ allow(instance).to receive(:redirect_count).and_return(4)
380
+ allow(instance).to receive(:redirect_limit).and_return(5)
381
+ end
382
+
383
+ it { expect(action).to be_falsey }
384
+
385
+ end
386
+
387
+ context 'when redirect count is equal to redirect limit' do
388
+
389
+ before do
390
+ allow(instance).to receive(:redirect_count).and_return(5)
391
+ allow(instance).to receive(:redirect_limit).and_return(5)
392
+ end
393
+
394
+ it { expect(action).to be_falsey }
395
+
396
+ end
397
+
398
+ end
399
+
400
+ describe '#url=' do
401
+
402
+ before do
403
+ instance.send(:url=, url)
404
+ end
405
+
406
+ it { expect(instance.url).to be_a(URI) }
407
+
408
+ end
409
+
410
+ end