]> git.immae.eu Git - github/shaarli/Shaarli.git/blob - tests/api/controllers/GetLinksTest.php
Merge pull request #769 from ArthurHoaro/api/getlinks-visibility
[github/shaarli/Shaarli.git] / tests / api / controllers / GetLinksTest.php
1 <?php
2
3 namespace Shaarli\Api\Controllers;
4
5
6 use Slim\Container;
7 use Slim\Http\Environment;
8 use Slim\Http\Request;
9 use Slim\Http\Response;
10
11 /**
12 * Class GetLinksTest
13 *
14 * Test get Link list REST API service.
15 *
16 * @see http://shaarli.github.io/api-documentation/#links-links-collection-get
17 *
18 * @package Shaarli\Api\Controllers
19 */
20 class GetLinksTest 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 field per link.
49 */
50 const NB_FIELDS_LINK = 9;
51
52 /**
53 * Before every 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 every test, remove the test datastore.
70 */
71 public function tearDown()
72 {
73 @unlink(self::$testDatastore);
74 }
75
76 /**
77 * Test basic getLinks service: returns all links.
78 */
79 public function testGetLinks()
80 {
81 // Used by index_url().
82 $_SERVER['SERVER_NAME'] = 'domain.tld';
83 $_SERVER['SERVER_PORT'] = 80;
84 $_SERVER['SCRIPT_NAME'] = '/';
85
86 $env = Environment::mock([
87 'REQUEST_METHOD' => 'GET',
88 ]);
89 $request = Request::createFromEnvironment($env);
90
91 $response = $this->controller->getLinks($request, new Response());
92 $this->assertEquals(200, $response->getStatusCode());
93 $data = json_decode((string) $response->getBody(), true);
94 $this->assertEquals($this->refDB->countLinks(), count($data));
95
96 // Check order
97 $order = [41, 8, 6, 7, 0, 1, 4, 42];
98 $cpt = 0;
99 foreach ($data as $link) {
100 $this->assertEquals(self::NB_FIELDS_LINK, count($link));
101 $this->assertEquals($order[$cpt++], $link['id']);
102 }
103
104 // Check first element fields
105 $first = $data[0];
106 $this->assertEquals('http://domain.tld/?WDWyig', $first['url']);
107 $this->assertEquals('WDWyig', $first['shorturl']);
108 $this->assertEquals('Link title: @website', $first['title']);
109 $this->assertEquals(
110 'Stallman has a beard and is part of the Free Software Foundation (or not). Seriously, read this. #hashtag',
111 $first['description']
112 );
113 $this->assertEquals('sTuff', $first['tags'][0]);
114 $this->assertEquals(false, $first['private']);
115 $this->assertEquals(
116 \DateTime::createFromFormat(\LinkDB::LINK_DATE_FORMAT, '20150310_114651')->format(\DateTime::ATOM),
117 $first['created']
118 );
119 $this->assertEmpty($first['updated']);
120
121 // Multi tags
122 $link = $data[1];
123 $this->assertEquals(7, count($link['tags']));
124
125 // Update date
126 $this->assertEquals(
127 \DateTime::createFromFormat(\LinkDB::LINK_DATE_FORMAT, '20160803_093033')->format(\DateTime::ATOM),
128 $link['updated']
129 );
130 }
131
132 /**
133 * Test getLinks service with offset and limit parameter:
134 * limit=1 and offset=1 should return only the second link, ID=8 (ordered by creation date DESC).
135 */
136 public function testGetLinksOffsetLimit()
137 {
138 $env = Environment::mock([
139 'REQUEST_METHOD' => 'GET',
140 'QUERY_STRING' => 'offset=1&limit=1'
141 ]);
142 $request = Request::createFromEnvironment($env);
143 $response = $this->controller->getLinks($request, new Response());
144 $this->assertEquals(200, $response->getStatusCode());
145 $data = json_decode((string) $response->getBody(), true);
146 $this->assertEquals(1, count($data));
147 $this->assertEquals(8, $data[0]['id']);
148 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
149 }
150
151 /**
152 * Test getLinks with limit=all (return all link).
153 */
154 public function testGetLinksLimitAll()
155 {
156 $env = Environment::mock([
157 'REQUEST_METHOD' => 'GET',
158 'QUERY_STRING' => 'limit=all'
159 ]);
160 $request = Request::createFromEnvironment($env);
161 $response = $this->controller->getLinks($request, new Response());
162 $this->assertEquals(200, $response->getStatusCode());
163 $data = json_decode((string) $response->getBody(), true);
164 $this->assertEquals($this->refDB->countLinks(), count($data));
165 // Check order
166 $order = [41, 8, 6, 7, 0, 1, 4, 42];
167 $cpt = 0;
168 foreach ($data as $link) {
169 $this->assertEquals(self::NB_FIELDS_LINK, count($link));
170 $this->assertEquals($order[$cpt++], $link['id']);
171 }
172 }
173
174 /**
175 * Test getLinks service with offset and limit parameter:
176 * limit=1 and offset=1 should return only the second link, ID=8 (ordered by creation date DESC).
177 */
178 public function testGetLinksOffsetTooHigh()
179 {
180 $env = Environment::mock([
181 'REQUEST_METHOD' => 'GET',
182 'QUERY_STRING' => 'offset=100'
183 ]);
184 $request = Request::createFromEnvironment($env);
185 $response = $this->controller->getLinks($request, new Response());
186 $this->assertEquals(200, $response->getStatusCode());
187 $data = json_decode((string) $response->getBody(), true);
188 $this->assertEmpty(count($data));
189 }
190
191 /**
192 * Test getLinks with visibility parameter set to all
193 */
194 public function testGetLinksVisibilityAll()
195 {
196 $env = Environment::mock(
197 [
198 'REQUEST_METHOD' => 'GET',
199 'QUERY_STRING' => 'visibility=all'
200 ]
201 );
202 $request = Request::createFromEnvironment($env);
203 $response = $this->controller->getLinks($request, new Response());
204 $this->assertEquals(200, $response->getStatusCode());
205 $data = json_decode((string)$response->getBody(), true);
206 $this->assertEquals($this->refDB->countLinks(), count($data));
207 $this->assertEquals(41, $data[0]['id']);
208 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
209 }
210
211 /**
212 * Test getLinks with visibility parameter set to private
213 */
214 public function testGetLinksVisibilityPrivate()
215 {
216 $env = Environment::mock([
217 'REQUEST_METHOD' => 'GET',
218 'QUERY_STRING' => 'visibility=private'
219 ]);
220 $request = Request::createFromEnvironment($env);
221 $response = $this->controller->getLinks($request, new Response());
222 $this->assertEquals(200, $response->getStatusCode());
223 $data = json_decode((string) $response->getBody(), true);
224 $this->assertEquals($this->refDB->countPrivateLinks(), count($data));
225 $this->assertEquals(6, $data[0]['id']);
226 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
227 }
228
229 /**
230 * Test getLinks with visibility parameter set to public
231 */
232 public function testGetLinksVisibilityPublic()
233 {
234 $env = Environment::mock(
235 [
236 'REQUEST_METHOD' => 'GET',
237 'QUERY_STRING' => 'visibility=public'
238 ]
239 );
240 $request = Request::createFromEnvironment($env);
241 $response = $this->controller->getLinks($request, new Response());
242 $this->assertEquals(200, $response->getStatusCode());
243 $data = json_decode((string)$response->getBody(), true);
244 $this->assertEquals($this->refDB->countPublicLinks(), count($data));
245 $this->assertEquals(41, $data[0]['id']);
246 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
247 }
248
249 /**
250 * Test getLinks service with offset and limit parameter:
251 * limit=1 and offset=1 should return only the second link, ID=8 (ordered by creation date DESC).
252 */
253 public function testGetLinksSearchTerm()
254 {
255 // Only in description - 1 result
256 $env = Environment::mock([
257 'REQUEST_METHOD' => 'GET',
258 'QUERY_STRING' => 'searchterm=Tropical'
259 ]);
260 $request = Request::createFromEnvironment($env);
261 $response = $this->controller->getLinks($request, new Response());
262 $this->assertEquals(200, $response->getStatusCode());
263 $data = json_decode((string) $response->getBody(), true);
264 $this->assertEquals(1, count($data));
265 $this->assertEquals(1, $data[0]['id']);
266 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
267
268 // Only in tags - 1 result
269 $env = Environment::mock([
270 'REQUEST_METHOD' => 'GET',
271 'QUERY_STRING' => 'searchterm=tag3'
272 ]);
273 $request = Request::createFromEnvironment($env);
274 $response = $this->controller->getLinks($request, new Response());
275 $this->assertEquals(200, $response->getStatusCode());
276 $data = json_decode((string) $response->getBody(), true);
277 $this->assertEquals(1, count($data));
278 $this->assertEquals(0, $data[0]['id']);
279 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
280
281 // Multiple results (2)
282 $env = Environment::mock([
283 'REQUEST_METHOD' => 'GET',
284 'QUERY_STRING' => 'searchterm=stallman'
285 ]);
286 $request = Request::createFromEnvironment($env);
287 $response = $this->controller->getLinks($request, new Response());
288 $this->assertEquals(200, $response->getStatusCode());
289 $data = json_decode((string) $response->getBody(), true);
290 $this->assertEquals(2, count($data));
291 $this->assertEquals(41, $data[0]['id']);
292 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
293 $this->assertEquals(8, $data[1]['id']);
294 $this->assertEquals(self::NB_FIELDS_LINK, count($data[1]));
295
296 // Multiword - 2 results
297 $env = Environment::mock([
298 'REQUEST_METHOD' => 'GET',
299 'QUERY_STRING' => 'searchterm=stallman+software'
300 ]);
301 $request = Request::createFromEnvironment($env);
302 $response = $this->controller->getLinks($request, new Response());
303 $this->assertEquals(200, $response->getStatusCode());
304 $data = json_decode((string) $response->getBody(), true);
305 $this->assertEquals(2, count($data));
306 $this->assertEquals(41, $data[0]['id']);
307 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
308 $this->assertEquals(8, $data[1]['id']);
309 $this->assertEquals(self::NB_FIELDS_LINK, count($data[1]));
310
311 // URL encoding
312 $env = Environment::mock([
313 'REQUEST_METHOD' => 'GET',
314 'QUERY_STRING' => 'searchterm='. urlencode('@web')
315 ]);
316 $request = Request::createFromEnvironment($env);
317 $response = $this->controller->getLinks($request, new Response());
318 $this->assertEquals(200, $response->getStatusCode());
319 $data = json_decode((string) $response->getBody(), true);
320 $this->assertEquals(2, count($data));
321 $this->assertEquals(41, $data[0]['id']);
322 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
323 $this->assertEquals(8, $data[1]['id']);
324 $this->assertEquals(self::NB_FIELDS_LINK, count($data[1]));
325 }
326
327 public function testGetLinksSearchTermNoResult()
328 {
329 $env = Environment::mock([
330 'REQUEST_METHOD' => 'GET',
331 'QUERY_STRING' => 'searchterm=nope'
332 ]);
333 $request = Request::createFromEnvironment($env);
334 $response = $this->controller->getLinks($request, new Response());
335 $this->assertEquals(200, $response->getStatusCode());
336 $data = json_decode((string) $response->getBody(), true);
337 $this->assertEquals(0, count($data));
338 }
339
340 public function testGetLinksSearchTags()
341 {
342 // Single tag
343 $env = Environment::mock([
344 'REQUEST_METHOD' => 'GET',
345 'QUERY_STRING' => 'searchtags=dev',
346 ]);
347 $request = Request::createFromEnvironment($env);
348 $response = $this->controller->getLinks($request, new Response());
349 $this->assertEquals(200, $response->getStatusCode());
350 $data = json_decode((string) $response->getBody(), true);
351 $this->assertEquals(2, count($data));
352 $this->assertEquals(0, $data[0]['id']);
353 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
354 $this->assertEquals(4, $data[1]['id']);
355 $this->assertEquals(self::NB_FIELDS_LINK, count($data[1]));
356
357 // Multitag + exclude
358 $env = Environment::mock([
359 'REQUEST_METHOD' => 'GET',
360 'QUERY_STRING' => 'searchtags=stuff+-gnu',
361 ]);
362 $request = Request::createFromEnvironment($env);
363 $response = $this->controller->getLinks($request, new Response());
364 $this->assertEquals(200, $response->getStatusCode());
365 $data = json_decode((string) $response->getBody(), true);
366 $this->assertEquals(1, count($data));
367 $this->assertEquals(41, $data[0]['id']);
368 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
369 }
370
371 /**
372 * Test getLinks service with search tags+terms.
373 */
374 public function testGetLinksSearchTermsAndTags()
375 {
376 $env = Environment::mock([
377 'REQUEST_METHOD' => 'GET',
378 'QUERY_STRING' => 'searchterm=poke&searchtags=dev',
379 ]);
380 $request = Request::createFromEnvironment($env);
381 $response = $this->controller->getLinks($request, new Response());
382 $this->assertEquals(200, $response->getStatusCode());
383 $data = json_decode((string) $response->getBody(), true);
384 $this->assertEquals(1, count($data));
385 $this->assertEquals(0, $data[0]['id']);
386 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
387 }
388 }