]> git.immae.eu Git - github/wallabag/wallabag.git/blame - tests/Wallabag/ImportBundle/Import/PocketImportTest.php
Update docker-composer with RabbitMQ configuration
[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;
7ec2897e 7use Wallabag\ImportBundle\Import\PocketImport;
7ec2897e
JB
8use GuzzleHttp\Client;
9use GuzzleHttp\Subscriber\Mock;
10use GuzzleHttp\Message\Response;
11use GuzzleHttp\Stream\Stream;
252ebd60
JB
12use Monolog\Logger;
13use Monolog\Handler\TestHandler;
14
15class PocketImportMock extends PocketImport
16{
17 public function getAccessToken()
18 {
19 return $this->accessToken;
20 }
21}
7ec2897e
JB
22
23class PocketImportTest extends \PHPUnit_Framework_TestCase
24{
25 protected $token;
26 protected $user;
7ec2897e 27 protected $em;
252ebd60
JB
28 protected $contentProxy;
29 protected $logHandler;
56c778b4 30 protected $producer;
7ec2897e 31
56c778b4 32 private function getPocketImport($consumerKey = 'ConsumerKey', $rabbitMQ = false)
7ec2897e
JB
33 {
34 $this->user = new User();
35
36 $this->tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')
37 ->disableOriginalConstructor()
38 ->getMock();
39
40 $token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')
41 ->disableOriginalConstructor()
42 ->getMock();
43
252ebd60
JB
44 $this->contentProxy = $this->getMockBuilder('Wallabag\CoreBundle\Helper\ContentProxy')
45 ->disableOriginalConstructor()
46 ->getMock();
47
7ec2897e
JB
48 $token->expects($this->once())
49 ->method('getUser')
50 ->willReturn($this->user);
51
52 $this->tokenStorage->expects($this->once())
53 ->method('getToken')
54 ->willReturn($token);
55
7ec2897e
JB
56 $this->em = $this->getMockBuilder('Doctrine\ORM\EntityManager')
57 ->disableOriginalConstructor()
58 ->getMock();
59
63e40f2d
JB
60 $config = $this->getMockBuilder('Craue\ConfigBundle\Util\Config')
61 ->disableOriginalConstructor()
62 ->getMock();
63
64 $config->expects($this->any())
65 ->method('get')
66 ->with('pocket_consumer_key')
67 ->willReturn($consumerKey);
68
56c778b4
NL
69 $this->producer = $this->getMockBuilder('OldSound\RabbitMqBundle\RabbitMq\Producer')
70 ->disableOriginalConstructor()
71 ->getMock();
72
252ebd60 73 $pocket = new PocketImportMock(
7ec2897e 74 $this->tokenStorage,
7ec2897e 75 $this->em,
252ebd60 76 $this->contentProxy,
56c778b4 77 $config,
56c778b4 78 $this->producer
7ec2897e 79 );
252ebd60
JB
80
81 $this->logHandler = new TestHandler();
4094ea47 82 $logger = new Logger('test', [$this->logHandler]);
252ebd60
JB
83 $pocket->setLogger($logger);
84
85 return $pocket;
7ec2897e
JB
86 }
87
88 public function testInit()
89 {
90 $pocketImport = $this->getPocketImport();
91
92 $this->assertEquals('Pocket', $pocketImport->getName());
7019c7cf 93 $this->assertNotEmpty($pocketImport->getUrl());
0d42217e 94 $this->assertEquals('import.pocket.description', $pocketImport->getDescription());
7ec2897e
JB
95 }
96
97 public function testOAuthRequest()
98 {
99 $client = new Client();
100
101 $mock = new Mock([
252ebd60 102 new Response(200, ['Content-Type' => 'application/json'], Stream::factory(json_encode(['code' => 'wunderbar_code']))),
7ec2897e
JB
103 ]);
104
105 $client->getEmitter()->attach($mock);
106
107 $pocketImport = $this->getPocketImport();
108 $pocketImport->setClient($client);
109
252ebd60 110 $code = $pocketImport->getRequestToken('http://0.0.0.0/redirect');
7ec2897e 111
252ebd60
JB
112 $this->assertEquals('wunderbar_code', $code);
113 }
114
115 public function testOAuthRequestBadResponse()
116 {
117 $client = new Client();
118
119 $mock = new Mock([
120 new Response(403),
121 ]);
122
123 $client->getEmitter()->attach($mock);
124
125 $pocketImport = $this->getPocketImport();
126 $pocketImport->setClient($client);
127
128 $code = $pocketImport->getRequestToken('http://0.0.0.0/redirect');
129
130 $this->assertFalse($code);
131
132 $records = $this->logHandler->getRecords();
133 $this->assertContains('PocketImport: Failed to request token', $records[0]['message']);
134 $this->assertEquals('ERROR', $records[0]['level_name']);
7ec2897e
JB
135 }
136
137 public function testOAuthAuthorize()
138 {
139 $client = new Client();
140
141 $mock = new Mock([
252ebd60 142 new Response(200, ['Content-Type' => 'application/json'], Stream::factory(json_encode(['access_token' => 'wunderbar_token']))),
7ec2897e
JB
143 ]);
144
145 $client->getEmitter()->attach($mock);
146
147 $pocketImport = $this->getPocketImport();
148 $pocketImport->setClient($client);
149
252ebd60 150 $res = $pocketImport->authorize('wunderbar_code');
7ec2897e 151
252ebd60
JB
152 $this->assertTrue($res);
153 $this->assertEquals('wunderbar_token', $pocketImport->getAccessToken());
7ec2897e
JB
154 }
155
252ebd60
JB
156 public function testOAuthAuthorizeBadResponse()
157 {
158 $client = new Client();
159
160 $mock = new Mock([
161 new Response(403),
162 ]);
163
164 $client->getEmitter()->attach($mock);
165
166 $pocketImport = $this->getPocketImport();
167 $pocketImport->setClient($client);
168
169 $res = $pocketImport->authorize('wunderbar_code');
170
171 $this->assertFalse($res);
172
173 $records = $this->logHandler->getRecords();
174 $this->assertContains('PocketImport: Failed to authorize client', $records[0]['message']);
175 $this->assertEquals('ERROR', $records[0]['level_name']);
176 }
177
178 /**
179 * Will sample results from https://getpocket.com/developer/docs/v3/retrieve.
180 */
7ec2897e
JB
181 public function testImport()
182 {
183 $client = new Client();
184
185 $mock = new Mock([
252ebd60
JB
186 new Response(200, ['Content-Type' => 'application/json'], Stream::factory(json_encode(['access_token' => 'wunderbar_token']))),
187 new Response(200, ['Content-Type' => 'application/json'], Stream::factory('
188 {
189 "status": 1,
190 "list": {
191 "229279689": {
192 "item_id": "229279689",
193 "resolved_id": "229279689",
194 "given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
195 "given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland",
196 "favorite": "1",
197 "status": "1",
198 "resolved_title": "The Massive Ryder Cup Preview",
199 "resolved_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
200 "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.",
201 "is_article": "1",
202 "has_video": "1",
203 "has_image": "1",
204 "word_count": "3197",
205 "images": {
206 "1": {
207 "item_id": "229279689",
208 "image_id": "1",
209 "src": "http://a.espncdn.com/combiner/i?img=/photo/2012/0927/grant_g_ryder_cr_640.jpg&w=640&h=360",
210 "width": "0",
211 "height": "0",
212 "credit": "Jamie Squire/Getty Images",
213 "caption": ""
214 }
215 },
216 "videos": {
217 "1": {
218 "item_id": "229279689",
219 "video_id": "1",
220 "src": "http://www.youtube.com/v/Er34PbFkVGk?version=3&hl=en_US&rel=0",
221 "width": "420",
222 "height": "315",
223 "type": "1",
224 "vid": "Er34PbFkVGk"
225 }
226 },
227 "tags": {
228 "grantland": {
229 "item_id": "1147652870",
230 "tag": "grantland"
231 },
232 "Ryder Cup": {
233 "item_id": "1147652870",
234 "tag": "Ryder Cup"
235 }
236 }
237 },
238 "229279690": {
239 "item_id": "229279689",
240 "resolved_id": "229279689",
241 "given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
242 "given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland",
243 "favorite": "1",
244 "status": "1",
245 "resolved_title": "The Massive Ryder Cup Preview",
246 "resolved_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
247 "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.",
248 "is_article": "1",
249 "has_video": "0",
250 "has_image": "0",
251 "word_count": "3197"
252 }
253 }
254 }
255 ')),
256 ]);
257
258 $client->getEmitter()->attach($mock);
259
260 $pocketImport = $this->getPocketImport();
261
262 $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
263 ->disableOriginalConstructor()
264 ->getMock();
265
266 $entryRepo->expects($this->exactly(2))
78833672 267 ->method('findByUrlAndUserId')
252ebd60
JB
268 ->will($this->onConsecutiveCalls(false, true));
269
252ebd60 270 $this->em
c2656f96 271 ->expects($this->exactly(2))
252ebd60 272 ->method('getRepository')
c2656f96 273 ->willReturn($entryRepo);
252ebd60 274
79d0e38e 275 $entry = new Entry($this->user);
252ebd60
JB
276
277 $this->contentProxy
278 ->expects($this->once())
279 ->method('updateEntry')
280 ->willReturn($entry);
281
282 $pocketImport->setClient($client);
283 $pocketImport->authorize('wunderbar_code');
284
285 $res = $pocketImport->import();
286
287 $this->assertTrue($res);
288 $this->assertEquals(['skipped' => 1, 'imported' => 1], $pocketImport->getSummary());
289 }
290
79d0e38e
JB
291 /**
292 * Will sample results from https://getpocket.com/developer/docs/v3/retrieve.
293 */
294 public function testImportAndMarkAllAsRead()
295 {
296 $client = new Client();
297
298 $mock = new Mock([
299 new Response(200, ['Content-Type' => 'application/json'], Stream::factory(json_encode(['access_token' => 'wunderbar_token']))),
300 new Response(200, ['Content-Type' => 'application/json'], Stream::factory('
301 {
302 "status": 1,
303 "list": {
304 "229279689": {
305 "item_id": "229279689",
306 "resolved_id": "229279689",
307 "given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
308 "given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland",
309 "favorite": "1",
310 "status": "1",
79d0e38e
JB
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.",
312 "is_article": "1",
313 "has_video": "1",
314 "has_image": "1",
315 "word_count": "3197"
316 },
317 "229279690": {
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",
322 "favorite": "1",
323 "status": "0",
79d0e38e
JB
324 "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.",
325 "is_article": "1",
326 "has_video": "0",
327 "has_image": "0",
328 "word_count": "3197"
329 }
330 }
331 }
332 ')),
333 ]);
334
335 $client->getEmitter()->attach($mock);
336
337 $pocketImport = $this->getPocketImport();
338
339 $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
340 ->disableOriginalConstructor()
341 ->getMock();
342
343 $entryRepo->expects($this->exactly(2))
344 ->method('findByUrlAndUserId')
345 ->will($this->onConsecutiveCalls(false, false));
346
347 $this->em
348 ->expects($this->exactly(2))
349 ->method('getRepository')
350 ->willReturn($entryRepo);
351
352 // check that every entry persisted are archived
353 $this->em
354 ->expects($this->any())
355 ->method('persist')
cebb4223 356 ->with($this->callback(function ($persistedEntry) {
79d0e38e
JB
357 return $persistedEntry->isArchived();
358 }));
359
360 $entry = new Entry($this->user);
361
362 $this->contentProxy
363 ->expects($this->exactly(2))
364 ->method('updateEntry')
365 ->willReturn($entry);
366
367 $pocketImport->setClient($client);
368 $pocketImport->authorize('wunderbar_code');
369
370 $res = $pocketImport->setMarkAsRead(true)->import();
371
372 $this->assertTrue($res);
373 $this->assertEquals(['skipped' => 0, 'imported' => 2], $pocketImport->getSummary());
374 }
375
252ebd60
JB
376 public function testImportBadResponse()
377 {
378 $client = new Client();
379
380 $mock = new Mock([
381 new Response(200, ['Content-Type' => 'application/json'], Stream::factory(json_encode(['access_token' => 'wunderbar_token']))),
382 new Response(403),
7ec2897e
JB
383 ]);
384
385 $client->getEmitter()->attach($mock);
386
387 $pocketImport = $this->getPocketImport();
388 $pocketImport->setClient($client);
252ebd60
JB
389 $pocketImport->authorize('wunderbar_code');
390
391 $res = $pocketImport->import();
7ec2897e 392
252ebd60 393 $this->assertFalse($res);
7ec2897e 394
252ebd60
JB
395 $records = $this->logHandler->getRecords();
396 $this->assertContains('PocketImport: Failed to import', $records[0]['message']);
397 $this->assertEquals('ERROR', $records[0]['level_name']);
7ec2897e 398 }
19d9efab
JB
399
400 public function testImportWithExceptionFromGraby()
401 {
402 $client = new Client();
403
404 $mock = new Mock([
405 new Response(200, ['Content-Type' => 'application/json'], Stream::factory(json_encode(['access_token' => 'wunderbar_token']))),
406 new Response(200, ['Content-Type' => 'application/json'], Stream::factory('
407 {
408 "status": 1,
409 "list": {
410 "229279689": {
411 "resolved_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview"
412 }
413 }
414 }
415 ')),
416 ]);
417
418 $client->getEmitter()->attach($mock);
419
420 $pocketImport = $this->getPocketImport();
421
422 $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
423 ->disableOriginalConstructor()
424 ->getMock();
425
426 $entryRepo->expects($this->once())
427 ->method('findByUrlAndUserId')
428 ->will($this->onConsecutiveCalls(false, true));
429
430 $this->em
431 ->expects($this->once())
432 ->method('getRepository')
433 ->willReturn($entryRepo);
434
435 $entry = new Entry($this->user);
436
437 $this->contentProxy
438 ->expects($this->once())
439 ->method('updateEntry')
440 ->will($this->throwException(new \Exception()));
441
442 $pocketImport->setClient($client);
443 $pocketImport->authorize('wunderbar_code');
444
445 $res = $pocketImport->import();
446
447 $this->assertTrue($res);
448 $this->assertEquals(['skipped' => 1, 'imported' => 0], $pocketImport->getSummary());
449 }
7ec2897e 450}