]> git.immae.eu Git - github/wallabag/wallabag.git/blame - tests/Wallabag/CoreBundle/Helper/ContentProxyTest.php
Merge pull request #3258 from wallabag/cs-fixer
[github/wallabag/wallabag.git] / tests / Wallabag / CoreBundle / Helper / ContentProxyTest.php
CommitLineData
558d9aab
JB
1<?php
2
a2c1b94e 3namespace Tests\Wallabag\CoreBundle\Helper;
558d9aab 4
f808b016 5use Graby\Graby;
d5c2cc54 6use Monolog\Handler\TestHandler;
f808b016
JB
7use Monolog\Logger;
8use Psr\Log\NullLogger;
9use Symfony\Component\Validator\ConstraintViolation;
10use Symfony\Component\Validator\ConstraintViolationList;
11use Symfony\Component\Validator\Validator\RecursiveValidator;
c2656f96
JB
12use Wallabag\CoreBundle\Entity\Entry;
13use Wallabag\CoreBundle\Entity\Tag;
f808b016 14use Wallabag\CoreBundle\Helper\ContentProxy;
6bc6fb1f 15use Wallabag\CoreBundle\Helper\RuleBasedTagger;
f808b016 16use Wallabag\UserBundle\Entity\User;
558d9aab 17
a2c1b94e 18class ContentProxyTest extends \PHPUnit_Framework_TestCase
558d9aab 19{
ac1509a6 20 private $fetchingErrorMessage = 'wallabag can\'t retrieve contents for this article. Please <a href="http://doc.wallabag.org/en/user/errors_during_fetching.html#how-can-i-help-to-fix-that">troubleshoot this issue</a>.';
a2c1b94e 21
4d0ec0e7
JB
22 public function testWithBadUrl()
23 {
24 $tagger = $this->getTaggerMock();
25 $tagger->expects($this->once())
26 ->method('tag');
27
28 $graby = $this->getMockBuilder('Graby\Graby')
4094ea47 29 ->setMethods(['fetchContent'])
4d0ec0e7
JB
30 ->disableOriginalConstructor()
31 ->getMock();
32
33 $graby->expects($this->any())
34 ->method('fetchContent')
4094ea47 35 ->willReturn([
4d0ec0e7
JB
36 'html' => false,
37 'title' => '',
38 'url' => '',
39 'content_type' => '',
40 'language' => '',
4094ea47 41 ]);
4d0ec0e7 42
0d349ea6 43 $proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
7aba665e
JC
44 $entry = new Entry(new User());
45 $proxy->updateEntry($entry, 'http://user@:80');
4d0ec0e7 46
f808b016 47 $this->assertSame('http://user@:80', $entry->getUrl());
4d0ec0e7 48 $this->assertEmpty($entry->getTitle());
f808b016 49 $this->assertSame($this->fetchingErrorMessage, $entry->getContent());
4d0ec0e7
JB
50 $this->assertEmpty($entry->getPreviewPicture());
51 $this->assertEmpty($entry->getMimetype());
52 $this->assertEmpty($entry->getLanguage());
f808b016 53 $this->assertSame(0.0, $entry->getReadingTime());
38520658 54 $this->assertSame(null, $entry->getDomainName());
4d0ec0e7
JB
55 }
56
558d9aab
JB
57 public function testWithEmptyContent()
58 {
f530f7f5
KG
59 $tagger = $this->getTaggerMock();
60 $tagger->expects($this->once())
61 ->method('tag');
62
558d9aab 63 $graby = $this->getMockBuilder('Graby\Graby')
4094ea47 64 ->setMethods(['fetchContent'])
558d9aab
JB
65 ->disableOriginalConstructor()
66 ->getMock();
67
68 $graby->expects($this->any())
69 ->method('fetchContent')
4094ea47 70 ->willReturn([
98f0929f
JB
71 'html' => false,
72 'title' => '',
73 'url' => '',
74 'content_type' => '',
75 'language' => '',
4094ea47 76 ]);
558d9aab 77
0d349ea6 78 $proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
7aba665e
JC
79 $entry = new Entry(new User());
80 $proxy->updateEntry($entry, 'http://0.0.0.0');
558d9aab 81
f808b016 82 $this->assertSame('http://0.0.0.0', $entry->getUrl());
558d9aab 83 $this->assertEmpty($entry->getTitle());
f808b016 84 $this->assertSame($this->fetchingErrorMessage, $entry->getContent());
558d9aab
JB
85 $this->assertEmpty($entry->getPreviewPicture());
86 $this->assertEmpty($entry->getMimetype());
98f0929f 87 $this->assertEmpty($entry->getLanguage());
f808b016
JB
88 $this->assertSame(0.0, $entry->getReadingTime());
89 $this->assertSame('0.0.0.0', $entry->getDomainName());
558d9aab
JB
90 }
91
92 public function testWithEmptyContentButOG()
93 {
f530f7f5
KG
94 $tagger = $this->getTaggerMock();
95 $tagger->expects($this->once())
96 ->method('tag');
97
558d9aab 98 $graby = $this->getMockBuilder('Graby\Graby')
4094ea47 99 ->setMethods(['fetchContent'])
558d9aab
JB
100 ->disableOriginalConstructor()
101 ->getMock();
102
103 $graby->expects($this->any())
104 ->method('fetchContent')
4094ea47 105 ->willReturn([
98f0929f
JB
106 'html' => false,
107 'title' => '',
108 'url' => '',
109 'content_type' => '',
110 'language' => '',
10b35097 111 'status' => '',
4094ea47 112 'open_graph' => [
98f0929f
JB
113 'og_title' => 'my title',
114 'og_description' => 'desc',
4094ea47
JB
115 ],
116 ]);
558d9aab 117
0d349ea6 118 $proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
7aba665e
JC
119 $entry = new Entry(new User());
120 $proxy->updateEntry($entry, 'http://domain.io');
558d9aab 121
f808b016
JB
122 $this->assertSame('http://domain.io', $entry->getUrl());
123 $this->assertSame('my title', $entry->getTitle());
124 $this->assertSame($this->fetchingErrorMessage . '<p><i>But we found a short description: </i></p>desc', $entry->getContent());
558d9aab 125 $this->assertEmpty($entry->getPreviewPicture());
98f0929f 126 $this->assertEmpty($entry->getLanguage());
10b35097 127 $this->assertEmpty($entry->getHttpStatus());
558d9aab 128 $this->assertEmpty($entry->getMimetype());
f808b016
JB
129 $this->assertSame(0.0, $entry->getReadingTime());
130 $this->assertSame('domain.io', $entry->getDomainName());
558d9aab
JB
131 }
132
133 public function testWithContent()
134 {
f530f7f5
KG
135 $tagger = $this->getTaggerMock();
136 $tagger->expects($this->once())
137 ->method('tag');
138
558d9aab 139 $graby = $this->getMockBuilder('Graby\Graby')
4094ea47 140 ->setMethods(['fetchContent'])
558d9aab
JB
141 ->disableOriginalConstructor()
142 ->getMock();
143
144 $graby->expects($this->any())
145 ->method('fetchContent')
4094ea47 146 ->willReturn([
da3d4998 147 'html' => str_repeat('this is my content', 325),
558d9aab
JB
148 'title' => 'this is my title',
149 'url' => 'http://1.1.1.1',
150 'content_type' => 'text/html',
98f0929f 151 'language' => 'fr',
10b35097 152 'status' => '200',
4094ea47 153 'open_graph' => [
558d9aab
JB
154 'og_title' => 'my OG title',
155 'og_description' => 'OG desc',
f1e29e69 156 'og_image' => 'http://3.3.3.3/cover.jpg',
4094ea47
JB
157 ],
158 ]);
558d9aab 159
0d349ea6 160 $proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
7aba665e
JC
161 $entry = new Entry(new User());
162 $proxy->updateEntry($entry, 'http://0.0.0.0');
558d9aab 163
f808b016
JB
164 $this->assertSame('http://1.1.1.1', $entry->getUrl());
165 $this->assertSame('this is my title', $entry->getTitle());
da3d4998 166 $this->assertContains('this is my content', $entry->getContent());
f808b016
JB
167 $this->assertSame('http://3.3.3.3/cover.jpg', $entry->getPreviewPicture());
168 $this->assertSame('text/html', $entry->getMimetype());
169 $this->assertSame('fr', $entry->getLanguage());
170 $this->assertSame('200', $entry->getHttpStatus());
171 $this->assertSame(4.0, $entry->getReadingTime());
172 $this->assertSame('1.1.1.1', $entry->getDomainName());
558d9aab 173 }
f530f7f5 174
3d71d403
JB
175 public function testWithContentAndNoOgImage()
176 {
177 $tagger = $this->getTaggerMock();
178 $tagger->expects($this->once())
179 ->method('tag');
180
181 $graby = $this->getMockBuilder('Graby\Graby')
182 ->setMethods(['fetchContent'])
183 ->disableOriginalConstructor()
184 ->getMock();
185
186 $graby->expects($this->any())
187 ->method('fetchContent')
188 ->willReturn([
189 'html' => str_repeat('this is my content', 325),
190 'title' => 'this is my title',
191 'url' => 'http://1.1.1.1',
192 'content_type' => 'text/html',
193 'language' => 'fr',
194 'status' => '200',
195 'open_graph' => [
196 'og_title' => 'my OG title',
197 'og_description' => 'OG desc',
0d349ea6 198 'og_image' => null,
3d71d403
JB
199 ],
200 ]);
201
0d349ea6 202 $proxy = new ContentProxy($graby, $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
d5c2cc54
JB
203 $entry = new Entry(new User());
204 $proxy->updateEntry($entry, 'http://0.0.0.0');
3d71d403 205
f808b016
JB
206 $this->assertSame('http://1.1.1.1', $entry->getUrl());
207 $this->assertSame('this is my title', $entry->getTitle());
3d71d403 208 $this->assertContains('this is my content', $entry->getContent());
41d45c61 209 $this->assertNull($entry->getPreviewPicture());
f808b016
JB
210 $this->assertSame('text/html', $entry->getMimetype());
211 $this->assertSame('fr', $entry->getLanguage());
212 $this->assertSame('200', $entry->getHttpStatus());
213 $this->assertSame(4.0, $entry->getReadingTime());
214 $this->assertSame('1.1.1.1', $entry->getDomainName());
0d349ea6
JB
215 }
216
217 public function testWithContentAndBadLanguage()
218 {
219 $tagger = $this->getTaggerMock();
220 $tagger->expects($this->once())
221 ->method('tag');
222
223 $validator = $this->getValidator();
224 $validator->expects($this->exactly(2))
225 ->method('validate')
226 ->will($this->onConsecutiveCalls(
227 new ConstraintViolationList([new ConstraintViolation('oops', 'oops', [], 'oops', 'language', 'dontexist')]),
228 new ConstraintViolationList()
229 ));
230
231 $graby = $this->getMockBuilder('Graby\Graby')
232 ->setMethods(['fetchContent'])
233 ->disableOriginalConstructor()
234 ->getMock();
235
236 $graby->expects($this->any())
237 ->method('fetchContent')
238 ->willReturn([
239 'html' => str_repeat('this is my content', 325),
240 'title' => 'this is my title',
241 'url' => 'http://1.1.1.1',
242 'content_type' => 'text/html',
243 'language' => 'dontexist',
244 'status' => '200',
245 ]);
246
247 $proxy = new ContentProxy($graby, $tagger, $validator, $this->getLogger(), $this->fetchingErrorMessage);
248 $entry = new Entry(new User());
249 $proxy->updateEntry($entry, 'http://0.0.0.0');
250
f808b016
JB
251 $this->assertSame('http://1.1.1.1', $entry->getUrl());
252 $this->assertSame('this is my title', $entry->getTitle());
0d349ea6 253 $this->assertContains('this is my content', $entry->getContent());
f808b016 254 $this->assertSame('text/html', $entry->getMimetype());
41d45c61 255 $this->assertNull($entry->getLanguage());
f808b016
JB
256 $this->assertSame('200', $entry->getHttpStatus());
257 $this->assertSame(4.0, $entry->getReadingTime());
258 $this->assertSame('1.1.1.1', $entry->getDomainName());
0d349ea6
JB
259 }
260
261 public function testWithContentAndBadOgImage()
262 {
263 $tagger = $this->getTaggerMock();
264 $tagger->expects($this->once())
265 ->method('tag');
266
267 $validator = $this->getValidator();
268 $validator->expects($this->exactly(2))
269 ->method('validate')
270 ->will($this->onConsecutiveCalls(
271 new ConstraintViolationList(),
272 new ConstraintViolationList([new ConstraintViolation('oops', 'oops', [], 'oops', 'url', 'https://')])
273 ));
274
275 $graby = $this->getMockBuilder('Graby\Graby')
276 ->setMethods(['fetchContent'])
277 ->disableOriginalConstructor()
278 ->getMock();
279
280 $graby->expects($this->any())
281 ->method('fetchContent')
282 ->willReturn([
283 'html' => str_repeat('this is my content', 325),
284 'title' => 'this is my title',
285 'url' => 'http://1.1.1.1',
286 'content_type' => 'text/html',
287 'language' => 'fr',
288 'status' => '200',
289 'open_graph' => [
290 'og_title' => 'my OG title',
291 'og_description' => 'OG desc',
292 'og_image' => 'https://',
293 ],
294 ]);
295
296 $proxy = new ContentProxy($graby, $tagger, $validator, $this->getLogger(), $this->fetchingErrorMessage);
297 $entry = new Entry(new User());
298 $proxy->updateEntry($entry, 'http://0.0.0.0');
299
f808b016
JB
300 $this->assertSame('http://1.1.1.1', $entry->getUrl());
301 $this->assertSame('this is my title', $entry->getTitle());
0d349ea6 302 $this->assertContains('this is my content', $entry->getContent());
41d45c61 303 $this->assertNull($entry->getPreviewPicture());
f808b016
JB
304 $this->assertSame('text/html', $entry->getMimetype());
305 $this->assertSame('fr', $entry->getLanguage());
306 $this->assertSame('200', $entry->getHttpStatus());
307 $this->assertSame(4.0, $entry->getReadingTime());
308 $this->assertSame('1.1.1.1', $entry->getDomainName());
3d71d403
JB
309 }
310
4d0ec0e7
JB
311 public function testWithForcedContent()
312 {
313 $tagger = $this->getTaggerMock();
314 $tagger->expects($this->once())
315 ->method('tag');
316
0d349ea6 317 $proxy = new ContentProxy((new Graby()), $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
7aba665e
JC
318 $entry = new Entry(new User());
319 $proxy->updateEntry(
320 $entry,
0d6cfb88
JB
321 'http://0.0.0.0',
322 [
323 'html' => str_repeat('this is my content', 325),
324 'title' => 'this is my title',
325 'url' => 'http://1.1.1.1',
326 'content_type' => 'text/html',
327 'language' => 'fr',
f0378b4d
JB
328 'date' => '1395635872',
329 'authors' => ['Jeremy', 'Nico', 'Thomas'],
330 'all_headers' => [
331 'Cache-Control' => 'no-cache',
38a04dee 332 ],
0d6cfb88
JB
333 ]
334 );
4d0ec0e7 335
f808b016
JB
336 $this->assertSame('http://1.1.1.1', $entry->getUrl());
337 $this->assertSame('this is my title', $entry->getTitle());
4d0ec0e7 338 $this->assertContains('this is my content', $entry->getContent());
f808b016
JB
339 $this->assertSame('text/html', $entry->getMimetype());
340 $this->assertSame('fr', $entry->getLanguage());
341 $this->assertSame(4.0, $entry->getReadingTime());
342 $this->assertSame('1.1.1.1', $entry->getDomainName());
343 $this->assertSame('24/03/2014', $entry->getPublishedAt()->format('d/m/Y'));
f0378b4d
JB
344 $this->assertContains('Jeremy', $entry->getPublishedBy());
345 $this->assertContains('Nico', $entry->getPublishedBy());
346 $this->assertContains('Thomas', $entry->getPublishedBy());
347 $this->assertContains('no-cache', $entry->getHeaders());
348 }
349
350 public function testWithForcedContentAndDatetime()
351 {
352 $tagger = $this->getTaggerMock();
353 $tagger->expects($this->once())
354 ->method('tag');
355
d5c2cc54 356 $logHandler = new TestHandler();
6acadf8e 357 $logger = new Logger('test', [$logHandler]);
d5c2cc54 358
0d349ea6 359 $proxy = new ContentProxy((new Graby()), $tagger, $this->getValidator(), $logger, $this->fetchingErrorMessage);
7aba665e 360 $entry = new Entry(new User());
6acadf8e 361 $proxy->updateEntry(
7aba665e 362 $entry,
6acadf8e 363 'http://1.1.1.1',
f0378b4d
JB
364 [
365 'html' => str_repeat('this is my content', 325),
366 'title' => 'this is my title',
367 'url' => 'http://1.1.1.1',
368 'content_type' => 'text/html',
369 'language' => 'fr',
370 'date' => '2016-09-08T11:55:58+0200',
371 ]
372 );
373
f808b016
JB
374 $this->assertSame('http://1.1.1.1', $entry->getUrl());
375 $this->assertSame('this is my title', $entry->getTitle());
f0378b4d 376 $this->assertContains('this is my content', $entry->getContent());
f808b016
JB
377 $this->assertSame('text/html', $entry->getMimetype());
378 $this->assertSame('fr', $entry->getLanguage());
379 $this->assertSame(4.0, $entry->getReadingTime());
380 $this->assertSame('1.1.1.1', $entry->getDomainName());
381 $this->assertSame('08/09/2016', $entry->getPublishedAt()->format('d/m/Y'));
f0378b4d
JB
382 }
383
384 public function testWithForcedContentAndBadDate()
385 {
386 $tagger = $this->getTaggerMock();
387 $tagger->expects($this->once())
388 ->method('tag');
389
390 $logger = new Logger('foo');
391 $handler = new TestHandler();
392 $logger->pushHandler($handler);
393
0d349ea6 394 $proxy = new ContentProxy((new Graby()), $tagger, $this->getValidator(), $logger, $this->fetchingErrorMessage);
7aba665e
JC
395 $entry = new Entry(new User());
396 $proxy->updateEntry(
397 $entry,
6acadf8e 398 'http://1.1.1.1',
f0378b4d
JB
399 [
400 'html' => str_repeat('this is my content', 325),
401 'title' => 'this is my title',
402 'url' => 'http://1.1.1.1',
403 'content_type' => 'text/html',
404 'language' => 'fr',
405 'date' => '01 02 2012',
406 ]
407 );
408
f808b016
JB
409 $this->assertSame('http://1.1.1.1', $entry->getUrl());
410 $this->assertSame('this is my title', $entry->getTitle());
f0378b4d 411 $this->assertContains('this is my content', $entry->getContent());
f808b016
JB
412 $this->assertSame('text/html', $entry->getMimetype());
413 $this->assertSame('fr', $entry->getLanguage());
414 $this->assertSame(4.0, $entry->getReadingTime());
415 $this->assertSame('1.1.1.1', $entry->getDomainName());
f0378b4d
JB
416 $this->assertNull($entry->getPublishedAt());
417
418 $records = $handler->getRecords();
419
420 $this->assertCount(1, $records);
421 $this->assertContains('Error while defining date', $records[0]['message']);
4d0ec0e7
JB
422 }
423
424 public function testTaggerThrowException()
425 {
4d0ec0e7
JB
426 $tagger = $this->getTaggerMock();
427 $tagger->expects($this->once())
428 ->method('tag')
429 ->will($this->throwException(new \Exception()));
430
0d349ea6 431 $proxy = new ContentProxy((new Graby()), $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
7aba665e 432 $entry = new Entry(new User());
6acadf8e
JB
433 $proxy->updateEntry(
434 $entry,
435 'http://1.1.1.1',
436 [
437 'html' => str_repeat('this is my content', 325),
438 'title' => 'this is my title',
439 'url' => 'http://1.1.1.1',
440 'content_type' => 'text/html',
441 'language' => 'fr',
442 ]
d0e9b3d6 443 );
4d0ec0e7
JB
444
445 $this->assertCount(0, $entry->getTags());
446 }
447
74a75f7d
JB
448 public function dataForCrazyHtml()
449 {
450 return [
451 'script and comment' => [
452 '<strong>Script inside:</strong> <!--[if gte IE 4]><script>alert(\'lol\');</script><![endif]--><br />',
38a04dee 453 'lol',
74a75f7d
JB
454 ],
455 'script' => [
456 '<strong>Script inside:</strong><script>alert(\'lol\');</script>',
38a04dee 457 'script',
74a75f7d
JB
458 ],
459 ];
460 }
461
462 /**
463 * @dataProvider dataForCrazyHtml
464 */
465 public function testWithCrazyHtmlContent($html, $escapedString)
466 {
467 $tagger = $this->getTaggerMock();
468 $tagger->expects($this->once())
469 ->method('tag');
470
0d349ea6 471 $proxy = new ContentProxy((new Graby()), $tagger, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage);
6acadf8e
JB
472 $entry = new Entry(new User());
473 $proxy->updateEntry(
474 $entry,
74a75f7d
JB
475 'http://1.1.1.1',
476 [
477 'html' => $html,
478 'title' => 'this is my title',
479 'url' => 'http://1.1.1.1',
480 'content_type' => 'text/html',
481 'language' => 'fr',
482 'status' => '200',
483 'open_graph' => [
484 'og_title' => 'my OG title',
485 'og_description' => 'OG desc',
486 'og_image' => 'http://3.3.3.3/cover.jpg',
487 ],
488 ]
489 );
490
f808b016
JB
491 $this->assertSame('http://1.1.1.1', $entry->getUrl());
492 $this->assertSame('this is my title', $entry->getTitle());
74a75f7d 493 $this->assertNotContains($escapedString, $entry->getContent());
f808b016
JB
494 $this->assertSame('http://3.3.3.3/cover.jpg', $entry->getPreviewPicture());
495 $this->assertSame('text/html', $entry->getMimetype());
496 $this->assertSame('fr', $entry->getLanguage());
497 $this->assertSame('200', $entry->getHttpStatus());
498 $this->assertSame('1.1.1.1', $entry->getDomainName());
74a75f7d
JB
499 }
500
f530f7f5
KG
501 private function getTaggerMock()
502 {
6bc6fb1f 503 return $this->getMockBuilder(RuleBasedTagger::class)
4094ea47 504 ->setMethods(['tag'])
f530f7f5
KG
505 ->disableOriginalConstructor()
506 ->getMock();
507 }
1c9cd2a7 508
0c5bcd82 509 private function getLogger()
1c9cd2a7 510 {
0c5bcd82 511 return new NullLogger();
1c9cd2a7 512 }
0d349ea6
JB
513
514 private function getValidator()
515 {
516 return $this->getMockBuilder(RecursiveValidator::class)
517 ->setMethods(['validate'])
518 ->disableOriginalConstructor()
519 ->getMock();
520 }
558d9aab 521}