]> git.immae.eu Git - github/wallabag/wallabag.git/blame - tests/Wallabag/ImportBundle/Import/PocketImportTest.php
Missing some migrations
[github/wallabag/wallabag.git] / tests / Wallabag / ImportBundle / Import / PocketImportTest.php
CommitLineData
7ec2897e
JB
1<?php
2
23634d5d 3namespace Tests\Wallabag\ImportBundle\Import;
7ec2897e
JB
4
5use Wallabag\UserBundle\Entity\User;
79d0e38e 6use Wallabag\CoreBundle\Entity\Entry;
ebe0787e 7use Wallabag\CoreBundle\Entity\Config;
7ec2897e 8use Wallabag\ImportBundle\Import\PocketImport;
7ec2897e
JB
9use GuzzleHttp\Client;
10use GuzzleHttp\Subscriber\Mock;
11use GuzzleHttp\Message\Response;
12use GuzzleHttp\Stream\Stream;
b3437d58 13use Wallabag\ImportBundle\Redis\Producer;
252ebd60
JB
14use Monolog\Logger;
15use Monolog\Handler\TestHandler;
b3437d58
JB
16use Simpleue\Queue\RedisQueue;
17use M6Web\Component\RedisMock\RedisMockFactory;
252ebd60 18
7ec2897e
JB
19class PocketImportTest extends \PHPUnit_Framework_TestCase
20{
21 protected $token;
22 protected $user;
7ec2897e 23 protected $em;
252ebd60
JB
24 protected $contentProxy;
25 protected $logHandler;
7ec2897e 26
ef75e122 27 private function getPocketImport($consumerKey = 'ConsumerKey')
7ec2897e
JB
28 {
29 $this->user = new User();
30
ebe0787e
JB
31 $config = new Config($this->user);
32 $config->setPocketConsumerKey('xxx');
33
34 $this->user->setConfig($config);
35
252ebd60
JB
36 $this->contentProxy = $this->getMockBuilder('Wallabag\CoreBundle\Helper\ContentProxy')
37 ->disableOriginalConstructor()
38 ->getMock();
39
7ec2897e
JB
40 $this->em = $this->getMockBuilder('Doctrine\ORM\EntityManager')
41 ->disableOriginalConstructor()
42 ->getMock();
43
02f64895 44 $pocket = new PocketImport(
7ec2897e 45 $this->em,
ebe0787e 46 $this->contentProxy
7ec2897e 47 );
ef75e122 48 $pocket->setUser($this->user);
252ebd60
JB
49
50 $this->logHandler = new TestHandler();
4094ea47 51 $logger = new Logger('test', [$this->logHandler]);
252ebd60
JB
52 $pocket->setLogger($logger);
53
54 return $pocket;
7ec2897e
JB
55 }
56
57 public function testInit()
58 {
59 $pocketImport = $this->getPocketImport();
60
61 $this->assertEquals('Pocket', $pocketImport->getName());
7019c7cf 62 $this->assertNotEmpty($pocketImport->getUrl());
0d42217e 63 $this->assertEquals('import.pocket.description', $pocketImport->getDescription());
7ec2897e
JB
64 }
65
66 public function testOAuthRequest()
67 {
68 $client = new Client();
69
70 $mock = new Mock([
252ebd60 71 new Response(200, ['Content-Type' => 'application/json'], Stream::factory(json_encode(['code' => 'wunderbar_code']))),
7ec2897e
JB
72 ]);
73
74 $client->getEmitter()->attach($mock);
75
76 $pocketImport = $this->getPocketImport();
77 $pocketImport->setClient($client);
78
252ebd60 79 $code = $pocketImport->getRequestToken('http://0.0.0.0/redirect');
7ec2897e 80
252ebd60
JB
81 $this->assertEquals('wunderbar_code', $code);
82 }
83
84 public function testOAuthRequestBadResponse()
85 {
86 $client = new Client();
87
88 $mock = new Mock([
89 new Response(403),
90 ]);
91
92 $client->getEmitter()->attach($mock);
93
94 $pocketImport = $this->getPocketImport();
95 $pocketImport->setClient($client);
96
97 $code = $pocketImport->getRequestToken('http://0.0.0.0/redirect');
98
99 $this->assertFalse($code);
100
101 $records = $this->logHandler->getRecords();
102 $this->assertContains('PocketImport: Failed to request token', $records[0]['message']);
103 $this->assertEquals('ERROR', $records[0]['level_name']);
7ec2897e
JB
104 }
105
106 public function testOAuthAuthorize()
107 {
108 $client = new Client();
109
110 $mock = new Mock([
252ebd60 111 new Response(200, ['Content-Type' => 'application/json'], Stream::factory(json_encode(['access_token' => 'wunderbar_token']))),
7ec2897e
JB
112 ]);
113
114 $client->getEmitter()->attach($mock);
115
116 $pocketImport = $this->getPocketImport();
117 $pocketImport->setClient($client);
118
252ebd60 119 $res = $pocketImport->authorize('wunderbar_code');
7ec2897e 120
252ebd60
JB
121 $this->assertTrue($res);
122 $this->assertEquals('wunderbar_token', $pocketImport->getAccessToken());
7ec2897e
JB
123 }
124
252ebd60
JB
125 public function testOAuthAuthorizeBadResponse()
126 {
127 $client = new Client();
128
129 $mock = new Mock([
130 new Response(403),
131 ]);
132
133 $client->getEmitter()->attach($mock);
134
135 $pocketImport = $this->getPocketImport();
136 $pocketImport->setClient($client);
137
138 $res = $pocketImport->authorize('wunderbar_code');
139
140 $this->assertFalse($res);
141
142 $records = $this->logHandler->getRecords();
143 $this->assertContains('PocketImport: Failed to authorize client', $records[0]['message']);
144 $this->assertEquals('ERROR', $records[0]['level_name']);
145 }
146
147 /**
148 * Will sample results from https://getpocket.com/developer/docs/v3/retrieve.
149 */
7ec2897e
JB
150 public function testImport()
151 {
152 $client = new Client();
153
154 $mock = new Mock([
252ebd60
JB
155 new Response(200, ['Content-Type' => 'application/json'], Stream::factory(json_encode(['access_token' => 'wunderbar_token']))),
156 new Response(200, ['Content-Type' => 'application/json'], Stream::factory('
157 {
158 "status": 1,
159 "list": {
160 "229279689": {
161 "item_id": "229279689",
162 "resolved_id": "229279689",
163 "given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
164 "given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland",
165 "favorite": "1",
166 "status": "1",
7f753117
JB
167 "time_added": "1473020899",
168 "time_updated": "1473020899",
169 "time_read": "0",
170 "time_favorited": "0",
171 "sort_id": 0,
252ebd60
JB
172 "resolved_title": "The Massive Ryder Cup Preview",
173 "resolved_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
174 "excerpt": "The list of things I love about the Ryder Cup is so long that it could fill a (tedious) novel, and golf fans can probably guess most of them.",
175 "is_article": "1",
7f753117 176 "is_index": "0",
252ebd60
JB
177 "has_video": "1",
178 "has_image": "1",
179 "word_count": "3197",
180 "images": {
181 "1": {
182 "item_id": "229279689",
183 "image_id": "1",
184 "src": "http://a.espncdn.com/combiner/i?img=/photo/2012/0927/grant_g_ryder_cr_640.jpg&w=640&h=360",
185 "width": "0",
186 "height": "0",
187 "credit": "Jamie Squire/Getty Images",
188 "caption": ""
189 }
190 },
191 "videos": {
192 "1": {
193 "item_id": "229279689",
194 "video_id": "1",
195 "src": "http://www.youtube.com/v/Er34PbFkVGk?version=3&hl=en_US&rel=0",
196 "width": "420",
197 "height": "315",
198 "type": "1",
199 "vid": "Er34PbFkVGk"
200 }
201 },
202 "tags": {
203 "grantland": {
204 "item_id": "1147652870",
205 "tag": "grantland"
206 },
207 "Ryder Cup": {
208 "item_id": "1147652870",
209 "tag": "Ryder Cup"
210 }
211 }
212 },
213 "229279690": {
214 "item_id": "229279689",
215 "resolved_id": "229279689",
216 "given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
217 "given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland",
218 "favorite": "1",
219 "status": "1",
7f753117
JB
220 "time_added": "1473020899",
221 "time_updated": "1473020899",
222 "time_read": "0",
223 "time_favorited": "0",
224 "sort_id": 1,
252ebd60
JB
225 "resolved_title": "The Massive Ryder Cup Preview",
226 "resolved_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
227 "excerpt": "The list of things I love about the Ryder Cup is so long that it could fill a (tedious) novel, and golf fans can probably guess most of them.",
228 "is_article": "1",
7f753117 229 "is_index": "0",
252ebd60
JB
230 "has_video": "0",
231 "has_image": "0",
232 "word_count": "3197"
233 }
234 }
235 }
236 ')),
237 ]);
238
239 $client->getEmitter()->attach($mock);
240
241 $pocketImport = $this->getPocketImport();
242
243 $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
244 ->disableOriginalConstructor()
245 ->getMock();
246
247 $entryRepo->expects($this->exactly(2))
78833672 248 ->method('findByUrlAndUserId')
252ebd60
JB
249 ->will($this->onConsecutiveCalls(false, true));
250
252ebd60 251 $this->em
c2656f96 252 ->expects($this->exactly(2))
252ebd60 253 ->method('getRepository')
c2656f96 254 ->willReturn($entryRepo);
252ebd60 255
79d0e38e 256 $entry = new Entry($this->user);
252ebd60
JB
257
258 $this->contentProxy
259 ->expects($this->once())
260 ->method('updateEntry')
261 ->willReturn($entry);
262
263 $pocketImport->setClient($client);
264 $pocketImport->authorize('wunderbar_code');
265
266 $res = $pocketImport->import();
267
268 $this->assertTrue($res);
c80cc01a 269 $this->assertEquals(['skipped' => 1, 'imported' => 1, 'queued' => 0], $pocketImport->getSummary());
252ebd60
JB
270 }
271
79d0e38e
JB
272 /**
273 * Will sample results from https://getpocket.com/developer/docs/v3/retrieve.
274 */
275 public function testImportAndMarkAllAsRead()
276 {
277 $client = new Client();
278
279 $mock = new Mock([
280 new Response(200, ['Content-Type' => 'application/json'], Stream::factory(json_encode(['access_token' => 'wunderbar_token']))),
281 new Response(200, ['Content-Type' => 'application/json'], Stream::factory('
282 {
283 "status": 1,
284 "list": {
285 "229279689": {
286 "item_id": "229279689",
287 "resolved_id": "229279689",
288 "given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
289 "given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland",
290 "favorite": "1",
291 "status": "1",
7f753117
JB
292 "time_added": "1473020899",
293 "time_updated": "1473020899",
294 "time_read": "0",
295 "time_favorited": "0",
296 "sort_id": 0,
79d0e38e
JB
297 "excerpt": "The list of things I love about the Ryder Cup is so long that it could fill a (tedious) novel, and golf fans can probably guess most of them.",
298 "is_article": "1",
299 "has_video": "1",
300 "has_image": "1",
301 "word_count": "3197"
302 },
303 "229279690": {
304 "item_id": "229279689",
305 "resolved_id": "229279689",
306 "given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview/2",
307 "given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland",
308 "favorite": "1",
309 "status": "0",
7f753117
JB
310 "time_added": "1473020899",
311 "time_updated": "1473020899",
312 "time_read": "0",
313 "time_favorited": "0",
314 "sort_id": 1,
79d0e38e
JB
315 "excerpt": "The list of things I love about the Ryder Cup is so long that it could fill a (tedious) novel, and golf fans can probably guess most of them.",
316 "is_article": "1",
317 "has_video": "0",
318 "has_image": "0",
319 "word_count": "3197"
320 }
321 }
322 }
323 ')),
324 ]);
325
326 $client->getEmitter()->attach($mock);
327
328 $pocketImport = $this->getPocketImport();
329
330 $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
331 ->disableOriginalConstructor()
332 ->getMock();
333
334 $entryRepo->expects($this->exactly(2))
335 ->method('findByUrlAndUserId')
336 ->will($this->onConsecutiveCalls(false, false));
337
338 $this->em
339 ->expects($this->exactly(2))
340 ->method('getRepository')
341 ->willReturn($entryRepo);
342
343 // check that every entry persisted are archived
344 $this->em
345 ->expects($this->any())
346 ->method('persist')
cebb4223 347 ->with($this->callback(function ($persistedEntry) {
79d0e38e
JB
348 return $persistedEntry->isArchived();
349 }));
350
351 $entry = new Entry($this->user);
352
353 $this->contentProxy
354 ->expects($this->exactly(2))
355 ->method('updateEntry')
356 ->willReturn($entry);
357
358 $pocketImport->setClient($client);
359 $pocketImport->authorize('wunderbar_code');
360
361 $res = $pocketImport->setMarkAsRead(true)->import();
362
363 $this->assertTrue($res);
c80cc01a 364 $this->assertEquals(['skipped' => 0, 'imported' => 2, 'queued' => 0], $pocketImport->getSummary());
79d0e38e
JB
365 }
366
13470c35
JB
367 /**
368 * Will sample results from https://getpocket.com/developer/docs/v3/retrieve.
369 */
370 public function testImportWithRabbit()
371 {
372 $client = new Client();
373
374 $body = <<<'JSON'
375{
376 "item_id": "229279689",
377 "resolved_id": "229279689",
378 "given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
379 "given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland",
380 "favorite": "1",
381 "status": "1",
7f753117
JB
382 "time_added": "1473020899",
383 "time_updated": "1473020899",
384 "time_read": "0",
385 "time_favorited": "0",
386 "sort_id": 0,
13470c35
JB
387 "resolved_title": "The Massive Ryder Cup Preview",
388 "resolved_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
389 "excerpt": "The list of things I love about the Ryder Cup is so long that it could fill a (tedious) novel, and golf fans can probably guess most of them.",
390 "is_article": "1",
391 "has_video": "0",
392 "has_image": "0",
393 "word_count": "3197"
394}
395JSON;
396
397 $mock = new Mock([
398 new Response(200, ['Content-Type' => 'application/json'], Stream::factory(json_encode(['access_token' => 'wunderbar_token']))),
399 new Response(200, ['Content-Type' => 'application/json'], Stream::factory('
400 {
401 "status": 1,
402 "list": {
403 "229279690": '.$body.'
404 }
405 }
406 ')),
407 ]);
408
409 $client->getEmitter()->attach($mock);
410
411 $pocketImport = $this->getPocketImport();
412
413 $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
414 ->disableOriginalConstructor()
415 ->getMock();
416
417 $entryRepo->expects($this->never())
418 ->method('findByUrlAndUserId');
419
420 $this->em
421 ->expects($this->never())
422 ->method('getRepository');
423
424 $entry = new Entry($this->user);
425
426 $this->contentProxy
427 ->expects($this->never())
428 ->method('updateEntry');
429
430 $producer = $this->getMockBuilder('OldSound\RabbitMqBundle\RabbitMq\Producer')
431 ->disableOriginalConstructor()
432 ->getMock();
433
434 $bodyAsArray = json_decode($body, true);
435 // because with just use `new User()` so it doesn't have an id
436 $bodyAsArray['userId'] = null;
437
438 $producer
439 ->expects($this->once())
440 ->method('publish')
441 ->with(json_encode($bodyAsArray));
442
443 $pocketImport->setClient($client);
b3437d58 444 $pocketImport->setProducer($producer);
13470c35
JB
445 $pocketImport->authorize('wunderbar_code');
446
447 $res = $pocketImport->setMarkAsRead(true)->import();
448
449 $this->assertTrue($res);
c80cc01a 450 $this->assertEquals(['skipped' => 0, 'imported' => 0, 'queued' => 1], $pocketImport->getSummary());
13470c35
JB
451 }
452
b3437d58
JB
453 /**
454 * Will sample results from https://getpocket.com/developer/docs/v3/retrieve.
455 */
456 public function testImportWithRedis()
457 {
458 $client = new Client();
459
460 $body = <<<'JSON'
461{
462 "item_id": "229279689",
463 "resolved_id": "229279689",
464 "given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
465 "given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland",
466 "favorite": "1",
467 "status": "1",
468 "time_added": "1473020899",
469 "time_updated": "1473020899",
470 "time_read": "0",
471 "time_favorited": "0",
472 "sort_id": 0,
473 "resolved_title": "The Massive Ryder Cup Preview",
474 "resolved_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
475 "excerpt": "The list of things I love about the Ryder Cup is so long that it could fill a (tedious) novel, and golf fans can probably guess most of them.",
476 "is_article": "1",
477 "has_video": "0",
478 "has_image": "0",
479 "word_count": "3197"
480}
481JSON;
482
483 $mock = new Mock([
484 new Response(200, ['Content-Type' => 'application/json'], Stream::factory(json_encode(['access_token' => 'wunderbar_token']))),
485 new Response(200, ['Content-Type' => 'application/json'], Stream::factory('
486 {
487 "status": 1,
488 "list": {
489 "229279690": '.$body.'
490 }
491 }
492 ')),
493 ]);
494
495 $client->getEmitter()->attach($mock);
496
497 $pocketImport = $this->getPocketImport();
498
499 $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
500 ->disableOriginalConstructor()
501 ->getMock();
502
503 $entryRepo->expects($this->never())
504 ->method('findByUrlAndUserId');
505
506 $this->em
507 ->expects($this->never())
508 ->method('getRepository');
509
510 $entry = new Entry($this->user);
511
512 $this->contentProxy
513 ->expects($this->never())
514 ->method('updateEntry');
515
516 $factory = new RedisMockFactory();
517 $redisMock = $factory->getAdapter('Predis\Client', true);
518
519 $queue = new RedisQueue($redisMock, 'pocket');
520 $producer = new Producer($queue);
521
522 $pocketImport->setClient($client);
523 $pocketImport->setProducer($producer);
524 $pocketImport->authorize('wunderbar_code');
525
526 $res = $pocketImport->setMarkAsRead(true)->import();
527
528 $this->assertTrue($res);
c80cc01a 529 $this->assertEquals(['skipped' => 0, 'imported' => 0, 'queued' => 1], $pocketImport->getSummary());
b3437d58
JB
530
531 $this->assertNotEmpty($redisMock->lpop('pocket'));
532 }
533
252ebd60
JB
534 public function testImportBadResponse()
535 {
536 $client = new Client();
537
538 $mock = new Mock([
539 new Response(200, ['Content-Type' => 'application/json'], Stream::factory(json_encode(['access_token' => 'wunderbar_token']))),
540 new Response(403),
7ec2897e
JB
541 ]);
542
543 $client->getEmitter()->attach($mock);
544
545 $pocketImport = $this->getPocketImport();
546 $pocketImport->setClient($client);
252ebd60
JB
547 $pocketImport->authorize('wunderbar_code');
548
549 $res = $pocketImport->import();
7ec2897e 550
252ebd60 551 $this->assertFalse($res);
7ec2897e 552
252ebd60
JB
553 $records = $this->logHandler->getRecords();
554 $this->assertContains('PocketImport: Failed to import', $records[0]['message']);
555 $this->assertEquals('ERROR', $records[0]['level_name']);
7ec2897e 556 }
19d9efab
JB
557
558 public function testImportWithExceptionFromGraby()
559 {
560 $client = new Client();
561
562 $mock = new Mock([
563 new Response(200, ['Content-Type' => 'application/json'], Stream::factory(json_encode(['access_token' => 'wunderbar_token']))),
564 new Response(200, ['Content-Type' => 'application/json'], Stream::factory('
565 {
566 "status": 1,
567 "list": {
568 "229279689": {
569 "resolved_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview"
570 }
571 }
572 }
573 ')),
574 ]);
575
576 $client->getEmitter()->attach($mock);
577
578 $pocketImport = $this->getPocketImport();
579
580 $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
581 ->disableOriginalConstructor()
582 ->getMock();
583
584 $entryRepo->expects($this->once())
585 ->method('findByUrlAndUserId')
586 ->will($this->onConsecutiveCalls(false, true));
587
588 $this->em
589 ->expects($this->once())
590 ->method('getRepository')
591 ->willReturn($entryRepo);
592
593 $entry = new Entry($this->user);
594
595 $this->contentProxy
596 ->expects($this->once())
597 ->method('updateEntry')
598 ->will($this->throwException(new \Exception()));
599
600 $pocketImport->setClient($client);
601 $pocketImport->authorize('wunderbar_code');
602
603 $res = $pocketImport->import();
604
605 $this->assertTrue($res);
c80cc01a 606 $this->assertEquals(['skipped' => 1, 'imported' => 0, 'queued' => 0], $pocketImport->getSummary());
19d9efab 607 }
7ec2897e 608}