link_thumbnailer 1.1.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +5 -13
  2. data/.travis.yml +1 -1
  3. data/CHANGELOG.md +117 -104
  4. data/Gemfile +1 -1
  5. data/{LICENSE → LICENSE.txt} +21 -21
  6. data/README.md +153 -184
  7. data/lib/generators/link_thumbnailer/install_generator.rb +0 -4
  8. data/lib/generators/templates/initializer.rb +63 -41
  9. data/lib/link_thumbnailer/configuration.rb +52 -10
  10. data/lib/link_thumbnailer/exceptions.rb +6 -0
  11. data/lib/link_thumbnailer/grader.rb +37 -0
  12. data/lib/link_thumbnailer/graders/base.rb +32 -0
  13. data/lib/link_thumbnailer/graders/html_attribute.rb +49 -0
  14. data/lib/link_thumbnailer/graders/length.rb +19 -0
  15. data/lib/link_thumbnailer/graders/link_density.rb +21 -0
  16. data/lib/link_thumbnailer/graders/position.rb +11 -0
  17. data/lib/link_thumbnailer/image_comparator.rb +24 -0
  18. data/lib/link_thumbnailer/image_comparators/base.rb +17 -0
  19. data/lib/link_thumbnailer/image_comparators/size.rb +11 -0
  20. data/lib/link_thumbnailer/image_parser.rb +18 -0
  21. data/lib/link_thumbnailer/image_parsers/size.rb +15 -0
  22. data/lib/link_thumbnailer/image_parsers/type.rb +15 -0
  23. data/lib/link_thumbnailer/image_validator.rb +30 -0
  24. data/lib/link_thumbnailer/model.rb +16 -0
  25. data/lib/link_thumbnailer/models/description.rb +34 -0
  26. data/lib/link_thumbnailer/models/image.rb +54 -0
  27. data/lib/link_thumbnailer/models/title.rb +20 -0
  28. data/lib/link_thumbnailer/models/website.rb +39 -0
  29. data/lib/link_thumbnailer/page.rb +40 -0
  30. data/lib/link_thumbnailer/parser.rb +13 -0
  31. data/lib/link_thumbnailer/processor.rb +94 -0
  32. data/lib/link_thumbnailer/railtie.rb +9 -9
  33. data/lib/link_thumbnailer/scraper.rb +64 -0
  34. data/lib/link_thumbnailer/scrapers/base.rb +63 -0
  35. data/lib/link_thumbnailer/scrapers/default/base.rb +10 -0
  36. data/lib/link_thumbnailer/scrapers/default/description.rb +47 -0
  37. data/lib/link_thumbnailer/scrapers/default/images.rb +64 -0
  38. data/lib/link_thumbnailer/scrapers/default/title.rb +25 -0
  39. data/lib/link_thumbnailer/scrapers/opengraph/base.rb +43 -0
  40. data/lib/link_thumbnailer/scrapers/opengraph/description.rb +10 -0
  41. data/lib/link_thumbnailer/scrapers/opengraph/image.rb +30 -0
  42. data/lib/link_thumbnailer/scrapers/opengraph/images.rb +16 -0
  43. data/lib/link_thumbnailer/scrapers/opengraph/title.rb +10 -0
  44. data/lib/link_thumbnailer/version.rb +3 -3
  45. data/lib/link_thumbnailer.rb +36 -119
  46. data/link_thumbnailer.gemspec +26 -28
  47. data/spec/configuration_spec.rb +51 -0
  48. data/spec/examples/empty_og_image_example.html +9 -0
  49. data/spec/fixture_spec.rb +88 -0
  50. data/spec/fixtures/bar.png +2907 -0
  51. data/spec/fixtures/default_from_body.html +12 -0
  52. data/spec/fixtures/default_from_meta.html +11 -0
  53. data/spec/{examples → fixtures}/example.html +53 -53
  54. data/spec/fixtures/foo.png +0 -0
  55. data/spec/fixtures/og_not_valid_example.html +12 -0
  56. data/spec/fixtures/og_valid_example.html +12 -0
  57. data/spec/fixtures/og_valid_multi_image_example.html +13 -0
  58. data/spec/grader_spec.rb +24 -0
  59. data/spec/graders/base_spec.rb +12 -0
  60. data/spec/graders/html_attribute_spec.rb +48 -0
  61. data/spec/graders/length_spec.rb +81 -0
  62. data/spec/graders/link_density_spec.rb +22 -0
  63. data/spec/image_comparators/size_spec.rb +39 -0
  64. data/spec/image_parsers/size_spec.rb +34 -0
  65. data/spec/image_parsers/type_spec.rb +34 -0
  66. data/spec/image_validator_spec.rb +35 -0
  67. data/spec/model_spec.rb +17 -0
  68. data/spec/models/description_spec.rb +64 -0
  69. data/spec/models/image_spec.rb +71 -0
  70. data/spec/models/title_spec.rb +24 -0
  71. data/spec/models/website_spec.rb +49 -0
  72. data/spec/page_spec.rb +26 -0
  73. data/spec/processor_spec.rb +349 -0
  74. data/spec/scraper_spec.rb +95 -0
  75. data/spec/scrapers/base_spec.rb +67 -0
  76. data/spec/scrapers/opengraph/base_spec.rb +94 -0
  77. data/spec/spec_helper.rb +15 -13
  78. metadata +126 -120
  79. data/app/controllers/link_thumbnailer/application_controller.rb +0 -4
  80. data/app/controllers/link_thumbnailer/previews_controller.rb +0 -11
  81. data/lib/link_thumbnailer/doc.rb +0 -65
  82. data/lib/link_thumbnailer/doc_parser.rb +0 -15
  83. data/lib/link_thumbnailer/engine.rb +0 -4
  84. data/lib/link_thumbnailer/fetcher.rb +0 -34
  85. data/lib/link_thumbnailer/img_comparator.rb +0 -17
  86. data/lib/link_thumbnailer/img_parser.rb +0 -41
  87. data/lib/link_thumbnailer/img_url_filter.rb +0 -13
  88. data/lib/link_thumbnailer/object.rb +0 -41
  89. data/lib/link_thumbnailer/opengraph.rb +0 -20
  90. data/lib/link_thumbnailer/rails/routes/mapper.rb +0 -30
  91. data/lib/link_thumbnailer/rails/routes/mapping.rb +0 -33
  92. data/lib/link_thumbnailer/rails/routes.rb +0 -47
  93. data/lib/link_thumbnailer/web_image.rb +0 -19
  94. data/spec/doc_parser_spec.rb +0 -25
  95. data/spec/doc_spec.rb +0 -23
  96. data/spec/examples/empty_example.html +0 -11
  97. data/spec/examples/og_example.html +0 -12
  98. data/spec/fetcher_spec.rb +0 -97
  99. data/spec/img_comparator_spec.rb +0 -16
  100. data/spec/img_url_filter_spec.rb +0 -31
  101. data/spec/link_thumbnailer_spec.rb +0 -205
  102. data/spec/object_spec.rb +0 -130
  103. data/spec/opengraph_spec.rb +0 -7
  104. data/spec/web_image_spec.rb +0 -57
@@ -0,0 +1,12 @@
1
+ <html>
2
+ <head>
3
+ <title>Title from meta</title>
4
+ </head>
5
+ <body>
6
+
7
+ <p>Description from body</p>
8
+
9
+ <img src="http://foo.com/foo.png">
10
+
11
+ </body>
12
+ </html>
@@ -0,0 +1,11 @@
1
+ <html>
2
+ <head>
3
+ <title>Title from meta</title>
4
+ <meta content="Description from meta" name="description">
5
+ </head>
6
+ <body>
7
+
8
+ <p>Description from body</p>
9
+
10
+ </body>
11
+ </html>
@@ -2,7 +2,7 @@
2
2
  <!-- saved from url=(0019)http://www.foo.com/ -->
3
3
  <html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
4
4
  <meta charset="UTF-8">
5
- <title>Foo.com</title>
5
+ <title>Title</title>
6
6
  <link href="./example_files/style-3706572431311a3a4cf5c6f3266c9bce.css" media="all" rel="stylesheet" type="text/css">
7
7
  <link href="./example_files/belt_layout1_google-1c8ee8bd905a6121e7a7ac73b7ffb888.css" media="all" rel="stylesheet" type="text/css">
8
8
  <script src="./example_files/application-e8b3208729190cb9cc8a800ff3283fd8.js" type="text/javascript"></script>
@@ -111,9 +111,9 @@ function gadlink(ga, inner_text, visible_url){
111
111
  visible_url = visible_url.replace(/<b>/gi,'')
112
112
  visible_url = visible_url.replace(/<\/b>/gi,'')
113
113
  return '<a ' +
114
- 'href="http://' + visible_url + '"' +
114
+ 'href="http://' + visible_url + '"' +
115
115
  ' onclick="window.open(\'' + ga.url + '\');return false;"' +
116
- ' target="_blank" ' +
116
+ ' target="_blank" ' +
117
117
  '>' +
118
118
  inner_text + '</a>';
119
119
 
@@ -138,7 +138,7 @@ function google_afd_ad_request_done(google_afd_response) {
138
138
  ads="";
139
139
  ads +=
140
140
  '<div class="listing"><div class="url">' +
141
- gadlink(google_ads[i], google_ads[i].line1, google_ads[i].visible_url) +
141
+ gadlink(google_ads[i], google_ads[i].line1, google_ads[i].visible_url) +
142
142
  '</div>';
143
143
  if (seller_ratings) {
144
144
  ads += '<div class="ratings">'+seller_ratings.advertiser_info+' <img src="/assets/'+seller_ratings.rating+'star.gif" border="0"> <a href="'+seller_ratings.source_url+'" target="_blank">('+seller_ratings.review_count+')</a></div>';
@@ -147,7 +147,7 @@ function google_afd_ad_request_done(google_afd_response) {
147
147
  '<div class="description">' + google_ads[i].line2 + ' ' +
148
148
  (google_ads[i].line3 != undefined ? google_ads[i].line3 + '' : '') +
149
149
  '</div>' +
150
- '<div class="host">' +
150
+ '<div class="host">' +
151
151
  gadlink(google_ads[i], google_ads[i].visible_url, google_ads[i].visible_url) +
152
152
  '</div>';
153
153
  if (site_links && site_links.length > 0) {
@@ -156,8 +156,8 @@ function google_afd_ad_request_done(google_afd_response) {
156
156
  if(x % 2 == 0){
157
157
  ads += '<tr>';
158
158
  }
159
- ads +=
160
- '<td class="sitelink">' +
159
+ ads +=
160
+ '<td class="sitelink">' +
161
161
  gadlink(site_links[x], site_links[x].link_text, google_ads[i].visible_url) +
162
162
  '</td>';
163
163
  if(x % 2 == 1){
@@ -183,26 +183,26 @@ function google_afd_ad_request_done(google_afd_response) {
183
183
  var google_categories = google_afd_response.categories;
184
184
  for (var i = 0; i < google_categories.length; i++) {
185
185
  subcats = google_categories[i].subcategories;
186
- popularCategories =
187
- '<div class="termgroup">' +
188
- '<h3><a class="popular_category" ' +
189
- 'href="/#' + google_categories[i].term + '"' +
186
+ popularCategories =
187
+ '<div class="termgroup">' +
188
+ '<h3><a class="popular_category" ' +
189
+ 'href="/#' + google_categories[i].term + '"' +
190
190
  ' onclick="window.location=\'/results' +
191
191
  '?q=' + encodeURIComponent(google_categories[i].term) +
192
192
  '&token=' + google_categories[i].token + '\';return false;"' +
193
- '>' +
194
- google_categories[i].term +
193
+ '>' +
194
+ google_categories[i].term +
195
195
  '</a></h3>';
196
196
  for(var gci =0; gci < subcats.length; gci++){
197
197
  popularCategories = popularCategories +
198
- '<div class="term">' +
199
- '<a class="popular_category" ' +
200
- 'href="/#' + subcats[gci].term + '"' +
198
+ '<div class="term">' +
199
+ '<a class="popular_category" ' +
200
+ 'href="/#' + subcats[gci].term + '"' +
201
201
  ' onclick="window.location=\'/results' +
202
202
  '?q=' + encodeURIComponent(subcats[gci].term) +
203
203
  '&token=' + subcats[gci].token + '\';return false;"' +
204
- '>' +
205
- subcats[gci].term +
204
+ '>' +
205
+ subcats[gci].term +
206
206
  '</a></div>';
207
207
  }
208
208
  popularCategories = popularCategories + '</div>';
@@ -214,58 +214,58 @@ function google_afd_ad_request_done(google_afd_response) {
214
214
  var google_link_units = google_afd_response.link_units;
215
215
  for (var i = 0; i < google_link_units.length; i++) {
216
216
  relatedSearches =
217
- '<div class="term">' +
218
- '<a class="related_searches" ' +
219
- 'href="/#' + google_link_units[i].term + '"' +
217
+ '<div class="term">' +
218
+ '<a class="related_searches" ' +
219
+ 'href="/#' + google_link_units[i].term + '"' +
220
220
  ' onclick="window.location=\'/results' +
221
221
  '?q=' + encodeURIComponent(google_link_units[i].term) +
222
222
  '&token=' + google_link_units[i].token + '\';return false;"' +
223
223
  '>' +
224
- google_link_units[i].term +
225
- '</a>' +
224
+ google_link_units[i].term +
225
+ '</a>' +
226
226
  '</div>';
227
227
  relatedSearches_array.push(relatedSearches);
228
228
  }
229
-
229
+
230
230
  }
231
231
  if (google_afd_response.link_units && google_afd_response.link_units.length > 0) {
232
- var google_link_units = google_afd_response.link_units;
233
- for (var i = 0; i < google_link_units.length; i++) {
234
- relatedSearches = "";
235
- if(i % 5 == 0){
236
- relatedSearches += "<div class='termgroup'>";
237
- }
238
- relatedSearches +=
239
- '<div class="term">' +
240
- '<a class="related_searches" ' +
241
- 'href="/#' + google_link_units[i].term + '"' +
242
- ' onclick="window.location=\'/results' +
243
- '?q=' + encodeURIComponent(google_link_units[i].term) +
244
- '&token=' + google_link_units[i].token + '\';return false;"' +
245
- '>' +
246
- google_link_units[i].term +
247
- '</a>' +
248
- '</div>';
232
+ var google_link_units = google_afd_response.link_units;
233
+ for (var i = 0; i < google_link_units.length; i++) {
234
+ relatedSearches = "";
235
+ if(i % 5 == 0){
236
+ relatedSearches += "<div class='termgroup'>";
237
+ }
238
+ relatedSearches +=
239
+ '<div class="term">' +
240
+ '<a class="related_searches" ' +
241
+ 'href="/#' + google_link_units[i].term + '"' +
242
+ ' onclick="window.location=\'/results' +
243
+ '?q=' + encodeURIComponent(google_link_units[i].term) +
244
+ '&token=' + google_link_units[i].token + '\';return false;"' +
245
+ '>' +
246
+ google_link_units[i].term +
247
+ '</a>' +
248
+ '</div>';
249
249
  if(((i % 5) == 4) || ((i-1)==google_link_units.length)){
250
- relatedSearches += "</div>";
251
- }
252
- if(((i+1) % 10 == 0)){
253
- relatedSearches += "<div class='clear'>&nbsp;</div>";
254
- }
255
- genCatSearches_array.push(relatedSearches);
256
- }
257
-
250
+ relatedSearches += "</div>";
251
+ }
252
+ if(((i+1) % 10 == 0)){
253
+ relatedSearches += "<div class='clear'>&nbsp;</div>";
254
+ }
255
+ genCatSearches_array.push(relatedSearches);
256
+ }
257
+
258
258
  }
259
259
  try{document.getElementById('results').innerHTML = ads_array.join("\n");}catch(error){}
260
260
  try{document.getElementById('bottomresults').innerHTML = bottom_ads_array.join("\n");}catch(error){}
261
-
261
+
262
262
  if(ads_array.length>1){
263
263
  document.getElementById('sponsoredresults').style.display='block';
264
264
  }
265
265
  if(bottom_ads_array.length>1){
266
266
  document.getElementById('bottomsponsoredresults').style.display='block';
267
267
  }
268
-
268
+
269
269
  try{document.getElementById('keywords').innerHTML = relatedSearches_array.join("\n");}catch(error){}
270
270
  try{document.getElementById('gencats').innerHTML = genCatSearches_array.join("\n");}catch(error){}
271
271
  // if(genCatSearches_array.length==0){
@@ -325,7 +325,7 @@ function getParam(name) {
325
325
 
326
326
  <div id="footer">
327
327
  <a href="http://www.foo.com/digimedia_privacy_policy.html" target="_blank">Privacy Policy</a>
328
- -
328
+ -
329
329
  © 2012 Digimedia.com, L.P.
330
330
  </div>
331
331
 
@@ -360,4 +360,4 @@ channel: 'afsonly'
360
360
 
361
361
 
362
362
 
363
- </body></html>
363
+ </body></html>
Binary file
@@ -0,0 +1,12 @@
1
+ <html xmlns:og="http://opengraphprotocol.org/schema/">
2
+ <head>
3
+ <meta charset="utf-8"/>
4
+ <meta name="og:type" content="website"/>
5
+ <meta name="og:site_name" content="foo.com">
6
+ <meta name="og:title" content="Title from og">
7
+ <meta name="og:description" content="Description from og">
8
+ <meta name="og:image" content="http://foo.com/foo.png">
9
+ <title>Title</title>
10
+ </head>
11
+
12
+ </html>
@@ -0,0 +1,12 @@
1
+ <html xmlns:og="http://opengraphprotocol.org/schema/">
2
+ <head>
3
+ <meta charset="utf-8"/>
4
+ <meta property="og:type" content="website"/>
5
+ <meta property="og:site_name" content="foo.com">
6
+ <meta property="og:title" content="Title from og">
7
+ <meta property="og:description" content="Description from og">
8
+ <meta property="og:image" content="http://foo.com/foo.png">
9
+ <title>Title</title>
10
+ </head>
11
+
12
+ </html>
@@ -0,0 +1,13 @@
1
+ <html xmlns:og="http://opengraphprotocol.org/schema/">
2
+ <head>
3
+ <meta charset="utf-8"/>
4
+ <meta property="og:type" content="website"/>
5
+ <meta property="og:site_name" content="foo.com">
6
+ <meta property="og:title" content="Title from og">
7
+ <meta property="og:description" content="Description from og">
8
+ <meta property="og:image" content="http://foo.com/foo.png">
9
+ <meta property="og:image" content="http://foo.com/bar.png">
10
+ <title>Title</title>
11
+ </head>
12
+
13
+ </html>
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe LinkThumbnailer::Grader do
4
+
5
+ let(:description) { double('description') }
6
+ let(:instance) { described_class.new(description) }
7
+
8
+ describe '#call' do
9
+
10
+ let(:score) { 10 }
11
+ let(:grader) { double('grader', call: score) }
12
+ let(:lambda) { ->(_) { grader } }
13
+ let(:graders) { [lambda, lambda] }
14
+ let(:action) { instance.call }
15
+
16
+ before do
17
+ instance.stub(:graders).and_return(graders)
18
+ end
19
+
20
+ it { expect(action).to eq(score * graders.size) }
21
+
22
+ end
23
+
24
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe LinkThumbnailer::Graders::Base do
4
+
5
+ let(:description) { double('description', node: node) }
6
+ let(:node) { double('node', text: 'foo') }
7
+ let(:instance) { described_class.new(description) }
8
+
9
+ it { expect(instance.send(:node)).to eq(description.node) }
10
+ it { expect(instance.send(:text)).to eq(description.node.text) }
11
+
12
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe LinkThumbnailer::Graders::HtmlAttribute do
4
+
5
+ let(:description) { double('description') }
6
+ let(:instance) { described_class.new(description, :class) }
7
+
8
+ describe '#call' do
9
+
10
+ let(:action) { instance.call(0) }
11
+
12
+ context 'when current node does not match attribute' do
13
+
14
+ before do
15
+ instance.stub(:attribute?).and_return(false)
16
+ end
17
+
18
+ it { expect(action).to eq(0) }
19
+
20
+ end
21
+
22
+ context 'when current node has a negative attribute' do
23
+
24
+ before do
25
+ instance.stub(:attribute?).and_return(true)
26
+ instance.stub(:negative?).and_return(true)
27
+ instance.stub(:positive?).and_return(false)
28
+ end
29
+
30
+ it { expect(action).to eq(-25) }
31
+
32
+ end
33
+
34
+ context 'when current node has a positive attribute' do
35
+
36
+ before do
37
+ instance.stub(:attribute?).and_return(true)
38
+ instance.stub(:negative?).and_return(false)
39
+ instance.stub(:positive?).and_return(true)
40
+ end
41
+
42
+ it { expect(action).to eq(25) }
43
+
44
+ end
45
+
46
+ end
47
+
48
+ end
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+
3
+ describe LinkThumbnailer::Graders::Length do
4
+
5
+ let(:config) { double('config') }
6
+ let(:description) { double('description') }
7
+ let(:instance) { described_class.new(description) }
8
+
9
+ before do
10
+ instance.stub(:config).and_return(config)
11
+ end
12
+
13
+ describe '#call' do
14
+
15
+ let(:action) { instance.call(0) }
16
+
17
+ context 'when text is too short' do
18
+
19
+ before do
20
+ instance.stub(:too_short?).and_return(true)
21
+ end
22
+
23
+ it { expect(action).to eq(-Float::INFINITY) }
24
+
25
+ end
26
+
27
+ context 'when text is not too short' do
28
+
29
+ before do
30
+ instance.stub(:too_short?).and_return(false)
31
+ instance.stub(:text).and_return(text)
32
+ end
33
+
34
+ context 'when text length is greater than 400' do
35
+
36
+ let(:text) { 'f' * 400 }
37
+
38
+ it { expect(action).to eq(3) }
39
+
40
+ end
41
+
42
+ context 'when text length is less than 300' do
43
+
44
+ let(:text) { 'f' * 299 }
45
+
46
+ it { expect(action).to eq(2) }
47
+
48
+ end
49
+
50
+ end
51
+
52
+ end
53
+
54
+ describe '#too_short?' do
55
+
56
+ let(:action) { instance.send(:too_short?) }
57
+
58
+ before do
59
+ instance.stub_chain(:config, :description_min_length).and_return(10)
60
+ instance.stub(:text).and_return(text)
61
+ end
62
+
63
+ context 'when true' do
64
+
65
+ let(:text) { 'f' * 9 }
66
+
67
+ it { expect(action).to be_true }
68
+
69
+ end
70
+
71
+ context 'when false' do
72
+
73
+ let(:text) { 'f' * 10 }
74
+
75
+ it { expect(action).to be_false }
76
+
77
+ end
78
+
79
+ end
80
+
81
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe LinkThumbnailer::Graders::LinkDensity do
4
+
5
+ let(:description) { double('description') }
6
+ let(:instance) { described_class.new(description) }
7
+
8
+ describe '#call' do
9
+
10
+ let(:previous_score) { 1 }
11
+ let(:density) { 10 }
12
+ let(:action) { instance.call(previous_score) }
13
+
14
+ before do
15
+ instance.stub(:density).and_return(density)
16
+ end
17
+
18
+ it { expect(action).to eq(-9) }
19
+
20
+ end
21
+
22
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe LinkThumbnailer::ImageComparators::Size do
4
+
5
+ let(:image) { double(size: [20, 20]) }
6
+ let(:instance) { described_class.new(image) }
7
+
8
+ describe '#call' do
9
+
10
+ let(:other) { double(size: other_size) }
11
+ let(:action) { instance.call(other) }
12
+
13
+ context 'when other has a better image' do
14
+
15
+ let(:other_size) { [10, 10] }
16
+
17
+ it { expect(action).to eq(-1) }
18
+
19
+ end
20
+
21
+ context 'when other has an identical image' do
22
+
23
+ let(:other_size) { [20, 20] }
24
+
25
+ it { expect(action).to eq(0) }
26
+
27
+ end
28
+
29
+ context 'when other has a weaker image' do
30
+
31
+ let(:other_size) { [30, 30] }
32
+
33
+ it { expect(action).to eq(1) }
34
+
35
+ end
36
+
37
+ end
38
+
39
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe LinkThumbnailer::ImageParsers::Size do
4
+
5
+ describe '.perform' do
6
+
7
+ let(:size) { [10, 10] }
8
+ let(:src) { 'http://foo.com' }
9
+ let(:image) { double(src: src) }
10
+ let(:action) { described_class.perform(image) }
11
+
12
+ context 'when no exception is raised' do
13
+
14
+ before do
15
+ expect(FastImage).to receive(:size).with(src, raise_on_failure: true).and_return(size)
16
+ end
17
+
18
+ it { expect(action).to eq(size) }
19
+
20
+ end
21
+
22
+ context 'when an exception is raised' do
23
+
24
+ before do
25
+ expect(FastImage).to receive(:size).with(src, raise_on_failure: true).and_raise(FastImage::FastImageException)
26
+ end
27
+
28
+ it { expect(action).to eq([0, 0]) }
29
+
30
+ end
31
+
32
+ end
33
+
34
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe LinkThumbnailer::ImageParsers::Type do
4
+
5
+ describe '.perform' do
6
+
7
+ let(:type) { 'png' }
8
+ let(:src) { 'http://foo.com' }
9
+ let(:image) { double(src: src) }
10
+ let(:action) { described_class.perform(image) }
11
+
12
+ context 'when no exception is raised' do
13
+
14
+ before do
15
+ expect(FastImage).to receive(:type).with(src, raise_on_failure: true).and_return(type)
16
+ end
17
+
18
+ it { expect(action).to eq(type) }
19
+
20
+ end
21
+
22
+ context 'when an exception is raised' do
23
+
24
+ before do
25
+ expect(FastImage).to receive(:type).with(src, raise_on_failure: true).and_raise(FastImage::FastImageException)
26
+ end
27
+
28
+ it { expect(action).to eq(:jpg) }
29
+
30
+ end
31
+
32
+ end
33
+
34
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe LinkThumbnailer::ImageValidator do
4
+
5
+ let(:src) { 'http://foo.com' }
6
+ let(:image) { double(src: src) }
7
+ let(:instance) { described_class.new(image) }
8
+
9
+ describe '#call' do
10
+
11
+ let(:action) { instance.call }
12
+
13
+ before do
14
+ instance.stub(:blacklist_urls).and_return(blacklist_urls)
15
+ end
16
+
17
+ context 'when image url is blacklisted' do
18
+
19
+ let(:blacklist_urls) { [src] }
20
+
21
+ it { expect(action).to be_false }
22
+
23
+ end
24
+
25
+ context 'when image url is not blacklisted' do
26
+
27
+ let(:blacklist_urls) { [] }
28
+
29
+ it { expect(action).to be_true }
30
+
31
+ end
32
+
33
+ end
34
+
35
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe LinkThumbnailer::Model do
4
+
5
+ let(:instance) { described_class.new }
6
+
7
+ describe '#sanitize' do
8
+
9
+ let(:str) { "foo\r\n" }
10
+ let(:result) { "foo" }
11
+ let(:action) { instance.send(:sanitize, str) }
12
+
13
+ it { expect(action).to eq(result) }
14
+
15
+ end
16
+
17
+ end