link_thumbnailer 3.2.0 → 3.4.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 (88) hide show
  1. checksums.yaml +5 -5
  2. data/.ruby-version +1 -0
  3. data/.travis.yml +2 -4
  4. data/CHANGELOG.md +252 -75
  5. data/Gemfile +5 -3
  6. data/README.md +4 -0
  7. data/Rakefile +2 -0
  8. data/lib/generators/link_thumbnailer/install_generator.rb +2 -0
  9. data/lib/generators/templates/initializer.rb +15 -0
  10. data/lib/link_thumbnailer.rb +2 -0
  11. data/lib/link_thumbnailer/configuration.rb +74 -68
  12. data/lib/link_thumbnailer/exceptions.rb +3 -0
  13. data/lib/link_thumbnailer/grader.rb +2 -0
  14. data/lib/link_thumbnailer/graders/base.rb +2 -0
  15. data/lib/link_thumbnailer/graders/html_attribute.rb +2 -0
  16. data/lib/link_thumbnailer/graders/length.rb +2 -0
  17. data/lib/link_thumbnailer/graders/link_density.rb +2 -0
  18. data/lib/link_thumbnailer/graders/position.rb +2 -0
  19. data/lib/link_thumbnailer/image_comparator.rb +2 -0
  20. data/lib/link_thumbnailer/image_comparators/base.rb +2 -0
  21. data/lib/link_thumbnailer/image_comparators/size.rb +2 -0
  22. data/lib/link_thumbnailer/image_parser.rb +13 -1
  23. data/lib/link_thumbnailer/image_validator.rb +2 -0
  24. data/lib/link_thumbnailer/model.rb +20 -17
  25. data/lib/link_thumbnailer/models/description.rb +2 -0
  26. data/lib/link_thumbnailer/models/favicon.rb +2 -0
  27. data/lib/link_thumbnailer/models/image.rb +56 -54
  28. data/lib/link_thumbnailer/models/title.rb +2 -0
  29. data/lib/link_thumbnailer/models/video.rb +2 -0
  30. data/lib/link_thumbnailer/models/website.rb +54 -52
  31. data/lib/link_thumbnailer/page.rb +4 -1
  32. data/lib/link_thumbnailer/parser.rb +3 -1
  33. data/lib/link_thumbnailer/processor.rb +38 -5
  34. data/lib/link_thumbnailer/railtie.rb +2 -0
  35. data/lib/link_thumbnailer/response.rb +39 -0
  36. data/lib/link_thumbnailer/scraper.rb +62 -60
  37. data/lib/link_thumbnailer/scrapers/base.rb +69 -67
  38. data/lib/link_thumbnailer/scrapers/default/base.rb +2 -0
  39. data/lib/link_thumbnailer/scrapers/default/description.rb +2 -0
  40. data/lib/link_thumbnailer/scrapers/default/favicon.rb +16 -2
  41. data/lib/link_thumbnailer/scrapers/default/images.rb +5 -1
  42. data/lib/link_thumbnailer/scrapers/default/title.rb +2 -0
  43. data/lib/link_thumbnailer/scrapers/default/videos.rb +2 -0
  44. data/lib/link_thumbnailer/scrapers/opengraph/base.rb +2 -0
  45. data/lib/link_thumbnailer/scrapers/opengraph/description.rb +2 -0
  46. data/lib/link_thumbnailer/scrapers/opengraph/favicon.rb +2 -0
  47. data/lib/link_thumbnailer/scrapers/opengraph/image.rb +7 -1
  48. data/lib/link_thumbnailer/scrapers/opengraph/images.rb +2 -0
  49. data/lib/link_thumbnailer/scrapers/opengraph/title.rb +2 -0
  50. data/lib/link_thumbnailer/scrapers/opengraph/video.rb +2 -0
  51. data/lib/link_thumbnailer/scrapers/opengraph/videos.rb +2 -0
  52. data/lib/link_thumbnailer/uri.rb +20 -0
  53. data/lib/link_thumbnailer/version.rb +3 -1
  54. data/lib/link_thumbnailer/video_parser.rb +3 -1
  55. data/link_thumbnailer.gemspec +8 -6
  56. data/spec/configuration_spec.rb +4 -2
  57. data/spec/fixture_spec.rb +21 -0
  58. data/spec/fixtures/default_with_few_favicons.html +15 -0
  59. data/spec/fixtures/google_shift_jis.html +6 -0
  60. data/spec/fixtures/google_utf8.html +6 -0
  61. data/spec/fixtures/google_utf8_no_meta_charset.html +6 -0
  62. data/spec/fixtures/with_related_path_in_href.html +13 -0
  63. data/spec/fixtures/with_root_path_in_href.html +13 -0
  64. data/spec/grader_spec.rb +3 -1
  65. data/spec/graders/base_spec.rb +2 -0
  66. data/spec/graders/html_attribute_spec.rb +9 -7
  67. data/spec/graders/length_spec.rb +10 -6
  68. data/spec/graders/link_density_spec.rb +4 -2
  69. data/spec/graders/position_spec.rb +8 -6
  70. data/spec/image_comparators/size_spec.rb +2 -0
  71. data/spec/image_validator_spec.rb +3 -1
  72. data/spec/model_spec.rb +2 -0
  73. data/spec/models/description_spec.rb +3 -1
  74. data/spec/models/favicon_spec.rb +2 -0
  75. data/spec/models/image_spec.rb +6 -4
  76. data/spec/models/title_spec.rb +2 -0
  77. data/spec/models/video_spec.rb +7 -5
  78. data/spec/models/website_spec.rb +5 -3
  79. data/spec/page_spec.rb +2 -0
  80. data/spec/processor_spec.rb +74 -23
  81. data/spec/response_spec.rb +84 -0
  82. data/spec/scraper_spec.rb +6 -4
  83. data/spec/scrapers/base_spec.rb +6 -4
  84. data/spec/scrapers/opengraph/base_spec.rb +8 -6
  85. data/spec/spec_helper.rb +2 -0
  86. data/spec/uri_spec.rb +44 -0
  87. data/spec/video_parser_spec.rb +15 -13
  88. metadata +37 -19
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe LinkThumbnailer::Graders::LinkDensity do
@@ -10,8 +12,8 @@ describe LinkThumbnailer::Graders::LinkDensity do
10
12
  let(:action) { instance.call }
11
13
 
12
14
  before do
13
- instance.stub(:text).and_return(text)
14
- instance.stub(:links).and_return(links)
15
+ allow(instance).to receive(:text).and_return(text)
16
+ allow(instance).to receive(:links).and_return(links)
15
17
  end
16
18
 
17
19
  context 'when text length is 0' do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe LinkThumbnailer::Graders::Position do
@@ -12,8 +14,8 @@ describe LinkThumbnailer::Graders::Position do
12
14
  context 'when position is 0' do
13
15
 
14
16
  before do
15
- description.stub(:position).and_return(0)
16
- description.stub(:candidates_number).and_return(1)
17
+ allow(description).to receive(:position).and_return(0)
18
+ allow(description).to receive(:candidates_number).and_return(1)
17
19
  end
18
20
 
19
21
  it { expect(action).to eq(1.0) }
@@ -23,8 +25,8 @@ describe LinkThumbnailer::Graders::Position do
23
25
  context 'when position is 1 over 1 candidates' do
24
26
 
25
27
  before do
26
- description.stub(:position).and_return(1)
27
- description.stub(:candidates_number).and_return(1)
28
+ allow(description).to receive(:position).and_return(1)
29
+ allow(description).to receive(:candidates_number).and_return(1)
28
30
  end
29
31
 
30
32
  it { expect(action).to eq(0.0) }
@@ -34,8 +36,8 @@ describe LinkThumbnailer::Graders::Position do
34
36
  context 'when position is 1 over more than 1 candidates' do
35
37
 
36
38
  before do
37
- description.stub(:position).and_return(1)
38
- description.stub(:candidates_number).and_return(2)
39
+ allow(description).to receive(:position).and_return(1)
40
+ allow(description).to receive(:candidates_number).and_return(2)
39
41
  end
40
42
 
41
43
  it { expect(action).to eq(0.5) }
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe LinkThumbnailer::ImageComparators::Size do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe LinkThumbnailer::ImageValidator do
@@ -11,7 +13,7 @@ describe LinkThumbnailer::ImageValidator do
11
13
  let(:action) { instance.call }
12
14
 
13
15
  before do
14
- instance.stub(:blacklist_urls).and_return(blacklist_urls)
16
+ allow(instance).to receive(:blacklist_urls).and_return(blacklist_urls)
15
17
  end
16
18
 
17
19
  context 'when image url is blacklisted' do
@@ -1,4 +1,6 @@
1
1
  # -*- encoding : utf-8 -*-
2
+ # frozen_string_literal: true
3
+
2
4
  require 'spec_helper'
3
5
 
4
6
  describe LinkThumbnailer::Model do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe LinkThumbnailer::Models::Description do
@@ -8,7 +10,7 @@ describe LinkThumbnailer::Models::Description do
8
10
  let(:instance) { described_class.new(node, text) }
9
11
 
10
12
  before do
11
- ::LinkThumbnailer::Grader.should_receive(:new).at_least(1).and_return(grader)
13
+ expect(LinkThumbnailer::Grader).to receive(:new).at_least(1).times.and_return(grader)
12
14
  end
13
15
 
14
16
  describe '#to_s' do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe LinkThumbnailer::Models::Favicon do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe LinkThumbnailer::Models::Image do
@@ -23,7 +25,7 @@ describe LinkThumbnailer::Models::Image do
23
25
  let(:action) { instance <=> other }
24
26
 
25
27
  before do
26
- instance.stub(:size).and_return([20, 20])
28
+ allow(instance).to receive(:size).and_return([20, 20])
27
29
  end
28
30
 
29
31
  context 'when other has a smaller image' do
@@ -58,7 +60,7 @@ describe LinkThumbnailer::Models::Image do
58
60
  let(:action) { instance.valid? }
59
61
 
60
62
  before do
61
- instance.stub(:validator).and_return(validator)
63
+ allow(instance).to receive(:validator).and_return(validator)
62
64
  end
63
65
 
64
66
  it 'calls validator public method' do
@@ -82,8 +84,8 @@ describe LinkThumbnailer::Models::Image do
82
84
  }
83
85
 
84
86
  before do
85
- instance.stub(:size).and_return(size)
86
- instance.stub(:type).and_return(type)
87
+ allow(instance).to receive(:size).and_return(size)
88
+ allow(instance).to receive(:type).and_return(type)
87
89
  end
88
90
 
89
91
  it { expect(action).to eq(result) }
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe LinkThumbnailer::Models::Title do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe LinkThumbnailer::Models::Video do
@@ -33,11 +35,11 @@ describe LinkThumbnailer::Models::Video do
33
35
  }
34
36
 
35
37
  before do
36
- instance.stub(:id).and_return(id)
37
- instance.stub(:size).and_return(size)
38
- instance.stub(:duration).and_return(duration)
39
- instance.stub(:provider).and_return(provider)
40
- instance.stub(:embed_code).and_return(embed_code)
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)
41
43
  end
42
44
 
43
45
  it { expect(action).to eq(result) }
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe LinkThumbnailer::Models::Website do
@@ -12,7 +14,7 @@ describe LinkThumbnailer::Models::Website do
12
14
  let(:action) { instance.image = image }
13
15
 
14
16
  before do
15
- image.stub(:valid?).and_return(true)
17
+ allow(image).to receive(:valid?).and_return(true)
16
18
  end
17
19
 
18
20
  it { expect { action }.to change { instance.images.size }.by(1) }
@@ -27,7 +29,7 @@ describe LinkThumbnailer::Models::Website do
27
29
  context 'when image is valid' do
28
30
 
29
31
  before do
30
- image.stub(:valid?).and_return(true)
32
+ allow(image).to receive(:valid?).and_return(true)
31
33
  end
32
34
 
33
35
  it { expect { action }.to change { instance.images.size }.by(1) }
@@ -37,7 +39,7 @@ describe LinkThumbnailer::Models::Website do
37
39
  context 'when image is not valid' do
38
40
 
39
41
  before do
40
- image.stub(:valid?).and_return(false)
42
+ allow(image).to receive(:valid?).and_return(false)
41
43
  end
42
44
 
43
45
  it { expect { action }.to_not change { instance.images.size } }
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe LinkThumbnailer::Page do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe LinkThumbnailer::Processor do
@@ -5,14 +7,14 @@ describe LinkThumbnailer::Processor do
5
7
  let(:page) { ::LinkThumbnailer::Page.new(url, {}) }
6
8
  let(:instance) { described_class.new }
7
9
  let(:url) { 'http://foo.com' }
8
-
9
10
  before do
10
- LinkThumbnailer.stub(:page).and_return(page)
11
+ allow(LinkThumbnailer).to receive(:page).and_return(page)
11
12
  end
12
13
 
13
14
  describe '#call' do
14
15
 
15
16
  let(:action) { instance.call(url) }
17
+ let(:https_action) { instance.call(https_url) }
16
18
 
17
19
  context 'when redirect_count is greater than config' do
18
20
 
@@ -42,6 +44,16 @@ describe LinkThumbnailer::Processor do
42
44
 
43
45
  end
44
46
 
47
+ context 'on http unauthorized error' do
48
+
49
+ before do
50
+ stub_request(:get, url).to_return(status: 401, body: '', headers: {})
51
+ end
52
+
53
+ it { expect { action }.to raise_error(LinkThumbnailer::HTTPError) }
54
+
55
+ end
56
+
45
57
  context 'on http redirection' do
46
58
 
47
59
  let(:body) { 'foo' }
@@ -81,7 +93,7 @@ describe LinkThumbnailer::Processor do
81
93
  context 'when valid' do
82
94
 
83
95
  before do
84
- instance.stub(:valid_url_format?).and_return(true)
96
+ allow(instance).to receive(:valid_url_format?).and_return(true)
85
97
  end
86
98
 
87
99
  it 'yields' do
@@ -94,7 +106,7 @@ describe LinkThumbnailer::Processor do
94
106
  context 'when not valid' do
95
107
 
96
108
  before do
97
- instance.stub(:valid_url_format?).and_return(false)
109
+ allow(instance).to receive(:valid_url_format?).and_return(false)
98
110
  end
99
111
 
100
112
  it { expect { instance.send(:with_valid_url) }.to raise_error(LinkThumbnailer::BadUriFormat) }
@@ -106,11 +118,11 @@ describe LinkThumbnailer::Processor do
106
118
  describe '#set_http_headers' do
107
119
 
108
120
  let(:user_agent) { 'foo' }
109
- let(:headers) { instance.send(:http).headers }
121
+ let(:headers) { instance.send(:http).override_headers }
110
122
  let(:action) { instance.send(:set_http_headers) }
111
123
 
112
124
  before do
113
- instance.stub(:user_agent).and_return(user_agent)
125
+ allow(instance).to receive(:user_agent).and_return(user_agent)
114
126
  action
115
127
  end
116
128
 
@@ -128,7 +140,7 @@ describe LinkThumbnailer::Processor do
128
140
  context 'when verify_ssl is true' do
129
141
 
130
142
  before do
131
- instance.stub(:ssl_required?).and_return(true)
143
+ allow(instance).to receive(:ssl_required?).and_return(true)
132
144
  action
133
145
  end
134
146
 
@@ -139,7 +151,7 @@ describe LinkThumbnailer::Processor do
139
151
  context 'when verify_ssl is not true' do
140
152
 
141
153
  before do
142
- instance.stub(:ssl_required?).and_return(false)
154
+ allow(instance).to receive(:ssl_required?).and_return(false)
143
155
  action
144
156
  end
145
157
 
@@ -154,7 +166,7 @@ describe LinkThumbnailer::Processor do
154
166
  let(:http_open_timeout) { 1 }
155
167
 
156
168
  before do
157
- instance.stub(:http_open_timeout).and_return(http_open_timeout)
169
+ allow(instance).to receive(:http_open_timeout).and_return(http_open_timeout)
158
170
  action
159
171
  end
160
172
 
@@ -167,7 +179,7 @@ describe LinkThumbnailer::Processor do
167
179
  let(:http_read_timeout) { 1 }
168
180
 
169
181
  before do
170
- instance.stub(:http_read_timeout).and_return(http_read_timeout)
182
+ allow(instance).to receive(:http_read_timeout).and_return(http_read_timeout)
171
183
  action
172
184
  end
173
185
 
@@ -179,9 +191,11 @@ describe LinkThumbnailer::Processor do
179
191
  describe '#perform_request' do
180
192
 
181
193
  let(:action) { instance.send(:perform_request) }
194
+ let(:http) { double }
182
195
 
183
196
  before do
184
- instance.stub_chain(:http, :request).and_return(response)
197
+ allow(instance).to receive(:http).and_return(http)
198
+ allow(http).to receive(:request).and_return(response)
185
199
  end
186
200
 
187
201
  context 'when http success' do
@@ -191,13 +205,50 @@ describe LinkThumbnailer::Processor do
191
205
  let(:response) { ::Net::HTTPSuccess.new('', code, body) }
192
206
 
193
207
  before do
194
- response.stub(:body).and_return(body)
208
+ allow(response).to receive(:body).and_return(body)
195
209
  end
196
210
 
197
211
  it { expect(action).to eq(body) }
198
212
 
199
213
  end
200
214
 
215
+ context 'when access non-utf8 encoded website' do
216
+
217
+ let(:code) { 200 }
218
+ let(:utf8_encoded_body) { File.read(File.expand_path('fixtures/google_utf8.html', File.dirname(__FILE__))) }
219
+ let(:shift_jis_encoded_body) { File.read(File.expand_path('fixtures/google_shift_jis.html', File.dirname(__FILE__))) }
220
+ let(:response) { ::Net::HTTPSuccess.new('', code, body) }
221
+
222
+ before do
223
+ allow(response).to receive(:body).and_return(body)
224
+ end
225
+
226
+ context 'when http success with valid charset provided in Content-Type header' do
227
+
228
+ let(:body) { shift_jis_encoded_body }
229
+
230
+ before do
231
+ response['Content-Type'] = 'text/html; charset=Shift-JIS'
232
+ end
233
+
234
+ it { expect(action).to eq(shift_jis_encoded_body) }
235
+
236
+ end
237
+
238
+ context 'when http success with valid charset provided in Content-Type header' do
239
+
240
+ let(:body) { shift_jis_encoded_body }
241
+
242
+ before do
243
+ response['Content-Type'] = 'text/html; charset=Shift_JIS'
244
+ end
245
+
246
+ it { expect(action).to eq(utf8_encoded_body) }
247
+
248
+ end
249
+
250
+ end
251
+
201
252
  context 'when http redirection' do
202
253
 
203
254
  let(:code) { 200 }
@@ -206,8 +257,8 @@ describe LinkThumbnailer::Processor do
206
257
  let(:new_url) { 'http://foo.com/bar' }
207
258
 
208
259
  before do
209
- instance.stub(:redirect_count).and_return(0)
210
- instance.stub(:resolve_relative_url).and_return(new_url)
260
+ allow(instance).to receive(:redirect_count).and_return(0)
261
+ allow(instance).to receive(:resolve_relative_url).and_return(new_url)
211
262
  end
212
263
 
213
264
  it 'calls call method' do
@@ -229,7 +280,7 @@ describe LinkThumbnailer::Processor do
229
280
  let(:action) { instance.send(:build_absolute_url_for, relative_url).to_s }
230
281
 
231
282
  before do
232
- instance.stub(:url).and_return(url)
283
+ allow(instance).to receive(:url).and_return(url)
233
284
  end
234
285
 
235
286
  it { expect(action).to eq("#{scheme}://#{host}#{relative_url}") }
@@ -308,7 +359,7 @@ describe LinkThumbnailer::Processor do
308
359
  context 'when bad format' do
309
360
 
310
361
  before do
311
- instance.stub(:url).and_return("http://foo.com")
362
+ allow(instance).to receive(:url).and_return("http://foo.com")
312
363
  end
313
364
 
314
365
  it { expect(action).to be_falsey }
@@ -318,7 +369,7 @@ describe LinkThumbnailer::Processor do
318
369
  context 'when valid format' do
319
370
 
320
371
  before do
321
- instance.stub(:url).and_return(URI("http://foo.com"))
372
+ allow(instance).to receive(:url).and_return(URI("http://foo.com"))
322
373
  end
323
374
 
324
375
  it { expect(action).to be_truthy }
@@ -334,8 +385,8 @@ describe LinkThumbnailer::Processor do
334
385
  context 'when redirect count is greater than redirect limit' do
335
386
 
336
387
  before do
337
- instance.stub(:redirect_count).and_return(5)
338
- instance.stub(:redirect_limit).and_return(4)
388
+ allow(instance).to receive(:redirect_count).and_return(5)
389
+ allow(instance).to receive(:redirect_limit).and_return(4)
339
390
  end
340
391
 
341
392
  it { expect(action).to be_truthy }
@@ -345,8 +396,8 @@ describe LinkThumbnailer::Processor do
345
396
  context 'when redirect count is less than redirect limit' do
346
397
 
347
398
  before do
348
- instance.stub(:redirect_count).and_return(4)
349
- instance.stub(:redirect_limit).and_return(5)
399
+ allow(instance).to receive(:redirect_count).and_return(4)
400
+ allow(instance).to receive(:redirect_limit).and_return(5)
350
401
  end
351
402
 
352
403
  it { expect(action).to be_falsey }
@@ -356,8 +407,8 @@ describe LinkThumbnailer::Processor do
356
407
  context 'when redirect count is equal to redirect limit' do
357
408
 
358
409
  before do
359
- instance.stub(:redirect_count).and_return(5)
360
- instance.stub(:redirect_limit).and_return(5)
410
+ allow(instance).to receive(:redirect_count).and_return(5)
411
+ allow(instance).to receive(:redirect_limit).and_return(5)
361
412
  end
362
413
 
363
414
  it { expect(action).to be_falsey }
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe LinkThumbnailer::Response do
6
+ let(:url) { 'https://www.google.co.jp' }
7
+ let(:page) { ::LinkThumbnailer::Page.new(url, {}) }
8
+
9
+ let(:response) do
10
+ r = ::Net::HTTPSuccess.new('', 200, body_shift_jis)
11
+ r['Content-Type'] = 'text/html'
12
+ r.body = body_shift_jis
13
+ r.instance_variable_set(:@read, true)
14
+ r
15
+ end
16
+
17
+ let(:instance) { described_class.new(response) }
18
+
19
+ let(:body_shift_jis) do
20
+ File.read(File.expand_path('fixtures/google_shift_jis.html', File.dirname(__FILE__)))
21
+ end
22
+
23
+ let(:body_utf8) do
24
+ File.read(File.expand_path('fixtures/google_utf8.html', File.dirname(__FILE__)))
25
+ end
26
+
27
+ let(:body_utf8_no_meta_charset) do
28
+ File.read(File.expand_path('fixtures/google_utf8_no_meta_charset.html', File.dirname(__FILE__)))
29
+ end
30
+
31
+ before do
32
+ allow(LinkThumbnailer).to receive(:page).and_return(page)
33
+ end
34
+
35
+ describe '#charset' do
36
+ context 'when charset provided in content-type "Shift_JIS"' do
37
+ before do
38
+ response['Content-Type'] = 'text/html; charset=Shift_JIS'
39
+ end
40
+
41
+ it { expect(instance.charset).to eq 'Shift_JIS' }
42
+ end
43
+
44
+ context 'when charset provided in content-type "utf-8"' do
45
+ before do
46
+ response['Content-Type'] = 'text/html; charset=utf-8'
47
+ end
48
+
49
+ it { expect(instance.charset).to eq 'utf-8' }
50
+ end
51
+
52
+ context 'when no charset available in content-type and charset provided in meta tag "UTF-8"' do
53
+ before do
54
+ response.body = body_utf8
55
+ end
56
+ it { expect(instance.charset).to eq 'UTF-8' }
57
+ end
58
+
59
+ context 'when no charset available in content-type and body' do
60
+ before do
61
+ response.body = body_utf8_no_meta_charset
62
+ end
63
+ it { expect(instance.charset).to eq '' }
64
+ end
65
+ end
66
+
67
+ describe '#body' do
68
+ context 'when provide valid charset' do
69
+ before do
70
+ response['Content-Type'] = 'text/html; charset=Shift_JIS'
71
+ end
72
+
73
+ it { expect(instance.body).to eq body_utf8 }
74
+ end
75
+
76
+ context 'when provide invalid charset' do
77
+ before do
78
+ response['Content-Type'] = 'text/html; charset=Shift-JIS'
79
+ end
80
+
81
+ it { expect(instance.body).to eq body_shift_jis }
82
+ end
83
+ end
84
+ end