]> git.immae.eu Git - github/shaarli/Shaarli.git/commitdiff
API: add DELETE endpoint 856/head
authorArthurHoaro <arthur@hoa.ro>
Sat, 6 May 2017 15:32:16 +0000 (17:32 +0200)
committerArthurHoaro <arthur@hoa.ro>
Sun, 7 May 2017 13:58:49 +0000 (15:58 +0200)
Based on #840

See http://shaarli.github.io/api-documentation/\#links-link-delete

application/api/controllers/Links.php
composer.lock
index.php
tests/api/controllers/DeleteLinkTest.php [new file with mode: 0644]

index 1c68b0620a3eb919734106720e0577142a06ae42..a40e974df8b9f375431bc67991f2f5f4c36da1b5 100644 (file)
@@ -188,4 +188,27 @@ class Links extends ApiController
         $out = ApiUtils::formatLink($responseLink, $index);
         return $response->withJson($out, 200, $this->jsonStyle);
     }
+
+    /**
+     * Delete an existing link by its ID.
+     *
+     * @param Request  $request  Slim request.
+     * @param Response $response Slim response.
+     * @param array    $args     Path parameters. including the ID.
+     *
+     * @return Response response.
+     *
+     * @throws ApiLinkNotFoundException generating a 404 error.
+     */
+    public function deleteLink($request, $response, $args)
+    {
+        if (! isset($this->linkDb[$args['id']])) {
+            throw new ApiLinkNotFoundException();
+        }
+
+        unset($this->linkDb[(int) $args['id']]);
+        $this->linkDb->save($this->conf->get('resource.page_cache'));
+
+        return $response->withStatus(204);
+    }
 }
index b285fcc962b6c026728d7ac79ee5b6e95381fa97..0c1efa6b8084a1998c3263540450b7f26904d768 100644 (file)
         },
         {
             "name": "squizlabs/php_codesniffer",
-            "version": "2.8.1",
+            "version": "2.9.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
-                "reference": "d7cf0d894e8aa4c73712ee4a331cc1eaa37cdc7d"
+                "reference": "f7dfecbee89d68ab475a6c9e17d22bc9b69aed97"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/d7cf0d894e8aa4c73712ee4a331cc1eaa37cdc7d",
-                "reference": "d7cf0d894e8aa4c73712ee4a331cc1eaa37cdc7d",
+                "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/f7dfecbee89d68ab475a6c9e17d22bc9b69aed97",
+                "reference": "f7dfecbee89d68ab475a6c9e17d22bc9b69aed97",
                 "shasum": ""
             },
             "require": {
                 "phpcs",
                 "standards"
             ],
-            "time": "2017-03-01T22:17:45+00:00"
+            "time": "2017-05-03T23:30:39+00:00"
         },
         {
             "name": "symfony/config",
-            "version": "v3.2.6",
+            "version": "v3.2.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/config.git",
-                "reference": "741d6d4cd1414d67d48eb71aba6072b46ba740c2"
+                "reference": "e5533fcc0b3dd377626153b2852707878f363728"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/config/zipball/741d6d4cd1414d67d48eb71aba6072b46ba740c2",
-                "reference": "741d6d4cd1414d67d48eb71aba6072b46ba740c2",
+                "url": "https://api.github.com/repos/symfony/config/zipball/e5533fcc0b3dd377626153b2852707878f363728",
+                "reference": "e5533fcc0b3dd377626153b2852707878f363728",
                 "shasum": ""
             },
             "require": {
             ],
             "description": "Symfony Config Component",
             "homepage": "https://symfony.com",
-            "time": "2017-03-01T18:18:25+00:00"
+            "time": "2017-04-12T14:13:17+00:00"
         },
         {
             "name": "symfony/console",
-            "version": "v2.8.18",
+            "version": "v2.8.20",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/console.git",
-                "reference": "81508e6fac4476771275a3f4f53c3fee9b956bfa"
+                "reference": "2cfcbced8e39e2313ed4da8896fc8c59a56c0d7e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/console/zipball/81508e6fac4476771275a3f4f53c3fee9b956bfa",
-                "reference": "81508e6fac4476771275a3f4f53c3fee9b956bfa",
+                "url": "https://api.github.com/repos/symfony/console/zipball/2cfcbced8e39e2313ed4da8896fc8c59a56c0d7e",
+                "reference": "2cfcbced8e39e2313ed4da8896fc8c59a56c0d7e",
                 "shasum": ""
             },
             "require": {
             ],
             "description": "Symfony Console Component",
             "homepage": "https://symfony.com",
-            "time": "2017-03-04T11:00:12+00:00"
+            "time": "2017-04-26T01:38:53+00:00"
         },
         {
             "name": "symfony/debug",
         },
         {
             "name": "symfony/dependency-injection",
-            "version": "v3.2.6",
+            "version": "v3.2.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/dependency-injection.git",
-                "reference": "74e0935e414ad33d5e82074212c0eedb4681a691"
+                "reference": "5e00857475b6d1fa31ff4c76f1fddf1cfa9e8d59"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/74e0935e414ad33d5e82074212c0eedb4681a691",
-                "reference": "74e0935e414ad33d5e82074212c0eedb4681a691",
+                "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/5e00857475b6d1fa31ff4c76f1fddf1cfa9e8d59",
+                "reference": "5e00857475b6d1fa31ff4c76f1fddf1cfa9e8d59",
                 "shasum": ""
             },
             "require": {
             ],
             "description": "Symfony DependencyInjection Component",
             "homepage": "https://symfony.com",
-            "time": "2017-03-05T00:06:55+00:00"
+            "time": "2017-04-26T01:39:17+00:00"
         },
         {
             "name": "symfony/filesystem",
-            "version": "v3.2.6",
+            "version": "v3.2.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/filesystem.git",
-                "reference": "bc0f17bed914df2cceb989972c3b996043c4da4a"
+                "reference": "040651db13cf061827a460cc10f6e36a445c45b4"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/filesystem/zipball/bc0f17bed914df2cceb989972c3b996043c4da4a",
-                "reference": "bc0f17bed914df2cceb989972c3b996043c4da4a",
+                "url": "https://api.github.com/repos/symfony/filesystem/zipball/040651db13cf061827a460cc10f6e36a445c45b4",
+                "reference": "040651db13cf061827a460cc10f6e36a445c45b4",
                 "shasum": ""
             },
             "require": {
             ],
             "description": "Symfony Filesystem Component",
             "homepage": "https://symfony.com",
-            "time": "2017-03-06T19:30:27+00:00"
+            "time": "2017-04-12T14:13:17+00:00"
         },
         {
             "name": "symfony/finder",
-            "version": "v3.2.6",
+            "version": "v3.2.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/finder.git",
-                "reference": "92d7476d2df60cd851a3e13e078664b1deb8ce10"
+                "reference": "9cf076f8f492f4b1ffac40aae9c2d287b4ca6930"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/finder/zipball/92d7476d2df60cd851a3e13e078664b1deb8ce10",
-                "reference": "92d7476d2df60cd851a3e13e078664b1deb8ce10",
+                "url": "https://api.github.com/repos/symfony/finder/zipball/9cf076f8f492f4b1ffac40aae9c2d287b4ca6930",
+                "reference": "9cf076f8f492f4b1ffac40aae9c2d287b4ca6930",
                 "shasum": ""
             },
             "require": {
             ],
             "description": "Symfony Finder Component",
             "homepage": "https://symfony.com",
-            "time": "2017-02-21T09:12:04+00:00"
+            "time": "2017-04-12T14:13:17+00:00"
         },
         {
             "name": "symfony/polyfill-mbstring",
         },
         {
             "name": "symfony/yaml",
-            "version": "v3.2.6",
+            "version": "v3.2.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/yaml.git",
-                "reference": "093e416ad096355149e265ea2e4cc1f9ee40ab1a"
+                "reference": "acec26fcf7f3031e094e910b94b002fa53d4e4d6"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/yaml/zipball/093e416ad096355149e265ea2e4cc1f9ee40ab1a",
-                "reference": "093e416ad096355149e265ea2e4cc1f9ee40ab1a",
+                "url": "https://api.github.com/repos/symfony/yaml/zipball/acec26fcf7f3031e094e910b94b002fa53d4e4d6",
+                "reference": "acec26fcf7f3031e094e910b94b002fa53d4e4d6",
                 "shasum": ""
             },
             "require": {
             ],
             "description": "Symfony Yaml Component",
             "homepage": "https://symfony.com",
-            "time": "2017-03-07T16:47:02+00:00"
+            "time": "2017-05-01T14:55:58+00:00"
         },
         {
             "name": "theseer/fdomdocument",
-            "version": "1.6.1",
+            "version": "1.6.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/theseer/fDOMDocument.git",
-                "reference": "d9ad139d6c2e8edf5e313ffbe37ff13344cf0684"
+                "reference": "8dcfd392135a5bd938c3c83ea71419501ad9855d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/theseer/fDOMDocument/zipball/d9ad139d6c2e8edf5e313ffbe37ff13344cf0684",
-                "reference": "d9ad139d6c2e8edf5e313ffbe37ff13344cf0684",
+                "url": "https://api.github.com/repos/theseer/fDOMDocument/zipball/8dcfd392135a5bd938c3c83ea71419501ad9855d",
+                "reference": "8dcfd392135a5bd938c3c83ea71419501ad9855d",
                 "shasum": ""
             },
             "require": {
             ],
             "description": "The classes contained within this repository extend the standard DOM to use exceptions at all occasions of errors instead of PHP warnings or notices. They also add various custom methods and shortcuts for convenience and to simplify the usage of DOM.",
             "homepage": "https://github.com/theseer/fDOMDocument",
-            "time": "2015-05-27T22:58:02+00:00"
+            "time": "2017-04-21T14:50:31+00:00"
         },
         {
             "name": "webmozart/assert",
index d6642b68e9471e8d1d9a4f372a2d88ce131438bd..6eaa56c210931d5e5afcb296e71e51fc1614ae66 100644 (file)
--- a/index.php
+++ b/index.php
@@ -2247,6 +2247,7 @@ $app->group('/api/v1', function() {
     $this->get('/links/{id:[\d]+}', '\Shaarli\Api\Controllers\Links:getLink')->setName('getLink');
     $this->post('/links', '\Shaarli\Api\Controllers\Links:postLink')->setName('postLink');
     $this->put('/links/{id:[\d]+}', '\Shaarli\Api\Controllers\Links:putLink')->setName('putLink');
+    $this->delete('/links/{id:[\d]+}', '\Shaarli\Api\Controllers\Links:deleteLink')->setName('deleteLink');
 })->add('\Shaarli\Api\ApiMiddleware');
 
 $response = $app->run(true);
diff --git a/tests/api/controllers/DeleteLinkTest.php b/tests/api/controllers/DeleteLinkTest.php
new file mode 100644 (file)
index 0000000..6894e8a
--- /dev/null
@@ -0,0 +1,104 @@
+<?php
+
+
+namespace Shaarli\Api\Controllers;
+
+use Shaarli\Config\ConfigManager;
+use Slim\Container;
+use Slim\Http\Environment;
+use Slim\Http\Request;
+use Slim\Http\Response;
+
+class DeleteLinkTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var string datastore to test write operations
+     */
+    protected static $testDatastore = 'sandbox/datastore.php';
+
+    /**
+     * @var ConfigManager instance
+     */
+    protected $conf;
+
+    /**
+     * @var \ReferenceLinkDB instance.
+     */
+    protected $refDB = null;
+
+    /**
+     * @var \LinkDB instance.
+     */
+    protected $linkDB;
+
+    /**
+     * @var Container instance.
+     */
+    protected $container;
+
+    /**
+     * @var Links controller instance.
+     */
+    protected $controller;
+
+    /**
+     * Before each test, instantiate a new Api with its config, plugins and links.
+     */
+    public function setUp()
+    {
+        $this->conf = new ConfigManager('tests/utils/config/configJson');
+        $this->refDB = new \ReferenceLinkDB();
+        $this->refDB->write(self::$testDatastore);
+        $this->linkDB = new \LinkDB(self::$testDatastore, true, false);
+        $this->container = new Container();
+        $this->container['conf'] = $this->conf;
+        $this->container['db'] = $this->linkDB;
+
+        $this->controller = new Links($this->container);
+    }
+
+    /**
+     * After each test, remove the test datastore.
+     */
+    public function tearDown()
+    {
+        @unlink(self::$testDatastore);
+    }
+
+    /**
+     * Test DELETE link endpoint: the link should be removed.
+     */
+    public function testDeleteLinkValid()
+    {
+        $id = '41';
+        $this->assertTrue(isset($this->linkDB[$id]));
+        $env = Environment::mock([
+            'REQUEST_METHOD' => 'DELETE',
+        ]);
+        $request = Request::createFromEnvironment($env);
+
+        $response = $this->controller->deleteLink($request, new Response(), ['id' => $id]);
+        $this->assertEquals(204, $response->getStatusCode());
+        $this->assertEmpty((string) $response->getBody());
+
+        $this->linkDB = new \LinkDB(self::$testDatastore, true, false);
+        $this->assertFalse(isset($this->linkDB[$id]));
+    }
+
+    /**
+     * Test DELETE link endpoint: reach not existing ID.
+     *
+     * @expectedException Shaarli\Api\Exceptions\ApiLinkNotFoundException
+     */
+    public function testDeleteLink404()
+    {
+        $id = -1;
+        $this->assertFalse(isset($this->linkDB[$id]));
+        $env = Environment::mock([
+            'REQUEST_METHOD' => 'DELETE',
+        ]);
+        $request = Request::createFromEnvironment($env);
+
+        $this->controller->deleteLink($request, new Response(), ['id' => $id]);
+    }
+}