]> git.immae.eu Git - github/wallabag/wallabag.git/commitdiff
Exploded WallabagRestController into many controllers
authorNicolas Lœuillet <nicolas@loeuillet.org>
Fri, 28 Oct 2016 12:46:30 +0000 (14:46 +0200)
committerNicolas Lœuillet <nicolas@loeuillet.org>
Fri, 28 Oct 2016 12:46:30 +0000 (14:46 +0200)
Fix #2503

src/Wallabag/ApiBundle/Controller/EntryRestController.php [new file with mode: 0644]
src/Wallabag/ApiBundle/Controller/TagRestController.php [new file with mode: 0644]
src/Wallabag/ApiBundle/Controller/WallabagRestController.php
src/Wallabag/ApiBundle/Resources/config/routing_rest.yml
tests/Wallabag/ApiBundle/Controller/EntryRestControllerTest.php [new file with mode: 0644]
tests/Wallabag/ApiBundle/Controller/TagRestControllerTest.php [new file with mode: 0644]
tests/Wallabag/ApiBundle/Controller/WallabagRestControllerTest.php

diff --git a/src/Wallabag/ApiBundle/Controller/EntryRestController.php b/src/Wallabag/ApiBundle/Controller/EntryRestController.php
new file mode 100644 (file)
index 0000000..24fa7b3
--- /dev/null
@@ -0,0 +1,367 @@
+<?php
+
+namespace Wallabag\ApiBundle\Controller;
+
+use Hateoas\Configuration\Route;
+use Hateoas\Representation\Factory\PagerfantaFactory;
+use Nelmio\ApiDocBundle\Annotation\ApiDoc;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\JsonResponse;
+use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
+use Wallabag\CoreBundle\Entity\Entry;
+use Wallabag\CoreBundle\Entity\Tag;
+
+class EntryRestController extends WallabagRestController
+{
+    /**
+     * Check if an entry exist by url.
+     *
+     * @ApiDoc(
+     *       parameters={
+     *          {"name"="url", "dataType"="string", "required"=true, "format"="An url", "description"="Url to check if it exists"},
+     *          {"name"="urls", "dataType"="string", "required"=false, "format"="An array of urls (?urls[]=http...&urls[]=http...)", "description"="Urls (as an array) to check if it exists"}
+     *       }
+     * )
+     *
+     * @return JsonResponse
+     */
+    public function getEntriesExistsAction(Request $request)
+    {
+        $this->validateAuthentication();
+
+        $urls = $request->query->get('urls', []);
+
+        // handle multiple urls first
+        if (!empty($urls)) {
+            $results = [];
+            foreach ($urls as $url) {
+                $res = $this->getDoctrine()
+                    ->getRepository('WallabagCoreBundle:Entry')
+                    ->findByUrlAndUserId($url, $this->getUser()->getId());
+
+                $results[$url] = false === $res ? false : true;
+            }
+
+            $json = $this->get('serializer')->serialize($results, 'json');
+
+            return (new JsonResponse())->setJson($json);
+        }
+
+        // let's see if it is a simple url?
+        $url = $request->query->get('url', '');
+
+        if (empty($url)) {
+            throw $this->createAccessDeniedException('URL is empty?, logged user id: '.$this->getUser()->getId());
+        }
+
+        $res = $this->getDoctrine()
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findByUrlAndUserId($url, $this->getUser()->getId());
+
+        $exists = false === $res ? false : true;
+
+        $json = $this->get('serializer')->serialize(['exists' => $exists], 'json');
+
+        return (new JsonResponse())->setJson($json);
+    }
+
+    /**
+     * Retrieve all entries. It could be filtered by many options.
+     *
+     * @ApiDoc(
+     *       parameters={
+     *          {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0, all entries by default", "description"="filter by archived status."},
+     *          {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0, all entries by default", "description"="filter by starred status."},
+     *          {"name"="sort", "dataType"="string", "required"=false, "format"="'created' or 'updated', default 'created'", "description"="sort entries by date."},
+     *          {"name"="order", "dataType"="string", "required"=false, "format"="'asc' or 'desc', default 'desc'", "description"="order of sort."},
+     *          {"name"="page", "dataType"="integer", "required"=false, "format"="default '1'", "description"="what page you want."},
+     *          {"name"="perPage", "dataType"="integer", "required"=false, "format"="default'30'", "description"="results per page."},
+     *          {"name"="tags", "dataType"="string", "required"=false, "format"="api,rest", "description"="a list of tags url encoded. Will returns entries that matches ALL tags."},
+     *          {"name"="since", "dataType"="integer", "required"=false, "format"="default '0'", "description"="The timestamp since when you want entries updated."},
+     *       }
+     * )
+     *
+     * @return JsonResponse
+     */
+    public function getEntriesAction(Request $request)
+    {
+        $this->validateAuthentication();
+
+        $isArchived = (null === $request->query->get('archive')) ? null : (bool) $request->query->get('archive');
+        $isStarred = (null === $request->query->get('starred')) ? null : (bool) $request->query->get('starred');
+        $sort = $request->query->get('sort', 'created');
+        $order = $request->query->get('order', 'desc');
+        $page = (int) $request->query->get('page', 1);
+        $perPage = (int) $request->query->get('perPage', 30);
+        $tags = $request->query->get('tags', '');
+        $since = $request->query->get('since', 0);
+
+        $pager = $this->getDoctrine()
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findEntries($this->getUser()->getId(), $isArchived, $isStarred, $sort, $order, $since, $tags);
+
+        $pager->setCurrentPage($page);
+        $pager->setMaxPerPage($perPage);
+
+        $pagerfantaFactory = new PagerfantaFactory('page', 'perPage');
+        $paginatedCollection = $pagerfantaFactory->createRepresentation(
+            $pager,
+            new Route(
+                'api_get_entries',
+                [
+                    'archive' => $isArchived,
+                    'starred' => $isStarred,
+                    'sort' => $sort,
+                    'order' => $order,
+                    'page' => $page,
+                    'perPage' => $perPage,
+                    'tags' => $tags,
+                    'since' => $since,
+                ],
+                UrlGeneratorInterface::ABSOLUTE_URL
+            )
+        );
+
+        $json = $this->get('serializer')->serialize($paginatedCollection, 'json');
+
+        return (new JsonResponse())->setJson($json);
+    }
+
+    /**
+     * Retrieve a single entry.
+     *
+     * @ApiDoc(
+     *      requirements={
+     *          {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
+     *      }
+     * )
+     *
+     * @return JsonResponse
+     */
+    public function getEntryAction(Entry $entry)
+    {
+        $this->validateAuthentication();
+        $this->validateUserAccess($entry->getUser()->getId());
+
+        $json = $this->get('serializer')->serialize($entry, 'json');
+
+        return (new JsonResponse())->setJson($json);
+    }
+
+    /**
+     * Create an entry.
+     *
+     * @ApiDoc(
+     *       parameters={
+     *          {"name"="url", "dataType"="string", "required"=true, "format"="http://www.test.com/article.html", "description"="Url for the entry."},
+     *          {"name"="title", "dataType"="string", "required"=false, "description"="Optional, we'll get the title from the page."},
+     *          {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."},
+     *          {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="entry already starred"},
+     *          {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="entry already archived"},
+     *       }
+     * )
+     *
+     * @return JsonResponse
+     */
+    public function postEntriesAction(Request $request)
+    {
+        $this->validateAuthentication();
+
+        $url = $request->request->get('url');
+        $title = $request->request->get('title');
+        $isArchived = $request->request->get('archive');
+        $isStarred = $request->request->get('starred');
+
+        $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId($url, $this->getUser()->getId());
+
+        if (false === $entry) {
+            $entry = $this->get('wallabag_core.content_proxy')->updateEntry(
+                new Entry($this->getUser()),
+                $url
+            );
+        }
+
+        if (!is_null($title)) {
+            $entry->setTitle($title);
+        }
+
+        $tags = $request->request->get('tags', '');
+        if (!empty($tags)) {
+            $this->get('wallabag_core.content_proxy')->assignTagsToEntry($entry, $tags);
+        }
+
+        if (!is_null($isStarred)) {
+            $entry->setStarred((bool) $isStarred);
+        }
+
+        if (!is_null($isArchived)) {
+            $entry->setArchived((bool) $isArchived);
+        }
+
+        $em = $this->getDoctrine()->getManager();
+        $em->persist($entry);
+
+        $em->flush();
+
+        $json = $this->get('serializer')->serialize($entry, 'json');
+
+        return (new JsonResponse())->setJson($json);
+    }
+
+    /**
+     * Change several properties of an entry.
+     *
+     * @ApiDoc(
+     *      requirements={
+     *          {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
+     *      },
+     *      parameters={
+     *          {"name"="title", "dataType"="string", "required"=false},
+     *          {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."},
+     *          {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="archived the entry."},
+     *          {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="starred the entry."},
+     *      }
+     * )
+     *
+     * @return JsonResponse
+     */
+    public function patchEntriesAction(Entry $entry, Request $request)
+    {
+        $this->validateAuthentication();
+        $this->validateUserAccess($entry->getUser()->getId());
+
+        $title = $request->request->get('title');
+        $isArchived = $request->request->get('archive');
+        $isStarred = $request->request->get('starred');
+
+        if (!is_null($title)) {
+            $entry->setTitle($title);
+        }
+
+        if (!is_null($isArchived)) {
+            $entry->setArchived((bool) $isArchived);
+        }
+
+        if (!is_null($isStarred)) {
+            $entry->setStarred((bool) $isStarred);
+        }
+
+        $tags = $request->request->get('tags', '');
+        if (!empty($tags)) {
+            $this->get('wallabag_core.content_proxy')->assignTagsToEntry($entry, $tags);
+        }
+
+        $em = $this->getDoctrine()->getManager();
+        $em->flush();
+
+        $json = $this->get('serializer')->serialize($entry, 'json');
+
+        return (new JsonResponse())->setJson($json);
+    }
+
+    /**
+     * Delete **permanently** an entry.
+     *
+     * @ApiDoc(
+     *      requirements={
+     *          {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
+     *      }
+     * )
+     *
+     * @return JsonResponse
+     */
+    public function deleteEntriesAction(Entry $entry)
+    {
+        $this->validateAuthentication();
+        $this->validateUserAccess($entry->getUser()->getId());
+
+        $em = $this->getDoctrine()->getManager();
+        $em->remove($entry);
+        $em->flush();
+
+        $json = $this->get('serializer')->serialize($entry, 'json');
+
+        return (new JsonResponse())->setJson($json);
+    }
+
+    /**
+     * Retrieve all tags for an entry.
+     *
+     * @ApiDoc(
+     *      requirements={
+     *          {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
+     *      }
+     * )
+     *
+     * @return JsonResponse
+     */
+    public function getEntriesTagsAction(Entry $entry)
+    {
+        $this->validateAuthentication();
+        $this->validateUserAccess($entry->getUser()->getId());
+
+        $json = $this->get('serializer')->serialize($entry->getTags(), 'json');
+
+        return (new JsonResponse())->setJson($json);
+    }
+
+    /**
+     * Add one or more tags to an entry.
+     *
+     * @ApiDoc(
+     *      requirements={
+     *          {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
+     *      },
+     *      parameters={
+     *          {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."},
+     *       }
+     * )
+     *
+     * @return JsonResponse
+     */
+    public function postEntriesTagsAction(Request $request, Entry $entry)
+    {
+        $this->validateAuthentication();
+        $this->validateUserAccess($entry->getUser()->getId());
+
+        $tags = $request->request->get('tags', '');
+        if (!empty($tags)) {
+            $this->get('wallabag_core.content_proxy')->assignTagsToEntry($entry, $tags);
+        }
+
+        $em = $this->getDoctrine()->getManager();
+        $em->persist($entry);
+        $em->flush();
+
+        $json = $this->get('serializer')->serialize($entry, 'json');
+
+        return (new JsonResponse())->setJson($json);
+    }
+
+    /**
+     * Permanently remove one tag for an entry.
+     *
+     * @ApiDoc(
+     *      requirements={
+     *          {"name"="tag", "dataType"="integer", "requirement"="\w+", "description"="The tag ID"},
+     *          {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
+     *      }
+     * )
+     *
+     * @return JsonResponse
+     */
+    public function deleteEntriesTagsAction(Entry $entry, Tag $tag)
+    {
+        $this->validateAuthentication();
+        $this->validateUserAccess($entry->getUser()->getId());
+
+        $entry->removeTag($tag);
+        $em = $this->getDoctrine()->getManager();
+        $em->persist($entry);
+        $em->flush();
+
+        $json = $this->get('serializer')->serialize($entry, 'json');
+
+        return (new JsonResponse())->setJson($json);
+    }
+}
diff --git a/src/Wallabag/ApiBundle/Controller/TagRestController.php b/src/Wallabag/ApiBundle/Controller/TagRestController.php
new file mode 100644 (file)
index 0000000..4e7ddc6
--- /dev/null
@@ -0,0 +1,171 @@
+<?php
+
+namespace Wallabag\ApiBundle\Controller;
+
+use Nelmio\ApiDocBundle\Annotation\ApiDoc;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\JsonResponse;
+use Wallabag\CoreBundle\Entity\Entry;
+use Wallabag\CoreBundle\Entity\Tag;
+
+class TagRestController extends WallabagRestController
+{
+    /**
+     * Retrieve all tags.
+     *
+     * @ApiDoc()
+     *
+     * @return JsonResponse
+     */
+    public function getTagsAction()
+    {
+        $this->validateAuthentication();
+
+        $tags = $this->getDoctrine()
+            ->getRepository('WallabagCoreBundle:Tag')
+            ->findAllTags($this->getUser()->getId());
+
+        $json = $this->get('serializer')->serialize($tags, 'json');
+
+        return (new JsonResponse())->setJson($json);
+    }
+
+    /**
+     * Permanently remove one tag from **every** entry.
+     *
+     * @ApiDoc(
+     *      requirements={
+     *          {"name"="tag", "dataType"="string", "required"=true, "requirement"="\w+", "description"="Tag as a string"}
+     *      }
+     * )
+     *
+     * @return JsonResponse
+     */
+    public function deleteTagLabelAction(Request $request)
+    {
+        $this->validateAuthentication();
+        $label = $request->request->get('tag', '');
+
+        $tag = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findOneByLabel($label);
+
+        if (empty($tag)) {
+            throw $this->createNotFoundException('Tag not found');
+        }
+
+        $this->getDoctrine()
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->removeTag($this->getUser()->getId(), $tag);
+
+        $this->cleanOrphanTag($tag);
+
+        $json = $this->get('serializer')->serialize($tag, 'json');
+
+        return (new JsonResponse())->setJson($json);
+    }
+
+    /**
+     * Permanently remove some tags from **every** entry.
+     *
+     * @ApiDoc(
+     *      requirements={
+     *          {"name"="tags", "dataType"="string", "required"=true, "format"="tag1,tag2", "description"="Tags as strings (comma splitted)"}
+     *      }
+     * )
+     *
+     * @return JsonResponse
+     */
+    public function deleteTagsLabelAction(Request $request)
+    {
+        $this->validateAuthentication();
+
+        $tagsLabels = $request->request->get('tags', '');
+
+        $tags = [];
+
+        foreach (explode(',', $tagsLabels) as $tagLabel) {
+            $tagEntity = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findOneByLabel($tagLabel);
+
+            if (!empty($tagEntity)) {
+                $tags[] = $tagEntity;
+            }
+        }
+
+        if (empty($tags)) {
+            throw $this->createNotFoundException('Tags not found');
+        }
+
+        $this->getDoctrine()
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->removeTags($this->getUser()->getId(), $tags);
+
+        $this->cleanOrphanTag($tags);
+
+        $json = $this->get('serializer')->serialize($tags, 'json');
+
+        return (new JsonResponse())->setJson($json);
+    }
+
+    /**
+     * Permanently remove one tag from **every** entry.
+     *
+     * @ApiDoc(
+     *      requirements={
+     *          {"name"="tag", "dataType"="integer", "requirement"="\w+", "description"="The tag"}
+     *      }
+     * )
+     *
+     * @return JsonResponse
+     */
+    public function deleteTagAction(Tag $tag)
+    {
+        $this->validateAuthentication();
+
+        $this->getDoctrine()
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->removeTag($this->getUser()->getId(), $tag);
+
+        $this->cleanOrphanTag($tag);
+
+        $json = $this->get('serializer')->serialize($tag, 'json');
+
+        return (new JsonResponse())->setJson($json);
+    }
+
+    /**
+     * Retrieve version number.
+     *
+     * @ApiDoc()
+     *
+     * @return JsonResponse
+     */
+    public function getVersionAction()
+    {
+        $version = $this->container->getParameter('wallabag_core.version');
+
+        $json = $this->get('serializer')->serialize($version, 'json');
+
+        return (new JsonResponse())->setJson($json);
+    }
+
+    /**
+     * Remove orphan tag in case no entries are associated to it.
+     *
+     * @param Tag|array $tags
+     */
+    private function cleanOrphanTag($tags)
+    {
+        if (!is_array($tags)) {
+            $tags = [$tags];
+        }
+
+        $em = $this->getDoctrine()->getManager();
+
+        foreach ($tags as $tag) {
+            if (count($tag->getEntries()) === 0) {
+                $em->remove($tag);
+            }
+        }
+
+        $em->flush();
+    }
+}
index 9997913d2afefbd7c0f03143b17640470f1a42ae..e927a8903a26af16f796fa8016e6dad7322d5b5a 100644 (file)
 namespace Wallabag\ApiBundle\Controller;
 
 use FOS\RestBundle\Controller\FOSRestController;
-use Hateoas\Configuration\Route;
-use Hateoas\Representation\Factory\PagerfantaFactory;
-use Nelmio\ApiDocBundle\Annotation\ApiDoc;
-use Symfony\Component\HttpFoundation\Request;
-use Symfony\Component\HttpFoundation\JsonResponse;
-use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
 use Symfony\Component\Security\Core\Exception\AccessDeniedException;
 use Wallabag\CoreBundle\Entity\Entry;
-use Wallabag\CoreBundle\Entity\Tag;
 
 class WallabagRestController extends FOSRestController
 {
-    private function validateAuthentication()
+    protected function validateAuthentication()
     {
         if (false === $this->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_FULLY')) {
             throw new AccessDeniedException();
         }
     }
 
-    /**
-     * Check if an entry exist by url.
-     *
-     * @ApiDoc(
-     *       parameters={
-     *          {"name"="url", "dataType"="string", "required"=true, "format"="An url", "description"="Url to check if it exists"},
-     *          {"name"="urls", "dataType"="string", "required"=false, "format"="An array of urls (?urls[]=http...&urls[]=http...)", "description"="Urls (as an array) to check if it exists"}
-     *       }
-     * )
-     *
-     * @return JsonResponse
-     */
-    public function getEntriesExistsAction(Request $request)
-    {
-        $this->validateAuthentication();
-
-        $urls = $request->query->get('urls', []);
-
-        // handle multiple urls first
-        if (!empty($urls)) {
-            $results = [];
-            foreach ($urls as $url) {
-                $res = $this->getDoctrine()
-                    ->getRepository('WallabagCoreBundle:Entry')
-                    ->findByUrlAndUserId($url, $this->getUser()->getId());
-
-                $results[$url] = false === $res ? false : true;
-            }
-
-            $json = $this->get('serializer')->serialize($results, 'json');
-
-            return (new JsonResponse())->setJson($json);
-        }
-
-        // let's see if it is a simple url?
-        $url = $request->query->get('url', '');
-
-        if (empty($url)) {
-            throw $this->createAccessDeniedException('URL is empty?, logged user id: '.$this->getUser()->getId());
-        }
-
-        $res = $this->getDoctrine()
-            ->getRepository('WallabagCoreBundle:Entry')
-            ->findByUrlAndUserId($url, $this->getUser()->getId());
-
-        $exists = false === $res ? false : true;
-
-        $json = $this->get('serializer')->serialize(['exists' => $exists], 'json');
-
-        return (new JsonResponse())->setJson($json);
-    }
-
-    /**
-     * Retrieve all entries. It could be filtered by many options.
-     *
-     * @ApiDoc(
-     *       parameters={
-     *          {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0, all entries by default", "description"="filter by archived status."},
-     *          {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0, all entries by default", "description"="filter by starred status."},
-     *          {"name"="sort", "dataType"="string", "required"=false, "format"="'created' or 'updated', default 'created'", "description"="sort entries by date."},
-     *          {"name"="order", "dataType"="string", "required"=false, "format"="'asc' or 'desc', default 'desc'", "description"="order of sort."},
-     *          {"name"="page", "dataType"="integer", "required"=false, "format"="default '1'", "description"="what page you want."},
-     *          {"name"="perPage", "dataType"="integer", "required"=false, "format"="default'30'", "description"="results per page."},
-     *          {"name"="tags", "dataType"="string", "required"=false, "format"="api,rest", "description"="a list of tags url encoded. Will returns entries that matches ALL tags."},
-     *          {"name"="since", "dataType"="integer", "required"=false, "format"="default '0'", "description"="The timestamp since when you want entries updated."},
-     *       }
-     * )
-     *
-     * @return JsonResponse
-     */
-    public function getEntriesAction(Request $request)
-    {
-        $this->validateAuthentication();
-
-        $isArchived = (null === $request->query->get('archive')) ? null : (bool) $request->query->get('archive');
-        $isStarred = (null === $request->query->get('starred')) ? null : (bool) $request->query->get('starred');
-        $sort = $request->query->get('sort', 'created');
-        $order = $request->query->get('order', 'desc');
-        $page = (int) $request->query->get('page', 1);
-        $perPage = (int) $request->query->get('perPage', 30);
-        $tags = $request->query->get('tags', '');
-        $since = $request->query->get('since', 0);
-
-        $pager = $this->getDoctrine()
-            ->getRepository('WallabagCoreBundle:Entry')
-            ->findEntries($this->getUser()->getId(), $isArchived, $isStarred, $sort, $order, $since, $tags);
-
-        $pager->setCurrentPage($page);
-        $pager->setMaxPerPage($perPage);
-
-        $pagerfantaFactory = new PagerfantaFactory('page', 'perPage');
-        $paginatedCollection = $pagerfantaFactory->createRepresentation(
-            $pager,
-            new Route(
-                'api_get_entries',
-                [
-                    'archive' => $isArchived,
-                    'starred' => $isStarred,
-                    'sort' => $sort,
-                    'order' => $order,
-                    'page' => $page,
-                    'perPage' => $perPage,
-                    'tags' => $tags,
-                    'since' => $since,
-                ],
-                UrlGeneratorInterface::ABSOLUTE_URL
-            )
-        );
-
-        $json = $this->get('serializer')->serialize($paginatedCollection, 'json');
-
-        return (new JsonResponse())->setJson($json);
-    }
-
-    /**
-     * Retrieve a single entry.
-     *
-     * @ApiDoc(
-     *      requirements={
-     *          {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
-     *      }
-     * )
-     *
-     * @return JsonResponse
-     */
-    public function getEntryAction(Entry $entry)
-    {
-        $this->validateAuthentication();
-        $this->validateUserAccess($entry->getUser()->getId());
-
-        $json = $this->get('serializer')->serialize($entry, 'json');
-
-        return (new JsonResponse())->setJson($json);
-    }
-
-    /**
-     * Create an entry.
-     *
-     * @ApiDoc(
-     *       parameters={
-     *          {"name"="url", "dataType"="string", "required"=true, "format"="http://www.test.com/article.html", "description"="Url for the entry."},
-     *          {"name"="title", "dataType"="string", "required"=false, "description"="Optional, we'll get the title from the page."},
-     *          {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."},
-     *          {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="entry already starred"},
-     *          {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="entry already archived"},
-     *       }
-     * )
-     *
-     * @return JsonResponse
-     */
-    public function postEntriesAction(Request $request)
-    {
-        $this->validateAuthentication();
-
-        $url = $request->request->get('url');
-        $title = $request->request->get('title');
-        $isArchived = $request->request->get('archive');
-        $isStarred = $request->request->get('starred');
-
-        $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId($url, $this->getUser()->getId());
-
-        if (false === $entry) {
-            $entry = $this->get('wallabag_core.content_proxy')->updateEntry(
-                new Entry($this->getUser()),
-                $url
-            );
-        }
-
-        if (!is_null($title)) {
-            $entry->setTitle($title);
-        }
-
-        $tags = $request->request->get('tags', '');
-        if (!empty($tags)) {
-            $this->get('wallabag_core.content_proxy')->assignTagsToEntry($entry, $tags);
-        }
-
-        if (!is_null($isStarred)) {
-            $entry->setStarred((bool) $isStarred);
-        }
-
-        if (!is_null($isArchived)) {
-            $entry->setArchived((bool) $isArchived);
-        }
-
-        $em = $this->getDoctrine()->getManager();
-        $em->persist($entry);
-
-        $em->flush();
-
-        $json = $this->get('serializer')->serialize($entry, 'json');
-
-        return (new JsonResponse())->setJson($json);
-    }
-
-    /**
-     * Change several properties of an entry.
-     *
-     * @ApiDoc(
-     *      requirements={
-     *          {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
-     *      },
-     *      parameters={
-     *          {"name"="title", "dataType"="string", "required"=false},
-     *          {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."},
-     *          {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="archived the entry."},
-     *          {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="starred the entry."},
-     *      }
-     * )
-     *
-     * @return JsonResponse
-     */
-    public function patchEntriesAction(Entry $entry, Request $request)
-    {
-        $this->validateAuthentication();
-        $this->validateUserAccess($entry->getUser()->getId());
-
-        $title = $request->request->get('title');
-        $isArchived = $request->request->get('archive');
-        $isStarred = $request->request->get('starred');
-
-        if (!is_null($title)) {
-            $entry->setTitle($title);
-        }
-
-        if (!is_null($isArchived)) {
-            $entry->setArchived((bool) $isArchived);
-        }
-
-        if (!is_null($isStarred)) {
-            $entry->setStarred((bool) $isStarred);
-        }
-
-        $tags = $request->request->get('tags', '');
-        if (!empty($tags)) {
-            $this->get('wallabag_core.content_proxy')->assignTagsToEntry($entry, $tags);
-        }
-
-        $em = $this->getDoctrine()->getManager();
-        $em->flush();
-
-        $json = $this->get('serializer')->serialize($entry, 'json');
-
-        return (new JsonResponse())->setJson($json);
-    }
-
-    /**
-     * Delete **permanently** an entry.
-     *
-     * @ApiDoc(
-     *      requirements={
-     *          {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
-     *      }
-     * )
-     *
-     * @return JsonResponse
-     */
-    public function deleteEntriesAction(Entry $entry)
-    {
-        $this->validateAuthentication();
-        $this->validateUserAccess($entry->getUser()->getId());
-
-        $em = $this->getDoctrine()->getManager();
-        $em->remove($entry);
-        $em->flush();
-
-        $json = $this->get('serializer')->serialize($entry, 'json');
-
-        return (new JsonResponse())->setJson($json);
-    }
-
-    /**
-     * Retrieve all tags for an entry.
-     *
-     * @ApiDoc(
-     *      requirements={
-     *          {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
-     *      }
-     * )
-     *
-     * @return JsonResponse
-     */
-    public function getEntriesTagsAction(Entry $entry)
-    {
-        $this->validateAuthentication();
-        $this->validateUserAccess($entry->getUser()->getId());
-
-        $json = $this->get('serializer')->serialize($entry->getTags(), 'json');
-
-        return (new JsonResponse())->setJson($json);
-    }
-
-    /**
-     * Add one or more tags to an entry.
-     *
-     * @ApiDoc(
-     *      requirements={
-     *          {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
-     *      },
-     *      parameters={
-     *          {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."},
-     *       }
-     * )
-     *
-     * @return JsonResponse
-     */
-    public function postEntriesTagsAction(Request $request, Entry $entry)
-    {
-        $this->validateAuthentication();
-        $this->validateUserAccess($entry->getUser()->getId());
-
-        $tags = $request->request->get('tags', '');
-        if (!empty($tags)) {
-            $this->get('wallabag_core.content_proxy')->assignTagsToEntry($entry, $tags);
-        }
-
-        $em = $this->getDoctrine()->getManager();
-        $em->persist($entry);
-        $em->flush();
-
-        $json = $this->get('serializer')->serialize($entry, 'json');
-
-        return (new JsonResponse())->setJson($json);
-    }
-
-    /**
-     * Permanently remove one tag for an entry.
-     *
-     * @ApiDoc(
-     *      requirements={
-     *          {"name"="tag", "dataType"="integer", "requirement"="\w+", "description"="The tag ID"},
-     *          {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
-     *      }
-     * )
-     *
-     * @return JsonResponse
-     */
-    public function deleteEntriesTagsAction(Entry $entry, Tag $tag)
-    {
-        $this->validateAuthentication();
-        $this->validateUserAccess($entry->getUser()->getId());
-
-        $entry->removeTag($tag);
-        $em = $this->getDoctrine()->getManager();
-        $em->persist($entry);
-        $em->flush();
-
-        $json = $this->get('serializer')->serialize($entry, 'json');
-
-        return (new JsonResponse())->setJson($json);
-    }
-
-    /**
-     * Retrieve all tags.
-     *
-     * @ApiDoc()
-     *
-     * @return JsonResponse
-     */
-    public function getTagsAction()
-    {
-        $this->validateAuthentication();
-
-        $tags = $this->getDoctrine()
-            ->getRepository('WallabagCoreBundle:Tag')
-            ->findAllTags($this->getUser()->getId());
-
-        $json = $this->get('serializer')->serialize($tags, 'json');
-
-        return (new JsonResponse())->setJson($json);
-    }
-
-    /**
-     * Permanently remove one tag from **every** entry.
-     *
-     * @ApiDoc(
-     *      requirements={
-     *          {"name"="tag", "dataType"="string", "required"=true, "requirement"="\w+", "description"="Tag as a string"}
-     *      }
-     * )
-     *
-     * @return JsonResponse
-     */
-    public function deleteTagLabelAction(Request $request)
-    {
-        $this->validateAuthentication();
-        $label = $request->request->get('tag', '');
-
-        $tag = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findOneByLabel($label);
-
-        if (empty($tag)) {
-            throw $this->createNotFoundException('Tag not found');
-        }
-
-        $this->getDoctrine()
-            ->getRepository('WallabagCoreBundle:Entry')
-            ->removeTag($this->getUser()->getId(), $tag);
-
-        $this->cleanOrphanTag($tag);
-
-        $json = $this->get('serializer')->serialize($tag, 'json');
-
-        return (new JsonResponse())->setJson($json);
-    }
-
-    /**
-     * Permanently remove some tags from **every** entry.
-     *
-     * @ApiDoc(
-     *      requirements={
-     *          {"name"="tags", "dataType"="string", "required"=true, "format"="tag1,tag2", "description"="Tags as strings (comma splitted)"}
-     *      }
-     * )
-     *
-     * @return JsonResponse
-     */
-    public function deleteTagsLabelAction(Request $request)
-    {
-        $this->validateAuthentication();
-
-        $tagsLabels = $request->request->get('tags', '');
-
-        $tags = [];
-
-        foreach (explode(',', $tagsLabels) as $tagLabel) {
-            $tagEntity = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findOneByLabel($tagLabel);
-
-            if (!empty($tagEntity)) {
-                $tags[] = $tagEntity;
-            }
-        }
-
-        if (empty($tags)) {
-            throw $this->createNotFoundException('Tags not found');
-        }
-
-        $this->getDoctrine()
-            ->getRepository('WallabagCoreBundle:Entry')
-            ->removeTags($this->getUser()->getId(), $tags);
-
-        $this->cleanOrphanTag($tags);
-
-        $json = $this->get('serializer')->serialize($tags, 'json');
-
-        return (new JsonResponse())->setJson($json);
-    }
-
-    /**
-     * Permanently remove one tag from **every** entry.
-     *
-     * @ApiDoc(
-     *      requirements={
-     *          {"name"="tag", "dataType"="integer", "requirement"="\w+", "description"="The tag"}
-     *      }
-     * )
-     *
-     * @return JsonResponse
-     */
-    public function deleteTagAction(Tag $tag)
-    {
-        $this->validateAuthentication();
-
-        $this->getDoctrine()
-            ->getRepository('WallabagCoreBundle:Entry')
-            ->removeTag($this->getUser()->getId(), $tag);
-
-        $this->cleanOrphanTag($tag);
-
-        $json = $this->get('serializer')->serialize($tag, 'json');
-
-        return (new JsonResponse())->setJson($json);
-    }
-
-    /**
-     * Retrieve version number.
-     *
-     * @ApiDoc()
-     *
-     * @return JsonResponse
-     */
-    public function getVersionAction()
-    {
-        $version = $this->container->getParameter('wallabag_core.version');
-
-        $json = $this->get('serializer')->serialize($version, 'json');
-
-        return (new JsonResponse())->setJson($json);
-    }
-
-    /**
-     * Remove orphan tag in case no entries are associated to it.
-     *
-     * @param Tag|array $tags
-     */
-    private function cleanOrphanTag($tags)
-    {
-        if (!is_array($tags)) {
-            $tags = [$tags];
-        }
-
-        $em = $this->getDoctrine()->getManager();
-
-        foreach ($tags as $tag) {
-            if (count($tag->getEntries()) === 0) {
-                $em->remove($tag);
-            }
-        }
-
-        $em->flush();
-    }
-
     /**
      * Validate that the first id is equal to the second one.
      * If not, throw exception. It means a user try to access information from an other user.
      *
      * @param int $requestUserId User id from the requested source
      */
-    private function validateUserAccess($requestUserId)
+    protected function validateUserAccess($requestUserId)
     {
         $user = $this->get('security.token_storage')->getToken()->getUser();
         if ($requestUserId != $user->getId()) {
index 5f43f9716a46fb31b206196658da0de9e45cc954..901cf449ce2ea5669786f930ea18d24203635cf3 100644 (file)
@@ -1,4 +1,14 @@
-entries:
+api:
   type: rest
   resource:     "WallabagApiBundle:WallabagRest"
   name_prefix:  api_
+
+entries:
+  type: rest
+  resource:     "WallabagApiBundle:EntryRest"
+  name_prefix:  api_
+
+tags:
+  type: rest
+  resource:     "WallabagApiBundle:TagRest"
+  name_prefix:  api_
diff --git a/tests/Wallabag/ApiBundle/Controller/EntryRestControllerTest.php b/tests/Wallabag/ApiBundle/Controller/EntryRestControllerTest.php
new file mode 100644 (file)
index 0000000..825f8f7
--- /dev/null
@@ -0,0 +1,673 @@
+<?php
+
+namespace Tests\Wallabag\ApiBundle\Controller;
+
+use Tests\Wallabag\ApiBundle\WallabagApiTestCase;
+use Wallabag\CoreBundle\Entity\Tag;
+
+class EntryRestControllerTest extends WallabagApiTestCase
+{
+    public function testGetOneEntry()
+    {
+        $entry = $this->client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findOneBy(['user' => 1, 'isArchived' => false]);
+
+        if (!$entry) {
+            $this->markTestSkipped('No content found in db.');
+        }
+
+        $this->client->request('GET', '/api/entries/'.$entry->getId().'.json');
+        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+        $content = json_decode($this->client->getResponse()->getContent(), true);
+
+        $this->assertEquals($entry->getTitle(), $content['title']);
+        $this->assertEquals($entry->getUrl(), $content['url']);
+        $this->assertCount(count($entry->getTags()), $content['tags']);
+        $this->assertEquals($entry->getUserName(), $content['user_name']);
+        $this->assertEquals($entry->getUserEmail(), $content['user_email']);
+        $this->assertEquals($entry->getUserId(), $content['user_id']);
+
+        $this->assertTrue(
+            $this->client->getResponse()->headers->contains(
+                'Content-Type',
+                'application/json'
+            )
+        );
+    }
+
+    public function testGetOneEntryWrongUser()
+    {
+        $entry = $this->client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findOneBy(['user' => 2, 'isArchived' => false]);
+
+        if (!$entry) {
+            $this->markTestSkipped('No content found in db.');
+        }
+
+        $this->client->request('GET', '/api/entries/'.$entry->getId().'.json');
+
+        $this->assertEquals(403, $this->client->getResponse()->getStatusCode());
+    }
+
+    public function testGetEntries()
+    {
+        $this->client->request('GET', '/api/entries');
+
+        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+        $content = json_decode($this->client->getResponse()->getContent(), true);
+
+        $this->assertGreaterThanOrEqual(1, count($content));
+        $this->assertNotEmpty($content['_embedded']['items']);
+        $this->assertGreaterThanOrEqual(1, $content['total']);
+        $this->assertEquals(1, $content['page']);
+        $this->assertGreaterThanOrEqual(1, $content['pages']);
+
+        $this->assertTrue(
+            $this->client->getResponse()->headers->contains(
+                'Content-Type',
+                'application/json'
+            )
+        );
+    }
+
+    public function testGetEntriesWithFullOptions()
+    {
+        $this->client->request('GET', '/api/entries', [
+            'archive' => 1,
+            'starred' => 1,
+            'sort' => 'updated',
+            'order' => 'asc',
+            'page' => 1,
+            'perPage' => 2,
+            'tags' => 'foo',
+            'since' => 1443274283,
+        ]);
+
+        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+        $content = json_decode($this->client->getResponse()->getContent(), true);
+
+        $this->assertGreaterThanOrEqual(1, count($content));
+        $this->assertArrayHasKey('items', $content['_embedded']);
+        $this->assertGreaterThanOrEqual(0, $content['total']);
+        $this->assertEquals(1, $content['page']);
+        $this->assertEquals(2, $content['limit']);
+        $this->assertGreaterThanOrEqual(1, $content['pages']);
+
+        $this->assertArrayHasKey('_links', $content);
+        $this->assertArrayHasKey('self', $content['_links']);
+        $this->assertArrayHasKey('first', $content['_links']);
+        $this->assertArrayHasKey('last', $content['_links']);
+
+        foreach (['self', 'first', 'last'] as $link) {
+            $this->assertArrayHasKey('href', $content['_links'][$link]);
+            $this->assertContains('archive=1', $content['_links'][$link]['href']);
+            $this->assertContains('starred=1', $content['_links'][$link]['href']);
+            $this->assertContains('sort=updated', $content['_links'][$link]['href']);
+            $this->assertContains('order=asc', $content['_links'][$link]['href']);
+            $this->assertContains('tags=foo', $content['_links'][$link]['href']);
+            $this->assertContains('since=1443274283', $content['_links'][$link]['href']);
+        }
+
+        $this->assertTrue(
+            $this->client->getResponse()->headers->contains(
+                'Content-Type',
+                'application/json'
+            )
+        );
+    }
+
+    public function testGetStarredEntries()
+    {
+        $this->client->request('GET', '/api/entries', ['starred' => 1, 'sort' => 'updated']);
+
+        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+        $content = json_decode($this->client->getResponse()->getContent(), true);
+
+        $this->assertGreaterThanOrEqual(1, count($content));
+        $this->assertNotEmpty($content['_embedded']['items']);
+        $this->assertGreaterThanOrEqual(1, $content['total']);
+        $this->assertEquals(1, $content['page']);
+        $this->assertGreaterThanOrEqual(1, $content['pages']);
+
+        $this->assertArrayHasKey('_links', $content);
+        $this->assertArrayHasKey('self', $content['_links']);
+        $this->assertArrayHasKey('first', $content['_links']);
+        $this->assertArrayHasKey('last', $content['_links']);
+
+        foreach (['self', 'first', 'last'] as $link) {
+            $this->assertArrayHasKey('href', $content['_links'][$link]);
+            $this->assertContains('starred=1', $content['_links'][$link]['href']);
+            $this->assertContains('sort=updated', $content['_links'][$link]['href']);
+        }
+
+        $this->assertTrue(
+            $this->client->getResponse()->headers->contains(
+                'Content-Type',
+                'application/json'
+            )
+        );
+    }
+
+    public function testGetArchiveEntries()
+    {
+        $this->client->request('GET', '/api/entries', ['archive' => 1]);
+
+        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+        $content = json_decode($this->client->getResponse()->getContent(), true);
+
+        $this->assertGreaterThanOrEqual(1, count($content));
+        $this->assertNotEmpty($content['_embedded']['items']);
+        $this->assertGreaterThanOrEqual(1, $content['total']);
+        $this->assertEquals(1, $content['page']);
+        $this->assertGreaterThanOrEqual(1, $content['pages']);
+
+        $this->assertArrayHasKey('_links', $content);
+        $this->assertArrayHasKey('self', $content['_links']);
+        $this->assertArrayHasKey('first', $content['_links']);
+        $this->assertArrayHasKey('last', $content['_links']);
+
+        foreach (['self', 'first', 'last'] as $link) {
+            $this->assertArrayHasKey('href', $content['_links'][$link]);
+            $this->assertContains('archive=1', $content['_links'][$link]['href']);
+        }
+
+        $this->assertTrue(
+            $this->client->getResponse()->headers->contains(
+                'Content-Type',
+                'application/json'
+            )
+        );
+    }
+
+    public function testGetTaggedEntries()
+    {
+        $this->client->request('GET', '/api/entries', ['tags' => 'foo,bar']);
+
+        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+        $content = json_decode($this->client->getResponse()->getContent(), true);
+
+        $this->assertGreaterThanOrEqual(1, count($content));
+        $this->assertNotEmpty($content['_embedded']['items']);
+        $this->assertGreaterThanOrEqual(1, $content['total']);
+        $this->assertEquals(1, $content['page']);
+        $this->assertGreaterThanOrEqual(1, $content['pages']);
+
+        $this->assertArrayHasKey('_links', $content);
+        $this->assertArrayHasKey('self', $content['_links']);
+        $this->assertArrayHasKey('first', $content['_links']);
+        $this->assertArrayHasKey('last', $content['_links']);
+
+        foreach (['self', 'first', 'last'] as $link) {
+            $this->assertArrayHasKey('href', $content['_links'][$link]);
+            $this->assertContains('tags='.urlencode('foo,bar'), $content['_links'][$link]['href']);
+        }
+
+        $this->assertTrue(
+            $this->client->getResponse()->headers->contains(
+                'Content-Type',
+                'application/json'
+            )
+        );
+    }
+
+    public function testGetDatedEntries()
+    {
+        $this->client->request('GET', '/api/entries', ['since' => 1443274283]);
+
+        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+        $content = json_decode($this->client->getResponse()->getContent(), true);
+
+        $this->assertGreaterThanOrEqual(1, count($content));
+        $this->assertNotEmpty($content['_embedded']['items']);
+        $this->assertGreaterThanOrEqual(1, $content['total']);
+        $this->assertEquals(1, $content['page']);
+        $this->assertGreaterThanOrEqual(1, $content['pages']);
+
+        $this->assertArrayHasKey('_links', $content);
+        $this->assertArrayHasKey('self', $content['_links']);
+        $this->assertArrayHasKey('first', $content['_links']);
+        $this->assertArrayHasKey('last', $content['_links']);
+
+        foreach (['self', 'first', 'last'] as $link) {
+            $this->assertArrayHasKey('href', $content['_links'][$link]);
+            $this->assertContains('since=1443274283', $content['_links'][$link]['href']);
+        }
+
+        $this->assertTrue(
+            $this->client->getResponse()->headers->contains(
+                'Content-Type',
+                'application/json'
+            )
+        );
+    }
+
+    public function testGetDatedSupEntries()
+    {
+        $future = new \DateTime(date('Y-m-d H:i:s'));
+        $this->client->request('GET', '/api/entries', ['since' => $future->getTimestamp() + 1000]);
+
+        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+        $content = json_decode($this->client->getResponse()->getContent(), true);
+
+        $this->assertGreaterThanOrEqual(1, count($content));
+        $this->assertEmpty($content['_embedded']['items']);
+        $this->assertEquals(0, $content['total']);
+        $this->assertEquals(1, $content['page']);
+        $this->assertEquals(1, $content['pages']);
+
+        $this->assertArrayHasKey('_links', $content);
+        $this->assertArrayHasKey('self', $content['_links']);
+        $this->assertArrayHasKey('first', $content['_links']);
+        $this->assertArrayHasKey('last', $content['_links']);
+
+        foreach (['self', 'first', 'last'] as $link) {
+            $this->assertArrayHasKey('href', $content['_links'][$link]);
+            $this->assertContains('since='.($future->getTimestamp() + 1000), $content['_links'][$link]['href']);
+        }
+
+        $this->assertTrue(
+            $this->client->getResponse()->headers->contains(
+                'Content-Type',
+                'application/json'
+            )
+        );
+    }
+
+    public function testDeleteEntry()
+    {
+        $entry = $this->client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findOneByUser(1);
+
+        if (!$entry) {
+            $this->markTestSkipped('No content found in db.');
+        }
+
+        $this->client->request('DELETE', '/api/entries/'.$entry->getId().'.json');
+
+        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+        $content = json_decode($this->client->getResponse()->getContent(), true);
+
+        $this->assertEquals($entry->getTitle(), $content['title']);
+        $this->assertEquals($entry->getUrl(), $content['url']);
+
+        // We'll try to delete this entry again
+        $this->client->request('DELETE', '/api/entries/'.$entry->getId().'.json');
+
+        $this->assertEquals(404, $this->client->getResponse()->getStatusCode());
+    }
+
+    public function testPostEntry()
+    {
+        $this->client->request('POST', '/api/entries.json', [
+            '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',
+            'tags' => 'google',
+            'title' => 'New title for my article',
+        ]);
+
+        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+        $content = json_decode($this->client->getResponse()->getContent(), true);
+
+        $this->assertGreaterThan(0, $content['id']);
+        $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']);
+        $this->assertEquals(false, $content['is_archived']);
+        $this->assertEquals(false, $content['is_starred']);
+        $this->assertEquals('New title for my article', $content['title']);
+        $this->assertEquals(1, $content['user_id']);
+        $this->assertCount(1, $content['tags']);
+    }
+
+    public function testPostSameEntry()
+    {
+        $this->client->request('POST', '/api/entries.json', [
+            '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',
+            'archive' => '1',
+            'tags' => 'google, apple',
+        ]);
+
+        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+        $content = json_decode($this->client->getResponse()->getContent(), true);
+
+        $this->assertGreaterThan(0, $content['id']);
+        $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']);
+        $this->assertEquals(true, $content['is_archived']);
+        $this->assertEquals(false, $content['is_starred']);
+        $this->assertCount(2, $content['tags']);
+    }
+
+    public function testPostArchivedAndStarredEntry()
+    {
+        $this->client->request('POST', '/api/entries.json', [
+            'url' => 'http://www.lemonde.fr/idees/article/2016/02/08/preserver-la-liberte-d-expression-sur-les-reseaux-sociaux_4861503_3232.html',
+            'archive' => '1',
+            'starred' => '1',
+        ]);
+
+        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+        $content = json_decode($this->client->getResponse()->getContent(), true);
+
+        $this->assertGreaterThan(0, $content['id']);
+        $this->assertEquals('http://www.lemonde.fr/idees/article/2016/02/08/preserver-la-liberte-d-expression-sur-les-reseaux-sociaux_4861503_3232.html', $content['url']);
+        $this->assertEquals(true, $content['is_archived']);
+        $this->assertEquals(true, $content['is_starred']);
+        $this->assertEquals(1, $content['user_id']);
+    }
+
+    public function testPostArchivedAndStarredEntryWithoutQuotes()
+    {
+        $this->client->request('POST', '/api/entries.json', [
+            'url' => 'http://www.lemonde.fr/idees/article/2016/02/08/preserver-la-liberte-d-expression-sur-les-reseaux-sociaux_4861503_3232.html',
+            'archive' => 0,
+            'starred' => 1,
+        ]);
+
+        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+        $content = json_decode($this->client->getResponse()->getContent(), true);
+
+        $this->assertGreaterThan(0, $content['id']);
+        $this->assertEquals('http://www.lemonde.fr/idees/article/2016/02/08/preserver-la-liberte-d-expression-sur-les-reseaux-sociaux_4861503_3232.html', $content['url']);
+        $this->assertEquals(false, $content['is_archived']);
+        $this->assertEquals(true, $content['is_starred']);
+    }
+
+    public function testPatchEntry()
+    {
+        $entry = $this->client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findOneByUser(1);
+
+        if (!$entry) {
+            $this->markTestSkipped('No content found in db.');
+        }
+
+        // hydrate the tags relations
+        $nbTags = count($entry->getTags());
+
+        $this->client->request('PATCH', '/api/entries/'.$entry->getId().'.json', [
+            'title' => 'New awesome title',
+            'tags' => 'new tag '.uniqid(),
+            'starred' => '1',
+            'archive' => '0',
+        ]);
+
+        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+        $content = json_decode($this->client->getResponse()->getContent(), true);
+
+        $this->assertEquals($entry->getId(), $content['id']);
+        $this->assertEquals($entry->getUrl(), $content['url']);
+        $this->assertEquals('New awesome title', $content['title']);
+        $this->assertGreaterThan($nbTags, count($content['tags']));
+        $this->assertEquals(1, $content['user_id']);
+    }
+
+    public function testPatchEntryWithoutQuotes()
+    {
+        $entry = $this->client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findOneByUser(1);
+
+        if (!$entry) {
+            $this->markTestSkipped('No content found in db.');
+        }
+
+        // hydrate the tags relations
+        $nbTags = count($entry->getTags());
+
+        $this->client->request('PATCH', '/api/entries/'.$entry->getId().'.json', [
+            'title' => 'New awesome title',
+            'tags' => 'new tag '.uniqid(),
+            'starred' => 1,
+            'archive' => 0,
+        ]);
+
+        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+        $content = json_decode($this->client->getResponse()->getContent(), true);
+
+        $this->assertEquals($entry->getId(), $content['id']);
+        $this->assertEquals($entry->getUrl(), $content['url']);
+        $this->assertEquals('New awesome title', $content['title']);
+        $this->assertGreaterThan($nbTags, count($content['tags']));
+    }
+
+    public function testGetTagsEntry()
+    {
+        $entry = $this->client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findOneWithTags($this->user->getId());
+
+        $entry = $entry[0];
+
+        if (!$entry) {
+            $this->markTestSkipped('No content found in db.');
+        }
+
+        $tags = [];
+        foreach ($entry->getTags() as $tag) {
+            $tags[] = ['id' => $tag->getId(), 'label' => $tag->getLabel(), 'slug' => $tag->getSlug()];
+        }
+
+        $this->client->request('GET', '/api/entries/'.$entry->getId().'/tags');
+
+        $this->assertEquals(json_encode($tags, JSON_HEX_QUOT), $this->client->getResponse()->getContent());
+    }
+
+    public function testPostTagsOnEntry()
+    {
+        $entry = $this->client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findOneByUser(1);
+
+        if (!$entry) {
+            $this->markTestSkipped('No content found in db.');
+        }
+
+        $nbTags = count($entry->getTags());
+
+        $newTags = 'tag1,tag2,tag3';
+
+        $this->client->request('POST', '/api/entries/'.$entry->getId().'/tags', ['tags' => $newTags]);
+
+        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+        $content = json_decode($this->client->getResponse()->getContent(), true);
+
+        $this->assertArrayHasKey('tags', $content);
+        $this->assertEquals($nbTags + 3, count($content['tags']));
+
+        $entryDB = $this->client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->find($entry->getId());
+
+        $tagsInDB = [];
+        foreach ($entryDB->getTags()->toArray() as $tag) {
+            $tagsInDB[$tag->getId()] = $tag->getLabel();
+        }
+
+        foreach (explode(',', $newTags) as $tag) {
+            $this->assertContains($tag, $tagsInDB);
+        }
+    }
+
+    public function testDeleteOneTagEntry()
+    {
+        $entry = $this->client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findOneWithTags($this->user->getId());
+        $entry = $entry[0];
+
+        if (!$entry) {
+            $this->markTestSkipped('No content found in db.');
+        }
+
+        // hydrate the tags relations
+        $nbTags = count($entry->getTags());
+        $tag = $entry->getTags()[0];
+
+        $this->client->request('DELETE', '/api/entries/'.$entry->getId().'/tags/'.$tag->getId().'.json');
+
+        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+        $content = json_decode($this->client->getResponse()->getContent(), true);
+
+        $this->assertArrayHasKey('tags', $content);
+        $this->assertEquals($nbTags - 1, count($content['tags']));
+    }
+
+    public function testSaveIsArchivedAfterPost()
+    {
+        $entry = $this->client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findOneBy(['user' => 1, 'isArchived' => true]);
+
+        if (!$entry) {
+            $this->markTestSkipped('No content found in db.');
+        }
+
+        $this->client->request('POST', '/api/entries.json', [
+            'url' => $entry->getUrl(),
+        ]);
+
+        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+        $content = json_decode($this->client->getResponse()->getContent(), true);
+
+        $this->assertEquals(true, $content['is_archived']);
+    }
+
+    public function testSaveIsStarredAfterPost()
+    {
+        $entry = $this->client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findOneBy(['user' => 1, 'isStarred' => true]);
+
+        if (!$entry) {
+            $this->markTestSkipped('No content found in db.');
+        }
+
+        $this->client->request('POST', '/api/entries.json', [
+            'url' => $entry->getUrl(),
+        ]);
+
+        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+        $content = json_decode($this->client->getResponse()->getContent(), true);
+
+        $this->assertEquals(true, $content['is_starred']);
+    }
+
+    public function testSaveIsArchivedAfterPatch()
+    {
+        $entry = $this->client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findOneBy(['user' => 1, 'isArchived' => true]);
+
+        if (!$entry) {
+            $this->markTestSkipped('No content found in db.');
+        }
+
+        $this->client->request('PATCH', '/api/entries/'.$entry->getId().'.json', [
+            'title' => $entry->getTitle().'++',
+        ]);
+
+        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+        $content = json_decode($this->client->getResponse()->getContent(), true);
+
+        $this->assertEquals(true, $content['is_archived']);
+    }
+
+    public function testSaveIsStarredAfterPatch()
+    {
+        $entry = $this->client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findOneBy(['user' => 1, 'isStarred' => true]);
+
+        if (!$entry) {
+            $this->markTestSkipped('No content found in db.');
+        }
+        $this->client->request('PATCH', '/api/entries/'.$entry->getId().'.json', [
+            'title' => $entry->getTitle().'++',
+        ]);
+
+        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+        $content = json_decode($this->client->getResponse()->getContent(), true);
+
+        $this->assertEquals(true, $content['is_starred']);
+    }
+
+    public function testGetEntriesExists()
+    {
+        $this->client->request('GET', '/api/entries/exists?url=http://0.0.0.0/entry2');
+
+        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+        $content = json_decode($this->client->getResponse()->getContent(), true);
+
+        $this->assertEquals(true, $content['exists']);
+    }
+
+    public function testGetEntriesExistsWithManyUrls()
+    {
+        $url1 = 'http://0.0.0.0/entry2';
+        $url2 = 'http://0.0.0.0/entry10';
+        $this->client->request('GET', '/api/entries/exists?urls[]='.$url1.'&urls[]='.$url2);
+
+        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+        $content = json_decode($this->client->getResponse()->getContent(), true);
+
+        $this->assertArrayHasKey($url1, $content);
+        $this->assertArrayHasKey($url2, $content);
+        $this->assertEquals(true, $content[$url1]);
+        $this->assertEquals(false, $content[$url2]);
+    }
+
+    public function testGetEntriesExistsWhichDoesNotExists()
+    {
+        $this->client->request('GET', '/api/entries/exists?url=http://google.com/entry2');
+
+        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+        $content = json_decode($this->client->getResponse()->getContent(), true);
+
+        $this->assertEquals(false, $content['exists']);
+    }
+
+    public function testGetEntriesExistsWithNoUrl()
+    {
+        $this->client->request('GET', '/api/entries/exists?url=');
+
+        $this->assertEquals(403, $this->client->getResponse()->getStatusCode());
+    }
+}
diff --git a/tests/Wallabag/ApiBundle/Controller/TagRestControllerTest.php b/tests/Wallabag/ApiBundle/Controller/TagRestControllerTest.php
new file mode 100644 (file)
index 0000000..bde5251
--- /dev/null
@@ -0,0 +1,162 @@
+<?php
+
+namespace Tests\Wallabag\ApiBundle\Controller;
+
+use Tests\Wallabag\ApiBundle\WallabagApiTestCase;
+use Wallabag\CoreBundle\Entity\Tag;
+
+class TagRestControllerTest extends WallabagApiTestCase
+{
+    public function testGetUserTags()
+    {
+        $this->client->request('GET', '/api/tags.json');
+
+        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+        $content = json_decode($this->client->getResponse()->getContent(), true);
+
+        $this->assertGreaterThan(0, $content);
+        $this->assertArrayHasKey('id', $content[0]);
+        $this->assertArrayHasKey('label', $content[0]);
+
+        return end($content);
+    }
+
+    /**
+     * @depends testGetUserTags
+     */
+    public function testDeleteUserTag($tag)
+    {
+        $tagName = $tag['label'];
+
+        $this->client->request('DELETE', '/api/tags/'.$tag['id'].'.json');
+
+        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+        $content = json_decode($this->client->getResponse()->getContent(), true);
+
+        $this->assertArrayHasKey('label', $content);
+        $this->assertEquals($tag['label'], $content['label']);
+        $this->assertEquals($tag['slug'], $content['slug']);
+
+        $entries = $this->client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findAllByTagId($this->user->getId(), $tag['id']);
+
+        $this->assertCount(0, $entries);
+
+        $tag = $this->client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Tag')
+            ->findOneByLabel($tagName);
+
+        $this->assertNull($tag, $tagName.' was removed because it begun an orphan tag');
+    }
+
+    public function testDeleteTagByLabel()
+    {
+        $em = $this->client->getContainer()->get('doctrine.orm.entity_manager');
+        $entry = $this->client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findOneWithTags($this->user->getId());
+
+        $entry = $entry[0];
+
+        $tag = new Tag();
+        $tag->setLabel('Awesome tag for test');
+        $em->persist($tag);
+
+        $entry->addTag($tag);
+
+        $em->persist($entry);
+        $em->flush();
+
+        $this->client->request('DELETE', '/api/tag/label.json', ['tag' => $tag->getLabel()]);
+
+        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+        $content = json_decode($this->client->getResponse()->getContent(), true);
+
+        $this->assertArrayHasKey('label', $content);
+        $this->assertEquals($tag->getLabel(), $content['label']);
+        $this->assertEquals($tag->getSlug(), $content['slug']);
+
+        $entries = $this->client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findAllByTagId($this->user->getId(), $tag->getId());
+
+        $this->assertCount(0, $entries);
+    }
+
+    public function testDeleteTagByLabelNotFound()
+    {
+        $this->client->request('DELETE', '/api/tag/label.json', ['tag' => 'does not exist']);
+
+        $this->assertEquals(404, $this->client->getResponse()->getStatusCode());
+    }
+
+    public function testDeleteTagsByLabel()
+    {
+        $em = $this->client->getContainer()->get('doctrine.orm.entity_manager');
+        $entry = $this->client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findOneWithTags($this->user->getId());
+
+        $entry = $entry[0];
+
+        $tag = new Tag();
+        $tag->setLabel('Awesome tag for tagsLabel');
+        $em->persist($tag);
+
+        $tag2 = new Tag();
+        $tag2->setLabel('Awesome tag for tagsLabel 2');
+        $em->persist($tag2);
+
+        $entry->addTag($tag);
+        $entry->addTag($tag2);
+
+        $em->persist($entry);
+        $em->flush();
+
+        $this->client->request('DELETE', '/api/tags/label.json', ['tags' => $tag->getLabel().','.$tag2->getLabel()]);
+
+        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+        $content = json_decode($this->client->getResponse()->getContent(), true);
+
+        $this->assertCount(2, $content);
+
+        $this->assertArrayHasKey('label', $content[0]);
+        $this->assertEquals($tag->getLabel(), $content[0]['label']);
+        $this->assertEquals($tag->getSlug(), $content[0]['slug']);
+
+        $this->assertArrayHasKey('label', $content[1]);
+        $this->assertEquals($tag2->getLabel(), $content[1]['label']);
+        $this->assertEquals($tag2->getSlug(), $content[1]['slug']);
+
+        $entries = $this->client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findAllByTagId($this->user->getId(), $tag->getId());
+
+        $this->assertCount(0, $entries);
+
+        $entries = $this->client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findAllByTagId($this->user->getId(), $tag2->getId());
+
+        $this->assertCount(0, $entries);
+    }
+
+    public function testDeleteTagsByLabelNotFound()
+    {
+        $this->client->request('DELETE', '/api/tags/label.json', ['tags' => 'does not exist']);
+
+        $this->assertEquals(404, $this->client->getResponse()->getStatusCode());
+    }
+}
index 5dcb3e000dac75d68f0026851856dcdc0692973b..c87e58de0d3fac350277290f9227e20cf08a0304 100644 (file)
@@ -3,697 +3,9 @@
 namespace Tests\Wallabag\ApiBundle\Controller;
 
 use Tests\Wallabag\ApiBundle\WallabagApiTestCase;
-use Wallabag\CoreBundle\Entity\Tag;
 
 class WallabagRestControllerTest extends WallabagApiTestCase
 {
-    protected static $salt;
-
-    public function testGetOneEntry()
-    {
-        $entry = $this->client->getContainer()
-            ->get('doctrine.orm.entity_manager')
-            ->getRepository('WallabagCoreBundle:Entry')
-            ->findOneBy(['user' => 1, 'isArchived' => false]);
-
-        if (!$entry) {
-            $this->markTestSkipped('No content found in db.');
-        }
-
-        $this->client->request('GET', '/api/entries/'.$entry->getId().'.json');
-        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
-
-        $content = json_decode($this->client->getResponse()->getContent(), true);
-
-        $this->assertEquals($entry->getTitle(), $content['title']);
-        $this->assertEquals($entry->getUrl(), $content['url']);
-        $this->assertCount(count($entry->getTags()), $content['tags']);
-        $this->assertEquals($entry->getUserName(), $content['user_name']);
-        $this->assertEquals($entry->getUserEmail(), $content['user_email']);
-        $this->assertEquals($entry->getUserId(), $content['user_id']);
-
-        $this->assertTrue(
-            $this->client->getResponse()->headers->contains(
-                'Content-Type',
-                'application/json'
-            )
-        );
-    }
-
-    public function testGetOneEntryWrongUser()
-    {
-        $entry = $this->client->getContainer()
-            ->get('doctrine.orm.entity_manager')
-            ->getRepository('WallabagCoreBundle:Entry')
-            ->findOneBy(['user' => 2, 'isArchived' => false]);
-
-        if (!$entry) {
-            $this->markTestSkipped('No content found in db.');
-        }
-
-        $this->client->request('GET', '/api/entries/'.$entry->getId().'.json');
-
-        $this->assertEquals(403, $this->client->getResponse()->getStatusCode());
-    }
-
-    public function testGetEntries()
-    {
-        $this->client->request('GET', '/api/entries');
-
-        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
-
-        $content = json_decode($this->client->getResponse()->getContent(), true);
-
-        $this->assertGreaterThanOrEqual(1, count($content));
-        $this->assertNotEmpty($content['_embedded']['items']);
-        $this->assertGreaterThanOrEqual(1, $content['total']);
-        $this->assertEquals(1, $content['page']);
-        $this->assertGreaterThanOrEqual(1, $content['pages']);
-
-        $this->assertTrue(
-            $this->client->getResponse()->headers->contains(
-                'Content-Type',
-                'application/json'
-            )
-        );
-    }
-
-    public function testGetEntriesWithFullOptions()
-    {
-        $this->client->request('GET', '/api/entries', [
-            'archive' => 1,
-            'starred' => 1,
-            'sort' => 'updated',
-            'order' => 'asc',
-            'page' => 1,
-            'perPage' => 2,
-            'tags' => 'foo',
-            'since' => 1443274283,
-        ]);
-
-        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
-
-        $content = json_decode($this->client->getResponse()->getContent(), true);
-
-        $this->assertGreaterThanOrEqual(1, count($content));
-        $this->assertArrayHasKey('items', $content['_embedded']);
-        $this->assertGreaterThanOrEqual(0, $content['total']);
-        $this->assertEquals(1, $content['page']);
-        $this->assertEquals(2, $content['limit']);
-        $this->assertGreaterThanOrEqual(1, $content['pages']);
-
-        $this->assertArrayHasKey('_links', $content);
-        $this->assertArrayHasKey('self', $content['_links']);
-        $this->assertArrayHasKey('first', $content['_links']);
-        $this->assertArrayHasKey('last', $content['_links']);
-
-        foreach (['self', 'first', 'last'] as $link) {
-            $this->assertArrayHasKey('href', $content['_links'][$link]);
-            $this->assertContains('archive=1', $content['_links'][$link]['href']);
-            $this->assertContains('starred=1', $content['_links'][$link]['href']);
-            $this->assertContains('sort=updated', $content['_links'][$link]['href']);
-            $this->assertContains('order=asc', $content['_links'][$link]['href']);
-            $this->assertContains('tags=foo', $content['_links'][$link]['href']);
-            $this->assertContains('since=1443274283', $content['_links'][$link]['href']);
-        }
-
-        $this->assertTrue(
-            $this->client->getResponse()->headers->contains(
-                'Content-Type',
-                'application/json'
-            )
-        );
-    }
-
-    public function testGetStarredEntries()
-    {
-        $this->client->request('GET', '/api/entries', ['starred' => 1, 'sort' => 'updated']);
-
-        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
-
-        $content = json_decode($this->client->getResponse()->getContent(), true);
-
-        $this->assertGreaterThanOrEqual(1, count($content));
-        $this->assertNotEmpty($content['_embedded']['items']);
-        $this->assertGreaterThanOrEqual(1, $content['total']);
-        $this->assertEquals(1, $content['page']);
-        $this->assertGreaterThanOrEqual(1, $content['pages']);
-
-        $this->assertArrayHasKey('_links', $content);
-        $this->assertArrayHasKey('self', $content['_links']);
-        $this->assertArrayHasKey('first', $content['_links']);
-        $this->assertArrayHasKey('last', $content['_links']);
-
-        foreach (['self', 'first', 'last'] as $link) {
-            $this->assertArrayHasKey('href', $content['_links'][$link]);
-            $this->assertContains('starred=1', $content['_links'][$link]['href']);
-            $this->assertContains('sort=updated', $content['_links'][$link]['href']);
-        }
-
-        $this->assertTrue(
-            $this->client->getResponse()->headers->contains(
-                'Content-Type',
-                'application/json'
-            )
-        );
-    }
-
-    public function testGetArchiveEntries()
-    {
-        $this->client->request('GET', '/api/entries', ['archive' => 1]);
-
-        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
-
-        $content = json_decode($this->client->getResponse()->getContent(), true);
-
-        $this->assertGreaterThanOrEqual(1, count($content));
-        $this->assertNotEmpty($content['_embedded']['items']);
-        $this->assertGreaterThanOrEqual(1, $content['total']);
-        $this->assertEquals(1, $content['page']);
-        $this->assertGreaterThanOrEqual(1, $content['pages']);
-
-        $this->assertArrayHasKey('_links', $content);
-        $this->assertArrayHasKey('self', $content['_links']);
-        $this->assertArrayHasKey('first', $content['_links']);
-        $this->assertArrayHasKey('last', $content['_links']);
-
-        foreach (['self', 'first', 'last'] as $link) {
-            $this->assertArrayHasKey('href', $content['_links'][$link]);
-            $this->assertContains('archive=1', $content['_links'][$link]['href']);
-        }
-
-        $this->assertTrue(
-            $this->client->getResponse()->headers->contains(
-                'Content-Type',
-                'application/json'
-            )
-        );
-    }
-
-    public function testGetTaggedEntries()
-    {
-        $this->client->request('GET', '/api/entries', ['tags' => 'foo,bar']);
-
-        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
-
-        $content = json_decode($this->client->getResponse()->getContent(), true);
-
-        $this->assertGreaterThanOrEqual(1, count($content));
-        $this->assertNotEmpty($content['_embedded']['items']);
-        $this->assertGreaterThanOrEqual(1, $content['total']);
-        $this->assertEquals(1, $content['page']);
-        $this->assertGreaterThanOrEqual(1, $content['pages']);
-
-        $this->assertArrayHasKey('_links', $content);
-        $this->assertArrayHasKey('self', $content['_links']);
-        $this->assertArrayHasKey('first', $content['_links']);
-        $this->assertArrayHasKey('last', $content['_links']);
-
-        foreach (['self', 'first', 'last'] as $link) {
-            $this->assertArrayHasKey('href', $content['_links'][$link]);
-            $this->assertContains('tags='.urlencode('foo,bar'), $content['_links'][$link]['href']);
-        }
-
-        $this->assertTrue(
-            $this->client->getResponse()->headers->contains(
-                'Content-Type',
-                'application/json'
-            )
-        );
-    }
-
-    public function testGetDatedEntries()
-    {
-        $this->client->request('GET', '/api/entries', ['since' => 1443274283]);
-
-        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
-
-        $content = json_decode($this->client->getResponse()->getContent(), true);
-
-        $this->assertGreaterThanOrEqual(1, count($content));
-        $this->assertNotEmpty($content['_embedded']['items']);
-        $this->assertGreaterThanOrEqual(1, $content['total']);
-        $this->assertEquals(1, $content['page']);
-        $this->assertGreaterThanOrEqual(1, $content['pages']);
-
-        $this->assertArrayHasKey('_links', $content);
-        $this->assertArrayHasKey('self', $content['_links']);
-        $this->assertArrayHasKey('first', $content['_links']);
-        $this->assertArrayHasKey('last', $content['_links']);
-
-        foreach (['self', 'first', 'last'] as $link) {
-            $this->assertArrayHasKey('href', $content['_links'][$link]);
-            $this->assertContains('since=1443274283', $content['_links'][$link]['href']);
-        }
-
-        $this->assertTrue(
-            $this->client->getResponse()->headers->contains(
-                'Content-Type',
-                'application/json'
-            )
-        );
-    }
-
-    public function testGetDatedSupEntries()
-    {
-        $future = new \DateTime(date('Y-m-d H:i:s'));
-        $this->client->request('GET', '/api/entries', ['since' => $future->getTimestamp() + 1000]);
-
-        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
-
-        $content = json_decode($this->client->getResponse()->getContent(), true);
-
-        $this->assertGreaterThanOrEqual(1, count($content));
-        $this->assertEmpty($content['_embedded']['items']);
-        $this->assertEquals(0, $content['total']);
-        $this->assertEquals(1, $content['page']);
-        $this->assertEquals(1, $content['pages']);
-
-        $this->assertArrayHasKey('_links', $content);
-        $this->assertArrayHasKey('self', $content['_links']);
-        $this->assertArrayHasKey('first', $content['_links']);
-        $this->assertArrayHasKey('last', $content['_links']);
-
-        foreach (['self', 'first', 'last'] as $link) {
-            $this->assertArrayHasKey('href', $content['_links'][$link]);
-            $this->assertContains('since='.($future->getTimestamp() + 1000), $content['_links'][$link]['href']);
-        }
-
-        $this->assertTrue(
-            $this->client->getResponse()->headers->contains(
-                'Content-Type',
-                'application/json'
-            )
-        );
-    }
-
-    public function testDeleteEntry()
-    {
-        $entry = $this->client->getContainer()
-            ->get('doctrine.orm.entity_manager')
-            ->getRepository('WallabagCoreBundle:Entry')
-            ->findOneByUser(1);
-
-        if (!$entry) {
-            $this->markTestSkipped('No content found in db.');
-        }
-
-        $this->client->request('DELETE', '/api/entries/'.$entry->getId().'.json');
-
-        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
-
-        $content = json_decode($this->client->getResponse()->getContent(), true);
-
-        $this->assertEquals($entry->getTitle(), $content['title']);
-        $this->assertEquals($entry->getUrl(), $content['url']);
-
-        // We'll try to delete this entry again
-        $this->client->request('DELETE', '/api/entries/'.$entry->getId().'.json');
-
-        $this->assertEquals(404, $this->client->getResponse()->getStatusCode());
-    }
-
-    public function testPostEntry()
-    {
-        $this->client->request('POST', '/api/entries.json', [
-            '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',
-            'tags' => 'google',
-            'title' => 'New title for my article',
-        ]);
-
-        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
-
-        $content = json_decode($this->client->getResponse()->getContent(), true);
-
-        $this->assertGreaterThan(0, $content['id']);
-        $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']);
-        $this->assertEquals(false, $content['is_archived']);
-        $this->assertEquals(false, $content['is_starred']);
-        $this->assertEquals('New title for my article', $content['title']);
-        $this->assertEquals(1, $content['user_id']);
-        $this->assertCount(1, $content['tags']);
-    }
-
-    public function testPostSameEntry()
-    {
-        $this->client->request('POST', '/api/entries.json', [
-            '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',
-            'archive' => '1',
-            'tags' => 'google, apple',
-        ]);
-
-        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
-
-        $content = json_decode($this->client->getResponse()->getContent(), true);
-
-        $this->assertGreaterThan(0, $content['id']);
-        $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']);
-        $this->assertEquals(true, $content['is_archived']);
-        $this->assertEquals(false, $content['is_starred']);
-        $this->assertCount(2, $content['tags']);
-    }
-
-    public function testPostArchivedAndStarredEntry()
-    {
-        $this->client->request('POST', '/api/entries.json', [
-            'url' => 'http://www.lemonde.fr/idees/article/2016/02/08/preserver-la-liberte-d-expression-sur-les-reseaux-sociaux_4861503_3232.html',
-            'archive' => '1',
-            'starred' => '1',
-        ]);
-
-        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
-
-        $content = json_decode($this->client->getResponse()->getContent(), true);
-
-        $this->assertGreaterThan(0, $content['id']);
-        $this->assertEquals('http://www.lemonde.fr/idees/article/2016/02/08/preserver-la-liberte-d-expression-sur-les-reseaux-sociaux_4861503_3232.html', $content['url']);
-        $this->assertEquals(true, $content['is_archived']);
-        $this->assertEquals(true, $content['is_starred']);
-        $this->assertEquals(1, $content['user_id']);
-    }
-
-    public function testPostArchivedAndStarredEntryWithoutQuotes()
-    {
-        $this->client->request('POST', '/api/entries.json', [
-            'url' => 'http://www.lemonde.fr/idees/article/2016/02/08/preserver-la-liberte-d-expression-sur-les-reseaux-sociaux_4861503_3232.html',
-            'archive' => 0,
-            'starred' => 1,
-        ]);
-
-        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
-
-        $content = json_decode($this->client->getResponse()->getContent(), true);
-
-        $this->assertGreaterThan(0, $content['id']);
-        $this->assertEquals('http://www.lemonde.fr/idees/article/2016/02/08/preserver-la-liberte-d-expression-sur-les-reseaux-sociaux_4861503_3232.html', $content['url']);
-        $this->assertEquals(false, $content['is_archived']);
-        $this->assertEquals(true, $content['is_starred']);
-    }
-
-    public function testPatchEntry()
-    {
-        $entry = $this->client->getContainer()
-            ->get('doctrine.orm.entity_manager')
-            ->getRepository('WallabagCoreBundle:Entry')
-            ->findOneByUser(1);
-
-        if (!$entry) {
-            $this->markTestSkipped('No content found in db.');
-        }
-
-        // hydrate the tags relations
-        $nbTags = count($entry->getTags());
-
-        $this->client->request('PATCH', '/api/entries/'.$entry->getId().'.json', [
-            'title' => 'New awesome title',
-            'tags' => 'new tag '.uniqid(),
-            'starred' => '1',
-            'archive' => '0',
-        ]);
-
-        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
-
-        $content = json_decode($this->client->getResponse()->getContent(), true);
-
-        $this->assertEquals($entry->getId(), $content['id']);
-        $this->assertEquals($entry->getUrl(), $content['url']);
-        $this->assertEquals('New awesome title', $content['title']);
-        $this->assertGreaterThan($nbTags, count($content['tags']));
-        $this->assertEquals(1, $content['user_id']);
-    }
-
-    public function testPatchEntryWithoutQuotes()
-    {
-        $entry = $this->client->getContainer()
-            ->get('doctrine.orm.entity_manager')
-            ->getRepository('WallabagCoreBundle:Entry')
-            ->findOneByUser(1);
-
-        if (!$entry) {
-            $this->markTestSkipped('No content found in db.');
-        }
-
-        // hydrate the tags relations
-        $nbTags = count($entry->getTags());
-
-        $this->client->request('PATCH', '/api/entries/'.$entry->getId().'.json', [
-            'title' => 'New awesome title',
-            'tags' => 'new tag '.uniqid(),
-            'starred' => 1,
-            'archive' => 0,
-        ]);
-
-        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
-
-        $content = json_decode($this->client->getResponse()->getContent(), true);
-
-        $this->assertEquals($entry->getId(), $content['id']);
-        $this->assertEquals($entry->getUrl(), $content['url']);
-        $this->assertEquals('New awesome title', $content['title']);
-        $this->assertGreaterThan($nbTags, count($content['tags']));
-    }
-
-    public function testGetTagsEntry()
-    {
-        $entry = $this->client->getContainer()
-            ->get('doctrine.orm.entity_manager')
-            ->getRepository('WallabagCoreBundle:Entry')
-            ->findOneWithTags($this->user->getId());
-
-        $entry = $entry[0];
-
-        if (!$entry) {
-            $this->markTestSkipped('No content found in db.');
-        }
-
-        $tags = [];
-        foreach ($entry->getTags() as $tag) {
-            $tags[] = ['id' => $tag->getId(), 'label' => $tag->getLabel(), 'slug' => $tag->getSlug()];
-        }
-
-        $this->client->request('GET', '/api/entries/'.$entry->getId().'/tags');
-
-        $this->assertEquals(json_encode($tags, JSON_HEX_QUOT), $this->client->getResponse()->getContent());
-    }
-
-    public function testPostTagsOnEntry()
-    {
-        $entry = $this->client->getContainer()
-            ->get('doctrine.orm.entity_manager')
-            ->getRepository('WallabagCoreBundle:Entry')
-            ->findOneByUser(1);
-
-        if (!$entry) {
-            $this->markTestSkipped('No content found in db.');
-        }
-
-        $nbTags = count($entry->getTags());
-
-        $newTags = 'tag1,tag2,tag3';
-
-        $this->client->request('POST', '/api/entries/'.$entry->getId().'/tags', ['tags' => $newTags]);
-
-        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
-
-        $content = json_decode($this->client->getResponse()->getContent(), true);
-
-        $this->assertArrayHasKey('tags', $content);
-        $this->assertEquals($nbTags + 3, count($content['tags']));
-
-        $entryDB = $this->client->getContainer()
-            ->get('doctrine.orm.entity_manager')
-            ->getRepository('WallabagCoreBundle:Entry')
-            ->find($entry->getId());
-
-        $tagsInDB = [];
-        foreach ($entryDB->getTags()->toArray() as $tag) {
-            $tagsInDB[$tag->getId()] = $tag->getLabel();
-        }
-
-        foreach (explode(',', $newTags) as $tag) {
-            $this->assertContains($tag, $tagsInDB);
-        }
-    }
-
-    public function testDeleteOneTagEntry()
-    {
-        $entry = $this->client->getContainer()
-            ->get('doctrine.orm.entity_manager')
-            ->getRepository('WallabagCoreBundle:Entry')
-            ->findOneWithTags($this->user->getId());
-        $entry = $entry[0];
-
-        if (!$entry) {
-            $this->markTestSkipped('No content found in db.');
-        }
-
-        // hydrate the tags relations
-        $nbTags = count($entry->getTags());
-        $tag = $entry->getTags()[0];
-
-        $this->client->request('DELETE', '/api/entries/'.$entry->getId().'/tags/'.$tag->getId().'.json');
-
-        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
-
-        $content = json_decode($this->client->getResponse()->getContent(), true);
-
-        $this->assertArrayHasKey('tags', $content);
-        $this->assertEquals($nbTags - 1, count($content['tags']));
-    }
-
-    public function testGetUserTags()
-    {
-        $this->client->request('GET', '/api/tags.json');
-
-        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
-
-        $content = json_decode($this->client->getResponse()->getContent(), true);
-
-        $this->assertGreaterThan(0, $content);
-        $this->assertArrayHasKey('id', $content[0]);
-        $this->assertArrayHasKey('label', $content[0]);
-
-        return end($content);
-    }
-
-    /**
-     * @depends testGetUserTags
-     */
-    public function testDeleteUserTag($tag)
-    {
-        $tagName = $tag['label'];
-
-        $this->client->request('DELETE', '/api/tags/'.$tag['id'].'.json');
-
-        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
-
-        $content = json_decode($this->client->getResponse()->getContent(), true);
-
-        $this->assertArrayHasKey('label', $content);
-        $this->assertEquals($tag['label'], $content['label']);
-        $this->assertEquals($tag['slug'], $content['slug']);
-
-        $entries = $this->client->getContainer()
-            ->get('doctrine.orm.entity_manager')
-            ->getRepository('WallabagCoreBundle:Entry')
-            ->findAllByTagId($this->user->getId(), $tag['id']);
-
-        $this->assertCount(0, $entries);
-
-        $tag = $this->client->getContainer()
-            ->get('doctrine.orm.entity_manager')
-            ->getRepository('WallabagCoreBundle:Tag')
-            ->findOneByLabel($tagName);
-
-        $this->assertNull($tag, $tagName.' was removed because it begun an orphan tag');
-    }
-
-    public function testDeleteTagByLabel()
-    {
-        $em = $this->client->getContainer()->get('doctrine.orm.entity_manager');
-        $entry = $this->client->getContainer()
-            ->get('doctrine.orm.entity_manager')
-            ->getRepository('WallabagCoreBundle:Entry')
-            ->findOneWithTags($this->user->getId());
-
-        $entry = $entry[0];
-
-        $tag = new Tag();
-        $tag->setLabel('Awesome tag for test');
-        $em->persist($tag);
-
-        $entry->addTag($tag);
-
-        $em->persist($entry);
-        $em->flush();
-
-        $this->client->request('DELETE', '/api/tag/label.json', ['tag' => $tag->getLabel()]);
-
-        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
-
-        $content = json_decode($this->client->getResponse()->getContent(), true);
-
-        $this->assertArrayHasKey('label', $content);
-        $this->assertEquals($tag->getLabel(), $content['label']);
-        $this->assertEquals($tag->getSlug(), $content['slug']);
-
-        $entries = $this->client->getContainer()
-            ->get('doctrine.orm.entity_manager')
-            ->getRepository('WallabagCoreBundle:Entry')
-            ->findAllByTagId($this->user->getId(), $tag->getId());
-
-        $this->assertCount(0, $entries);
-    }
-
-    public function testDeleteTagByLabelNotFound()
-    {
-        $this->client->request('DELETE', '/api/tag/label.json', ['tag' => 'does not exist']);
-
-        $this->assertEquals(404, $this->client->getResponse()->getStatusCode());
-    }
-
-    public function testDeleteTagsByLabel()
-    {
-        $em = $this->client->getContainer()->get('doctrine.orm.entity_manager');
-        $entry = $this->client->getContainer()
-            ->get('doctrine.orm.entity_manager')
-            ->getRepository('WallabagCoreBundle:Entry')
-            ->findOneWithTags($this->user->getId());
-
-        $entry = $entry[0];
-
-        $tag = new Tag();
-        $tag->setLabel('Awesome tag for tagsLabel');
-        $em->persist($tag);
-
-        $tag2 = new Tag();
-        $tag2->setLabel('Awesome tag for tagsLabel 2');
-        $em->persist($tag2);
-
-        $entry->addTag($tag);
-        $entry->addTag($tag2);
-
-        $em->persist($entry);
-        $em->flush();
-
-        $this->client->request('DELETE', '/api/tags/label.json', ['tags' => $tag->getLabel().','.$tag2->getLabel()]);
-
-        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
-
-        $content = json_decode($this->client->getResponse()->getContent(), true);
-
-        $this->assertCount(2, $content);
-
-        $this->assertArrayHasKey('label', $content[0]);
-        $this->assertEquals($tag->getLabel(), $content[0]['label']);
-        $this->assertEquals($tag->getSlug(), $content[0]['slug']);
-
-        $this->assertArrayHasKey('label', $content[1]);
-        $this->assertEquals($tag2->getLabel(), $content[1]['label']);
-        $this->assertEquals($tag2->getSlug(), $content[1]['slug']);
-
-        $entries = $this->client->getContainer()
-            ->get('doctrine.orm.entity_manager')
-            ->getRepository('WallabagCoreBundle:Entry')
-            ->findAllByTagId($this->user->getId(), $tag->getId());
-
-        $this->assertCount(0, $entries);
-
-        $entries = $this->client->getContainer()
-            ->get('doctrine.orm.entity_manager')
-            ->getRepository('WallabagCoreBundle:Entry')
-            ->findAllByTagId($this->user->getId(), $tag2->getId());
-
-        $this->assertCount(0, $entries);
-    }
-
-    public function testDeleteTagsByLabelNotFound()
-    {
-        $this->client->request('DELETE', '/api/tags/label.json', ['tags' => 'does not exist']);
-
-        $this->assertEquals(404, $this->client->getResponse()->getStatusCode());
-    }
-
     public function testGetVersion()
     {
         $this->client->request('GET', '/api/version');
@@ -704,136 +16,4 @@ class WallabagRestControllerTest extends WallabagApiTestCase
 
         $this->assertEquals($this->client->getContainer()->getParameter('wallabag_core.version'), $content);
     }
-
-    public function testSaveIsArchivedAfterPost()
-    {
-        $entry = $this->client->getContainer()
-            ->get('doctrine.orm.entity_manager')
-            ->getRepository('WallabagCoreBundle:Entry')
-            ->findOneBy(['user' => 1, 'isArchived' => true]);
-
-        if (!$entry) {
-            $this->markTestSkipped('No content found in db.');
-        }
-
-        $this->client->request('POST', '/api/entries.json', [
-            'url' => $entry->getUrl(),
-        ]);
-
-        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
-
-        $content = json_decode($this->client->getResponse()->getContent(), true);
-
-        $this->assertEquals(true, $content['is_archived']);
-    }
-
-    public function testSaveIsStarredAfterPost()
-    {
-        $entry = $this->client->getContainer()
-            ->get('doctrine.orm.entity_manager')
-            ->getRepository('WallabagCoreBundle:Entry')
-            ->findOneBy(['user' => 1, 'isStarred' => true]);
-
-        if (!$entry) {
-            $this->markTestSkipped('No content found in db.');
-        }
-
-        $this->client->request('POST', '/api/entries.json', [
-            'url' => $entry->getUrl(),
-        ]);
-
-        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
-
-        $content = json_decode($this->client->getResponse()->getContent(), true);
-
-        $this->assertEquals(true, $content['is_starred']);
-    }
-
-    public function testSaveIsArchivedAfterPatch()
-    {
-        $entry = $this->client->getContainer()
-            ->get('doctrine.orm.entity_manager')
-            ->getRepository('WallabagCoreBundle:Entry')
-            ->findOneBy(['user' => 1, 'isArchived' => true]);
-
-        if (!$entry) {
-            $this->markTestSkipped('No content found in db.');
-        }
-
-        $this->client->request('PATCH', '/api/entries/'.$entry->getId().'.json', [
-            'title' => $entry->getTitle().'++',
-        ]);
-
-        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
-
-        $content = json_decode($this->client->getResponse()->getContent(), true);
-
-        $this->assertEquals(true, $content['is_archived']);
-    }
-
-    public function testSaveIsStarredAfterPatch()
-    {
-        $entry = $this->client->getContainer()
-            ->get('doctrine.orm.entity_manager')
-            ->getRepository('WallabagCoreBundle:Entry')
-            ->findOneBy(['user' => 1, 'isStarred' => true]);
-
-        if (!$entry) {
-            $this->markTestSkipped('No content found in db.');
-        }
-        $this->client->request('PATCH', '/api/entries/'.$entry->getId().'.json', [
-            'title' => $entry->getTitle().'++',
-        ]);
-
-        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
-
-        $content = json_decode($this->client->getResponse()->getContent(), true);
-
-        $this->assertEquals(true, $content['is_starred']);
-    }
-
-    public function testGetEntriesExists()
-    {
-        $this->client->request('GET', '/api/entries/exists?url=http://0.0.0.0/entry2');
-
-        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
-
-        $content = json_decode($this->client->getResponse()->getContent(), true);
-
-        $this->assertEquals(true, $content['exists']);
-    }
-
-    public function testGetEntriesExistsWithManyUrls()
-    {
-        $url1 = 'http://0.0.0.0/entry2';
-        $url2 = 'http://0.0.0.0/entry10';
-        $this->client->request('GET', '/api/entries/exists?urls[]='.$url1.'&urls[]='.$url2);
-
-        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
-
-        $content = json_decode($this->client->getResponse()->getContent(), true);
-
-        $this->assertArrayHasKey($url1, $content);
-        $this->assertArrayHasKey($url2, $content);
-        $this->assertEquals(true, $content[$url1]);
-        $this->assertEquals(false, $content[$url2]);
-    }
-
-    public function testGetEntriesExistsWhichDoesNotExists()
-    {
-        $this->client->request('GET', '/api/entries/exists?url=http://google.com/entry2');
-
-        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
-
-        $content = json_decode($this->client->getResponse()->getContent(), true);
-
-        $this->assertEquals(false, $content['exists']);
-    }
-
-    public function testGetEntriesExistsWithNoUrl()
-    {
-        $this->client->request('GET', '/api/entries/exists?url=');
-
-        $this->assertEquals(403, $this->client->getResponse()->getStatusCode());
-    }
 }