]> git.immae.eu Git - github/wallabag/wallabag.git/blob - src/Wallabag/ApiBundle/Tests/Controller/WallabagRestControllerTest.php
b36ae7c68083fb259b06354f93b490074d0f8b76
[github/wallabag/wallabag.git] / src / Wallabag / ApiBundle / Tests / Controller / WallabagRestControllerTest.php
1 <?php
2
3 namespace Wallabag\ApiBundle\Tests\Controller;
4
5 use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
6
7 class WallabagRestControllerTest extends WebTestCase
8 {
9 protected static $salt;
10
11 /**
12 * Grab the salt once and store it to be available for all tests
13 */
14 public static function setUpBeforeClass()
15 {
16 $client = self::createClient();
17
18 $user = $client->getContainer()
19 ->get('doctrine.orm.entity_manager')
20 ->getRepository('WallabagCoreBundle:User')
21 ->findOneByUsername('admin');
22
23 self::$salt = $user->getSalt();
24 }
25
26 /**
27 * Generate HTTP headers for authenticate user on API
28 *
29 * @param string $username
30 * @param string $password
31 *
32 * @return array
33 */
34 private function generateHeaders($username, $password)
35 {
36 $encryptedPassword = sha1($password.$username.self::$salt);
37 $nonce = substr(md5(uniqid('nonce_', true)), 0, 16);
38
39 $now = new \DateTime('now', new \DateTimeZone('UTC'));
40 $created = (string) $now->format('Y-m-d\TH:i:s\Z');
41 $digest = base64_encode(sha1(base64_decode($nonce).$created.$encryptedPassword, true));
42
43 return array(
44 'HTTP_AUTHORIZATION' => 'Authorization profile="UsernameToken"',
45 'HTTP_x-wsse' => 'X-WSSE: UsernameToken Username="'.$username.'", PasswordDigest="'.$digest.'", Nonce="'.$nonce.'", Created="'.$created.'"',
46 );
47 }
48
49 public function testGetSalt()
50 {
51 $client = $this->createClient();
52 $client->request('GET', '/api/salts/admin.json');
53
54 $user = $client->getContainer()
55 ->get('doctrine.orm.entity_manager')
56 ->getRepository('WallabagCoreBundle:User')
57 ->findOneByUsername('admin');
58
59 $this->assertEquals(200, $client->getResponse()->getStatusCode());
60
61 $content = json_decode($client->getResponse()->getContent(), true);
62
63 $this->assertArrayHasKey(0, $content);
64 $this->assertEquals($user->getSalt(), $content[0]);
65
66 $client->request('GET', '/api/salts/notfound.json');
67 $this->assertEquals(404, $client->getResponse()->getStatusCode());
68 }
69
70 public function testWithBadHeaders()
71 {
72 $client = $this->createClient();
73
74 $entry = $client->getContainer()
75 ->get('doctrine.orm.entity_manager')
76 ->getRepository('WallabagCoreBundle:Entry')
77 ->findOneByIsArchived(false);
78
79 if (!$entry) {
80 $this->markTestSkipped('No content found in db.');
81 }
82
83 $badHeaders = array(
84 'HTTP_AUTHORIZATION' => 'Authorization profile="UsernameToken"',
85 'HTTP_x-wsse' => 'X-WSSE: UsernameToken Username="admin", PasswordDigest="Wr0ngDig3st", Nonce="n0Nc3", Created="2015-01-01T13:37:00Z"',
86 );
87
88 $client->request('GET', '/api/entries/'.$entry->getId().'.json', array(), array(), $badHeaders);
89 $this->assertEquals(403, $client->getResponse()->getStatusCode());
90 }
91
92 public function testGetOneEntry()
93 {
94 $client = $this->createClient();
95 $headers = $this->generateHeaders('admin', 'mypassword');
96
97 $entry = $client->getContainer()
98 ->get('doctrine.orm.entity_manager')
99 ->getRepository('WallabagCoreBundle:Entry')
100 ->findOneBy(array('user' => 1, 'isArchived' => false));
101
102 if (!$entry) {
103 $this->markTestSkipped('No content found in db.');
104 }
105
106 $client->request('GET', '/api/entries/'.$entry->getId().'.json', array(), array(), $headers);
107
108 $this->assertEquals(200, $client->getResponse()->getStatusCode());
109
110 $content = json_decode($client->getResponse()->getContent(), true);
111
112 $this->assertEquals($entry->getTitle(), $content['title']);
113 $this->assertEquals($entry->getUrl(), $content['url']);
114 $this->assertCount(count($entry->getTags()), $content['tags']);
115
116 $this->assertTrue(
117 $client->getResponse()->headers->contains(
118 'Content-Type',
119 'application/json'
120 )
121 );
122 }
123
124 public function testGetOneEntryWrongUser()
125 {
126 $client = $this->createClient();
127 $headers = $this->generateHeaders('admin', 'mypassword');
128
129 $entry = $client->getContainer()
130 ->get('doctrine.orm.entity_manager')
131 ->getRepository('WallabagCoreBundle:Entry')
132 ->findOneBy(array('user' => 2, 'isArchived' => false));
133
134 if (!$entry) {
135 $this->markTestSkipped('No content found in db.');
136 }
137
138 $client->request('GET', '/api/entries/'.$entry->getId().'.json', array(), array(), $headers);
139
140 $this->assertEquals(403, $client->getResponse()->getStatusCode());
141 }
142
143 public function testGetEntries()
144 {
145 $client = $this->createClient();
146 $headers = $this->generateHeaders('admin', 'mypassword');
147
148 $client->request('GET', '/api/entries', array(), array(), $headers);
149
150 $this->assertEquals(200, $client->getResponse()->getStatusCode());
151
152 $content = json_decode($client->getResponse()->getContent(), true);
153
154 $this->assertGreaterThanOrEqual(1, count($content));
155 $this->assertNotEmpty($content['_embedded']['items']);
156 $this->assertGreaterThanOrEqual(1, $content['total']);
157 $this->assertEquals(1, $content['page']);
158 $this->assertGreaterThanOrEqual(1, $content['pages']);
159
160 $this->assertTrue(
161 $client->getResponse()->headers->contains(
162 'Content-Type',
163 'application/json'
164 )
165 );
166 }
167
168 public function testGetStarredEntries()
169 {
170 $client = $this->createClient();
171 $headers = $this->generateHeaders('admin', 'mypassword');
172
173 $client->request('GET', '/api/entries', array('archive' => 1), array(), $headers);
174
175 $this->assertEquals(200, $client->getResponse()->getStatusCode());
176
177 $content = json_decode($client->getResponse()->getContent(), true);
178
179 $this->assertGreaterThanOrEqual(1, count($content));
180 $this->assertNotEmpty($content['_embedded']['items']);
181 $this->assertGreaterThanOrEqual(1, $content['total']);
182 $this->assertEquals(1, $content['page']);
183 $this->assertGreaterThanOrEqual(1, $content['pages']);
184
185 $this->assertTrue(
186 $client->getResponse()->headers->contains(
187 'Content-Type',
188 'application/json'
189 )
190 );
191 }
192
193 public function testDeleteEntry()
194 {
195 $client = $this->createClient();
196 $headers = $this->generateHeaders('admin', 'mypassword');
197
198 $entry = $client->getContainer()
199 ->get('doctrine.orm.entity_manager')
200 ->getRepository('WallabagCoreBundle:Entry')
201 ->findOneByUser(1);
202
203 if (!$entry) {
204 $this->markTestSkipped('No content found in db.');
205 }
206
207 $client->request('DELETE', '/api/entries/'.$entry->getId().'.json', array(), array(), $headers);
208
209 $this->assertEquals(200, $client->getResponse()->getStatusCode());
210
211 $content = json_decode($client->getResponse()->getContent(), true);
212
213 $this->assertEquals($entry->getTitle(), $content['title']);
214 $this->assertEquals($entry->getUrl(), $content['url']);
215
216 // We'll try to delete this entry again
217 $headers = $this->generateHeaders('admin', 'mypassword');
218
219 $client->request('DELETE', '/api/entries/'.$entry->getId().'.json', array(), array(), $headers);
220
221 $this->assertEquals(404, $client->getResponse()->getStatusCode());
222 }
223
224 public function testPostEntry()
225 {
226 $client = $this->createClient();
227 $headers = $this->generateHeaders('admin', 'mypassword');
228
229 $client->request('POST', '/api/entries.json', array(
230 'url' => 'http://www.lemonde.fr/pixels/article/2015/03/28/plongee-dans-l-univers-d-ingress-le-jeu-de-google-aux-frontieres-du-reel_4601155_4408996.html',
231 'tags' => 'google',
232 ), array(), $headers);
233
234 $this->assertEquals(200, $client->getResponse()->getStatusCode());
235
236 $content = json_decode($client->getResponse()->getContent(), true);
237
238 $this->assertGreaterThan(0, $content['id']);
239 $this->assertEquals('http://www.lemonde.fr/pixels/article/2015/03/28/plongee-dans-l-univers-d-ingress-le-jeu-de-google-aux-frontieres-du-reel_4601155_4408996.html', $content['url']);
240 $this->assertEquals(false, $content['is_archived']);
241 $this->assertEquals(false, $content['is_starred']);
242 $this->assertCount(1, $content['tags']);
243 }
244
245 public function testPatchEntry()
246 {
247 $client = $this->createClient();
248 $headers = $this->generateHeaders('admin', 'mypassword');
249
250 $entry = $client->getContainer()
251 ->get('doctrine.orm.entity_manager')
252 ->getRepository('WallabagCoreBundle:Entry')
253 ->findOneByUser(1);
254
255 if (!$entry) {
256 $this->markTestSkipped('No content found in db.');
257 }
258
259 // hydrate the tags relations
260 $nbTags = count($entry->getTags());
261
262 $client->request('PATCH', '/api/entries/'.$entry->getId().'.json', array(
263 'title' => 'New awesome title',
264 'tags' => 'new tag '.uniqid(),
265 'star' => true,
266 'archive' => false,
267 ), array(), $headers);
268
269 $this->assertEquals(200, $client->getResponse()->getStatusCode());
270
271 $content = json_decode($client->getResponse()->getContent(), true);
272
273 $this->assertEquals($entry->getId(), $content['id']);
274 $this->assertEquals($entry->getUrl(), $content['url']);
275 $this->assertEquals('New awesome title', $content['title']);
276 $this->assertGreaterThan($nbTags, count($content['tags']));
277 }
278
279 public function testGetTagsEntry()
280 {
281 $client = $this->createClient();
282 $headers = $this->generateHeaders('admin', 'mypassword');
283
284 $entry = $client->getContainer()
285 ->get('doctrine.orm.entity_manager')
286 ->getRepository('WallabagCoreBundle:Entry')
287 ->findOneWithTags(1);
288
289 $entry = $entry[0];
290
291 if (!$entry) {
292 $this->markTestSkipped('No content found in db.');
293 }
294
295 $tags = array();
296 foreach ($entry->getTags() as $tag) {
297 $tags[] = array('id' => $tag->getId(), 'label' => $tag->getLabel());
298 }
299
300 $client->request('GET', '/api/entries/'.$entry->getId().'/tags', array(), array(), $headers);
301
302 $this->assertEquals(json_encode($tags, JSON_HEX_QUOT), $client->getResponse()->getContent());
303 }
304
305 public function testPostTagsOnEntry()
306 {
307 $client = $this->createClient();
308 $headers = $this->generateHeaders('admin', 'mypassword');
309
310 $entry = $client->getContainer()
311 ->get('doctrine.orm.entity_manager')
312 ->getRepository('WallabagCoreBundle:Entry')
313 ->findOneByUser(1);
314
315 if (!$entry) {
316 $this->markTestSkipped('No content found in db.');
317 }
318
319 $nbTags = count($entry->getTags());
320
321 $newTags = 'tag1,tag2,tag3';
322
323 $client->request('POST', '/api/entries/'.$entry->getId().'/tags', array('tags' => $newTags), array(), $headers);
324
325 $this->assertEquals(200, $client->getResponse()->getStatusCode());
326
327 $content = json_decode($client->getResponse()->getContent(), true);
328
329 $this->assertArrayHasKey('tags', $content);
330 $this->assertEquals($nbTags+3, count($content['tags']));
331
332 $entryDB = $client->getContainer()
333 ->get('doctrine.orm.entity_manager')
334 ->getRepository('WallabagCoreBundle:Entry')
335 ->find($entry->getId());
336
337 $tagsInDB = array();
338 foreach ($entryDB->getTags()->toArray() as $tag) {
339 $tagsInDB[$tag->getId()] = $tag->getLabel();
340 }
341
342 foreach (explode(',', $newTags) as $tag) {
343 $this->assertContains($tag, $tagsInDB);
344 }
345 }
346
347 public function testDeleteOneTagEntrie()
348 {
349 $client = $this->createClient();
350 $headers = $this->generateHeaders('admin', 'mypassword');
351
352 $entry = $client->getContainer()
353 ->get('doctrine.orm.entity_manager')
354 ->getRepository('WallabagCoreBundle:Entry')
355 ->findOneByUser(1);
356
357 if (!$entry) {
358 $this->markTestSkipped('No content found in db.');
359 }
360
361 // hydrate the tags relations
362 $nbTags = count($entry->getTags());
363 $tag = $entry->getTags()[0];
364
365 $client->request('DELETE', '/api/entries/'.$entry->getId().'/tags/'.$tag->getId().'.json', array(), array(), $headers);
366
367 $this->assertEquals(200, $client->getResponse()->getStatusCode());
368
369 $content = json_decode($client->getResponse()->getContent(), true);
370
371 $this->assertArrayHasKey('tags', $content);
372 $this->assertEquals($nbTags-1, count($content['tags']));
373 }
374
375 public function testGetUserTags()
376 {
377 $client = $this->createClient();
378 $headers = $this->generateHeaders('admin', 'mypassword');
379
380 $client->request('GET', '/api/tags.json', array(), array(), $headers);
381
382 $this->assertEquals(200, $client->getResponse()->getStatusCode());
383
384 $content = json_decode($client->getResponse()->getContent(), true);
385
386 $this->assertGreaterThan(0, $content);
387 $this->assertArrayHasKey('id', $content[0]);
388 $this->assertArrayHasKey('label', $content[0]);
389
390 return end($content);
391 }
392
393 /**
394 * @depends testGetUserTags
395 */
396 public function testDeleteUserTag($tag)
397 {
398 $client = $this->createClient();
399 $headers = $this->generateHeaders('admin', 'mypassword');
400
401 $client->request('DELETE', '/api/tags/'.$tag['id'].'.json', array(), array(), $headers);
402
403 $this->assertEquals(200, $client->getResponse()->getStatusCode());
404
405 $content = json_decode($client->getResponse()->getContent(), true);
406
407 $this->assertArrayHasKey('label', $content);
408 $this->assertEquals($tag['label'], $content['label']);
409 }
410 }