aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorArthurHoaro <arthur@hoa.ro>2017-02-19 16:48:59 +0100
committerGitHub <noreply@github.com>2017-02-19 16:48:59 +0100
commitb9eb50c09947ec35838051e1bcfe5bc09a839f8e (patch)
tree514ddc5f97d12d5d0582f081cbdfc8a318aa9d17
parent65e56cbe49a7eb2a0cb09dda85daab3b921472ee (diff)
parent16e3d006e9e9386001881053f610657525feb188 (diff)
downloadShaarli-b9eb50c09947ec35838051e1bcfe5bc09a839f8e.tar.gz
Shaarli-b9eb50c09947ec35838051e1bcfe5bc09a839f8e.tar.zst
Shaarli-b9eb50c09947ec35838051e1bcfe5bc09a839f8e.zip
Merge pull request #728 from ArthurHoaro/api/getLink
REST API: implements getLink by ID service
-rw-r--r--application/api/controllers/Links.php25
-rw-r--r--application/api/exceptions/ApiLinkNotFoundException.php32
-rw-r--r--index.php5
-rw-r--r--tests/api/controllers/GetLinkIdTest.php130
-rw-r--r--tests/api/controllers/GetLinksTest.php (renamed from tests/api/controllers/LinksTest.php)13
5 files changed, 195 insertions, 10 deletions
diff --git a/application/api/controllers/Links.php b/application/api/controllers/Links.php
index 0a7968e3..d4f1a09c 100644
--- a/application/api/controllers/Links.php
+++ b/application/api/controllers/Links.php
@@ -4,6 +4,7 @@ namespace Shaarli\Api\Controllers;
4 4
5use Shaarli\Api\ApiUtils; 5use Shaarli\Api\ApiUtils;
6use Shaarli\Api\Exceptions\ApiBadParametersException; 6use Shaarli\Api\Exceptions\ApiBadParametersException;
7use Shaarli\Api\Exceptions\ApiLinkNotFoundException;
7use Slim\Http\Request; 8use Slim\Http\Request;
8use Slim\Http\Response; 9use Slim\Http\Response;
9 10
@@ -58,8 +59,7 @@ class Links extends ApiController
58 $limit = $request->getParam('limit'); 59 $limit = $request->getParam('limit');
59 if (empty($limit)) { 60 if (empty($limit)) {
60 $limit = self::$DEFAULT_LIMIT; 61 $limit = self::$DEFAULT_LIMIT;
61 } 62 } else if (ctype_digit($limit)) {
62 else if (ctype_digit($limit)) {
63 $limit = intval($limit); 63 $limit = intval($limit);
64 } else if ($limit === 'all') { 64 } else if ($limit === 'all') {
65 $limit = count($links); 65 $limit = count($links);
@@ -83,4 +83,25 @@ class Links extends ApiController
83 83
84 return $response->withJson($out, 200, $this->jsonStyle); 84 return $response->withJson($out, 200, $this->jsonStyle);
85 } 85 }
86
87 /**
88 * Return a single formatted link by its ID.
89 *
90 * @param Request $request Slim request.
91 * @param Response $response Slim response.
92 * @param array $args Path parameters. including the ID.
93 *
94 * @return Response containing the link array.
95 *
96 * @throws ApiLinkNotFoundException generating a 404 error.
97 */
98 public function getLink($request, $response, $args)
99 {
100 if (! isset($this->linkDb[$args['id']])) {
101 throw new ApiLinkNotFoundException();
102 }
103 $index = index_url($this->ci['environment']);
104 $out = ApiUtils::formatLink($this->linkDb[$args['id']], $index);
105 return $response->withJson($out, 200, $this->jsonStyle);
106 }
86} 107}
diff --git a/application/api/exceptions/ApiLinkNotFoundException.php b/application/api/exceptions/ApiLinkNotFoundException.php
new file mode 100644
index 00000000..de7e14f5
--- /dev/null
+++ b/application/api/exceptions/ApiLinkNotFoundException.php
@@ -0,0 +1,32 @@
1<?php
2
3namespace Shaarli\Api\Exceptions;
4
5
6use Slim\Http\Response;
7
8/**
9 * Class ApiLinkNotFoundException
10 *
11 * Link selected by ID couldn't be found, results in a 404 error.
12 *
13 * @package Shaarli\Api\Exceptions
14 */
15class ApiLinkNotFoundException extends ApiException
16{
17 /**
18 * ApiLinkNotFoundException constructor.
19 */
20 public function __construct()
21 {
22 $this->message = 'Link not found';
23 }
24
25 /**
26 * {@inheritdoc}
27 */
28 public function getApiResponse()
29 {
30 return $this->buildApiResponse(404);
31 }
32}
diff --git a/index.php b/index.php
index d1eee098..8eb36d81 100644
--- a/index.php
+++ b/index.php
@@ -2232,12 +2232,13 @@ $app = new \Slim\App($container);
2232$app->group('/api/v1', function() { 2232$app->group('/api/v1', function() {
2233 $this->get('/info', '\Shaarli\Api\Controllers\Info:getInfo'); 2233 $this->get('/info', '\Shaarli\Api\Controllers\Info:getInfo');
2234 $this->get('/links', '\Shaarli\Api\Controllers\Links:getLinks'); 2234 $this->get('/links', '\Shaarli\Api\Controllers\Links:getLinks');
2235 $this->get('/links/{id:[\d]+}', '\Shaarli\Api\Controllers\Links:getLink');
2235})->add('\Shaarli\Api\ApiMiddleware'); 2236})->add('\Shaarli\Api\ApiMiddleware');
2236 2237
2237$response = $app->run(true); 2238$response = $app->run(true);
2238// Hack to make Slim and Shaarli router work together: 2239// Hack to make Slim and Shaarli router work together:
2239// If a Slim route isn't found, we call renderPage(). 2240// If a Slim route isn't found and NOT API call, we call renderPage().
2240if ($response->getStatusCode() == 404) { 2241if ($response->getStatusCode() == 404 && strpos($_SERVER['REQUEST_URI'], '/api/v1') === false) {
2241 // We use UTF-8 for proper international characters handling. 2242 // We use UTF-8 for proper international characters handling.
2242 header('Content-Type: text/html; charset=utf-8'); 2243 header('Content-Type: text/html; charset=utf-8');
2243 renderPage($conf, $pluginManager, $linkDb); 2244 renderPage($conf, $pluginManager, $linkDb);
diff --git a/tests/api/controllers/GetLinkIdTest.php b/tests/api/controllers/GetLinkIdTest.php
new file mode 100644
index 00000000..1b020505
--- /dev/null
+++ b/tests/api/controllers/GetLinkIdTest.php
@@ -0,0 +1,130 @@
1<?php
2
3namespace Shaarli\Api\Controllers;
4
5
6use Slim\Container;
7use Slim\Http\Environment;
8use Slim\Http\Request;
9use Slim\Http\Response;
10
11/**
12 * Class GetLinkIdTest
13 *
14 * Test getLink by ID API service.
15 *
16 * @see http://shaarli.github.io/api-documentation/#links-link-get
17 *
18 * @package Shaarli\Api\Controllers
19 */
20class GetLinkIdTest extends \PHPUnit_Framework_TestCase
21{
22 /**
23 * @var string datastore to test write operations
24 */
25 protected static $testDatastore = 'sandbox/datastore.php';
26
27 /**
28 * @var \ConfigManager instance
29 */
30 protected $conf;
31
32 /**
33 * @var \ReferenceLinkDB instance.
34 */
35 protected $refDB = null;
36
37 /**
38 * @var Container instance.
39 */
40 protected $container;
41
42 /**
43 * @var Links controller instance.
44 */
45 protected $controller;
46
47 /**
48 * Number of JSON fields per link.
49 */
50 const NB_FIELDS_LINK = 9;
51
52 /**
53 * Before each test, instantiate a new Api with its config, plugins and links.
54 */
55 public function setUp()
56 {
57 $this->conf = new \ConfigManager('tests/utils/config/configJson');
58 $this->refDB = new \ReferenceLinkDB();
59 $this->refDB->write(self::$testDatastore);
60
61 $this->container = new Container();
62 $this->container['conf'] = $this->conf;
63 $this->container['db'] = new \LinkDB(self::$testDatastore, true, false);
64
65 $this->controller = new Links($this->container);
66 }
67
68 /**
69 * After each test, remove the test datastore.
70 */
71 public function tearDown()
72 {
73 @unlink(self::$testDatastore);
74 }
75
76 /**
77 * Test basic getLink service: return link ID=41.
78 */
79 public function testGetLinkId()
80 {
81 // Used by index_url().
82 $_SERVER['SERVER_NAME'] = 'domain.tld';
83 $_SERVER['SERVER_PORT'] = 80;
84 $_SERVER['SCRIPT_NAME'] = '/';
85
86 $id = 41;
87 $env = Environment::mock([
88 'REQUEST_METHOD' => 'GET',
89 ]);
90 $request = Request::createFromEnvironment($env);
91
92 $response = $this->controller->getLink($request, new Response(), ['id' => $id]);
93 $this->assertEquals(200, $response->getStatusCode());
94 $data = json_decode((string) $response->getBody(), true);
95 $this->assertEquals(self::NB_FIELDS_LINK, count($data));
96 $this->assertEquals($id, $data['id']);
97
98 // Check link elements
99 $this->assertEquals('http://domain.tld/?WDWyig', $data['url']);
100 $this->assertEquals('WDWyig', $data['shorturl']);
101 $this->assertEquals('Link title: @website', $data['title']);
102 $this->assertEquals(
103 'Stallman has a beard and is part of the Free Software Foundation (or not). Seriously, read this. #hashtag',
104 $data['description']
105 );
106 $this->assertEquals('sTuff', $data['tags'][0]);
107 $this->assertEquals(false, $data['private']);
108 $this->assertEquals(
109 \DateTime::createFromFormat(\LinkDB::LINK_DATE_FORMAT, '20150310_114651')->format(\DateTime::ATOM),
110 $data['created']
111 );
112 $this->assertEmpty($data['updated']);
113 }
114
115 /**
116 * Test basic getLink service: get non existent link => ApiLinkNotFoundException.
117 *
118 * @expectedException Shaarli\Api\Exceptions\ApiLinkNotFoundException
119 * @expectedExceptionMessage Link not found
120 */
121 public function testGetLink404()
122 {
123 $env = Environment::mock([
124 'REQUEST_METHOD' => 'GET',
125 ]);
126 $request = Request::createFromEnvironment($env);
127
128 $this->controller->getLink($request, new Response(), ['id' => -1]);
129 }
130}
diff --git a/tests/api/controllers/LinksTest.php b/tests/api/controllers/GetLinksTest.php
index 284c3a9d..da54fcf1 100644
--- a/tests/api/controllers/LinksTest.php
+++ b/tests/api/controllers/GetLinksTest.php
@@ -9,14 +9,15 @@ use Slim\Http\Request;
9use Slim\Http\Response; 9use Slim\Http\Response;
10 10
11/** 11/**
12 * Class LinksTest 12 * Class GetLinksTest
13 * 13 *
14 * Test Links REST API services. 14 * Test get Link list REST API service.
15 * Note that api call results are tightly related to data contained in ReferenceLinkDB. 15 *
16 * @see http://shaarli.github.io/api-documentation/#links-links-collection-get
16 * 17 *
17 * @package Shaarli\Api\Controllers 18 * @package Shaarli\Api\Controllers
18 */ 19 */
19class LinksTest extends \PHPUnit_Framework_TestCase 20class GetLinksTest extends \PHPUnit_Framework_TestCase
20{ 21{
21 /** 22 /**
22 * @var string datastore to test write operations 23 * @var string datastore to test write operations
@@ -53,7 +54,7 @@ class LinksTest extends \PHPUnit_Framework_TestCase
53 */ 54 */
54 public function setUp() 55 public function setUp()
55 { 56 {
56 $this->conf = new \ConfigManager('tests/utils/config/configJson.json.php'); 57 $this->conf = new \ConfigManager('tests/utils/config/configJson');
57 $this->refDB = new \ReferenceLinkDB(); 58 $this->refDB = new \ReferenceLinkDB();
58 $this->refDB->write(self::$testDatastore); 59 $this->refDB->write(self::$testDatastore);
59 60
@@ -100,7 +101,7 @@ class LinksTest extends \PHPUnit_Framework_TestCase
100 $this->assertEquals($order[$cpt++], $link['id']); 101 $this->assertEquals($order[$cpt++], $link['id']);
101 } 102 }
102 103
103 // Check first element fields\ 104 // Check first element fields
104 $first = $data[0]; 105 $first = $data[0];
105 $this->assertEquals('http://domain.tld/?WDWyig', $first['url']); 106 $this->assertEquals('http://domain.tld/?WDWyig', $first['url']);
106 $this->assertEquals('WDWyig', $first['shorturl']); 107 $this->assertEquals('WDWyig', $first['shorturl']);