3 namespace Tests\Wallabag\ImportBundle\Import
;
5 use Wallabag\UserBundle\Entity\User
;
6 use Wallabag\CoreBundle\Entity\Entry
;
7 use Wallabag\ImportBundle\Import\PocketImport
;
9 use GuzzleHttp\Subscriber\Mock
;
10 use GuzzleHttp\Message\Response
;
11 use GuzzleHttp\Stream\Stream
;
12 use Wallabag\ImportBundle\Redis\Producer
;
14 use Monolog\Handler\TestHandler
;
15 use Simpleue\Queue\RedisQueue
;
16 use M6Web\Component\RedisMock\RedisMockFactory
;
18 class PocketImportTest
extends \PHPUnit_Framework_TestCase
23 protected $contentProxy;
24 protected $logHandler;
26 private function getPocketImport($consumerKey = 'ConsumerKey')
28 $this->user
= new User();
30 $this->contentProxy
= $this->getMockBuilder('Wallabag\CoreBundle\Helper\ContentProxy')
31 ->disableOriginalConstructor()
34 $this->em
= $this->getMockBuilder('Doctrine\ORM\EntityManager')
35 ->disableOriginalConstructor()
38 $config = $this->getMockBuilder('Craue\ConfigBundle\Util\Config')
39 ->disableOriginalConstructor()
42 $config->expects($this->any())
44 ->with('pocket_consumer_key')
45 ->willReturn($consumerKey);
47 $pocket = new PocketImport(
52 $pocket->setUser($this->user
);
54 $this->logHandler
= new TestHandler();
55 $logger = new Logger('test', [$this->logHandler
]);
56 $pocket->setLogger($logger);
61 public function testInit()
63 $pocketImport = $this->getPocketImport();
65 $this->assertEquals('Pocket', $pocketImport->getName());
66 $this->assertNotEmpty($pocketImport->getUrl());
67 $this->assertEquals('import.pocket.description', $pocketImport->getDescription());
70 public function testOAuthRequest()
72 $client = new Client();
75 new Response(200, ['Content-Type' => 'application/json'], Stream
::factory(json_encode(['code' => 'wunderbar_code']))),
78 $client->getEmitter()->attach($mock);
80 $pocketImport = $this->getPocketImport();
81 $pocketImport->setClient($client);
83 $code = $pocketImport->getRequestToken('http://0.0.0.0/redirect');
85 $this->assertEquals('wunderbar_code', $code);
88 public function testOAuthRequestBadResponse()
90 $client = new Client();
96 $client->getEmitter()->attach($mock);
98 $pocketImport = $this->getPocketImport();
99 $pocketImport->setClient($client);
101 $code = $pocketImport->getRequestToken('http://0.0.0.0/redirect');
103 $this->assertFalse($code);
105 $records = $this->logHandler
->getRecords();
106 $this->assertContains('PocketImport: Failed to request token', $records[0]['message']);
107 $this->assertEquals('ERROR', $records[0]['level_name']);
110 public function testOAuthAuthorize()
112 $client = new Client();
115 new Response(200, ['Content-Type' => 'application/json'], Stream
::factory(json_encode(['access_token' => 'wunderbar_token']))),
118 $client->getEmitter()->attach($mock);
120 $pocketImport = $this->getPocketImport();
121 $pocketImport->setClient($client);
123 $res = $pocketImport->authorize('wunderbar_code');
125 $this->assertTrue($res);
126 $this->assertEquals('wunderbar_token', $pocketImport->getAccessToken());
129 public function testOAuthAuthorizeBadResponse()
131 $client = new Client();
137 $client->getEmitter()->attach($mock);
139 $pocketImport = $this->getPocketImport();
140 $pocketImport->setClient($client);
142 $res = $pocketImport->authorize('wunderbar_code');
144 $this->assertFalse($res);
146 $records = $this->logHandler
->getRecords();
147 $this->assertContains('PocketImport: Failed to authorize client', $records[0]['message']);
148 $this->assertEquals('ERROR', $records[0]['level_name']);
152 * Will sample results from https://getpocket.com/developer/docs/v3/retrieve.
154 public function testImport()
156 $client = new Client();
159 new Response(200, ['Content-Type' => 'application/json'], Stream
::factory(json_encode(['access_token' => 'wunderbar_token']))),
160 new Response(200, ['Content-Type' => 'application/json'], Stream
::factory('
165 "item_id": "229279689",
166 "resolved_id": "229279689",
167 "given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
168 "given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland",
171 "time_added": "1473020899",
172 "time_updated": "1473020899",
174 "time_favorited": "0",
176 "resolved_title": "The Massive Ryder Cup Preview",
177 "resolved_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
178 "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.",
183 "word_count": "3197",
186 "item_id": "229279689",
188 "src": "http://a.espncdn.com/combiner/i?img=/photo/2012/0927/grant_g_ryder_cr_640.jpg&w=640&h=360",
191 "credit": "Jamie Squire/Getty Images",
197 "item_id": "229279689",
199 "src": "http://www.youtube.com/v/Er34PbFkVGk?version=3&hl=en_US&rel=0",
208 "item_id": "1147652870",
212 "item_id": "1147652870",
218 "item_id": "229279689",
219 "resolved_id": "229279689",
220 "given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
221 "given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland",
224 "time_added": "1473020899",
225 "time_updated": "1473020899",
227 "time_favorited": "0",
229 "resolved_title": "The Massive Ryder Cup Preview",
230 "resolved_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
231 "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.",
243 $client->getEmitter()->attach($mock);
245 $pocketImport = $this->getPocketImport();
247 $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
248 ->disableOriginalConstructor()
251 $entryRepo->expects($this->exactly(2))
252 ->method('findByUrlAndUserId')
253 ->will($this->onConsecutiveCalls(false, true));
256 ->expects($this->exactly(2))
257 ->method('getRepository')
258 ->willReturn($entryRepo);
260 $entry = new Entry($this->user
);
263 ->expects($this->once())
264 ->method('updateEntry')
265 ->willReturn($entry);
267 $pocketImport->setClient($client);
268 $pocketImport->authorize('wunderbar_code');
270 $res = $pocketImport->import();
272 $this->assertTrue($res);
273 $this->assertEquals(['skipped' => 1, 'imported' => 1, 'queued' => 0], $pocketImport->getSummary());
277 * Will sample results from https://getpocket.com/developer/docs/v3/retrieve.
279 public function testImportAndMarkAllAsRead()
281 $client = new Client();
284 new Response(200, ['Content-Type' => 'application/json'], Stream
::factory(json_encode(['access_token' => 'wunderbar_token']))),
285 new Response(200, ['Content-Type' => 'application/json'], Stream
::factory('
290 "item_id": "229279689",
291 "resolved_id": "229279689",
292 "given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
293 "given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland",
296 "time_added": "1473020899",
297 "time_updated": "1473020899",
299 "time_favorited": "0",
301 "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.",
308 "item_id": "229279689",
309 "resolved_id": "229279689",
310 "given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview/2",
311 "given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland",
314 "time_added": "1473020899",
315 "time_updated": "1473020899",
317 "time_favorited": "0",
319 "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.",
330 $client->getEmitter()->attach($mock);
332 $pocketImport = $this->getPocketImport();
334 $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
335 ->disableOriginalConstructor()
338 $entryRepo->expects($this->exactly(2))
339 ->method('findByUrlAndUserId')
340 ->will($this->onConsecutiveCalls(false, false));
343 ->expects($this->exactly(2))
344 ->method('getRepository')
345 ->willReturn($entryRepo);
347 // check that every entry persisted are archived
349 ->expects($this->any())
351 ->with($this->callback(function ($persistedEntry) {
352 return $persistedEntry->isArchived();
355 $entry = new Entry($this->user
);
358 ->expects($this->exactly(2))
359 ->method('updateEntry')
360 ->willReturn($entry);
362 $pocketImport->setClient($client);
363 $pocketImport->authorize('wunderbar_code');
365 $res = $pocketImport->setMarkAsRead(true)->import();
367 $this->assertTrue($res);
368 $this->assertEquals(['skipped' => 0, 'imported' => 2, 'queued' => 0], $pocketImport->getSummary());
372 * Will sample results from https://getpocket.com/developer/docs/v3/retrieve.
374 public function testImportWithRabbit()
376 $client = new Client();
380 "item_id": "229279689",
381 "resolved_id": "229279689",
382 "given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
383 "given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland",
386 "time_added": "1473020899",
387 "time_updated": "1473020899",
389 "time_favorited": "0",
391 "resolved_title": "The Massive Ryder Cup Preview",
392 "resolved_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
393 "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.",
402 new Response(200, ['Content-Type' => 'application/json'], Stream
::factory(json_encode(['access_token' => 'wunderbar_token']))),
403 new Response(200, ['Content-Type' => 'application/json'], Stream
::factory('
407 "229279690": '.$body.'
413 $client->getEmitter()->attach($mock);
415 $pocketImport = $this->getPocketImport();
417 $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
418 ->disableOriginalConstructor()
421 $entryRepo->expects($this->never())
422 ->method('findByUrlAndUserId');
425 ->expects($this->never())
426 ->method('getRepository');
428 $entry = new Entry($this->user
);
431 ->expects($this->never())
432 ->method('updateEntry');
434 $producer = $this->getMockBuilder('OldSound\RabbitMqBundle\RabbitMq\Producer')
435 ->disableOriginalConstructor()
438 $bodyAsArray = json_decode($body, true);
439 // because with just use `new User()` so it doesn't have an id
440 $bodyAsArray['userId'] = null;
443 ->expects($this->once())
445 ->with(json_encode($bodyAsArray));
447 $pocketImport->setClient($client);
448 $pocketImport->setProducer($producer);
449 $pocketImport->authorize('wunderbar_code');
451 $res = $pocketImport->setMarkAsRead(true)->import();
453 $this->assertTrue($res);
454 $this->assertEquals(['skipped' => 0, 'imported' => 0, 'queued' => 1], $pocketImport->getSummary());
458 * Will sample results from https://getpocket.com/developer/docs/v3/retrieve.
460 public function testImportWithRedis()
462 $client = new Client();
466 "item_id": "229279689",
467 "resolved_id": "229279689",
468 "given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
469 "given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland",
472 "time_added": "1473020899",
473 "time_updated": "1473020899",
475 "time_favorited": "0",
477 "resolved_title": "The Massive Ryder Cup Preview",
478 "resolved_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
479 "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.",
488 new Response(200, ['Content-Type' => 'application/json'], Stream
::factory(json_encode(['access_token' => 'wunderbar_token']))),
489 new Response(200, ['Content-Type' => 'application/json'], Stream
::factory('
493 "229279690": '.$body.'
499 $client->getEmitter()->attach($mock);
501 $pocketImport = $this->getPocketImport();
503 $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
504 ->disableOriginalConstructor()
507 $entryRepo->expects($this->never())
508 ->method('findByUrlAndUserId');
511 ->expects($this->never())
512 ->method('getRepository');
514 $entry = new Entry($this->user
);
517 ->expects($this->never())
518 ->method('updateEntry');
520 $factory = new RedisMockFactory();
521 $redisMock = $factory->getAdapter('Predis\Client', true);
523 $queue = new RedisQueue($redisMock, 'pocket');
524 $producer = new Producer($queue);
526 $pocketImport->setClient($client);
527 $pocketImport->setProducer($producer);
528 $pocketImport->authorize('wunderbar_code');
530 $res = $pocketImport->setMarkAsRead(true)->import();
532 $this->assertTrue($res);
533 $this->assertEquals(['skipped' => 0, 'imported' => 0, 'queued' => 1], $pocketImport->getSummary());
535 $this->assertNotEmpty($redisMock->lpop('pocket'));
538 public function testImportBadResponse()
540 $client = new Client();
543 new Response(200, ['Content-Type' => 'application/json'], Stream
::factory(json_encode(['access_token' => 'wunderbar_token']))),
547 $client->getEmitter()->attach($mock);
549 $pocketImport = $this->getPocketImport();
550 $pocketImport->setClient($client);
551 $pocketImport->authorize('wunderbar_code');
553 $res = $pocketImport->import();
555 $this->assertFalse($res);
557 $records = $this->logHandler
->getRecords();
558 $this->assertContains('PocketImport: Failed to import', $records[0]['message']);
559 $this->assertEquals('ERROR', $records[0]['level_name']);
562 public function testImportWithExceptionFromGraby()
564 $client = new Client();
567 new Response(200, ['Content-Type' => 'application/json'], Stream
::factory(json_encode(['access_token' => 'wunderbar_token']))),
568 new Response(200, ['Content-Type' => 'application/json'], Stream
::factory('
573 "resolved_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview"
580 $client->getEmitter()->attach($mock);
582 $pocketImport = $this->getPocketImport();
584 $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
585 ->disableOriginalConstructor()
588 $entryRepo->expects($this->once())
589 ->method('findByUrlAndUserId')
590 ->will($this->onConsecutiveCalls(false, true));
593 ->expects($this->once())
594 ->method('getRepository')
595 ->willReturn($entryRepo);
597 $entry = new Entry($this->user
);
600 ->expects($this->once())
601 ->method('updateEntry')
602 ->will($this->throwException(new \
Exception()));
604 $pocketImport->setClient($client);
605 $pocketImport->authorize('wunderbar_code');
607 $res = $pocketImport->import();
609 $this->assertTrue($res);
610 $this->assertEquals(['skipped' => 1, 'imported' => 0, 'queued' => 0], $pocketImport->getSummary());