link_thumbnailer 3.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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