]> git.immae.eu Git - github/shaarli/Shaarli.git/blob - tests/api/controllers/LinksTest.php
Merge pull request #769 from ArthurHoaro/api/getlinks-visibility
[github/shaarli/Shaarli.git] / tests / api / controllers / LinksTest.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 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 */
19 class 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 visibility parameter set to all
192 */
193 public function testGetLinksVisibilityAll()
194 {
195 $env = Environment::mock(
196 [
197 'REQUEST_METHOD' => 'GET',
198 'QUERY_STRING' => 'visibility=all'
199 ]
200 );
201 $request = Request::createFromEnvironment($env);
202 $response = $this->controller->getLinks($request, new Response());
203 $this->assertEquals(200, $response->getStatusCode());
204 $data = json_decode((string)$response->getBody(), true);
205 $this->assertEquals($this->refDB->countLinks(), count($data));
206 $this->assertEquals(41, $data[0]['id']);
207 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
208 }
209
210 /**
211 * Test getLinks with visibility parameter set to private
212 */
213 public function testGetLinksVisibilityPrivate()
214 {
215 $env = Environment::mock([
216 'REQUEST_METHOD' => 'GET',
217 'QUERY_STRING' => 'visibility=private'
218 ]);
219 $request = Request::createFromEnvironment($env);
220 $response = $this->controller->getLinks($request, new Response());
221 $this->assertEquals(200, $response->getStatusCode());
222 $data = json_decode((string) $response->getBody(), true);
223 $this->assertEquals($this->refDB->countPrivateLinks(), count($data));
224 $this->assertEquals(6, $data[0]['id']);
225 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
226 }
227
228 /**
229 * Test getLinks with visibility parameter set to public
230 */
231 public function testGetLinksVisibilityPublic()
232 {
233 $env = Environment::mock(
234 [
235 'REQUEST_METHOD' => 'GET',
236 'QUERY_STRING' => 'visibility=public'
237 ]
238 );
239 $request = Request::createFromEnvironment($env);
240 $response = $this->controller->getLinks($request, new Response());
241 $this->assertEquals(200, $response->getStatusCode());
242 $data = json_decode((string)$response->getBody(), true);
243 $this->assertEquals($this->refDB->countPublicLinks(), count($data));
244 $this->assertEquals(41, $data[0]['id']);
245 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
246 }
247
248 /**
249 * Test getLinks service with offset and limit parameter:
250 * limit=1 and offset=1 should return only the second link, ID=8 (ordered by creation date DESC).
251 */
252 public function testGetLinksSearchTerm()
253 {
254 // Only in description - 1 result
255 $env = Environment::mock([
256 'REQUEST_METHOD' => 'GET',
257 'QUERY_STRING' => 'searchterm=Tropical'
258 ]);
259 $request = Request::createFromEnvironment($env);
260 $response = $this->controller->getLinks($request, new Response());
261 $this->assertEquals(200, $response->getStatusCode());
262 $data = json_decode((string) $response->getBody(), true);
263 $this->assertEquals(1, count($data));
264 $this->assertEquals(1, $data[0]['id']);
265 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
266
267 // Only in tags - 1 result
268 $env = Environment::mock([
269 'REQUEST_METHOD' => 'GET',
270 'QUERY_STRING' => 'searchterm=tag3'
271 ]);
272 $request = Request::createFromEnvironment($env);
273 $response = $this->controller->getLinks($request, new Response());
274 $this->assertEquals(200, $response->getStatusCode());
275 $data = json_decode((string) $response->getBody(), true);
276 $this->assertEquals(1, count($data));
277 $this->assertEquals(0, $data[0]['id']);
278 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
279
280 // Multiple results (2)
281 $env = Environment::mock([
282 'REQUEST_METHOD' => 'GET',
283 'QUERY_STRING' => 'searchterm=stallman'
284 ]);
285 $request = Request::createFromEnvironment($env);
286 $response = $this->controller->getLinks($request, new Response());
287 $this->assertEquals(200, $response->getStatusCode());
288 $data = json_decode((string) $response->getBody(), true);
289 $this->assertEquals(2, count($data));
290 $this->assertEquals(41, $data[0]['id']);
291 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
292 $this->assertEquals(8, $data[1]['id']);
293 $this->assertEquals(self::NB_FIELDS_LINK, count($data[1]));
294
295 // Multiword - 2 results
296 $env = Environment::mock([
297 'REQUEST_METHOD' => 'GET',
298 'QUERY_STRING' => 'searchterm=stallman+software'
299 ]);
300 $request = Request::createFromEnvironment($env);
301 $response = $this->controller->getLinks($request, new Response());
302 $this->assertEquals(200, $response->getStatusCode());
303 $data = json_decode((string) $response->getBody(), true);
304 $this->assertEquals(2, count($data));
305 $this->assertEquals(41, $data[0]['id']);
306 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
307 $this->assertEquals(8, $data[1]['id']);
308 $this->assertEquals(self::NB_FIELDS_LINK, count($data[1]));
309
310 // URL encoding
311 $env = Environment::mock([
312 'REQUEST_METHOD' => 'GET',
313 'QUERY_STRING' => 'searchterm='. urlencode('@web')
314 ]);
315 $request = Request::createFromEnvironment($env);
316 $response = $this->controller->getLinks($request, new Response());
317 $this->assertEquals(200, $response->getStatusCode());
318 $data = json_decode((string) $response->getBody(), true);
319 $this->assertEquals(2, count($data));
320 $this->assertEquals(41, $data[0]['id']);
321 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
322 $this->assertEquals(8, $data[1]['id']);
323 $this->assertEquals(self::NB_FIELDS_LINK, count($data[1]));
324 }
325
326 public function testGetLinksSearchTermNoResult()
327 {
328 $env = Environment::mock([
329 'REQUEST_METHOD' => 'GET',
330 'QUERY_STRING' => 'searchterm=nope'
331 ]);
332 $request = Request::createFromEnvironment($env);
333 $response = $this->controller->getLinks($request, new Response());
334 $this->assertEquals(200, $response->getStatusCode());
335 $data = json_decode((string) $response->getBody(), true);
336 $this->assertEquals(0, count($data));
337 }
338
339 public function testGetLinksSearchTags()
340 {
341 // Single tag
342 $env = Environment::mock([
343 'REQUEST_METHOD' => 'GET',
344 'QUERY_STRING' => 'searchtags=dev',
345 ]);
346 $request = Request::createFromEnvironment($env);
347 $response = $this->controller->getLinks($request, new Response());
348 $this->assertEquals(200, $response->getStatusCode());
349 $data = json_decode((string) $response->getBody(), true);
350 $this->assertEquals(2, count($data));
351 $this->assertEquals(0, $data[0]['id']);
352 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
353 $this->assertEquals(4, $data[1]['id']);
354 $this->assertEquals(self::NB_FIELDS_LINK, count($data[1]));
355
356 // Multitag + exclude
357 $env = Environment::mock([
358 'REQUEST_METHOD' => 'GET',
359 'QUERY_STRING' => 'searchtags=stuff+-gnu',
360 ]);
361 $request = Request::createFromEnvironment($env);
362 $response = $this->controller->getLinks($request, new Response());
363 $this->assertEquals(200, $response->getStatusCode());
364 $data = json_decode((string) $response->getBody(), true);
365 $this->assertEquals(1, count($data));
366 $this->assertEquals(41, $data[0]['id']);
367 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
368 }
369
370 /**
371 * Test getLinks service with search tags+terms.
372 */
373 public function testGetLinksSearchTermsAndTags()
374 {
375 $env = Environment::mock([
376 'REQUEST_METHOD' => 'GET',
377 'QUERY_STRING' => 'searchterm=poke&searchtags=dev',
378 ]);
379 $request = Request::createFromEnvironment($env);
380 $response = $this->controller->getLinks($request, new Response());
381 $this->assertEquals(200, $response->getStatusCode());
382 $data = json_decode((string) $response->getBody(), true);
383 $this->assertEquals(1, count($data));
384 $this->assertEquals(0, $data[0]['id']);
385 $this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
386 }
387 }