3 namespace Tests\Wallabag\ImportBundle\Import
;
5 use Wallabag\UserBundle\Entity\User
;
6 use Wallabag\CoreBundle\Entity\Entry
;
7 use Wallabag\CoreBundle\Entity\Config
;
8 use Wallabag\ImportBundle\Import\PocketImport
;
10 use GuzzleHttp\Subscriber\Mock
;
11 use GuzzleHttp\Message\Response
;
12 use GuzzleHttp\Stream\Stream
;
13 use Wallabag\ImportBundle\Redis\Producer
;
15 use Monolog\Handler\TestHandler
;
16 use Simpleue\Queue\RedisQueue
;
17 use M6Web\Component\RedisMock\RedisMockFactory
;
19 class PocketImportTest
extends \PHPUnit_Framework_TestCase
24 protected $contentProxy;
25 protected $logHandler;
27 private function getPocketImport($consumerKey = 'ConsumerKey')
29 $this->user
= new User();
31 $config = new Config($this->user
);
32 $config->setPocketConsumerKey('xxx');
34 $this->user
->setConfig($config);
36 $this->contentProxy
= $this->getMockBuilder('Wallabag\CoreBundle\Helper\ContentProxy')
37 ->disableOriginalConstructor()
40 $this->em
= $this->getMockBuilder('Doctrine\ORM\EntityManager')
41 ->disableOriginalConstructor()
44 $pocket = new PocketImport(
48 $pocket->setUser($this->user
);
50 $this->logHandler
= new TestHandler();
51 $logger = new Logger('test', [$this->logHandler
]);
52 $pocket->setLogger($logger);
57 public function testInit()
59 $pocketImport = $this->getPocketImport();
61 $this->assertEquals('Pocket', $pocketImport->getName());
62 $this->assertNotEmpty($pocketImport->getUrl());
63 $this->assertEquals('import.pocket.description', $pocketImport->getDescription());
66 public function testOAuthRequest()
68 $client = new Client();
71 new Response(200, ['Content-Type' => 'application/json'], Stream
::factory(json_encode(['code' => 'wunderbar_code']))),
74 $client->getEmitter()->attach($mock);
76 $pocketImport = $this->getPocketImport();
77 $pocketImport->setClient($client);
79 $code = $pocketImport->getRequestToken('http://0.0.0.0/redirect');
81 $this->assertEquals('wunderbar_code', $code);
84 public function testOAuthRequestBadResponse()
86 $client = new Client();
92 $client->getEmitter()->attach($mock);
94 $pocketImport = $this->getPocketImport();
95 $pocketImport->setClient($client);
97 $code = $pocketImport->getRequestToken('http://0.0.0.0/redirect');
99 $this->assertFalse($code);
101 $records = $this->logHandler
->getRecords();
102 $this->assertContains('PocketImport: Failed to request token', $records[0]['message']);
103 $this->assertEquals('ERROR', $records[0]['level_name']);
106 public function testOAuthAuthorize()
108 $client = new Client();
111 new Response(200, ['Content-Type' => 'application/json'], Stream
::factory(json_encode(['access_token' => 'wunderbar_token']))),
114 $client->getEmitter()->attach($mock);
116 $pocketImport = $this->getPocketImport();
117 $pocketImport->setClient($client);
119 $res = $pocketImport->authorize('wunderbar_code');
121 $this->assertTrue($res);
122 $this->assertEquals('wunderbar_token', $pocketImport->getAccessToken());
125 public function testOAuthAuthorizeBadResponse()
127 $client = new Client();
133 $client->getEmitter()->attach($mock);
135 $pocketImport = $this->getPocketImport();
136 $pocketImport->setClient($client);
138 $res = $pocketImport->authorize('wunderbar_code');
140 $this->assertFalse($res);
142 $records = $this->logHandler
->getRecords();
143 $this->assertContains('PocketImport: Failed to authorize client', $records[0]['message']);
144 $this->assertEquals('ERROR', $records[0]['level_name']);
148 * Will sample results from https://getpocket.com/developer/docs/v3/retrieve.
150 public function testImport()
152 $client = new Client();
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('
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",
167 "time_added": "1473020899",
168 "time_updated": "1473020899",
170 "time_favorited": "0",
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.",
179 "word_count": "3197",
182 "item_id": "229279689",
184 "src": "http://a.espncdn.com/combiner/i?img=/photo/2012/0927/grant_g_ryder_cr_640.jpg&w=640&h=360",
187 "credit": "Jamie Squire/Getty Images",
193 "item_id": "229279689",
195 "src": "http://www.youtube.com/v/Er34PbFkVGk?version=3&hl=en_US&rel=0",
204 "item_id": "1147652870",
208 "item_id": "1147652870",
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",
220 "time_added": "1473020899",
221 "time_updated": "1473020899",
223 "time_favorited": "0",
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.",
239 $client->getEmitter()->attach($mock);
241 $pocketImport = $this->getPocketImport();
243 $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
244 ->disableOriginalConstructor()
247 $entryRepo->expects($this->exactly(2))
248 ->method('findByUrlAndUserId')
249 ->will($this->onConsecutiveCalls(false, true));
252 ->expects($this->exactly(2))
253 ->method('getRepository')
254 ->willReturn($entryRepo);
256 $entry = new Entry($this->user
);
259 ->expects($this->once())
260 ->method('updateEntry')
261 ->willReturn($entry);
263 $pocketImport->setClient($client);
264 $pocketImport->authorize('wunderbar_code');
266 $res = $pocketImport->import();
268 $this->assertTrue($res);
269 $this->assertEquals(['skipped' => 1, 'imported' => 1, 'queued' => 0], $pocketImport->getSummary());
273 * Will sample results from https://getpocket.com/developer/docs/v3/retrieve.
275 public function testImportAndMarkAllAsRead()
277 $client = new Client();
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('
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",
292 "time_added": "1473020899",
293 "time_updated": "1473020899",
295 "time_favorited": "0",
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.",
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",
310 "time_added": "1473020899",
311 "time_updated": "1473020899",
313 "time_favorited": "0",
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.",
326 $client->getEmitter()->attach($mock);
328 $pocketImport = $this->getPocketImport();
330 $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
331 ->disableOriginalConstructor()
334 $entryRepo->expects($this->exactly(2))
335 ->method('findByUrlAndUserId')
336 ->will($this->onConsecutiveCalls(false, false));
339 ->expects($this->exactly(2))
340 ->method('getRepository')
341 ->willReturn($entryRepo);
343 // check that every entry persisted are archived
345 ->expects($this->any())
347 ->with($this->callback(function ($persistedEntry) {
348 return $persistedEntry->isArchived();
351 $entry = new Entry($this->user
);
354 ->expects($this->exactly(2))
355 ->method('updateEntry')
356 ->willReturn($entry);
358 $pocketImport->setClient($client);
359 $pocketImport->authorize('wunderbar_code');
361 $res = $pocketImport->setMarkAsRead(true)->import();
363 $this->assertTrue($res);
364 $this->assertEquals(['skipped' => 0, 'imported' => 2, 'queued' => 0], $pocketImport->getSummary());
368 * Will sample results from https://getpocket.com/developer/docs/v3/retrieve.
370 public function testImportWithRabbit()
372 $client = new Client();
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",
382 "time_added": "1473020899",
383 "time_updated": "1473020899",
385 "time_favorited": "0",
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.",
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('
403 "229279690": '.$body.'
409 $client->getEmitter()->attach($mock);
411 $pocketImport = $this->getPocketImport();
413 $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
414 ->disableOriginalConstructor()
417 $entryRepo->expects($this->never())
418 ->method('findByUrlAndUserId');
421 ->expects($this->never())
422 ->method('getRepository');
424 $entry = new Entry($this->user
);
427 ->expects($this->never())
428 ->method('updateEntry');
430 $producer = $this->getMockBuilder('OldSound\RabbitMqBundle\RabbitMq\Producer')
431 ->disableOriginalConstructor()
434 $bodyAsArray = json_decode($body, true);
435 // because with just use `new User()` so it doesn't have an id
436 $bodyAsArray['userId'] = null;
439 ->expects($this->once())
441 ->with(json_encode($bodyAsArray));
443 $pocketImport->setClient($client);
444 $pocketImport->setProducer($producer);
445 $pocketImport->authorize('wunderbar_code');
447 $res = $pocketImport->setMarkAsRead(true)->import();
449 $this->assertTrue($res);
450 $this->assertEquals(['skipped' => 0, 'imported' => 0, 'queued' => 1], $pocketImport->getSummary());
454 * Will sample results from https://getpocket.com/developer/docs/v3/retrieve.
456 public function testImportWithRedis()
458 $client = new Client();
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",
468 "time_added": "1473020899",
469 "time_updated": "1473020899",
471 "time_favorited": "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.",
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('
489 "229279690": '.$body.'
495 $client->getEmitter()->attach($mock);
497 $pocketImport = $this->getPocketImport();
499 $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
500 ->disableOriginalConstructor()
503 $entryRepo->expects($this->never())
504 ->method('findByUrlAndUserId');
507 ->expects($this->never())
508 ->method('getRepository');
510 $entry = new Entry($this->user
);
513 ->expects($this->never())
514 ->method('updateEntry');
516 $factory = new RedisMockFactory();
517 $redisMock = $factory->getAdapter('Predis\Client', true);
519 $queue = new RedisQueue($redisMock, 'pocket');
520 $producer = new Producer($queue);
522 $pocketImport->setClient($client);
523 $pocketImport->setProducer($producer);
524 $pocketImport->authorize('wunderbar_code');
526 $res = $pocketImport->setMarkAsRead(true)->import();
528 $this->assertTrue($res);
529 $this->assertEquals(['skipped' => 0, 'imported' => 0, 'queued' => 1], $pocketImport->getSummary());
531 $this->assertNotEmpty($redisMock->lpop('pocket'));
534 public function testImportBadResponse()
536 $client = new Client();
539 new Response(200, ['Content-Type' => 'application/json'], Stream
::factory(json_encode(['access_token' => 'wunderbar_token']))),
543 $client->getEmitter()->attach($mock);
545 $pocketImport = $this->getPocketImport();
546 $pocketImport->setClient($client);
547 $pocketImport->authorize('wunderbar_code');
549 $res = $pocketImport->import();
551 $this->assertFalse($res);
553 $records = $this->logHandler
->getRecords();
554 $this->assertContains('PocketImport: Failed to import', $records[0]['message']);
555 $this->assertEquals('ERROR', $records[0]['level_name']);
558 public function testImportWithExceptionFromGraby()
560 $client = new Client();
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('
571 "resolved_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview"
578 $client->getEmitter()->attach($mock);
580 $pocketImport = $this->getPocketImport();
582 $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
583 ->disableOriginalConstructor()
586 $entryRepo->expects($this->once())
587 ->method('findByUrlAndUserId')
588 ->will($this->onConsecutiveCalls(false, true));
591 ->expects($this->once())
592 ->method('getRepository')
593 ->willReturn($entryRepo);
595 $entry = new Entry($this->user
);
598 ->expects($this->once())
599 ->method('updateEntry')
600 ->will($this->throwException(new \
Exception()));
602 $pocketImport->setClient($client);
603 $pocketImport->authorize('wunderbar_code');
605 $res = $pocketImport->import();
607 $this->assertTrue($res);
608 $this->assertEquals(['skipped' => 0, 'imported' => 1, 'queued' => 0], $pocketImport->getSummary());