]> git.immae.eu Git - github/wallabag/wallabag.git/blob - tests/Wallabag/CoreBundle/Helper/ContentProxyTest.php
Avoid returning objects passed by reference.
[github/wallabag/wallabag.git] / tests / Wallabag / CoreBundle / Helper / ContentProxyTest.php
1 <?php
2
3 namespace Tests\Wallabag\CoreBundle\Helper;
4
5 use Psr\Log\NullLogger;
6 use Wallabag\CoreBundle\Helper\ContentProxy;
7 use Wallabag\CoreBundle\Entity\Entry;
8 use Wallabag\CoreBundle\Entity\Tag;
9 use Wallabag\UserBundle\Entity\User;
10 use Wallabag\CoreBundle\Helper\RuleBasedTagger;
11 use Graby\Graby;
12 use Monolog\Handler\TestHandler;
13 use Monolog\Logger;
14
15 class ContentProxyTest extends \PHPUnit_Framework_TestCase
16 {
17 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>.';
18
19 public function testWithBadUrl()
20 {
21 $tagger = $this->getTaggerMock();
22 $tagger->expects($this->once())
23 ->method('tag');
24
25 $graby = $this->getMockBuilder('Graby\Graby')
26 ->setMethods(['fetchContent'])
27 ->disableOriginalConstructor()
28 ->getMock();
29
30 $graby->expects($this->any())
31 ->method('fetchContent')
32 ->willReturn([
33 'html' => false,
34 'title' => '',
35 'url' => '',
36 'content_type' => '',
37 'language' => '',
38 ]);
39
40 $proxy = new ContentProxy($graby, $tagger, $this->getLogger(), $this->fetchingErrorMessage);
41 $entry = new Entry(new User());
42 $proxy->updateEntry($entry, 'http://user@:80');
43
44 $this->assertEquals('http://user@:80', $entry->getUrl());
45 $this->assertEmpty($entry->getTitle());
46 $this->assertEquals($this->fetchingErrorMessage, $entry->getContent());
47 $this->assertEmpty($entry->getPreviewPicture());
48 $this->assertEmpty($entry->getMimetype());
49 $this->assertEmpty($entry->getLanguage());
50 $this->assertEquals(0.0, $entry->getReadingTime());
51 $this->assertEquals(false, $entry->getDomainName());
52 }
53
54 public function testWithEmptyContent()
55 {
56 $tagger = $this->getTaggerMock();
57 $tagger->expects($this->once())
58 ->method('tag');
59
60 $graby = $this->getMockBuilder('Graby\Graby')
61 ->setMethods(['fetchContent'])
62 ->disableOriginalConstructor()
63 ->getMock();
64
65 $graby->expects($this->any())
66 ->method('fetchContent')
67 ->willReturn([
68 'html' => false,
69 'title' => '',
70 'url' => '',
71 'content_type' => '',
72 'language' => '',
73 ]);
74
75 $proxy = new ContentProxy($graby, $tagger, $this->getLogger(), $this->fetchingErrorMessage);
76 $entry = new Entry(new User());
77 $proxy->updateEntry($entry, 'http://0.0.0.0');
78
79 $this->assertEquals('http://0.0.0.0', $entry->getUrl());
80 $this->assertEmpty($entry->getTitle());
81 $this->assertEquals($this->fetchingErrorMessage, $entry->getContent());
82 $this->assertEmpty($entry->getPreviewPicture());
83 $this->assertEmpty($entry->getMimetype());
84 $this->assertEmpty($entry->getLanguage());
85 $this->assertEquals(0.0, $entry->getReadingTime());
86 $this->assertEquals('0.0.0.0', $entry->getDomainName());
87 }
88
89 public function testWithEmptyContentButOG()
90 {
91 $tagger = $this->getTaggerMock();
92 $tagger->expects($this->once())
93 ->method('tag');
94
95 $graby = $this->getMockBuilder('Graby\Graby')
96 ->setMethods(['fetchContent'])
97 ->disableOriginalConstructor()
98 ->getMock();
99
100 $graby->expects($this->any())
101 ->method('fetchContent')
102 ->willReturn([
103 'html' => false,
104 'title' => '',
105 'url' => '',
106 'content_type' => '',
107 'language' => '',
108 'status' => '',
109 'open_graph' => [
110 'og_title' => 'my title',
111 'og_description' => 'desc',
112 ],
113 ]);
114
115 $proxy = new ContentProxy($graby, $tagger, $this->getLogger(), $this->fetchingErrorMessage);
116 $entry = new Entry(new User());
117 $proxy->updateEntry($entry, 'http://domain.io');
118
119 $this->assertEquals('http://domain.io', $entry->getUrl());
120 $this->assertEquals('my title', $entry->getTitle());
121 $this->assertEquals($this->fetchingErrorMessage.'<p><i>But we found a short description: </i></p>desc', $entry->getContent());
122 $this->assertEmpty($entry->getPreviewPicture());
123 $this->assertEmpty($entry->getLanguage());
124 $this->assertEmpty($entry->getHttpStatus());
125 $this->assertEmpty($entry->getMimetype());
126 $this->assertEquals(0.0, $entry->getReadingTime());
127 $this->assertEquals('domain.io', $entry->getDomainName());
128 }
129
130 public function testWithContent()
131 {
132 $tagger = $this->getTaggerMock();
133 $tagger->expects($this->once())
134 ->method('tag');
135
136 $graby = $this->getMockBuilder('Graby\Graby')
137 ->setMethods(['fetchContent'])
138 ->disableOriginalConstructor()
139 ->getMock();
140
141 $graby->expects($this->any())
142 ->method('fetchContent')
143 ->willReturn([
144 'html' => str_repeat('this is my content', 325),
145 'title' => 'this is my title',
146 'url' => 'http://1.1.1.1',
147 'content_type' => 'text/html',
148 'language' => 'fr',
149 'status' => '200',
150 'open_graph' => [
151 'og_title' => 'my OG title',
152 'og_description' => 'OG desc',
153 'og_image' => 'http://3.3.3.3/cover.jpg',
154 ],
155 ]);
156
157 $proxy = new ContentProxy($graby, $tagger, $this->getLogger(), $this->fetchingErrorMessage);
158 $entry = new Entry(new User());
159 $proxy->updateEntry($entry, 'http://0.0.0.0');
160
161 $this->assertEquals('http://1.1.1.1', $entry->getUrl());
162 $this->assertEquals('this is my title', $entry->getTitle());
163 $this->assertContains('this is my content', $entry->getContent());
164 $this->assertEquals('http://3.3.3.3/cover.jpg', $entry->getPreviewPicture());
165 $this->assertEquals('text/html', $entry->getMimetype());
166 $this->assertEquals('fr', $entry->getLanguage());
167 $this->assertEquals('200', $entry->getHttpStatus());
168 $this->assertEquals(4.0, $entry->getReadingTime());
169 $this->assertEquals('1.1.1.1', $entry->getDomainName());
170 }
171
172 public function testWithContentAndNoOgImage()
173 {
174 $tagger = $this->getTaggerMock();
175 $tagger->expects($this->once())
176 ->method('tag');
177
178 $graby = $this->getMockBuilder('Graby\Graby')
179 ->setMethods(['fetchContent'])
180 ->disableOriginalConstructor()
181 ->getMock();
182
183 $graby->expects($this->any())
184 ->method('fetchContent')
185 ->willReturn([
186 'html' => str_repeat('this is my content', 325),
187 'title' => 'this is my title',
188 'url' => 'http://1.1.1.1',
189 'content_type' => 'text/html',
190 'language' => 'fr',
191 'status' => '200',
192 'open_graph' => [
193 'og_title' => 'my OG title',
194 'og_description' => 'OG desc',
195 'og_image' => false,
196 ],
197 ]);
198
199 $proxy = new ContentProxy($graby, $tagger, $this->getLogger(), $this->fetchingErrorMessage);
200 $entry = $proxy->updateEntry(new Entry(new User()), 'http://0.0.0.0');
201
202 $this->assertEquals('http://1.1.1.1', $entry->getUrl());
203 $this->assertEquals('this is my title', $entry->getTitle());
204 $this->assertContains('this is my content', $entry->getContent());
205 $this->assertNull($entry->getPreviewPicture());
206 $this->assertEquals('text/html', $entry->getMimetype());
207 $this->assertEquals('fr', $entry->getLanguage());
208 $this->assertEquals('200', $entry->getHttpStatus());
209 $this->assertEquals(4.0, $entry->getReadingTime());
210 $this->assertEquals('1.1.1.1', $entry->getDomainName());
211 }
212
213 public function testWithForcedContent()
214 {
215 $tagger = $this->getTaggerMock();
216 $tagger->expects($this->once())
217 ->method('tag');
218
219 $proxy = new ContentProxy((new Graby()), $tagger, $this->getLogger(), $this->fetchingErrorMessage);
220 $entry = new Entry(new User());
221 $proxy->updateEntry(
222 $entry,
223 'http://0.0.0.0',
224 [
225 'html' => str_repeat('this is my content', 325),
226 'title' => 'this is my title',
227 'url' => 'http://1.1.1.1',
228 'content_type' => 'text/html',
229 'language' => 'fr',
230 'date' => '1395635872',
231 'authors' => ['Jeremy', 'Nico', 'Thomas'],
232 'all_headers' => [
233 'Cache-Control' => 'no-cache',
234 ],
235 ]
236 );
237
238 $this->assertEquals('http://1.1.1.1', $entry->getUrl());
239 $this->assertEquals('this is my title', $entry->getTitle());
240 $this->assertContains('this is my content', $entry->getContent());
241 $this->assertEquals('text/html', $entry->getMimetype());
242 $this->assertEquals('fr', $entry->getLanguage());
243 $this->assertEquals(4.0, $entry->getReadingTime());
244 $this->assertEquals('1.1.1.1', $entry->getDomainName());
245 $this->assertEquals('24/03/2014', $entry->getPublishedAt()->format('d/m/Y'));
246 $this->assertContains('Jeremy', $entry->getPublishedBy());
247 $this->assertContains('Nico', $entry->getPublishedBy());
248 $this->assertContains('Thomas', $entry->getPublishedBy());
249 $this->assertContains('no-cache', $entry->getHeaders());
250 }
251
252 public function testWithForcedContentAndDatetime()
253 {
254 $tagger = $this->getTaggerMock();
255 $tagger->expects($this->once())
256 ->method('tag');
257
258 $proxy = new ContentProxy((new Graby()), $tagger, $this->getLogger(), $this->fetchingErrorMessage);
259 $entry = new Entry(new User());
260 $proxy->updateEntry(
261 $entry,
262 'http://0.0.0.0',
263 [
264 'html' => str_repeat('this is my content', 325),
265 'title' => 'this is my title',
266 'url' => 'http://1.1.1.1',
267 'content_type' => 'text/html',
268 'language' => 'fr',
269 'date' => '2016-09-08T11:55:58+0200',
270 ]
271 );
272
273 $this->assertEquals('http://1.1.1.1', $entry->getUrl());
274 $this->assertEquals('this is my title', $entry->getTitle());
275 $this->assertContains('this is my content', $entry->getContent());
276 $this->assertEquals('text/html', $entry->getMimetype());
277 $this->assertEquals('fr', $entry->getLanguage());
278 $this->assertEquals(4.0, $entry->getReadingTime());
279 $this->assertEquals('1.1.1.1', $entry->getDomainName());
280 $this->assertEquals('08/09/2016', $entry->getPublishedAt()->format('d/m/Y'));
281 }
282
283 public function testWithForcedContentAndBadDate()
284 {
285 $tagger = $this->getTaggerMock();
286 $tagger->expects($this->once())
287 ->method('tag');
288
289 $logger = new Logger('foo');
290 $handler = new TestHandler();
291 $logger->pushHandler($handler);
292
293 $proxy = new ContentProxy((new Graby()), $tagger, $logger, $this->fetchingErrorMessage);
294 $entry = new Entry(new User());
295 $proxy->updateEntry(
296 $entry,
297 'http://0.0.0.0',
298 [
299 'html' => str_repeat('this is my content', 325),
300 'title' => 'this is my title',
301 'url' => 'http://1.1.1.1',
302 'content_type' => 'text/html',
303 'language' => 'fr',
304 'date' => '01 02 2012',
305 ]
306 );
307
308 $this->assertEquals('http://1.1.1.1', $entry->getUrl());
309 $this->assertEquals('this is my title', $entry->getTitle());
310 $this->assertContains('this is my content', $entry->getContent());
311 $this->assertEquals('text/html', $entry->getMimetype());
312 $this->assertEquals('fr', $entry->getLanguage());
313 $this->assertEquals(4.0, $entry->getReadingTime());
314 $this->assertEquals('1.1.1.1', $entry->getDomainName());
315 $this->assertNull($entry->getPublishedAt());
316
317 $records = $handler->getRecords();
318
319 $this->assertCount(1, $records);
320 $this->assertContains('Error while defining date', $records[0]['message']);
321 }
322
323 public function testTaggerThrowException()
324 {
325 $graby = $this->getMockBuilder('Graby\Graby')
326 ->disableOriginalConstructor()
327 ->getMock();
328
329 $tagger = $this->getTaggerMock();
330 $tagger->expects($this->once())
331 ->method('tag')
332 ->will($this->throwException(new \Exception()));
333
334 $proxy = new ContentProxy($graby, $tagger, $this->getLogger(), $this->fetchingErrorMessage);
335
336 $entry = new Entry(new User());
337 $proxy->updateEntry($entry, 'http://0.0.0.0', [
338 'html' => str_repeat('this is my content', 325),
339 'title' => 'this is my title',
340 'url' => 'http://1.1.1.1',
341 'content_type' => 'text/html',
342 'language' => 'fr',
343 ]);
344
345 $this->assertCount(0, $entry->getTags());
346 }
347
348 public function dataForCrazyHtml()
349 {
350 return [
351 'script and comment' => [
352 '<strong>Script inside:</strong> <!--[if gte IE 4]><script>alert(\'lol\');</script><![endif]--><br />',
353 'lol',
354 ],
355 'script' => [
356 '<strong>Script inside:</strong><script>alert(\'lol\');</script>',
357 'script',
358 ],
359 ];
360 }
361
362 /**
363 * @dataProvider dataForCrazyHtml
364 */
365 public function testWithCrazyHtmlContent($html, $escapedString)
366 {
367 $tagger = $this->getTaggerMock();
368 $tagger->expects($this->once())
369 ->method('tag');
370
371 $proxy = new ContentProxy((new Graby()), $tagger, $this->getLogger(), $this->fetchingErrorMessage);
372 $entry = $proxy->updateEntry(
373 new Entry(new User()),
374 'http://1.1.1.1',
375 [
376 'html' => $html,
377 'title' => 'this is my title',
378 'url' => 'http://1.1.1.1',
379 'content_type' => 'text/html',
380 'language' => 'fr',
381 'status' => '200',
382 'open_graph' => [
383 'og_title' => 'my OG title',
384 'og_description' => 'OG desc',
385 'og_image' => 'http://3.3.3.3/cover.jpg',
386 ],
387 ]
388 );
389
390 $this->assertEquals('http://1.1.1.1', $entry->getUrl());
391 $this->assertEquals('this is my title', $entry->getTitle());
392 $this->assertNotContains($escapedString, $entry->getContent());
393 $this->assertEquals('http://3.3.3.3/cover.jpg', $entry->getPreviewPicture());
394 $this->assertEquals('text/html', $entry->getMimetype());
395 $this->assertEquals('fr', $entry->getLanguage());
396 $this->assertEquals('200', $entry->getHttpStatus());
397 $this->assertEquals('1.1.1.1', $entry->getDomainName());
398 }
399
400 private function getTaggerMock()
401 {
402 return $this->getMockBuilder(RuleBasedTagger::class)
403 ->setMethods(['tag'])
404 ->disableOriginalConstructor()
405 ->getMock();
406 }
407
408 private function getLogger()
409 {
410 return new NullLogger();
411 }
412 }