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