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 $this->uow
= $this->getMockBuilder('Doctrine\ORM\UnitOfWork')
45 ->disableOriginalConstructor()
49 ->expects($this->any())
50 ->method('getUnitOfWork')
51 ->willReturn($this->uow
);
54 ->expects($this->any())
55 ->method('getScheduledEntityInsertions')
58 $pocket = new PocketImport(
62 $pocket->setUser($this->user
);
64 $this->logHandler
= new TestHandler();
65 $logger = new Logger('test', [$this->logHandler
]);
66 $pocket->setLogger($logger);
71 public function testInit()
73 $pocketImport = $this->getPocketImport();
75 $this->assertEquals('Pocket', $pocketImport->getName());
76 $this->assertNotEmpty($pocketImport->getUrl());
77 $this->assertEquals('import.pocket.description', $pocketImport->getDescription());
80 public function testOAuthRequest()
82 $client = new Client();
85 new Response(200, ['Content-Type' => 'application/json'], Stream
::factory(json_encode(['code' => 'wunderbar_code']))),
88 $client->getEmitter()->attach($mock);
90 $pocketImport = $this->getPocketImport();
91 $pocketImport->setClient($client);
93 $code = $pocketImport->getRequestToken('http://0.0.0.0/redirect');
95 $this->assertEquals('wunderbar_code', $code);
98 public function testOAuthRequestBadResponse()
100 $client = new Client();
106 $client->getEmitter()->attach($mock);
108 $pocketImport = $this->getPocketImport();
109 $pocketImport->setClient($client);
111 $code = $pocketImport->getRequestToken('http://0.0.0.0/redirect');
113 $this->assertFalse($code);
115 $records = $this->logHandler
->getRecords();
116 $this->assertContains('PocketImport: Failed to request token', $records[0]['message']);
117 $this->assertEquals('ERROR', $records[0]['level_name']);
120 public function testOAuthAuthorize()
122 $client = new Client();
125 new Response(200, ['Content-Type' => 'application/json'], Stream
::factory(json_encode(['access_token' => 'wunderbar_token']))),
128 $client->getEmitter()->attach($mock);
130 $pocketImport = $this->getPocketImport();
131 $pocketImport->setClient($client);
133 $res = $pocketImport->authorize('wunderbar_code');
135 $this->assertTrue($res);
136 $this->assertEquals('wunderbar_token', $pocketImport->getAccessToken());
139 public function testOAuthAuthorizeBadResponse()
141 $client = new Client();
147 $client->getEmitter()->attach($mock);
149 $pocketImport = $this->getPocketImport();
150 $pocketImport->setClient($client);
152 $res = $pocketImport->authorize('wunderbar_code');
154 $this->assertFalse($res);
156 $records = $this->logHandler
->getRecords();
157 $this->assertContains('PocketImport: Failed to authorize client', $records[0]['message']);
158 $this->assertEquals('ERROR', $records[0]['level_name']);
162 * Will sample results from https://getpocket.com/developer/docs/v3/retrieve.
164 public function testImport()
166 $client = new Client();
169 new Response(200, ['Content-Type' => 'application/json'], Stream
::factory(json_encode(['access_token' => 'wunderbar_token']))),
170 new Response(200, ['Content-Type' => 'application/json'], Stream
::factory('
175 "item_id": "229279689",
176 "resolved_id": "229279689",
177 "given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
178 "given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland",
181 "time_added": "1473020899",
182 "time_updated": "1473020899",
184 "time_favorited": "0",
186 "resolved_title": "The Massive Ryder Cup Preview",
187 "resolved_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
188 "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.",
193 "word_count": "3197",
196 "item_id": "229279689",
198 "src": "http://a.espncdn.com/combiner/i?img=/photo/2012/0927/grant_g_ryder_cr_640.jpg&w=640&h=360",
201 "credit": "Jamie Squire/Getty Images",
207 "item_id": "229279689",
209 "src": "http://www.youtube.com/v/Er34PbFkVGk?version=3&hl=en_US&rel=0",
218 "item_id": "1147652870",
222 "item_id": "1147652870",
228 "item_id": "229279689",
229 "resolved_id": "229279689",
230 "given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
231 "given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland",
234 "time_added": "1473020899",
235 "time_updated": "1473020899",
237 "time_favorited": "0",
239 "resolved_title": "The Massive Ryder Cup Preview",
240 "resolved_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
241 "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.",
253 $client->getEmitter()->attach($mock);
255 $pocketImport = $this->getPocketImport();
257 $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
258 ->disableOriginalConstructor()
261 $entryRepo->expects($this->exactly(2))
262 ->method('findByUrlAndUserId')
263 ->will($this->onConsecutiveCalls(false, true));
266 ->expects($this->exactly(2))
267 ->method('getRepository')
268 ->willReturn($entryRepo);
270 $entry = new Entry($this->user
);
273 ->expects($this->once())
274 ->method('updateEntry')
275 ->willReturn($entry);
277 $pocketImport->setClient($client);
278 $pocketImport->authorize('wunderbar_code');
280 $res = $pocketImport->import();
282 $this->assertTrue($res);
283 $this->assertEquals(['skipped' => 1, 'imported' => 1, 'queued' => 0], $pocketImport->getSummary());
287 * Will sample results from https://getpocket.com/developer/docs/v3/retrieve.
289 public function testImportAndMarkAllAsRead()
291 $client = new Client();
294 new Response(200, ['Content-Type' => 'application/json'], Stream
::factory(json_encode(['access_token' => 'wunderbar_token']))),
295 new Response(200, ['Content-Type' => 'application/json'], Stream
::factory('
300 "item_id": "229279689",
301 "resolved_id": "229279689",
302 "given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
303 "given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland",
306 "time_added": "1473020899",
307 "time_updated": "1473020899",
309 "time_favorited": "0",
311 "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.",
318 "item_id": "229279689",
319 "resolved_id": "229279689",
320 "given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview/2",
321 "given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland",
324 "time_added": "1473020899",
325 "time_updated": "1473020899",
327 "time_favorited": "0",
329 "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.",
340 $client->getEmitter()->attach($mock);
342 $pocketImport = $this->getPocketImport();
344 $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
345 ->disableOriginalConstructor()
348 $entryRepo->expects($this->exactly(2))
349 ->method('findByUrlAndUserId')
350 ->will($this->onConsecutiveCalls(false, false));
353 ->expects($this->exactly(2))
354 ->method('getRepository')
355 ->willReturn($entryRepo);
357 // check that every entry persisted are archived
359 ->expects($this->any())
361 ->with($this->callback(function ($persistedEntry) {
362 return $persistedEntry->isArchived();
365 $entry = new Entry($this->user
);
368 ->expects($this->exactly(2))
369 ->method('updateEntry')
370 ->willReturn($entry);
372 $pocketImport->setClient($client);
373 $pocketImport->authorize('wunderbar_code');
375 $res = $pocketImport->setMarkAsRead(true)->import();
377 $this->assertTrue($res);
378 $this->assertEquals(['skipped' => 0, 'imported' => 2, 'queued' => 0], $pocketImport->getSummary());
382 * Will sample results from https://getpocket.com/developer/docs/v3/retrieve.
384 public function testImportWithRabbit()
386 $client = new Client();
390 "item_id": "229279689",
391 "resolved_id": "229279689",
392 "given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
393 "given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland",
396 "time_added": "1473020899",
397 "time_updated": "1473020899",
399 "time_favorited": "0",
401 "resolved_title": "The Massive Ryder Cup Preview",
402 "resolved_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
403 "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.",
412 new Response(200, ['Content-Type' => 'application/json'], Stream
::factory(json_encode(['access_token' => 'wunderbar_token']))),
413 new Response(200, ['Content-Type' => 'application/json'], Stream
::factory('
417 "229279690": '.$body.'
423 $client->getEmitter()->attach($mock);
425 $pocketImport = $this->getPocketImport();
427 $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
428 ->disableOriginalConstructor()
431 $entryRepo->expects($this->never())
432 ->method('findByUrlAndUserId');
435 ->expects($this->never())
436 ->method('getRepository');
438 $entry = new Entry($this->user
);
441 ->expects($this->never())
442 ->method('updateEntry');
444 $producer = $this->getMockBuilder('OldSound\RabbitMqBundle\RabbitMq\Producer')
445 ->disableOriginalConstructor()
448 $bodyAsArray = json_decode($body, true);
449 // because with just use `new User()` so it doesn't have an id
450 $bodyAsArray['userId'] = null;
453 ->expects($this->once())
455 ->with(json_encode($bodyAsArray));
457 $pocketImport->setClient($client);
458 $pocketImport->setProducer($producer);
459 $pocketImport->authorize('wunderbar_code');
461 $res = $pocketImport->setMarkAsRead(true)->import();
463 $this->assertTrue($res);
464 $this->assertEquals(['skipped' => 0, 'imported' => 0, 'queued' => 1], $pocketImport->getSummary());
468 * Will sample results from https://getpocket.com/developer/docs/v3/retrieve.
470 public function testImportWithRedis()
472 $client = new Client();
476 "item_id": "229279689",
477 "resolved_id": "229279689",
478 "given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
479 "given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland",
482 "time_added": "1473020899",
483 "time_updated": "1473020899",
485 "time_favorited": "0",
487 "resolved_title": "The Massive Ryder Cup Preview",
488 "resolved_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
489 "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.",
498 new Response(200, ['Content-Type' => 'application/json'], Stream
::factory(json_encode(['access_token' => 'wunderbar_token']))),
499 new Response(200, ['Content-Type' => 'application/json'], Stream
::factory('
503 "229279690": '.$body.'
509 $client->getEmitter()->attach($mock);
511 $pocketImport = $this->getPocketImport();
513 $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
514 ->disableOriginalConstructor()
517 $entryRepo->expects($this->never())
518 ->method('findByUrlAndUserId');
521 ->expects($this->never())
522 ->method('getRepository');
524 $entry = new Entry($this->user
);
527 ->expects($this->never())
528 ->method('updateEntry');
530 $factory = new RedisMockFactory();
531 $redisMock = $factory->getAdapter('Predis\Client', true);
533 $queue = new RedisQueue($redisMock, 'pocket');
534 $producer = new Producer($queue);
536 $pocketImport->setClient($client);
537 $pocketImport->setProducer($producer);
538 $pocketImport->authorize('wunderbar_code');
540 $res = $pocketImport->setMarkAsRead(true)->import();
542 $this->assertTrue($res);
543 $this->assertEquals(['skipped' => 0, 'imported' => 0, 'queued' => 1], $pocketImport->getSummary());
545 $this->assertNotEmpty($redisMock->lpop('pocket'));
548 public function testImportBadResponse()
550 $client = new Client();
553 new Response(200, ['Content-Type' => 'application/json'], Stream
::factory(json_encode(['access_token' => 'wunderbar_token']))),
557 $client->getEmitter()->attach($mock);
559 $pocketImport = $this->getPocketImport();
560 $pocketImport->setClient($client);
561 $pocketImport->authorize('wunderbar_code');
563 $res = $pocketImport->import();
565 $this->assertFalse($res);
567 $records = $this->logHandler
->getRecords();
568 $this->assertContains('PocketImport: Failed to import', $records[0]['message']);
569 $this->assertEquals('ERROR', $records[0]['level_name']);
572 public function testImportWithExceptionFromGraby()
574 $client = new Client();
577 new Response(200, ['Content-Type' => 'application/json'], Stream
::factory(json_encode(['access_token' => 'wunderbar_token']))),
578 new Response(200, ['Content-Type' => 'application/json'], Stream
::factory('
585 "resolved_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview"
592 $client->getEmitter()->attach($mock);
594 $pocketImport = $this->getPocketImport();
596 $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
597 ->disableOriginalConstructor()
600 $entryRepo->expects($this->once())
601 ->method('findByUrlAndUserId')
602 ->will($this->onConsecutiveCalls(false, true));
605 ->expects($this->once())
606 ->method('getRepository')
607 ->willReturn($entryRepo);
609 $entry = new Entry($this->user
);
612 ->expects($this->once())
613 ->method('updateEntry')
614 ->will($this->throwException(new \
Exception()));
616 $pocketImport->setClient($client);
617 $pocketImport->authorize('wunderbar_code');
619 $res = $pocketImport->import();
621 $this->assertTrue($res);
622 $this->assertEquals(['skipped' => 0, 'imported' => 1, 'queued' => 0], $pocketImport->getSummary());