]> git.immae.eu Git - github/wallabag/wallabag.git/commitdiff
Merge pull request #2519 from Jibec/master
authorJeremy Benoist <j0k3r@users.noreply.github.com>
Wed, 2 Nov 2016 06:48:10 +0000 (07:48 +0100)
committerGitHub <noreply@github.com>
Wed, 2 Nov 2016 06:48:10 +0000 (07:48 +0100)
Translation update - French

28 files changed:
Capfile
Gemfile
Gemfile.lock
app/config/capistrano/deploy.rb
docs/de/developer/api.rst
docs/en/developer/api.rst
docs/fr/developer/api.rst
scripts/dev.sh
scripts/install.sh
scripts/update.sh
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
src/Wallabag/CoreBundle/Controller/ExportController.php
src/Wallabag/CoreBundle/Helper/EntriesExport.php
src/Wallabag/CoreBundle/Resources/config/services.yml
src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entries.html.twig
src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entries.html.twig
src/Wallabag/ImportBundle/Command/ImportCommand.php
src/Wallabag/ImportBundle/Resources/config/services.yml
src/Wallabag/UserBundle/Mailer/AuthCodeMailer.php
src/Wallabag/UserBundle/Resources/config/services.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
tests/Wallabag/CoreBundle/Controller/ExportControllerTest.php
tests/Wallabag/UserBundle/Mailer/AuthCodeMailerTest.php

diff --git a/Capfile b/Capfile
index b80a5646b97a89a6c8db04db6d321ab65d22b862..cc807112044a606109297ded853e1ede4b2ded11 100644 (file)
--- a/Capfile
+++ b/Capfile
@@ -7,6 +7,8 @@ require 'capistrano/setup'
 # Include default deployment tasks
 require 'capistrano/deploy'
 
+require 'capistrano/composer'
+require 'capistrano/file-permissions'
 require 'capistrano/symfony'
 
 # Load custom tasks from `lib/capistrano/tasks` if you have any defined
diff --git a/Gemfile b/Gemfile
index 31f887a985dbc9d52062a71ea585dc5a187115da..233be899cb89e9168e5ea897a39b3407fd4603fa 100644 (file)
--- a/Gemfile
+++ b/Gemfile
@@ -1,5 +1,6 @@
 source "https://rubygems.org"
 
 gem 'capistrano',  '~> 3.4'
+gem 'capistrano-composer'
 gem 'capistrano-symfony', '~> 1.0.0.rc1'
-gem 'capistrano-composer', '~> 0.0.3'
+gem 'capistrano-file-permissions'
index aebbeba2708128534c27a3b4f828686b92f8bf0a..7b13b39914de8b9a8b9abfa34d08d2f2ec42d7f9 100644 (file)
@@ -29,8 +29,9 @@ PLATFORMS
 
 DEPENDENCIES
   capistrano (~> 3.4)
-  capistrano-composer (~> 0.0.3)
+  capistrano-composer
+  capistrano-file-permissions
   capistrano-symfony (~> 1.0.0.rc1)
 
 BUNDLED WITH
-   1.11.2
+   1.13.5
index f15eef3004415a421c0a5ae57a19f317854e2ea8..fee04620d683a2ead3d47dfafe5ac2ab79eced1b 100644 (file)
@@ -1,9 +1,4 @@
 # config valid only for current version of Capistrano
-lock '3.4.0'
-
-set :log_path, "var/logs"
-set :cache_path, "var/cache"
-set :symfony_console_path, 'bin/console'
 
 set :application, 'wallabag'
 set :repo_url, 'git@github.com:wallabag/wallabag.git'
@@ -11,8 +6,6 @@ set :repo_url, 'git@github.com:wallabag/wallabag.git'
 set :ssh_user, 'framasoft_bag'
 server '78.46.248.87', user: fetch(:ssh_user), roles: %w{web app db}
 
-set :scm, :git
-
 set :format, :pretty
 set :log_level, :info
 # set :log_level, :debug
@@ -23,4 +16,4 @@ set :linked_files, %w{app/config/parameters.yml}
 set :linked_dirs, [fetch(:log_path), "var/sessions", "web/uploads", "data"]
 set :keep_releases, 3
 
-after 'deploy:finishing', 'deploy:cleanup'
+after 'deploy:updated', 'symfony:cache:clear'
index f89111819b1b281e8f5f7b38e3e0ea2d4917cd12..bb21154d942937368e8cddca3bc798ce9a21ba30 100644 (file)
@@ -264,7 +264,8 @@ Drittanbieter Ressourcen
 
 Einige Applikationen oder Bibliotheken nutzen unsere API. Hier ist eine nicht abschließende Aufzählung von ihnen:
 
-- `Java wrapper for the wallabag API <https://github.com/Strubbl/wallabag-java>`_ von Strubbl.
+- `Java wrapper for the wallabag API <https://github.com/Strubbl/jWallabag>`_ von Strubbl.
 - `.NET library for the wallabag v2 API <https://github.com/jlnostr/wallabag-api>`_ von Julian Oster.
 - `Python API for wallabag <https://github.com/foxmask/wallabag_api>`_ von FoxMaSk, für sein Projekt `Trigger Happy <https://blog.trigger-happy.eu/>`_.
 - `A plugin <https://github.com/joshp23/ttrss-to-wallabag-v2>`_ entworfen für `Tiny Tiny RSS <https://tt-rss.org/gitlab/fox/tt-rss/wikis/home>`_, das die wallabag v2 API nutzt. Von Josh Panter.
+- `Golang wrapper for the wallabag API <https://github.com/Strubbl/wallabago>`_ von Strubbl, für sein Projekt `wallabag-stats Graph <https://github.com/Strubbl/wallabag-stats>`_.
index 4828cddd1c386e05830422d3bef4a53376d3b739..b6c9ed3fc6404d5bfed185325fe43e8fcd961b29 100644 (file)
@@ -263,7 +263,8 @@ Third party resources
 
 Some applications or libraries use our API. Here is a non-exhaustive list of them:
 
-- `Java wrapper for the wallabag API <https://github.com/Strubbl/wallabag-java>`_ by Strubbl.
+- `Java wrapper for the wallabag API <https://github.com/Strubbl/jWallabag>`_ by Strubbl.
 - `.NET library for the wallabag v2 API <https://github.com/jlnostr/wallabag-api>`_ by Julian Oster.
 - `Python API for wallabag <https://github.com/foxmask/wallabag_api>`_ by FoxMaSk, for his project `Trigger Happy <https://blog.trigger-happy.eu/>`_.
 - `A plugin <https://github.com/joshp23/ttrss-to-wallabag-v2>`_ designed for `Tiny Tiny RSS <https://tt-rss.org/gitlab/fox/tt-rss/wikis/home>`_ that makes use of the wallabag v2 API. By Josh Panter.
+- `Golang wrapper for the wallabag API <https://github.com/Strubbl/wallabago>`_ by Strubbl, for his project `wallabag-stats graph <https://github.com/Strubbl/wallabag-stats>`_.
index a0710a961db4a08e5ae6784023bb7f36dcbdd4d9..8a6e2a136386c7012041ac5debfc0353df8324a8 100644 (file)
@@ -263,7 +263,8 @@ Ressources tierces
 
 Certaines applications ou bibliothèques utilisent notre API. En voici une liste non exhaustive :
 
-- `Java wrapper for the wallabag API <https://github.com/Strubbl/wallabag-java>`_ par Strubbl.
+- `Java wrapper for the wallabag API <https://github.com/Strubbl/jWallabag>`_ par Strubbl.
 - `.NET library for the wallabag v2 API <https://github.com/jlnostr/wallabag-api>`_ par Julian Oster.
 - `Python API for wallabag <https://github.com/foxmask/wallabag_api>`_ par FoxMaSk, pour son projet `Trigger Happy <https://blog.trigger-happy.eu/>`_.
 - `Un plugin <https://github.com/joshp23/ttrss-to-wallabag-v2>`_ conçu pour `Tiny Tiny RSS <https://tt-rss.org/gitlab/fox/tt-rss/wikis/home>`_  qui utilise l'API wallabag v2. Par Josh Panter.
+- `Golang wrapper for the wallabag API <https://github.com/Strubbl/wallabago>`_ par Strubbl, pour son projet `wallabag-stats graphe <https://github.com/Strubbl/wallabag-stats>`_.
index fa3b2d5d5de32509e2e4160fd7a8b64ad9407c7f..0703ced1ef9111ef4c08d055db471fb43f50fad3 100644 (file)
@@ -1,11 +1,11 @@
-#! /usr/bin/env bash
+#!/usr/bin/env bash
 # You can execute this file to install wallabag dev environment
 # eg: `sh dev.sh`
 
 COMPOSER_COMMAND='composer'
 
-DIR="${BASH_SOURCE%/*}"
-if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi
+DIR="${BASH_SOURCE}"
+if [ ! -d "$DIR" ]; then DIR="$PWD/scripts"; fi
 . "$DIR/require.sh"
 
 $COMPOSER_COMMAND install
index 7a1f02bd80888c65fe7c97a2c33cc3e7346bd110..62a46f4fb60f8100b6228cfcc0a28d6f0ff3ec23 100644 (file)
@@ -1,11 +1,11 @@
-#! /usr/bin/env bash
+#!/usr/bin/env bash
 # You can execute this file to install wallabag
 # eg: `sh install.sh prod`
 
 COMPOSER_COMMAND='composer'
 
-DIR="${BASH_SOURCE%/*}"
-if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi
+DIR="${BASH_SOURCE}"
+if [ ! -d "$DIR" ]; then DIR="$PWD/scripts"; fi
 . "$DIR/require.sh"
 
 ENV=$1
index 45e93f3634eb09609852e5fd205a036ad4359ba2..f43c4f24c999ca0c6a72ca430a62ed66c2194466 100644 (file)
@@ -1,11 +1,11 @@
-#! /usr/bin/env bash
+#!/usr/bin/env bash
 # You can execute this file to update wallabag
 # eg: `sh update.sh prod`
 
 COMPOSER_COMMAND='composer'
 
-DIR="${BASH_SOURCE%/*}"
-if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi
+DIR="${BASH_SOURCE}"
+if [ ! -d "$DIR" ]; then DIR="$PWD/scripts"; fi
 . "$DIR/require.sh"
 
 ENV=$1
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..c1af9e023e91bfe1f43027057728ad14bb63f101 100644 (file)
@@ -1,4 +1,9 @@
 entries:
   type: rest
-  resource:     "WallabagApiBundle:WallabagRest"
+  resource:     "WallabagApiBundle:EntryRest"
+  name_prefix:  api_
+
+tags:
+  type: rest
+  resource:     "WallabagApiBundle:TagRest"
   name_prefix:  api_
index 6191d5d7973241f4582007b1db063766856e9f9b..79653cfe84831b792122fad960f68209a89fd3fd 100644 (file)
@@ -4,8 +4,10 @@ namespace Wallabag\CoreBundle\Controller;
 
 use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
 use Symfony\Bundle\FrameworkBundle\Controller\Controller;
+use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
 use Wallabag\CoreBundle\Entity\Entry;
+use Wallabag\CoreBundle\Entity\Tag;
 
 /**
  * The try/catch can be removed once all formats will be implemented.
@@ -51,15 +53,24 @@ class ExportController extends Controller
      *
      * @return \Symfony\Component\HttpFoundation\Response
      */
-    public function downloadEntriesAction($format, $category)
+    public function downloadEntriesAction(Request $request, $format, $category)
     {
         $method = ucfirst($category);
         $methodBuilder = 'getBuilderFor'.$method.'ByUser';
-        $entries = $this->getDoctrine()
-            ->getRepository('WallabagCoreBundle:Entry')
-            ->$methodBuilder($this->getUser()->getId())
-            ->getQuery()
-            ->getResult();
+
+        if ($category == 'tag_entries') {
+            $tag = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findOneBySlug($request->query->get('tag'));
+
+            $entries = $this->getDoctrine()
+                ->getRepository('WallabagCoreBundle:Entry')
+                ->findAllByTagId($this->getUser()->getId(), $tag->getId());
+        } else {
+            $entries = $this->getDoctrine()
+                ->getRepository('WallabagCoreBundle:Entry')
+                ->$methodBuilder($this->getUser()->getId())
+                ->getQuery()
+                ->getResult();
+        }
 
         try {
             return $this->get('wallabag_core.helper.entries_export')
index e50c68a67a91f0870a97f254df0328ace7e886c8..4bf292a4f815c0a32b4f26be31ea9cd76d9ce135 100644 (file)
@@ -8,7 +8,6 @@ use JMS\Serializer\SerializerBuilder;
 use PHPePub\Core\EPub;
 use PHPePub\Core\Structure\OPF\DublinCore;
 use Symfony\Component\HttpFoundation\Response;
-use Craue\ConfigBundle\Util\Config;
 
 /**
  * This class doesn't have unit test BUT it's fully covered by a functional test with ExportControllerTest.
@@ -27,12 +26,12 @@ class EntriesExport
         </div>';
 
     /**
-     * @param Config $craueConfig CraueConfig instance to get wallabag instance url from database
+     * @param string $wallabagUrl Wallabag instance url
      * @param string $logoPath    Path to the logo FROM THE BUNDLE SCOPE
      */
-    public function __construct(Config $craueConfig, $logoPath)
+    public function __construct($wallabagUrl, $logoPath)
     {
-        $this->wallabagUrl = $craueConfig->get('wallabag_url');
+        $this->wallabagUrl = $wallabagUrl;
         $this->logoPath = $logoPath;
     }
 
index 614488a64fd92596243a19ba5bea04d81c989c1a..90a2419eab70534ab93cba6417a6c3f55bede724 100644 (file)
@@ -55,6 +55,7 @@ services:
                         '.fok.nl': 'Googlebot/2.1'
                         'getpocket.com': 'PHP/5.2'
                         'iansommerville.com': 'PHP/5.2'
+                        '.slashdot.org': 'PHP/5.2'
         calls:
             - [ setLogger, [ "@logger" ] ]
         tags:
@@ -91,7 +92,7 @@ services:
     wallabag_core.helper.entries_export:
         class: Wallabag\CoreBundle\Helper\EntriesExport
         arguments:
-            - "@craue_config"
+            - '@=service(''craue_config'').get(''wallabag_url'')'
             - src/Wallabag/CoreBundle/Resources/public/themes/_global/img/appicon/apple-touch-icon-152.png
 
     wallabag.operator.array.matches:
index f19f2922c6168016c4f2529a10bdf2f198e6b497..5d657c7e7cb9a8bed158a52d9d01da3e7eb70ea5 100644 (file)
     <!-- Export -->
     <aside id="download-form">
     {% set currentRoute = app.request.attributes.get('_route') %}
+    {% set currentTag = '' %}
+    {% if tag is defined %}
+        {% set currentTag = tag %}
+    {% endif %}
     {% if currentRoute == 'homepage' %}
         {% set currentRoute = 'unread' %}
     {% endif %}
         <h2>{{ 'entry.list.export_title'|trans }}</h2>
         <a href="javascript: void(null);" id="download-form-close" class="close-button--popup close-button">&times;</a>
         <ul>
-            {% if craue_setting('export_epub') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'epub' }) }}">EPUB</a></li>{% endif %}
-            {% if craue_setting('export_mobi') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'mobi' }) }}">MOBI</a></li>{% endif %}
-            {% if craue_setting('export_pdf') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'pdf' }) }}">PDF</a></li>{% endif %}
-            {% if craue_setting('export_csv') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'json' }) }}">JSON</a></li>{% endif %}
-            {% if craue_setting('export_json') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'csv' }) }}">CSV</a></li>{% endif %}
-            {% if craue_setting('export_txt') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'txt' }) }}">TXT</a></li>{% endif %}
-            {% if craue_setting('export_xml') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'xml' }) }}">XML</a></li>{% endif %}
+            {% if craue_setting('export_epub') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'epub', 'tag' : currentTag }) }}">EPUB</a></li>{% endif %}
+            {% if craue_setting('export_mobi') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'mobi', 'tag' : currentTag }) }}">MOBI</a></li>{% endif %}
+            {% if craue_setting('export_pdf') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'pdf', 'tag' : currentTag }) }}">PDF</a></li>{% endif %}
+            {% if craue_setting('export_csv') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'json', 'tag' : currentTag }) }}">JSON</a></li>{% endif %}
+            {% if craue_setting('export_json') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'csv', 'tag' : currentTag }) }}">CSV</a></li>{% endif %}
+            {% if craue_setting('export_txt') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'txt', 'tag' : currentTag }) }}">TXT</a></li>{% endif %}
+            {% if craue_setting('export_xml') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'xml', 'tag' : currentTag }) }}">XML</a></li>{% endif %}
         </ul>
     </aside>
 
index 5c7cfd6538e46c9eb021059aed0cf2e5bb99762e..1225e68060d29934fac9e93c675b43f9b896eb96 100644 (file)
     <!-- Export -->
     <div id="export" class="side-nav fixed right-aligned">
     {% set currentRoute = app.request.attributes.get('_route') %}
+    {% set currentTag = '' %}
+    {% if tag is defined %}
+        {% set currentTag = tag %}
+    {% endif %}
     {% if currentRoute == 'homepage' %}
         {% set currentRoute = 'unread' %}
     {% endif %}
         <h4 class="center">{{ 'entry.list.export_title'|trans }}</h4>
         <ul>
-            {% if craue_setting('export_epub') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'epub' }) }}">EPUB</a></li>{% endif %}
-            {% if craue_setting('export_mobi') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'mobi' }) }}">MOBI</a></li>{% endif %}
-            {% if craue_setting('export_pdf') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'pdf' }) }}">PDF</a></li>{% endif %}
-            {% if craue_setting('export_csv') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'json' }) }}">JSON</a></li>{% endif %}
-            {% if craue_setting('export_json') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'csv' }) }}">CSV</a></li>{% endif %}
-            {% if craue_setting('export_txt') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'txt' }) }}">TXT</a></li>{% endif %}
-            {% if craue_setting('export_xml') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'xml' }) }}">XML</a></li>{% endif %}
+            {% if craue_setting('export_epub') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'epub', 'tag' : currentTag }) }}">EPUB</a></li>{% endif %}
+            {% if craue_setting('export_mobi') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'mobi', 'tag' : currentTag }) }}">MOBI</a></li>{% endif %}
+            {% if craue_setting('export_pdf') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'pdf', 'tag' : currentTag }) }}">PDF</a></li>{% endif %}
+            {% if craue_setting('export_csv') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'json', 'tag' : currentTag }) }}">JSON</a></li>{% endif %}
+            {% if craue_setting('export_json') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'csv', 'tag' : currentTag }) }}">CSV</a></li>{% endif %}
+            {% if craue_setting('export_txt') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'txt', 'tag' : currentTag }) }}">TXT</a></li>{% endif %}
+            {% if craue_setting('export_xml') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'xml', 'tag' : currentTag }) }}">XML</a></li>{% endif %}
         </ul>
     </div>
 
index 1df38295fca33dc64a3b7d54303f0eb1a4b8ce96..d1325338ddc8125f82dc3d0460b1515b0865859b 100644 (file)
@@ -50,6 +50,9 @@ class ImportCommand extends ContainerAwareCommand
             case 'chrome':
                 $wallabag = $this->getContainer()->get('wallabag_import.chrome.import');
                 break;
+            case 'instapaper':
+                $wallabag = $this->getContainer()->get('wallabag_import.instapaper.import');
+                break;
             case 'v1':
             default:
                 $wallabag = $this->getContainer()->get('wallabag_import.wallabag_v1.import');
index 89adc71b3453a4dd720b3a99bcc0ce5a438a1fd1..d600be0f800e25f8fb87045cf7dedec2cef05b10 100644 (file)
@@ -20,7 +20,6 @@ services:
         arguments:
             - "@doctrine.orm.entity_manager"
             - "@wallabag_core.content_proxy"
-            - "@craue_config"
         calls:
             - [ setClient, [ "@wallabag_import.pocket.client" ] ]
             - [ setLogger, [ "@logger" ]]
index ca9d18f171bc8974b64731774e62f001d78a0605..961208f27d2ff1340c93806d77a8a83a149c62af 100644 (file)
@@ -4,7 +4,6 @@ namespace Wallabag\UserBundle\Mailer;
 
 use Scheb\TwoFactorBundle\Model\Email\TwoFactorInterface;
 use Scheb\TwoFactorBundle\Mailer\AuthCodeMailerInterface;
-use Craue\ConfigBundle\Util\Config;
 
 /**
  * Custom mailer for TwoFactorBundle email.
@@ -61,16 +60,17 @@ class AuthCodeMailer implements AuthCodeMailerInterface
      * @param \Twig_Environment $twig
      * @param string            $senderEmail
      * @param string            $senderName
-     * @param Config            $craueConfig Craue\Config instance to get wallabag support url from database
+     * @param string            $supportUrl  wallabag support url
+     * @param string            $wallabagUrl wallabag instance url
      */
-    public function __construct(\Swift_Mailer $mailer, \Twig_Environment $twig, $senderEmail, $senderName, Config $craueConfig)
+    public function __construct(\Swift_Mailer $mailer, \Twig_Environment $twig, $senderEmail, $senderName, $supportUrl, $wallabagUrl)
     {
         $this->mailer = $mailer;
         $this->twig = $twig;
         $this->senderEmail = $senderEmail;
         $this->senderName = $senderName;
-        $this->supportUrl = $craueConfig->get('wallabag_support_url');
-        $this->wallabagUrl = $craueConfig->get('wallabag_url');
+        $this->supportUrl = $supportUrl;
+        $this->wallabagUrl = $wallabagUrl;
     }
 
     /**
index eb9c8e676e0cbd03b4f92eda2b502a1f5c88ad32..a8ee721b9e60f70a66071cc6e698849a92a02152 100644 (file)
@@ -6,7 +6,8 @@ services:
             - "@twig"
             - "%scheb_two_factor.email.sender_email%"
             - "%scheb_two_factor.email.sender_name%"
-            - "@craue_config"
+            - '@=service(''craue_config'').get(''wallabag_support_url'')'
+            - '@=service(''craue_config'').get(''wallabag_url'')'
 
     wallabag_user.password_resetting:
         class: Wallabag\UserBundle\EventListener\PasswordResettingListener
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());
-    }
 }
index 9ecd8bc4e62ddd950aa831c0c5cf1ffaa70c3b16..5ca886bd4d9e0a61ba29c12c76aac8ee80e948df 100644 (file)
@@ -117,6 +117,17 @@ class ExportControllerTest extends WallabagCoreTestCase
         $this->assertEquals('application/pdf', $headers->get('content-type'));
         $this->assertEquals('attachment; filename="All articles.pdf"', $headers->get('content-disposition'));
         $this->assertEquals('binary', $headers->get('content-transfer-encoding'));
+
+        ob_start();
+        $crawler = $client->request('GET', '/export/tag_entries.pdf?tag=foo');
+        ob_end_clean();
+
+        $this->assertEquals(200, $client->getResponse()->getStatusCode());
+
+        $headers = $client->getResponse()->headers;
+        $this->assertEquals('application/pdf', $headers->get('content-type'));
+        $this->assertEquals('attachment; filename="Tag_entries articles.pdf"', $headers->get('content-disposition'));
+        $this->assertEquals('binary', $headers->get('content-transfer-encoding'));
     }
 
     public function testTxtExport()
index 441d6519f5723537239b9e24f11863418e2abcba..21412da6e544d07d02f3b31d7f892207ff166049 100644 (file)
@@ -26,7 +26,6 @@ class AuthCodeMailerTest extends \PHPUnit_Framework_TestCase
     protected $mailer;
     protected $spool;
     protected $twig;
-    protected $config;
 
     protected function setUp()
     {
@@ -44,14 +43,6 @@ class AuthCodeMailerTest extends \PHPUnit_Framework_TestCase
 TWIG;
 
         $this->twig = new \Twig_Environment(new \Twig_Loader_Array(['WallabagUserBundle:TwoFactor:email_auth_code.html.twig' => $twigTemplate]));
-
-        $this->config = $this->getMockBuilder('Craue\ConfigBundle\Util\Config')
-            ->disableOriginalConstructor()
-            ->getMock();
-
-        $this->config->expects($this->any())
-            ->method('get')
-            ->willReturn('http://0.0.0.0/support');
     }
 
     public function testSendEmail()
@@ -67,7 +58,8 @@ TWIG;
             $this->twig,
             'nobody@test.io',
             'wallabag test',
-            $this->config
+            'http://0.0.0.0/support',
+            'http://0.0.0.0/'
         );
 
         $authCodeMailer->sendAuthCode($user);