aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests
diff options
context:
space:
mode:
authorArthurHoaro <arthur@hoa.ro>2016-12-22 14:36:45 +0100
committerArthurHoaro <arthur@hoa.ro>2017-01-15 13:55:22 +0100
commitc3b00963fe22479e87998c82bc83827a54c8d972 (patch)
tree4c3f47697f8e58e2c60aa94bdcb506c770e4bd5e /tests
parentfc11ab2f290a3712b766d78fdbcd354625a35d0a (diff)
downloadShaarli-c3b00963fe22479e87998c82bc83827a54c8d972.tar.gz
Shaarli-c3b00963fe22479e87998c82bc83827a54c8d972.tar.zst
Shaarli-c3b00963fe22479e87998c82bc83827a54c8d972.zip
REST API: implement getLinks service
See http://shaarli.github.io/api-documentation/#links-links-collection-get
Diffstat (limited to 'tests')
-rw-r--r--tests/api/ApiUtilsTest.php65
-rw-r--r--tests/api/controllers/LinksTest.php393
2 files changed, 458 insertions, 0 deletions
diff --git a/tests/api/ApiUtilsTest.php b/tests/api/ApiUtilsTest.php
index 10da1459..516ee686 100644
--- a/tests/api/ApiUtilsTest.php
+++ b/tests/api/ApiUtilsTest.php
@@ -203,4 +203,69 @@ class ApiUtilsTest extends \PHPUnit_Framework_TestCase
203 $token = $this->generateCustomJwtToken('{"JSON":1}', '{"iat":' . (time() + 60) . '}', 'secret'); 203 $token = $this->generateCustomJwtToken('{"JSON":1}', '{"iat":' . (time() + 60) . '}', 'secret');
204 ApiUtils::validateJwtToken($token, 'secret'); 204 ApiUtils::validateJwtToken($token, 'secret');
205 } 205 }
206
207 /**
208 * Test formatLink() with a link using all useful fields.
209 */
210 public function testFormatLinkComplete()
211 {
212 $indexUrl = 'https://domain.tld/sub/';
213 $link = [
214 'id' => 12,
215 'url' => 'http://lol.lol',
216 'shorturl' => 'abc',
217 'title' => 'Important Title',
218 'description' => 'It is very lol<tag>' . PHP_EOL . 'new line',
219 'tags' => 'blip .blop ',
220 'private' => '1',
221 'created' => \DateTime::createFromFormat('Ymd_His', '20170107_160102'),
222 'updated' => \DateTime::createFromFormat('Ymd_His', '20170107_160612'),
223 ];
224
225 $expected = [
226 'id' => 12,
227 'url' => 'http://lol.lol',
228 'shorturl' => 'abc',
229 'title' => 'Important Title',
230 'description' => 'It is very lol<tag>' . PHP_EOL . 'new line',
231 'tags' => ['blip', '.blop'],
232 'private' => true,
233 'created' => '2017-01-07T16:01:02+00:00',
234 'updated' => '2017-01-07T16:06:12+00:00',
235 ];
236
237 $this->assertEquals($expected, ApiUtils::formatLink($link, $indexUrl));
238 }
239
240 /**
241 * Test formatLink() with only minimal fields filled, and internal link.
242 */
243 public function testFormatLinkMinimalNote()
244 {
245 $indexUrl = 'https://domain.tld/sub/';
246 $link = [
247 'id' => 12,
248 'url' => '?abc',
249 'shorturl' => 'abc',
250 'title' => 'Note',
251 'description' => '',
252 'tags' => '',
253 'private' => '',
254 'created' => \DateTime::createFromFormat('Ymd_His', '20170107_160102'),
255 ];
256
257 $expected = [
258 'id' => 12,
259 'url' => 'https://domain.tld/sub/?abc',
260 'shorturl' => 'abc',
261 'title' => 'Note',
262 'description' => '',
263 'tags' => [],
264 'private' => false,
265 'created' => '2017-01-07T16:01:02+00:00',
266 'updated' => '',
267 ];
268
269 $this->assertEquals($expected, ApiUtils::formatLink($link, $indexUrl));
270 }
206} 271}
diff --git a/tests/api/controllers/LinksTest.php b/tests/api/controllers/LinksTest.php
new file mode 100644
index 00000000..4ead26b9
--- /dev/null
+++ b/tests/api/controllers/LinksTest.php
@@ -0,0 +1,393 @@
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 LinksTest
13 *
14 * Test Links REST API services.
15 * Note that api call results are tightly related to data contained in ReferenceLinkDB.
16 *
17 * @package Shaarli\Api\Controllers
18 */
19class LinksTest extends \PHPUnit_Framework_TestCase
20{
21 /**
22 * @var string datastore to test write operations
23 */
24 protected static $testDatastore = 'sandbox/datastore.php';
25
26 /**
27 * @var \ConfigManager instance
28 */
29 protected $conf;
30
31 /**
32 * @var \ReferenceLinkDB instance.
33 */
34 protected $refDB = null;
35
36 /**
37 * @var Container instance.
38 */
39 protected $container;
40
41 /**
42 * @var Links controller instance.
43 */
44 protected $controller;
45
46 /**
47 * Number of JSON field per link.
48 */
49 const NB_FIELDS_LINK = 9;
50
51 /**
52 * Before every test, instantiate a new Api with its config, plugins and links.
53 */
54 public function setUp()
55 {
56 $this->conf = new \ConfigManager('tests/utils/config/configJson.json.php');
57 $this->refDB = new \ReferenceLinkDB();
58 $this->refDB->write(self::$testDatastore);
59
60 $this->container = new Container();
61 $this->container['conf'] = $this->conf;
62 $this->container['db'] = new \LinkDB(self::$testDatastore, true, false);
63
64 $this->controller = new Links($this->container);
65 }
66
67 /**
68 * After every test, remove the test datastore.
69 */
70 public function tearDown()
71 {
72 @unlink(self::$testDatastore);
73 }
74
75 /**
76 * Test basic getLinks service: returns all links.
77 */
78 public function testGetLinks()
79 {
80 // Used by index_url().
81 $_SERVER['SERVER_NAME'] = 'domain.tld';
82 $_SERVER['SERVER_PORT'] = 80;
83 $_SERVER['SCRIPT_NAME'] = '/';
84
85 $env = Environment::mock([
86 'REQUEST_METHOD' => 'GET',
87 ]);
88 $request = Request::createFromEnvironment($env);
89
90 $response = $this->controller->getLinks($request, new Response());
91 $this->assertEquals(200, $response->getStatusCode());
92 $data = json_decode((string) $response->getBody(), true);
93 $this->assertEquals($this->refDB->countLinks(), count($data));
94
95 // Check order
96 $order = [41, 8, 6, 7, 0, 1, 4, 42];
97 $cpt = 0;
98 foreach ($data as $link) {
99 $this->assertEquals(self::NB_FIELDS_LINK, count($link));
100 $this->assertEquals($order[$cpt++], $link['id']);
101 }
102
103 // Check first element fields\
104 $first = $data[0];
105 $this->assertEquals('http://domain.tld/?WDWyig', $first['url']);
106 $this->assertEquals('WDWyig', $first['shorturl']);
107 $this->assertEquals('Link title: @website', $first['title']);
108 $this->assertEquals(
109 'Stallman has a beard and is part of the Free Software Foundation (or not). Seriously, read this. #hashtag',
110 $first['description']
111 );
112 $this->assertEquals('sTuff', $first['tags'][0]);
113 $this->assertEquals(false, $first['private']);
114 $this->assertEquals(
115 \DateTime::createFromFormat(\LinkDB::LINK_DATE_FORMAT, '20150310_114651')->format(\DateTime::ATOM),
116 $first['created']
117 );
118 $this->assertEmpty($first['updated']);
119
120 // Multi tags
121 $link = $data[1];
122 $this->assertEquals(7, count($link['tags']));
123
124 // Update date
125 $this->assertEquals(
126 \DateTime::createFromFormat(\LinkDB::LINK_DATE_FORMAT, '20160803_093033')->format(\DateTime::ATOM),
127 $link['updated']
128 );
129 }
130
131 /**
132 * Test getLinks service with offset and limit parameter:
133 * limit=1 and offset=1 should return only the second link, ID=8 (ordered by creation date DESC).
134 */
135 public function testGetLinksOffsetLimit()
136 {
137 $env = Environment::mock([
138 'REQUEST_METHOD' => 'GET',
139 'QUERY_STRING' => 'offset=1&limit=1'
140 ]);
141 $request = Request::createFromEnvironment($env);
142 $response = $this->controller->getLinks($request, new Response());
143 $this->assertEquals(200, $response->getStatusCode());
144 $data = json_decode((string) $response->getBody(), true);
145 $this->assertEquals(1, count($data));
146 $this->assertEquals(8, $data[0]['id']);
147 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
148 }
149
150 /**
151 * Test getLinks with limit=all (return all link).
152 */
153 public function testGetLinksLimitAll()
154 {
155 $env = Environment::mock([
156 'REQUEST_METHOD' => 'GET',
157 'QUERY_STRING' => 'limit=all'
158 ]);
159 $request = Request::createFromEnvironment($env);
160 $response = $this->controller->getLinks($request, new Response());
161 $this->assertEquals(200, $response->getStatusCode());
162 $data = json_decode((string) $response->getBody(), true);
163 $this->assertEquals($this->refDB->countLinks(), count($data));
164 // Check order
165 $order = [41, 8, 6, 7, 0, 1, 4, 42];
166 $cpt = 0;
167 foreach ($data as $link) {
168 $this->assertEquals(self::NB_FIELDS_LINK, count($link));
169 $this->assertEquals($order[$cpt++], $link['id']);
170 }
171 }
172
173 /**
174 * Test getLinks service with offset and limit parameter:
175 * limit=1 and offset=1 should return only the second link, ID=8 (ordered by creation date DESC).
176 */
177 public function testGetLinksOffsetTooHigh()
178 {
179 $env = Environment::mock([
180 'REQUEST_METHOD' => 'GET',
181 'QUERY_STRING' => 'offset=100'
182 ]);
183 $request = Request::createFromEnvironment($env);
184 $response = $this->controller->getLinks($request, new Response());
185 $this->assertEquals(200, $response->getStatusCode());
186 $data = json_decode((string) $response->getBody(), true);
187 $this->assertEmpty(count($data));
188 }
189
190 /**
191 * Test getLinks with private attribute to 1 or true.
192 */
193 public function testGetLinksPrivate()
194 {
195 $env = Environment::mock([
196 'REQUEST_METHOD' => 'GET',
197 'QUERY_STRING' => 'private=true'
198 ]);
199 $request = Request::createFromEnvironment($env);
200 $response = $this->controller->getLinks($request, new Response());
201 $this->assertEquals(200, $response->getStatusCode());
202 $data = json_decode((string) $response->getBody(), true);
203 $this->assertEquals($this->refDB->countPrivateLinks(), count($data));
204 $this->assertEquals(6, $data[0]['id']);
205 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
206
207 $env = Environment::mock([
208 'REQUEST_METHOD' => 'GET',
209 'QUERY_STRING' => 'private=1'
210 ]);
211 $request = Request::createFromEnvironment($env);
212 $response = $this->controller->getLinks($request, new Response());
213 $this->assertEquals(200, $response->getStatusCode());
214 $data = json_decode((string) $response->getBody(), true);
215 $this->assertEquals($this->refDB->countPrivateLinks(), count($data));
216 $this->assertEquals(6, $data[0]['id']);
217 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
218 }
219
220 /**
221 * Test getLinks with private attribute to false or 0
222 */
223 public function testGetLinksNotPrivate()
224 {
225 $env = Environment::mock(
226 [
227 'REQUEST_METHOD' => 'GET',
228 'QUERY_STRING' => 'private=0'
229 ]
230 );
231 $request = Request::createFromEnvironment($env);
232 $response = $this->controller->getLinks($request, new Response());
233 $this->assertEquals(200, $response->getStatusCode());
234 $data = json_decode((string)$response->getBody(), true);
235 $this->assertEquals($this->refDB->countLinks(), count($data));
236 $this->assertEquals(41, $data[0]['id']);
237 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
238
239 $env = Environment::mock(
240 [
241 'REQUEST_METHOD' => 'GET',
242 'QUERY_STRING' => 'private=false'
243 ]
244 );
245 $request = Request::createFromEnvironment($env);
246 $response = $this->controller->getLinks($request, new Response());
247 $this->assertEquals(200, $response->getStatusCode());
248 $data = json_decode((string)$response->getBody(), true);
249 $this->assertEquals($this->refDB->countLinks(), count($data));
250 $this->assertEquals(41, $data[0]['id']);
251 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
252 }
253
254 /**
255 * Test getLinks service with offset and limit parameter:
256 * limit=1 and offset=1 should return only the second link, ID=8 (ordered by creation date DESC).
257 */
258 public function testGetLinksSearchTerm()
259 {
260 // Only in description - 1 result
261 $env = Environment::mock([
262 'REQUEST_METHOD' => 'GET',
263 'QUERY_STRING' => 'searchterm=Tropical'
264 ]);
265 $request = Request::createFromEnvironment($env);
266 $response = $this->controller->getLinks($request, new Response());
267 $this->assertEquals(200, $response->getStatusCode());
268 $data = json_decode((string) $response->getBody(), true);
269 $this->assertEquals(1, count($data));
270 $this->assertEquals(1, $data[0]['id']);
271 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
272
273 // Only in tags - 1 result
274 $env = Environment::mock([
275 'REQUEST_METHOD' => 'GET',
276 'QUERY_STRING' => 'searchterm=tag3'
277 ]);
278 $request = Request::createFromEnvironment($env);
279 $response = $this->controller->getLinks($request, new Response());
280 $this->assertEquals(200, $response->getStatusCode());
281 $data = json_decode((string) $response->getBody(), true);
282 $this->assertEquals(1, count($data));
283 $this->assertEquals(0, $data[0]['id']);
284 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
285
286 // Multiple results (2)
287 $env = Environment::mock([
288 'REQUEST_METHOD' => 'GET',
289 'QUERY_STRING' => 'searchterm=stallman'
290 ]);
291 $request = Request::createFromEnvironment($env);
292 $response = $this->controller->getLinks($request, new Response());
293 $this->assertEquals(200, $response->getStatusCode());
294 $data = json_decode((string) $response->getBody(), true);
295 $this->assertEquals(2, count($data));
296 $this->assertEquals(41, $data[0]['id']);
297 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
298 $this->assertEquals(8, $data[1]['id']);
299 $this->assertEquals(self::NB_FIELDS_LINK, count($data[1]));
300
301 // Multiword - 2 results
302 $env = Environment::mock([
303 'REQUEST_METHOD' => 'GET',
304 'QUERY_STRING' => 'searchterm=stallman+software'
305 ]);
306 $request = Request::createFromEnvironment($env);
307 $response = $this->controller->getLinks($request, new Response());
308 $this->assertEquals(200, $response->getStatusCode());
309 $data = json_decode((string) $response->getBody(), true);
310 $this->assertEquals(2, count($data));
311 $this->assertEquals(41, $data[0]['id']);
312 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
313 $this->assertEquals(8, $data[1]['id']);
314 $this->assertEquals(self::NB_FIELDS_LINK, count($data[1]));
315
316 // URL encoding
317 $env = Environment::mock([
318 'REQUEST_METHOD' => 'GET',
319 'QUERY_STRING' => 'searchterm='. urlencode('@web')
320 ]);
321 $request = Request::createFromEnvironment($env);
322 $response = $this->controller->getLinks($request, new Response());
323 $this->assertEquals(200, $response->getStatusCode());
324 $data = json_decode((string) $response->getBody(), true);
325 $this->assertEquals(2, count($data));
326 $this->assertEquals(41, $data[0]['id']);
327 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
328 $this->assertEquals(8, $data[1]['id']);
329 $this->assertEquals(self::NB_FIELDS_LINK, count($data[1]));
330 }
331
332 public function testGetLinksSearchTermNoResult()
333 {
334 $env = Environment::mock([
335 'REQUEST_METHOD' => 'GET',
336 'QUERY_STRING' => 'searchterm=nope'
337 ]);
338 $request = Request::createFromEnvironment($env);
339 $response = $this->controller->getLinks($request, new Response());
340 $this->assertEquals(200, $response->getStatusCode());
341 $data = json_decode((string) $response->getBody(), true);
342 $this->assertEquals(0, count($data));
343 }
344
345 public function testGetLinksSearchTags()
346 {
347 // Single tag
348 $env = Environment::mock([
349 'REQUEST_METHOD' => 'GET',
350 'QUERY_STRING' => 'searchtags=dev',
351 ]);
352 $request = Request::createFromEnvironment($env);
353 $response = $this->controller->getLinks($request, new Response());
354 $this->assertEquals(200, $response->getStatusCode());
355 $data = json_decode((string) $response->getBody(), true);
356 $this->assertEquals(2, count($data));
357 $this->assertEquals(0, $data[0]['id']);
358 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
359 $this->assertEquals(4, $data[1]['id']);
360 $this->assertEquals(self::NB_FIELDS_LINK, count($data[1]));
361
362 // Multitag + exclude
363 $env = Environment::mock([
364 'REQUEST_METHOD' => 'GET',
365 'QUERY_STRING' => 'searchtags=stuff+-gnu',
366 ]);
367 $request = Request::createFromEnvironment($env);
368 $response = $this->controller->getLinks($request, new Response());
369 $this->assertEquals(200, $response->getStatusCode());
370 $data = json_decode((string) $response->getBody(), true);
371 $this->assertEquals(1, count($data));
372 $this->assertEquals(41, $data[0]['id']);
373 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
374 }
375
376 /**
377 * Test getLinks service with search tags+terms.
378 */
379 public function testGetLinksSearchTermsAndTags()
380 {
381 $env = Environment::mock([
382 'REQUEST_METHOD' => 'GET',
383 'QUERY_STRING' => 'searchterm=poke&searchtags=dev',
384 ]);
385 $request = Request::createFromEnvironment($env);
386 $response = $this->controller->getLinks($request, new Response());
387 $this->assertEquals(200, $response->getStatusCode());
388 $data = json_decode((string) $response->getBody(), true);
389 $this->assertEquals(1, count($data));
390 $this->assertEquals(0, $data[0]['id']);
391 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
392 }
393}