diff options
-rw-r--r-- | app/config/config.yml | 2 | ||||
-rw-r--r-- | src/Wallabag/ApiBundle/Controller/WallabagRestController.php | 38 | ||||
-rw-r--r-- | src/Wallabag/ApiBundle/Resources/config/routing_rest.yml | 10 | ||||
-rw-r--r-- | tests/Wallabag/ApiBundle/Controller/WallabagRestControllerTest.php | 104 |
4 files changed, 90 insertions, 64 deletions
diff --git a/app/config/config.yml b/app/config/config.yml index 75d7299c..48f317c7 100644 --- a/app/config/config.yml +++ b/app/config/config.yml | |||
@@ -130,6 +130,8 @@ fos_rest: | |||
130 | nelmio_api_doc: | 130 | nelmio_api_doc: |
131 | sandbox: | 131 | sandbox: |
132 | enabled: false | 132 | enabled: false |
133 | cache: | ||
134 | enabled: true | ||
133 | name: wallabag API documentation | 135 | name: wallabag API documentation |
134 | 136 | ||
135 | nelmio_cors: | 137 | nelmio_cors: |
diff --git a/src/Wallabag/ApiBundle/Controller/WallabagRestController.php b/src/Wallabag/ApiBundle/Controller/WallabagRestController.php index 072e5f85..85875589 100644 --- a/src/Wallabag/ApiBundle/Controller/WallabagRestController.php +++ b/src/Wallabag/ApiBundle/Controller/WallabagRestController.php | |||
@@ -3,7 +3,7 @@ | |||
3 | namespace Wallabag\ApiBundle\Controller; | 3 | namespace Wallabag\ApiBundle\Controller; |
4 | 4 | ||
5 | use FOS\RestBundle\Controller\FOSRestController; | 5 | use FOS\RestBundle\Controller\FOSRestController; |
6 | use Hateoas\Configuration\Route; | 6 | use Hateoas\Configuration\Route as HateoasRoute; |
7 | use Hateoas\Representation\Factory\PagerfantaFactory; | 7 | use Hateoas\Representation\Factory\PagerfantaFactory; |
8 | use Nelmio\ApiDocBundle\Annotation\ApiDoc; | 8 | use Nelmio\ApiDocBundle\Annotation\ApiDoc; |
9 | use Symfony\Component\HttpFoundation\Request; | 9 | use Symfony\Component\HttpFoundation\Request; |
@@ -12,6 +12,7 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface; | |||
12 | use Symfony\Component\Security\Core\Exception\AccessDeniedException; | 12 | use Symfony\Component\Security\Core\Exception\AccessDeniedException; |
13 | use Wallabag\CoreBundle\Entity\Entry; | 13 | use Wallabag\CoreBundle\Entity\Entry; |
14 | use Wallabag\CoreBundle\Entity\Tag; | 14 | use Wallabag\CoreBundle\Entity\Tag; |
15 | use FOS\RestBundle\Controller\Annotations\Route; | ||
15 | 16 | ||
16 | class WallabagRestController extends FOSRestController | 17 | class WallabagRestController extends FOSRestController |
17 | { | 18 | { |
@@ -95,7 +96,7 @@ class WallabagRestController extends FOSRestController | |||
95 | $pagerfantaFactory = new PagerfantaFactory('page', 'perPage'); | 96 | $pagerfantaFactory = new PagerfantaFactory('page', 'perPage'); |
96 | $paginatedCollection = $pagerfantaFactory->createRepresentation( | 97 | $paginatedCollection = $pagerfantaFactory->createRepresentation( |
97 | $pager, | 98 | $pager, |
98 | new Route( | 99 | new HateoasRoute( |
99 | 'api_get_entries', | 100 | 'api_get_entries', |
100 | [ | 101 | [ |
101 | 'archive' => $isArchived, | 102 | 'archive' => $isArchived, |
@@ -127,24 +128,41 @@ class WallabagRestController extends FOSRestController | |||
127 | * | 128 | * |
128 | * @return JsonResponse | 129 | * @return JsonResponse |
129 | */ | 130 | */ |
130 | public function getEntryAction(Entry $entry, $_format) | 131 | public function getEntryAction(Entry $entry) |
131 | { | 132 | { |
132 | $this->validateAuthentication(); | 133 | $this->validateAuthentication(); |
133 | $this->validateUserAccess($entry->getUser()->getId()); | 134 | $this->validateUserAccess($entry->getUser()->getId()); |
134 | 135 | ||
135 | if ($_format === 'epub') { | ||
136 | return $this->get('wallabag_core.helper.entries_export') | ||
137 | ->setEntries($entry) | ||
138 | ->updateTitle('entry') | ||
139 | ->exportAs($_format); | ||
140 | } | ||
141 | |||
142 | $json = $this->get('serializer')->serialize($entry, 'json'); | 136 | $json = $this->get('serializer')->serialize($entry, 'json'); |
143 | 137 | ||
144 | return (new JsonResponse())->setJson($json); | 138 | return (new JsonResponse())->setJson($json); |
145 | } | 139 | } |
146 | 140 | ||
147 | /** | 141 | /** |
142 | * Retrieve a single entry as a predefined format. | ||
143 | * | ||
144 | * @ApiDoc( | ||
145 | * requirements={ | ||
146 | * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"} | ||
147 | * } | ||
148 | * ) | ||
149 | * | ||
150 | * @Route(requirements={"_format"="epub|mobi|pdf|txt|csv"}) | ||
151 | * | ||
152 | * @return Response | ||
153 | */ | ||
154 | public function getEntryExportAction(Entry $entry, Request $request) | ||
155 | { | ||
156 | $this->validateAuthentication(); | ||
157 | $this->validateUserAccess($entry->getUser()->getId()); | ||
158 | |||
159 | return $this->get('wallabag_core.helper.entries_export') | ||
160 | ->setEntries($entry) | ||
161 | ->updateTitle('entry') | ||
162 | ->exportAs($request->attributes->get('_format')); | ||
163 | } | ||
164 | |||
165 | /** | ||
148 | * Create an entry. | 166 | * Create an entry. |
149 | * | 167 | * |
150 | * @ApiDoc( | 168 | * @ApiDoc( |
diff --git a/src/Wallabag/ApiBundle/Resources/config/routing_rest.yml b/src/Wallabag/ApiBundle/Resources/config/routing_rest.yml index 9aef7e8e..35f8b2c1 100644 --- a/src/Wallabag/ApiBundle/Resources/config/routing_rest.yml +++ b/src/Wallabag/ApiBundle/Resources/config/routing_rest.yml | |||
@@ -1,6 +1,4 @@ | |||
1 | entries: | 1 | api: |
2 | type: rest | 2 | type: rest |
3 | resource: "WallabagApiBundle:WallabagRest" | 3 | resource: "WallabagApiBundle:WallabagRest" |
4 | name_prefix: api_ | 4 | name_prefix: api_ |
5 | requirements: | ||
6 | _format: xml|json|html|epub | ||
diff --git a/tests/Wallabag/ApiBundle/Controller/WallabagRestControllerTest.php b/tests/Wallabag/ApiBundle/Controller/WallabagRestControllerTest.php index 65b65290..79353857 100644 --- a/tests/Wallabag/ApiBundle/Controller/WallabagRestControllerTest.php +++ b/tests/Wallabag/ApiBundle/Controller/WallabagRestControllerTest.php | |||
@@ -32,12 +32,55 @@ class WallabagRestControllerTest extends WallabagApiTestCase | |||
32 | $this->assertEquals($entry->getUserEmail(), $content['user_email']); | 32 | $this->assertEquals($entry->getUserEmail(), $content['user_email']); |
33 | $this->assertEquals($entry->getUserId(), $content['user_id']); | 33 | $this->assertEquals($entry->getUserId(), $content['user_id']); |
34 | 34 | ||
35 | $this->assertTrue( | 35 | $this->assertEquals('application/json', $this->client->getResponse()->headers->get('Content-Type')); |
36 | $this->client->getResponse()->headers->contains( | 36 | } |
37 | 'Content-Type', | 37 | |
38 | 'application/json' | 38 | public function testExportEntry() |
39 | ) | 39 | { |
40 | ); | 40 | $entry = $this->client->getContainer() |
41 | ->get('doctrine.orm.entity_manager') | ||
42 | ->getRepository('WallabagCoreBundle:Entry') | ||
43 | ->findOneBy(['user' => 1, 'isArchived' => false]); | ||
44 | |||
45 | if (!$entry) { | ||
46 | $this->markTestSkipped('No content found in db.'); | ||
47 | } | ||
48 | |||
49 | $this->client->request('GET', '/api/entries/'.$entry->getId().'/export.epub'); | ||
50 | $this->assertEquals(200, $this->client->getResponse()->getStatusCode()); | ||
51 | |||
52 | // epub format got the content type in the content | ||
53 | $this->assertContains('application/epub', $this->client->getResponse()->getContent()); | ||
54 | $this->assertEquals('application/epub+zip', $this->client->getResponse()->headers->get('Content-Type')); | ||
55 | |||
56 | // re-auth client for mobi | ||
57 | $client = $this->createAuthorizedClient(); | ||
58 | $client->request('GET', '/api/entries/'.$entry->getId().'/export.mobi'); | ||
59 | $this->assertEquals(200, $client->getResponse()->getStatusCode()); | ||
60 | |||
61 | $this->assertEquals('application/x-mobipocket-ebook', $client->getResponse()->headers->get('Content-Type')); | ||
62 | |||
63 | // re-auth client for pdf | ||
64 | $client = $this->createAuthorizedClient(); | ||
65 | $client->request('GET', '/api/entries/'.$entry->getId().'/export.pdf'); | ||
66 | $this->assertEquals(200, $client->getResponse()->getStatusCode()); | ||
67 | |||
68 | $this->assertContains('PDF-', $client->getResponse()->getContent()); | ||
69 | $this->assertEquals('application/pdf', $client->getResponse()->headers->get('Content-Type')); | ||
70 | |||
71 | // re-auth client for pdf | ||
72 | $client = $this->createAuthorizedClient(); | ||
73 | $client->request('GET', '/api/entries/'.$entry->getId().'/export.txt'); | ||
74 | $this->assertEquals(200, $client->getResponse()->getStatusCode()); | ||
75 | |||
76 | $this->assertContains('text/plain', $client->getResponse()->headers->get('Content-Type')); | ||
77 | |||
78 | // re-auth client for pdf | ||
79 | $client = $this->createAuthorizedClient(); | ||
80 | $client->request('GET', '/api/entries/'.$entry->getId().'/export.csv'); | ||
81 | $this->assertEquals(200, $client->getResponse()->getStatusCode()); | ||
82 | |||
83 | $this->assertContains('application/csv', $client->getResponse()->headers->get('Content-Type')); | ||
41 | } | 84 | } |
42 | 85 | ||
43 | public function testGetOneEntryWrongUser() | 86 | public function testGetOneEntryWrongUser() |
@@ -70,12 +113,7 @@ class WallabagRestControllerTest extends WallabagApiTestCase | |||
70 | $this->assertEquals(1, $content['page']); | 113 | $this->assertEquals(1, $content['page']); |
71 | $this->assertGreaterThanOrEqual(1, $content['pages']); | 114 | $this->assertGreaterThanOrEqual(1, $content['pages']); |
72 | 115 | ||
73 | $this->assertTrue( | 116 | $this->assertEquals('application/json', $this->client->getResponse()->headers->get('Content-Type')); |
74 | $this->client->getResponse()->headers->contains( | ||
75 | 'Content-Type', | ||
76 | 'application/json' | ||
77 | ) | ||
78 | ); | ||
79 | } | 117 | } |
80 | 118 | ||
81 | public function testGetEntriesWithFullOptions() | 119 | public function testGetEntriesWithFullOptions() |
@@ -117,12 +155,7 @@ class WallabagRestControllerTest extends WallabagApiTestCase | |||
117 | $this->assertContains('since=1443274283', $content['_links'][$link]['href']); | 155 | $this->assertContains('since=1443274283', $content['_links'][$link]['href']); |
118 | } | 156 | } |
119 | 157 | ||
120 | $this->assertTrue( | 158 | $this->assertEquals('application/json', $this->client->getResponse()->headers->get('Content-Type')); |
121 | $this->client->getResponse()->headers->contains( | ||
122 | 'Content-Type', | ||
123 | 'application/json' | ||
124 | ) | ||
125 | ); | ||
126 | } | 159 | } |
127 | 160 | ||
128 | public function testGetStarredEntries() | 161 | public function testGetStarredEntries() |
@@ -150,12 +183,7 @@ class WallabagRestControllerTest extends WallabagApiTestCase | |||
150 | $this->assertContains('sort=updated', $content['_links'][$link]['href']); | 183 | $this->assertContains('sort=updated', $content['_links'][$link]['href']); |
151 | } | 184 | } |
152 | 185 | ||
153 | $this->assertTrue( | 186 | $this->assertEquals('application/json', $this->client->getResponse()->headers->get('Content-Type')); |
154 | $this->client->getResponse()->headers->contains( | ||
155 | 'Content-Type', | ||
156 | 'application/json' | ||
157 | ) | ||
158 | ); | ||
159 | } | 187 | } |
160 | 188 | ||
161 | public function testGetArchiveEntries() | 189 | public function testGetArchiveEntries() |
@@ -182,12 +210,7 @@ class WallabagRestControllerTest extends WallabagApiTestCase | |||
182 | $this->assertContains('archive=1', $content['_links'][$link]['href']); | 210 | $this->assertContains('archive=1', $content['_links'][$link]['href']); |
183 | } | 211 | } |
184 | 212 | ||
185 | $this->assertTrue( | 213 | $this->assertEquals('application/json', $this->client->getResponse()->headers->get('Content-Type')); |
186 | $this->client->getResponse()->headers->contains( | ||
187 | 'Content-Type', | ||
188 | 'application/json' | ||
189 | ) | ||
190 | ); | ||
191 | } | 214 | } |
192 | 215 | ||
193 | public function testGetTaggedEntries() | 216 | public function testGetTaggedEntries() |
@@ -214,12 +237,7 @@ class WallabagRestControllerTest extends WallabagApiTestCase | |||
214 | $this->assertContains('tags='.urlencode('foo,bar'), $content['_links'][$link]['href']); | 237 | $this->assertContains('tags='.urlencode('foo,bar'), $content['_links'][$link]['href']); |
215 | } | 238 | } |
216 | 239 | ||
217 | $this->assertTrue( | 240 | $this->assertEquals('application/json', $this->client->getResponse()->headers->get('Content-Type')); |
218 | $this->client->getResponse()->headers->contains( | ||
219 | 'Content-Type', | ||
220 | 'application/json' | ||
221 | ) | ||
222 | ); | ||
223 | } | 241 | } |
224 | 242 | ||
225 | public function testGetDatedEntries() | 243 | public function testGetDatedEntries() |
@@ -246,12 +264,7 @@ class WallabagRestControllerTest extends WallabagApiTestCase | |||
246 | $this->assertContains('since=1443274283', $content['_links'][$link]['href']); | 264 | $this->assertContains('since=1443274283', $content['_links'][$link]['href']); |
247 | } | 265 | } |
248 | 266 | ||
249 | $this->assertTrue( | 267 | $this->assertEquals('application/json', $this->client->getResponse()->headers->get('Content-Type')); |
250 | $this->client->getResponse()->headers->contains( | ||
251 | 'Content-Type', | ||
252 | 'application/json' | ||
253 | ) | ||
254 | ); | ||
255 | } | 268 | } |
256 | 269 | ||
257 | public function testGetDatedSupEntries() | 270 | public function testGetDatedSupEntries() |
@@ -279,12 +292,7 @@ class WallabagRestControllerTest extends WallabagApiTestCase | |||
279 | $this->assertContains('since='.($future->getTimestamp() + 1000), $content['_links'][$link]['href']); | 292 | $this->assertContains('since='.($future->getTimestamp() + 1000), $content['_links'][$link]['href']); |
280 | } | 293 | } |
281 | 294 | ||
282 | $this->assertTrue( | 295 | $this->assertEquals('application/json', $this->client->getResponse()->headers->get('Content-Type')); |
283 | $this->client->getResponse()->headers->contains( | ||
284 | 'Content-Type', | ||
285 | 'application/json' | ||
286 | ) | ||
287 | ); | ||
288 | } | 296 | } |
289 | 297 | ||
290 | public function testDeleteEntry() | 298 | public function testDeleteEntry() |