link_thumbnailer 1.1.2 → 2.0.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 (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