289b3fcea54f278db4f5b099817d7dd7109b0f0f
[friendica.git/.git] / tests / include / ApiTest.php
1 <?php
2 /**
3  * ApiTest class.
4  */
5
6 namespace Friendica\Test;
7
8 use Friendica\App;
9 use Friendica\Core\Config;
10 use Friendica\Core\Config\Cache;
11 use Friendica\Core\PConfig;
12 use Friendica\Core\Protocol;
13 use Friendica\Core\System;
14 use Friendica\Factory;
15 use Friendica\Network\HTTPException;
16 use Friendica\Util\BasePath;
17 use Monolog\Handler\TestHandler;
18
19 require_once __DIR__ . '/../../include/api.php';
20
21 /**
22  * Tests for the API functions.
23  *
24  * Functions that use header() need to be tested in a separate process.
25  * @see https://phpunit.de/manual/5.7/en/appendixes.annotations.html#appendixes.annotations.runTestsInSeparateProcesses
26  */
27 class ApiTest extends DatabaseTest
28 {
29         /**
30          * @var TestHandler Can handle log-outputs
31          */
32         protected $logOutput;
33
34         /**
35          * Create variables used by tests.
36          */
37         public function setUp()
38         {
39                 $basedir = BasePath::create(dirname(__DIR__) . '/../');
40                 $configLoader = new Cache\ConfigCacheLoader($basedir);
41                 $configCache = Factory\ConfigFactory::createCache($configLoader);
42                 $profiler = Factory\ProfilerFactory::create($configCache);
43                 Factory\DBFactory::init($configCache, $profiler, $_SERVER);
44                 $config = Factory\ConfigFactory::createConfig($configCache);
45                 Factory\ConfigFactory::createPConfig($configCache);
46                 $logger = Factory\LoggerFactory::create('test', $config);
47                 $this->app = new App($config, $logger, $profiler, false);
48
49                 parent::setUp();
50
51                 // User data that the test database is populated with
52                 $this->selfUser = [
53                         'id' => 42,
54                         'name' => 'Self contact',
55                         'nick' => 'selfcontact',
56                         'nurl' => 'http://localhost/profile/selfcontact'
57                 ];
58                 $this->friendUser = [
59                         'id' => 44,
60                         'name' => 'Friend contact',
61                         'nick' => 'friendcontact',
62                         'nurl' => 'http://localhost/profile/friendcontact'
63                 ];
64                 $this->otherUser = [
65                         'id' => 43,
66                         'name' => 'othercontact',
67                         'nick' => 'othercontact',
68                         'nurl' => 'http://localhost/profile/othercontact'
69                 ];
70
71                 // User ID that we know is not in the database
72                 $this->wrongUserId = 666;
73
74                 // Most API require login so we force the session
75                 $_SESSION = [
76                         'allow_api' => true,
77                         'authenticated' => true,
78                         'uid' => $this->selfUser['id']
79                 ];
80
81                 Config::set('system', 'url', 'http://localhost');
82                 Config::set('system', 'hostname', 'localhost');
83                 Config::set('system', 'worker_dont_fork', true);
84
85                 // Default config
86                 Config::set('config', 'hostname', 'localhost');
87                 Config::set('system', 'throttle_limit_day', 100);
88                 Config::set('system', 'throttle_limit_week', 100);
89                 Config::set('system', 'throttle_limit_month', 100);
90                 Config::set('system', 'theme', 'system_theme');
91         }
92
93         /**
94          * Cleanup variables used by tests.
95          */
96         protected function tearDown()
97         {
98                 parent::tearDown();
99
100                 $this->app->argc = 1;
101                 $this->app->argv = ['home'];
102         }
103
104         /**
105          * Assert that an user array contains expected keys.
106          * @param array $user User array
107          * @return void
108          */
109         private function assertSelfUser(array $user)
110         {
111                 $this->assertEquals($this->selfUser['id'], $user['uid']);
112                 $this->assertEquals($this->selfUser['id'], $user['cid']);
113                 $this->assertEquals(1, $user['self']);
114                 $this->assertEquals('DFRN', $user['location']);
115                 $this->assertEquals($this->selfUser['name'], $user['name']);
116                 $this->assertEquals($this->selfUser['nick'], $user['screen_name']);
117                 $this->assertEquals('dfrn', $user['network']);
118                 $this->assertTrue($user['verified']);
119         }
120
121         /**
122          * Assert that an user array contains expected keys.
123          * @param array $user User array
124          * @return void
125          */
126         private function assertOtherUser(array $user)
127         {
128                 $this->assertEquals($this->otherUser['id'], $user['id']);
129                 $this->assertEquals($this->otherUser['id'], $user['id_str']);
130                 $this->assertEquals(0, $user['self']);
131                 $this->assertEquals($this->otherUser['name'], $user['name']);
132                 $this->assertEquals($this->otherUser['nick'], $user['screen_name']);
133                 $this->assertFalse($user['verified']);
134         }
135
136         /**
137          * Assert that a status array contains expected keys.
138          * @param array $status Status array
139          * @return void
140          */
141         private function assertStatus(array $status)
142         {
143                 $this->assertInternalType('string', $status['text']);
144                 $this->assertInternalType('int', $status['id']);
145                 // We could probably do more checks here.
146         }
147
148         /**
149          * Assert that a list array contains expected keys.
150          * @param array $list List array
151          * @return void
152          */
153         private function assertList(array $list)
154         {
155                 $this->assertInternalType('string', $list['name']);
156                 $this->assertInternalType('int', $list['id']);
157                 $this->assertInternalType('string', $list['id_str']);
158                 $this->assertContains($list['mode'], ['public', 'private']);
159                 // We could probably do more checks here.
160         }
161
162         /**
163          * Assert that the string is XML and contain the root element.
164          * @param string $result       XML string
165          * @param string $root_element Root element name
166          * @return void
167          */
168         private function assertXml($result, $root_element)
169         {
170                 $this->assertStringStartsWith('<?xml version="1.0"?>', $result);
171                 $this->assertContains('<'.$root_element, $result);
172                 // We could probably do more checks here.
173         }
174
175         /**
176          * Get the path to a temporary empty PNG image.
177          * @return string Path
178          */
179         private function getTempImage()
180         {
181                 $tmpFile = tempnam(sys_get_temp_dir(), 'tmp_file');
182                 file_put_contents(
183                         $tmpFile,
184                         base64_decode(
185                                 // Empty 1x1 px PNG image
186                                 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg=='
187                         )
188                 );
189
190                 return $tmpFile;
191         }
192
193         /**
194          * Test the api_user() function.
195          * @return void
196          */
197         public function testApiUser()
198         {
199                 $this->assertEquals($this->selfUser['id'], api_user());
200         }
201
202         /**
203          * Test the api_user() function with an unallowed user.
204          * @return void
205          */
206         public function testApiUserWithUnallowedUser()
207         {
208                 $_SESSION = ['allow_api' => false];
209                 $this->assertEquals(false, api_user());
210         }
211
212         /**
213          * Test the api_source() function.
214          * @return void
215          */
216         public function testApiSource()
217         {
218                 $this->assertEquals('api', api_source());
219         }
220
221         /**
222          * Test the api_source() function with a Twidere user agent.
223          * @return void
224          */
225         public function testApiSourceWithTwidere()
226         {
227                 $_SERVER['HTTP_USER_AGENT'] = 'Twidere';
228                 $this->assertEquals('Twidere', api_source());
229         }
230
231         /**
232          * Test the api_source() function with a GET parameter.
233          * @return void
234          */
235         public function testApiSourceWithGet()
236         {
237                 $_GET['source'] = 'source_name';
238                 $this->assertEquals('source_name', api_source());
239         }
240
241         /**
242          * Test the api_date() function.
243          * @return void
244          */
245         public function testApiDate()
246         {
247                 $this->assertEquals('Wed Oct 10 00:00:00 +0000 1990', api_date('1990-10-10'));
248         }
249
250         /**
251          * Test the api_register_func() function.
252          * @return void
253          */
254         public function testApiRegisterFunc()
255         {
256                 global $API;
257                 $this->assertNull(
258                         api_register_func(
259                                 'api_path',
260                                 function () {
261                                 },
262                                 true,
263                                 'method'
264                         )
265                 );
266                 $this->assertTrue($API['api_path']['auth']);
267                 $this->assertEquals('method', $API['api_path']['method']);
268                 $this->assertTrue(is_callable($API['api_path']['func']));
269         }
270
271         /**
272          * Test the api_login() function without any login.
273          * @return void
274          * @runInSeparateProcess
275          * @expectedException Friendica\Network\HTTPException\UnauthorizedException
276          */
277         public function testApiLoginWithoutLogin()
278         {
279                 api_login($this->app);
280         }
281
282         /**
283          * Test the api_login() function with a bad login.
284          * @return void
285          * @runInSeparateProcess
286          * @expectedException Friendica\Network\HTTPException\UnauthorizedException
287          */
288         public function testApiLoginWithBadLogin()
289         {
290                 $_SERVER['PHP_AUTH_USER'] = 'user@server';
291                 api_login($this->app);
292         }
293
294         /**
295          * Test the api_login() function with oAuth.
296          * @return void
297          */
298         public function testApiLoginWithOauth()
299         {
300                 $this->markTestIncomplete('Can we test this easily?');
301         }
302
303         /**
304          * Test the api_login() function with authentication provided by an addon.
305          * @return void
306          */
307         public function testApiLoginWithAddonAuth()
308         {
309                 $this->markTestIncomplete('Can we test this easily?');
310         }
311
312         /**
313          * Test the api_login() function with a correct login.
314          * @return void
315          * @runInSeparateProcess
316          */
317         public function testApiLoginWithCorrectLogin()
318         {
319                 $_SERVER['PHP_AUTH_USER'] = 'Test user';
320                 $_SERVER['PHP_AUTH_PW'] = 'password';
321                 api_login($this->app);
322         }
323
324         /**
325          * Test the api_login() function with a remote user.
326          * @return void
327          * @runInSeparateProcess
328          * @expectedException Friendica\Network\HTTPException\UnauthorizedException
329          */
330         public function testApiLoginWithRemoteUser()
331         {
332                 $_SERVER['REDIRECT_REMOTE_USER'] = '123456dXNlcjpwYXNzd29yZA==';
333                 api_login($this->app);
334         }
335
336         /**
337          * Test the api_check_method() function.
338          * @return void
339          */
340         public function testApiCheckMethod()
341         {
342                 $this->assertFalse(api_check_method('method'));
343         }
344
345         /**
346          * Test the api_check_method() function with a correct method.
347          * @return void
348          */
349         public function testApiCheckMethodWithCorrectMethod()
350         {
351                 $_SERVER['REQUEST_METHOD'] = 'method';
352                 $this->assertTrue(api_check_method('method'));
353         }
354
355         /**
356          * Test the api_check_method() function with a wildcard.
357          * @return void
358          */
359         public function testApiCheckMethodWithWildcard()
360         {
361                 $this->assertTrue(api_check_method('*'));
362         }
363
364         /**
365          * Test the api_call() function.
366          * @return void
367          * @runInSeparateProcess
368          */
369         public function testApiCall()
370         {
371                 global $API;
372                 $API['api_path'] = [
373                         'method' => 'method',
374                         'func' => function () {
375                                 return ['data' => ['some_data']];
376                         }
377                 ];
378                 $_SERVER['REQUEST_METHOD'] = 'method';
379                 $_GET['callback'] = 'callback_name';
380
381                 $this->app->query_string = 'api_path';
382                 $this->assertEquals(
383                         'callback_name(["some_data"])',
384                         api_call($this->app)
385                 );
386         }
387
388         /**
389          * Test the api_call() function with the profiled enabled.
390          * @return void
391          * @runInSeparateProcess
392          */
393         public function testApiCallWithProfiler()
394         {
395                 global $API;
396                 $API['api_path'] = [
397                         'method' => 'method',
398                         'func' => function () {
399                                 return ['data' => ['some_data']];
400                         }
401                 ];
402                 $_SERVER['REQUEST_METHOD'] = 'method';
403                 Config::set('system', 'profiler', true);
404                 Config::set('rendertime', 'callstack', true);
405                 $this->app->callstack = [
406                         'database' => ['some_function' => 200],
407                         'database_write' => ['some_function' => 200],
408                         'cache' => ['some_function' => 200],
409                         'cache_write' => ['some_function' => 200],
410                         'network' => ['some_function' => 200]
411                 ];
412
413                 $this->app->query_string = 'api_path';
414                 $this->assertEquals(
415                         '["some_data"]',
416                         api_call($this->app)
417                 );
418         }
419
420         /**
421          * Test the api_call() function without any result.
422          * @return void
423          * @runInSeparateProcess
424          */
425         public function testApiCallWithNoResult()
426         {
427                 global $API;
428                 $API['api_path'] = [
429                         'method' => 'method',
430                         'func' => function () {
431                                 return false;
432                         }
433                 ];
434                 $_SERVER['REQUEST_METHOD'] = 'method';
435
436                 $this->app->query_string = 'api_path';
437                 $this->assertEquals(
438                         '{"status":{"error":"Internal Server Error","code":"500 Internal Server Error","request":"api_path"}}',
439                         api_call($this->app)
440                 );
441         }
442
443         /**
444          * Test the api_call() function with an unimplemented API.
445          * @return void
446          * @runInSeparateProcess
447          */
448         public function testApiCallWithUninplementedApi()
449         {
450                 $this->assertEquals(
451                         '{"status":{"error":"Not Implemented","code":"501 Not Implemented","request":""}}',
452                         api_call($this->app)
453                 );
454         }
455
456         /**
457          * Test the api_call() function with a JSON result.
458          * @return void
459          * @runInSeparateProcess
460          */
461         public function testApiCallWithJson()
462         {
463                 global $API;
464                 $API['api_path'] = [
465                         'method' => 'method',
466                         'func' => function () {
467                                 return ['data' => ['some_data']];
468                         }
469                 ];
470                 $_SERVER['REQUEST_METHOD'] = 'method';
471
472                 $this->app->query_string = 'api_path.json';
473                 $this->assertEquals(
474                         '["some_data"]',
475                         api_call($this->app)
476                 );
477         }
478
479         /**
480          * Test the api_call() function with an XML result.
481          * @return void
482          * @runInSeparateProcess
483          */
484         public function testApiCallWithXml()
485         {
486                 global $API;
487                 $API['api_path'] = [
488                         'method' => 'method',
489                         'func' => function () {
490                                 return 'some_data';
491                         }
492                 ];
493                 $_SERVER['REQUEST_METHOD'] = 'method';
494
495                 $this->app->query_string = 'api_path.xml';
496                 $this->assertEquals(
497                         'some_data',
498                         api_call($this->app)
499                 );
500         }
501
502         /**
503          * Test the api_call() function with an RSS result.
504          * @return void
505          * @runInSeparateProcess
506          */
507         public function testApiCallWithRss()
508         {
509                 global $API;
510                 $API['api_path'] = [
511                         'method' => 'method',
512                         'func' => function () {
513                                 return 'some_data';
514                         }
515                 ];
516                 $_SERVER['REQUEST_METHOD'] = 'method';
517
518                 $this->app->query_string = 'api_path.rss';
519                 $this->assertEquals(
520                         '<?xml version="1.0" encoding="UTF-8"?>'."\n".
521                                 'some_data',
522                         api_call($this->app)
523                 );
524         }
525
526         /**
527          * Test the api_call() function with an Atom result.
528          * @return void
529          * @runInSeparateProcess
530          */
531         public function testApiCallWithAtom()
532         {
533                 global $API;
534                 $API['api_path'] = [
535                         'method' => 'method',
536                         'func' => function () {
537                                 return 'some_data';
538                         }
539                 ];
540                 $_SERVER['REQUEST_METHOD'] = 'method';
541
542                 $this->app->query_string = 'api_path.atom';
543                 $this->assertEquals(
544                         '<?xml version="1.0" encoding="UTF-8"?>'."\n".
545                                 'some_data',
546                         api_call($this->app)
547                 );
548         }
549
550         /**
551          * Test the api_call() function with an unallowed method.
552          * @return void
553          * @runInSeparateProcess
554          */
555         public function testApiCallWithWrongMethod()
556         {
557                 global $API;
558                 $API['api_path'] = ['method' => 'method'];
559
560                 $this->app->query_string = 'api_path';
561                 $this->assertEquals(
562                         '{"status":{"error":"Method Not Allowed","code":"405 Method Not Allowed","request":"api_path"}}',
563                         api_call($this->app)
564                 );
565         }
566
567         /**
568          * Test the api_call() function with an unauthorized user.
569          * @return void
570          * @runInSeparateProcess
571          */
572         public function testApiCallWithWrongAuth()
573         {
574                 global $API;
575                 $API['api_path'] = [
576                         'method' => 'method',
577                         'auth' => true
578                 ];
579                 $_SERVER['REQUEST_METHOD'] = 'method';
580                 $_SESSION['authenticated'] = false;
581
582                 $this->app->query_string = 'api_path';
583                 $this->assertEquals(
584                         '{"status":{"error":"This API requires login","code":"401 Unauthorized","request":"api_path"}}',
585                         api_call($this->app)
586                 );
587         }
588
589         /**
590          * Test the api_error() function with a JSON result.
591          * @return void
592          * @runInSeparateProcess
593          */
594         public function testApiErrorWithJson()
595         {
596                 $this->assertEquals(
597                         '{"status":{"error":"error_message","code":"200 Friendica\\\\Network\\\\HTTP","request":""}}',
598                         api_error('json', new HTTPException('error_message'))
599                 );
600         }
601
602         /**
603          * Test the api_error() function with an XML result.
604          * @return void
605          * @runInSeparateProcess
606          */
607         public function testApiErrorWithXml()
608         {
609                 $this->assertEquals(
610                         '<?xml version="1.0"?>'."\n".
611                         '<status xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" '.
612                                 'xmlns:friendica="http://friendi.ca/schema/api/1/" '.
613                                 'xmlns:georss="http://www.georss.org/georss">'."\n".
614                         '  <error>error_message</error>'."\n".
615                         '  <code>200 Friendica\Network\HTTP</code>'."\n".
616                         '  <request/>'."\n".
617                         '</status>'."\n",
618                         api_error('xml', new HTTPException('error_message'))
619                 );
620         }
621
622         /**
623          * Test the api_error() function with an RSS result.
624          * @return void
625          * @runInSeparateProcess
626          */
627         public function testApiErrorWithRss()
628         {
629                 $this->assertEquals(
630                         '<?xml version="1.0"?>'."\n".
631                         '<status xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" '.
632                                 'xmlns:friendica="http://friendi.ca/schema/api/1/" '.
633                                 'xmlns:georss="http://www.georss.org/georss">'."\n".
634                         '  <error>error_message</error>'."\n".
635                         '  <code>200 Friendica\Network\HTTP</code>'."\n".
636                         '  <request/>'."\n".
637                         '</status>'."\n",
638                         api_error('rss', new HTTPException('error_message'))
639                 );
640         }
641
642         /**
643          * Test the api_error() function with an Atom result.
644          * @return void
645          * @runInSeparateProcess
646          */
647         public function testApiErrorWithAtom()
648         {
649                 $this->assertEquals(
650                         '<?xml version="1.0"?>'."\n".
651                         '<status xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" '.
652                                 'xmlns:friendica="http://friendi.ca/schema/api/1/" '.
653                                 'xmlns:georss="http://www.georss.org/georss">'."\n".
654                         '  <error>error_message</error>'."\n".
655                         '  <code>200 Friendica\Network\HTTP</code>'."\n".
656                         '  <request/>'."\n".
657                         '</status>'."\n",
658                         api_error('atom', new HTTPException('error_message'))
659                 );
660         }
661
662         /**
663          * Test the api_rss_extra() function.
664          * @return void
665          */
666         public function testApiRssExtra()
667         {
668                 $user_info = ['url' => 'user_url', 'lang' => 'en'];
669                 $result = api_rss_extra($this->app, [], $user_info);
670                 $this->assertEquals($user_info, $result['$user']);
671                 $this->assertEquals($user_info['url'], $result['$rss']['alternate']);
672                 $this->assertArrayHasKey('self', $result['$rss']);
673                 $this->assertArrayHasKey('base', $result['$rss']);
674                 $this->assertArrayHasKey('updated', $result['$rss']);
675                 $this->assertArrayHasKey('atom_updated', $result['$rss']);
676                 $this->assertArrayHasKey('language', $result['$rss']);
677                 $this->assertArrayHasKey('logo', $result['$rss']);
678         }
679
680         /**
681          * Test the api_rss_extra() function without any user info.
682          * @return void
683          * @runInSeparateProcess
684          */
685         public function testApiRssExtraWithoutUserInfo()
686         {
687                 $result = api_rss_extra($this->app, [], null);
688                 $this->assertInternalType('array', $result['$user']);
689                 $this->assertArrayHasKey('alternate', $result['$rss']);
690                 $this->assertArrayHasKey('self', $result['$rss']);
691                 $this->assertArrayHasKey('base', $result['$rss']);
692                 $this->assertArrayHasKey('updated', $result['$rss']);
693                 $this->assertArrayHasKey('atom_updated', $result['$rss']);
694                 $this->assertArrayHasKey('language', $result['$rss']);
695                 $this->assertArrayHasKey('logo', $result['$rss']);
696         }
697
698         /**
699          * Test the api_unique_id_to_nurl() function.
700          * @return void
701          */
702         public function testApiUniqueIdToNurl()
703         {
704                 $this->assertFalse(api_unique_id_to_nurl($this->wrongUserId));
705         }
706
707         /**
708          * Test the api_unique_id_to_nurl() function with a correct ID.
709          * @return void
710          */
711         public function testApiUniqueIdToNurlWithCorrectId()
712         {
713                 $this->assertEquals($this->otherUser['nurl'], api_unique_id_to_nurl($this->otherUser['id']));
714         }
715
716         /**
717          * Test the api_get_user() function.
718          * @return void
719          * @runInSeparateProcess
720          */
721         public function testApiGetUser()
722         {
723                 $user = api_get_user($this->app);
724                 $this->assertSelfUser($user);
725                 $this->assertEquals('708fa0', $user['profile_sidebar_fill_color']);
726                 $this->assertEquals('6fdbe8', $user['profile_link_color']);
727                 $this->assertEquals('ededed', $user['profile_background_color']);
728         }
729
730         /**
731          * Test the api_get_user() function with a Frio schema.
732          * @return void
733          * @runInSeparateProcess
734          */
735         public function testApiGetUserWithFrioSchema()
736         {
737                 PConfig::set($this->selfUser['id'], 'frio', 'schema', 'red');
738                 $user = api_get_user($this->app);
739                 $this->assertSelfUser($user);
740                 $this->assertEquals('708fa0', $user['profile_sidebar_fill_color']);
741                 $this->assertEquals('6fdbe8', $user['profile_link_color']);
742                 $this->assertEquals('ededed', $user['profile_background_color']);
743         }
744
745         /**
746          * Test the api_get_user() function with a custom Frio schema.
747          * @return void
748          * @runInSeparateProcess
749          */
750         public function testApiGetUserWithCustomFrioSchema()
751         {
752                 $ret1 = PConfig::set($this->selfUser['id'], 'frio', 'schema', '---');
753                 $ret2 = PConfig::set($this->selfUser['id'], 'frio', 'nav_bg', '#123456');
754                 $ret3 = PConfig::set($this->selfUser['id'], 'frio', 'link_color', '#123456');
755                 $ret4 = PConfig::set($this->selfUser['id'], 'frio', 'background_color', '#123456');
756                 $user = api_get_user($this->app);
757                 $this->assertSelfUser($user);
758                 $this->assertEquals('123456', $user['profile_sidebar_fill_color']);
759                 $this->assertEquals('123456', $user['profile_link_color']);
760                 $this->assertEquals('123456', $user['profile_background_color']);
761         }
762
763         /**
764          * Test the api_get_user() function with an empty Frio schema.
765          * @return void
766          * @runInSeparateProcess
767          */
768         public function testApiGetUserWithEmptyFrioSchema()
769         {
770                 PConfig::set($this->selfUser['id'], 'frio', 'schema', '---');
771                 $user = api_get_user($this->app);
772                 $this->assertSelfUser($user);
773                 $this->assertEquals('708fa0', $user['profile_sidebar_fill_color']);
774                 $this->assertEquals('6fdbe8', $user['profile_link_color']);
775                 $this->assertEquals('ededed', $user['profile_background_color']);
776         }
777
778         /**
779          * Test the api_get_user() function with an user that is not allowed to use the API.
780          * @return void
781          * @runInSeparateProcess
782          */
783         public function testApiGetUserWithoutApiUser()
784         {
785                 $_SERVER['PHP_AUTH_USER'] = 'Test user';
786                 $_SERVER['PHP_AUTH_PW'] = 'password';
787                 $_SESSION['allow_api'] = false;
788                 $this->assertFalse(api_get_user($this->app));
789         }
790
791         /**
792          * Test the api_get_user() function with an user ID in a GET parameter.
793          * @return void
794          * @runInSeparateProcess
795          */
796         public function testApiGetUserWithGetId()
797         {
798                 $_GET['user_id'] = $this->otherUser['id'];
799                 $this->assertOtherUser(api_get_user($this->app));
800         }
801
802         /**
803          * Test the api_get_user() function with a wrong user ID in a GET parameter.
804          * @return void
805          * @runInSeparateProcess
806          * @expectedException Friendica\Network\HTTPException\BadRequestException
807          */
808         public function testApiGetUserWithWrongGetId()
809         {
810                 $_GET['user_id'] = $this->wrongUserId;
811                 $this->assertOtherUser(api_get_user($this->app));
812         }
813
814         /**
815          * Test the api_get_user() function with an user name in a GET parameter.
816          * @return void
817          * @runInSeparateProcess
818          */
819         public function testApiGetUserWithGetName()
820         {
821                 $_GET['screen_name'] = $this->selfUser['nick'];
822                 $this->assertSelfUser(api_get_user($this->app));
823         }
824
825         /**
826          * Test the api_get_user() function with a profile URL in a GET parameter.
827          * @return void
828          * @runInSeparateProcess
829          */
830         public function testApiGetUserWithGetUrl()
831         {
832                 $_GET['profileurl'] = $this->selfUser['nurl'];
833                 $this->assertSelfUser(api_get_user($this->app));
834         }
835
836         /**
837          * Test the api_get_user() function with an user ID in the API path.
838          * @return void
839          * @runInSeparateProcess
840          */
841         public function testApiGetUserWithNumericCalledApi()
842         {
843                 global $called_api;
844                 $called_api = ['api_path'];
845                 $this->app->argv[1] = $this->otherUser['id'].'.json';
846                 $this->assertOtherUser(api_get_user($this->app));
847         }
848
849         /**
850          * Test the api_get_user() function with the $called_api global variable.
851          * @return void
852          * @runInSeparateProcess
853          */
854         public function testApiGetUserWithCalledApi()
855         {
856                 global $called_api;
857                 $called_api = ['api', 'api_path'];
858                 $this->assertSelfUser(api_get_user($this->app));
859         }
860
861         /**
862          * Test the api_get_user() function with a valid user.
863          * @return void
864          * @runInSeparateProcess
865          */
866         public function testApiGetUserWithCorrectUser()
867         {
868                 $this->assertOtherUser(api_get_user($this->app, $this->otherUser['id']));
869         }
870
871         /**
872          * Test the api_get_user() function with a wrong user ID.
873          * @return void
874          * @runInSeparateProcess
875          * @expectedException Friendica\Network\HTTPException\BadRequestException
876          */
877         public function testApiGetUserWithWrongUser()
878         {
879                 $this->assertOtherUser(api_get_user($this->app, $this->wrongUserId));
880         }
881
882         /**
883          * Test the api_get_user() function with a 0 user ID.
884          * @return void
885          * @runInSeparateProcess
886          */
887         public function testApiGetUserWithZeroUser()
888         {
889                 $this->assertSelfUser(api_get_user($this->app, 0));
890         }
891
892         /**
893          * Test the api_item_get_user() function.
894          * @return void
895          * @runInSeparateProcess
896          */
897         public function testApiItemGetUser()
898         {
899                 $users = api_item_get_user($this->app, []);
900                 $this->assertSelfUser($users[0]);
901         }
902
903         /**
904          * Test the api_item_get_user() function with a different item parent.
905          * @return void
906          */
907         public function testApiItemGetUserWithDifferentParent()
908         {
909                 $users = api_item_get_user($this->app, ['thr-parent' => 'item_parent', 'uri' => 'item_uri']);
910                 $this->assertSelfUser($users[0]);
911                 $this->assertEquals($users[0], $users[1]);
912         }
913
914         /**
915          * Test the api_walk_recursive() function.
916          * @return void
917          */
918         public function testApiWalkRecursive()
919         {
920                 $array = ['item1'];
921                 $this->assertEquals(
922                         $array,
923                         api_walk_recursive(
924                                 $array,
925                                 function () {
926                                         // Should we test this with a callback that actually does something?
927                                         return true;
928                                 }
929                         )
930                 );
931         }
932
933         /**
934          * Test the api_walk_recursive() function with an array.
935          * @return void
936          */
937         public function testApiWalkRecursiveWithArray()
938         {
939                 $array = [['item1'], ['item2']];
940                 $this->assertEquals(
941                         $array,
942                         api_walk_recursive(
943                                 $array,
944                                 function () {
945                                         // Should we test this with a callback that actually does something?
946                                         return true;
947                                 }
948                         )
949                 );
950         }
951
952         /**
953          * Test the api_reformat_xml() function.
954          * @return void
955          */
956         public function testApiReformatXml()
957         {
958                 $item = true;
959                 $key = '';
960                 $this->assertTrue(api_reformat_xml($item, $key));
961                 $this->assertEquals('true', $item);
962         }
963
964         /**
965          * Test the api_reformat_xml() function with a statusnet_api key.
966          * @return void
967          */
968         public function testApiReformatXmlWithStatusnetKey()
969         {
970                 $item = '';
971                 $key = 'statusnet_api';
972                 $this->assertTrue(api_reformat_xml($item, $key));
973                 $this->assertEquals('statusnet:api', $key);
974         }
975
976         /**
977          * Test the api_reformat_xml() function with a friendica_api key.
978          * @return void
979          */
980         public function testApiReformatXmlWithFriendicaKey()
981         {
982                 $item = '';
983                 $key = 'friendica_api';
984                 $this->assertTrue(api_reformat_xml($item, $key));
985                 $this->assertEquals('friendica:api', $key);
986         }
987
988         /**
989          * Test the api_create_xml() function.
990          * @return void
991          */
992         public function testApiCreateXml()
993         {
994                 $this->assertEquals(
995                         '<?xml version="1.0"?>'."\n".
996                         '<root_element xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" '.
997                                 'xmlns:friendica="http://friendi.ca/schema/api/1/" '.
998                                 'xmlns:georss="http://www.georss.org/georss">'."\n".
999                                 '  <data>some_data</data>'."\n".
1000                         '</root_element>'."\n",
1001                         api_create_xml(['data' => ['some_data']], 'root_element')
1002                 );
1003         }
1004
1005         /**
1006          * Test the api_create_xml() function without any XML namespace.
1007          * @return void
1008          */
1009         public function testApiCreateXmlWithoutNamespaces()
1010         {
1011                 $this->assertEquals(
1012                         '<?xml version="1.0"?>'."\n".
1013                         '<ok>'."\n".
1014                                 '  <data>some_data</data>'."\n".
1015                         '</ok>'."\n",
1016                         api_create_xml(['data' => ['some_data']], 'ok')
1017                 );
1018         }
1019
1020         /**
1021          * Test the api_format_data() function.
1022          * @return void
1023          */
1024         public function testApiFormatData()
1025         {
1026                 $data = ['some_data'];
1027                 $this->assertEquals($data, api_format_data('root_element', 'json', $data));
1028         }
1029
1030         /**
1031          * Test the api_format_data() function with an XML result.
1032          * @return void
1033          */
1034         public function testApiFormatDataWithXml()
1035         {
1036                 $this->assertEquals(
1037                         '<?xml version="1.0"?>'."\n".
1038                         '<root_element xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" '.
1039                                 'xmlns:friendica="http://friendi.ca/schema/api/1/" '.
1040                                 'xmlns:georss="http://www.georss.org/georss">'."\n".
1041                                 '  <data>some_data</data>'."\n".
1042                         '</root_element>'."\n",
1043                         api_format_data('root_element', 'xml', ['data' => ['some_data']])
1044                 );
1045         }
1046
1047         /**
1048          * Test the api_account_verify_credentials() function.
1049          * @return void
1050          */
1051         public function testApiAccountVerifyCredentials()
1052         {
1053                 $this->assertArrayHasKey('user', api_account_verify_credentials('json'));
1054         }
1055
1056         /**
1057          * Test the api_account_verify_credentials() function without an authenticated user.
1058          * @return void
1059          * @expectedException Friendica\Network\HTTPException\ForbiddenException
1060          */
1061         public function testApiAccountVerifyCredentialsWithoutAuthenticatedUser()
1062         {
1063                 $_SESSION['authenticated'] = false;
1064                 api_account_verify_credentials('json');
1065         }
1066
1067         /**
1068          * Test the requestdata() function.
1069          * @return void
1070          */
1071         public function testRequestdata()
1072         {
1073                 $this->assertNull(requestdata('variable_name'));
1074         }
1075
1076         /**
1077          * Test the requestdata() function with a POST parameter.
1078          * @return void
1079          */
1080         public function testRequestdataWithPost()
1081         {
1082                 $_POST['variable_name'] = 'variable_value';
1083                 $this->assertEquals('variable_value', requestdata('variable_name'));
1084         }
1085
1086         /**
1087          * Test the requestdata() function with a GET parameter.
1088          * @return void
1089          */
1090         public function testRequestdataWithGet()
1091         {
1092                 $_GET['variable_name'] = 'variable_value';
1093                 $this->assertEquals('variable_value', requestdata('variable_name'));
1094         }
1095
1096         /**
1097          * Test the api_statuses_mediap() function.
1098          * @return void
1099          */
1100         public function testApiStatusesMediap()
1101         {
1102                 $this->app->argc = 2;
1103
1104                 $_FILES = [
1105                         'media' => [
1106                                 'id' => 666,
1107                                 'size' => 666,
1108                                 'width' => 666,
1109                                 'height' => 666,
1110                                 'tmp_name' => $this->getTempImage(),
1111                                 'name' => 'spacer.png',
1112                                 'type' => 'image/png'
1113                         ]
1114                 ];
1115                 $_GET['status'] = '<b>Status content</b>';
1116
1117                 $result = api_statuses_mediap('json');
1118                 $this->assertStatus($result['status']);
1119         }
1120
1121         /**
1122          * Test the api_statuses_mediap() function without an authenticated user.
1123          * @return void
1124          * @expectedException Friendica\Network\HTTPException\ForbiddenException
1125          */
1126         public function testApiStatusesMediapWithoutAuthenticatedUser()
1127         {
1128                 $_SESSION['authenticated'] = false;
1129                 api_statuses_mediap('json');
1130         }
1131
1132         /**
1133          * Test the api_statuses_update() function.
1134          * @return void
1135          */
1136         public function testApiStatusesUpdate()
1137         {
1138                 $_GET['status'] = 'Status content #friendica';
1139                 $_GET['in_reply_to_status_id'] = -1;
1140                 $_GET['lat'] = 48;
1141                 $_GET['long'] = 7;
1142                 $_FILES = [
1143                         'media' => [
1144                                 'id' => 666,
1145                                 'size' => 666,
1146                                 'width' => 666,
1147                                 'height' => 666,
1148                                 'tmp_name' => $this->getTempImage(),
1149                                 'name' => 'spacer.png',
1150                                 'type' => 'image/png'
1151                         ]
1152                 ];
1153
1154                 $result = api_statuses_update('json');
1155                 $this->assertStatus($result['status']);
1156         }
1157
1158         /**
1159          * Test the api_statuses_update() function with an HTML status.
1160          * @return void
1161          */
1162         public function testApiStatusesUpdateWithHtml()
1163         {
1164                 $_GET['htmlstatus'] = '<b>Status content</b>';
1165
1166                 $result = api_statuses_update('json');
1167                 $this->assertStatus($result['status']);
1168         }
1169
1170         /**
1171          * Test the api_statuses_update() function without an authenticated user.
1172          * @return void
1173          * @expectedException Friendica\Network\HTTPException\ForbiddenException
1174          */
1175         public function testApiStatusesUpdateWithoutAuthenticatedUser()
1176         {
1177                 $_SESSION['authenticated'] = false;
1178                 api_statuses_update('json');
1179         }
1180
1181         /**
1182          * Test the api_statuses_update() function with a parent status.
1183          * @return void
1184          */
1185         public function testApiStatusesUpdateWithParent()
1186         {
1187                 $this->markTestIncomplete('This triggers an exit() somewhere and kills PHPUnit.');
1188         }
1189
1190         /**
1191          * Test the api_statuses_update() function with a media_ids parameter.
1192          * @return void
1193          */
1194         public function testApiStatusesUpdateWithMediaIds()
1195         {
1196                 $this->markTestIncomplete();
1197         }
1198
1199         /**
1200          * Test the api_statuses_update() function with the throttle limit reached.
1201          * @return void
1202          */
1203         public function testApiStatusesUpdateWithDayThrottleReached()
1204         {
1205                 $this->markTestIncomplete();
1206         }
1207
1208         /**
1209          * Test the api_media_upload() function.
1210          * @return void
1211          * @expectedException Friendica\Network\HTTPException\BadRequestException
1212          */
1213         public function testApiMediaUpload()
1214         {
1215                 api_media_upload();
1216         }
1217
1218         /**
1219          * Test the api_media_upload() function without an authenticated user.
1220          * @return void
1221          * @expectedException Friendica\Network\HTTPException\ForbiddenException
1222          */
1223         public function testApiMediaUploadWithoutAuthenticatedUser()
1224         {
1225                 $_SESSION['authenticated'] = false;
1226                 api_media_upload();
1227         }
1228
1229         /**
1230          * Test the api_media_upload() function with an invalid uploaded media.
1231          * @return void
1232          * @expectedException Friendica\Network\HTTPException\InternalServerErrorException
1233          */
1234         public function testApiMediaUploadWithMedia()
1235         {
1236                 $_FILES = [
1237                         'media' => [
1238                                 'id' => 666,
1239                                 'tmp_name' => 'tmp_name'
1240                         ]
1241                 ];
1242                 api_media_upload();
1243         }
1244
1245         /**
1246          * Test the api_media_upload() function with an valid uploaded media.
1247          * @return void
1248          */
1249         public function testApiMediaUploadWithValidMedia()
1250         {
1251                 $_FILES = [
1252                         'media' => [
1253                                 'id' => 666,
1254                                 'size' => 666,
1255                                 'width' => 666,
1256                                 'height' => 666,
1257                                 'tmp_name' => $this->getTempImage(),
1258                                 'name' => 'spacer.png',
1259                                 'type' => 'image/png'
1260                         ]
1261                 ];
1262                 $app = \get_app();
1263                 $app->argc = 2;
1264
1265                 $result = api_media_upload();
1266                 $this->assertEquals('image/png', $result['media']['image']['image_type']);
1267                 $this->assertEquals(1, $result['media']['image']['w']);
1268                 $this->assertEquals(1, $result['media']['image']['h']);
1269                 $this->assertNotEmpty($result['media']['image']['friendica_preview_url']);
1270         }
1271
1272         /**
1273          * Test the api_status_show() function.
1274          * @return void
1275          */
1276         public function testApiStatusShow()
1277         {
1278                 $result = api_status_show('json');
1279                 $this->assertStatus($result['status']);
1280         }
1281
1282         /**
1283          * Test the api_status_show() function with an XML result.
1284          * @return void
1285          */
1286         public function testApiStatusShowWithXml()
1287         {
1288                 $result = api_status_show('xml');
1289                 $this->assertXml($result, 'statuses');
1290         }
1291
1292         /**
1293          * Test the api_status_show() function with a raw result.
1294          * @return void
1295          */
1296         public function testApiStatusShowWithRaw()
1297         {
1298                 $this->assertStatus(api_status_show('raw'));
1299         }
1300
1301         /**
1302          * Test the api_users_show() function.
1303          * @return void
1304          */
1305         public function testApiUsersShow()
1306         {
1307                 $result = api_users_show('json');
1308                 // We can't use assertSelfUser() here because the user object is missing some properties.
1309                 $this->assertEquals($this->selfUser['id'], $result['user']['cid']);
1310                 $this->assertEquals('DFRN', $result['user']['location']);
1311                 $this->assertEquals($this->selfUser['name'], $result['user']['name']);
1312                 $this->assertEquals($this->selfUser['nick'], $result['user']['screen_name']);
1313                 $this->assertEquals('dfrn', $result['user']['network']);
1314                 $this->assertTrue($result['user']['verified']);
1315         }
1316
1317         /**
1318          * Test the api_users_show() function with an XML result.
1319          * @return void
1320          */
1321         public function testApiUsersShowWithXml()
1322         {
1323                 $result = api_users_show('xml');
1324                 $this->assertXml($result, 'statuses');
1325         }
1326
1327         /**
1328          * Test the api_users_search() function.
1329          * @return void
1330          */
1331         public function testApiUsersSearch()
1332         {
1333                 $_GET['q'] = 'othercontact';
1334                 $result = api_users_search('json');
1335                 $this->assertOtherUser($result['users'][0]);
1336         }
1337
1338         /**
1339          * Test the api_users_search() function with an XML result.
1340          * @return void
1341          */
1342         public function testApiUsersSearchWithXml()
1343         {
1344                 $_GET['q'] = 'othercontact';
1345                 $result = api_users_search('xml');
1346                 $this->assertXml($result, 'users');
1347         }
1348
1349         /**
1350          * Test the api_users_search() function without a GET q parameter.
1351          * @return void
1352          * @expectedException Friendica\Network\HTTPException\BadRequestException
1353          */
1354         public function testApiUsersSearchWithoutQuery()
1355         {
1356                 api_users_search('json');
1357         }
1358
1359         /**
1360          * Test the api_users_lookup() function.
1361          * @return void
1362          * @expectedException Friendica\Network\HTTPException\NotFoundException
1363          */
1364         public function testApiUsersLookup()
1365         {
1366                 api_users_lookup('json');
1367         }
1368
1369         /**
1370          * Test the api_users_lookup() function with an user ID.
1371          * @return void
1372          */
1373         public function testApiUsersLookupWithUserId()
1374         {
1375                 $_REQUEST['user_id'] = $this->otherUser['id'];
1376                 $result = api_users_lookup('json');
1377                 $this->assertOtherUser($result['users'][0]);
1378         }
1379
1380         /**
1381          * Test the api_search() function.
1382          * @return void
1383          */
1384         public function testApiSearch()
1385         {
1386                 $_REQUEST['q'] = 'reply';
1387                 $_REQUEST['max_id'] = 10;
1388                 $result = api_search('json');
1389                 foreach ($result['status'] as $status) {
1390                         $this->assertStatus($status);
1391                         $this->assertContains('reply', $status['text'], null, true);
1392                 }
1393         }
1394
1395         /**
1396          * Test the api_search() function a count parameter.
1397          * @return void
1398          */
1399         public function testApiSearchWithCount()
1400         {
1401                 $_REQUEST['q'] = 'reply';
1402                 $_REQUEST['count'] = 20;
1403                 $result = api_search('json');
1404                 foreach ($result['status'] as $status) {
1405                         $this->assertStatus($status);
1406                         $this->assertContains('reply', $status['text'], null, true);
1407                 }
1408         }
1409
1410         /**
1411          * Test the api_search() function with an rpp parameter.
1412          * @return void
1413          */
1414         public function testApiSearchWithRpp()
1415         {
1416                 $_REQUEST['q'] = 'reply';
1417                 $_REQUEST['rpp'] = 20;
1418                 $result = api_search('json');
1419                 foreach ($result['status'] as $status) {
1420                         $this->assertStatus($status);
1421                         $this->assertContains('reply', $status['text'], null, true);
1422                 }
1423         }
1424
1425         /**
1426          * Test the api_search() function with an q parameter contains hashtag.
1427          * @return void
1428          */
1429         public function testApiSearchWithHashtag()
1430         {
1431                 $_REQUEST['q'] = '%23friendica';
1432                 $result = api_search('json');
1433                 foreach ($result['status'] as $status) {
1434                         $this->assertStatus($status);
1435                         $this->assertContains('#friendica', $status['text'], null, true);
1436                 }
1437         }
1438
1439         /**
1440          * Test the api_search() function with an exclude_replies parameter.
1441          * @return void
1442          */
1443         public function testApiSearchWithExcludeReplies()
1444         {
1445                 $_REQUEST['max_id'] = 10;
1446                 $_REQUEST['exclude_replies'] = true;
1447                 $_REQUEST['q'] = 'friendica';
1448                 $result = api_search('json');
1449                 foreach ($result['status'] as $status) {
1450                         $this->assertStatus($status);
1451                 }
1452         }
1453
1454         /**
1455          * Test the api_search() function without an authenticated user.
1456          * @return void
1457          * @expectedException Friendica\Network\HTTPException\ForbiddenException
1458          */
1459         public function testApiSearchWithUnallowedUser()
1460         {
1461                 $_SESSION['allow_api'] = false;
1462                 $_GET['screen_name'] = $this->selfUser['nick'];
1463                 api_search('json');
1464         }
1465
1466         /**
1467          * Test the api_search() function without any GET query parameter.
1468          * @return void
1469          * @expectedException Friendica\Network\HTTPException\BadRequestException
1470          */
1471         public function testApiSearchWithoutQuery()
1472         {
1473                 api_search('json');
1474         }
1475
1476         /**
1477          * Test the api_statuses_home_timeline() function.
1478          * @return void
1479          */
1480         public function testApiStatusesHomeTimeline()
1481         {
1482                 $_REQUEST['max_id'] = 10;
1483                 $_REQUEST['exclude_replies'] = true;
1484                 $_REQUEST['conversation_id'] = 1;
1485                 $result = api_statuses_home_timeline('json');
1486                 $this->assertNotEmpty($result['status']);
1487                 foreach ($result['status'] as $status) {
1488                         $this->assertStatus($status);
1489                 }
1490         }
1491
1492         /**
1493          * Test the api_statuses_home_timeline() function with a negative page parameter.
1494          * @return void
1495          */
1496         public function testApiStatusesHomeTimelineWithNegativePage()
1497         {
1498                 $_REQUEST['page'] = -2;
1499                 $result = api_statuses_home_timeline('json');
1500                 $this->assertNotEmpty($result['status']);
1501                 foreach ($result['status'] as $status) {
1502                         $this->assertStatus($status);
1503                 }
1504         }
1505
1506         /**
1507          * Test the api_statuses_home_timeline() with an unallowed user.
1508          * @return void
1509          * @expectedException Friendica\Network\HTTPException\ForbiddenException
1510          */
1511         public function testApiStatusesHomeTimelineWithUnallowedUser()
1512         {
1513                 $_SESSION['allow_api'] = false;
1514                 $_GET['screen_name'] = $this->selfUser['nick'];
1515                 api_statuses_home_timeline('json');
1516         }
1517
1518         /**
1519          * Test the api_statuses_home_timeline() function with an RSS result.
1520          * @return void
1521          */
1522         public function testApiStatusesHomeTimelineWithRss()
1523         {
1524                 $result = api_statuses_home_timeline('rss');
1525                 $this->assertXml($result, 'statuses');
1526         }
1527
1528         /**
1529          * Test the api_statuses_public_timeline() function.
1530          * @return void
1531          */
1532         public function testApiStatusesPublicTimeline()
1533         {
1534                 $_REQUEST['max_id'] = 10;
1535                 $_REQUEST['conversation_id'] = 1;
1536                 $result = api_statuses_public_timeline('json');
1537                 $this->assertNotEmpty($result['status']);
1538                 foreach ($result['status'] as $status) {
1539                         $this->assertStatus($status);
1540                 }
1541         }
1542
1543         /**
1544          * Test the api_statuses_public_timeline() function with the exclude_replies parameter.
1545          * @return void
1546          */
1547         public function testApiStatusesPublicTimelineWithExcludeReplies()
1548         {
1549                 $_REQUEST['max_id'] = 10;
1550                 $_REQUEST['exclude_replies'] = true;
1551                 $result = api_statuses_public_timeline('json');
1552                 $this->assertNotEmpty($result['status']);
1553                 foreach ($result['status'] as $status) {
1554                         $this->assertStatus($status);
1555                 }
1556         }
1557
1558         /**
1559          * Test the api_statuses_public_timeline() function with a negative page parameter.
1560          * @return void
1561          */
1562         public function testApiStatusesPublicTimelineWithNegativePage()
1563         {
1564                 $_REQUEST['page'] = -2;
1565                 $result = api_statuses_public_timeline('json');
1566                 $this->assertNotEmpty($result['status']);
1567                 foreach ($result['status'] as $status) {
1568                         $this->assertStatus($status);
1569                 }
1570         }
1571
1572         /**
1573          * Test the api_statuses_public_timeline() function with an unallowed user.
1574          * @return void
1575          * @expectedException Friendica\Network\HTTPException\ForbiddenException
1576          */
1577         public function testApiStatusesPublicTimelineWithUnallowedUser()
1578         {
1579                 $_SESSION['allow_api'] = false;
1580                 $_GET['screen_name'] = $this->selfUser['nick'];
1581                 api_statuses_public_timeline('json');
1582         }
1583
1584         /**
1585          * Test the api_statuses_public_timeline() function with an RSS result.
1586          * @return void
1587          */
1588         public function testApiStatusesPublicTimelineWithRss()
1589         {
1590                 $result = api_statuses_public_timeline('rss');
1591                 $this->assertXml($result, 'statuses');
1592         }
1593
1594         /**
1595          * Test the api_statuses_networkpublic_timeline() function.
1596          * @return void
1597          */
1598         public function testApiStatusesNetworkpublicTimeline()
1599         {
1600                 $_REQUEST['max_id'] = 10;
1601                 $result = api_statuses_networkpublic_timeline('json');
1602                 $this->assertNotEmpty($result['status']);
1603                 foreach ($result['status'] as $status) {
1604                         $this->assertStatus($status);
1605                 }
1606         }
1607
1608         /**
1609          * Test the api_statuses_networkpublic_timeline() function with a negative page parameter.
1610          * @return void
1611          */
1612         public function testApiStatusesNetworkpublicTimelineWithNegativePage()
1613         {
1614                 $_REQUEST['page'] = -2;
1615                 $result = api_statuses_networkpublic_timeline('json');
1616                 $this->assertNotEmpty($result['status']);
1617                 foreach ($result['status'] as $status) {
1618                         $this->assertStatus($status);
1619                 }
1620         }
1621
1622         /**
1623          * Test the api_statuses_networkpublic_timeline() function with an unallowed user.
1624          * @return void
1625          * @expectedException Friendica\Network\HTTPException\ForbiddenException
1626          */
1627         public function testApiStatusesNetworkpublicTimelineWithUnallowedUser()
1628         {
1629                 $_SESSION['allow_api'] = false;
1630                 $_GET['screen_name'] = $this->selfUser['nick'];
1631                 api_statuses_networkpublic_timeline('json');
1632         }
1633
1634         /**
1635          * Test the api_statuses_networkpublic_timeline() function with an RSS result.
1636          * @return void
1637          */
1638         public function testApiStatusesNetworkpublicTimelineWithRss()
1639         {
1640                 $result = api_statuses_networkpublic_timeline('rss');
1641                 $this->assertXml($result, 'statuses');
1642         }
1643
1644         /**
1645          * Test the api_statuses_show() function.
1646          * @return void
1647          * @expectedException Friendica\Network\HTTPException\BadRequestException
1648          */
1649         public function testApiStatusesShow()
1650         {
1651                 api_statuses_show('json');
1652         }
1653
1654         /**
1655          * Test the api_statuses_show() function with an ID.
1656          * @return void
1657          */
1658         public function testApiStatusesShowWithId()
1659         {
1660                 $this->app->argv[3] = 1;
1661                 $result = api_statuses_show('json');
1662                 $this->assertStatus($result['status']);
1663         }
1664
1665         /**
1666          * Test the api_statuses_show() function with the conversation parameter.
1667          * @return void
1668          */
1669         public function testApiStatusesShowWithConversation()
1670         {
1671                 $this->app->argv[3] = 1;
1672                 $_REQUEST['conversation'] = 1;
1673                 $result = api_statuses_show('json');
1674                 $this->assertNotEmpty($result['status']);
1675                 foreach ($result['status'] as $status) {
1676                         $this->assertStatus($status);
1677                 }
1678         }
1679
1680         /**
1681          * Test the api_statuses_show() function with an unallowed user.
1682          * @return void
1683          * @expectedException Friendica\Network\HTTPException\ForbiddenException
1684          */
1685         public function testApiStatusesShowWithUnallowedUser()
1686         {
1687                 $_SESSION['allow_api'] = false;
1688                 $_GET['screen_name'] = $this->selfUser['nick'];
1689                 api_statuses_show('json');
1690         }
1691
1692         /**
1693          * Test the api_conversation_show() function.
1694          * @return void
1695          * @expectedException Friendica\Network\HTTPException\BadRequestException
1696          */
1697         public function testApiConversationShow()
1698         {
1699                 api_conversation_show('json');
1700         }
1701
1702         /**
1703          * Test the api_conversation_show() function with an ID.
1704          * @return void
1705          */
1706         public function testApiConversationShowWithId()
1707         {
1708                 $this->app->argv[3] = 1;
1709                 $_REQUEST['max_id'] = 10;
1710                 $_REQUEST['page'] = -2;
1711                 $result = api_conversation_show('json');
1712                 $this->assertNotEmpty($result['status']);
1713                 foreach ($result['status'] as $status) {
1714                         $this->assertStatus($status);
1715                 }
1716         }
1717
1718         /**
1719          * Test the api_conversation_show() function with an unallowed user.
1720          * @return void
1721          * @expectedException Friendica\Network\HTTPException\ForbiddenException
1722          */
1723         public function testApiConversationShowWithUnallowedUser()
1724         {
1725                 $_SESSION['allow_api'] = false;
1726                 $_GET['screen_name'] = $this->selfUser['nick'];
1727                 api_conversation_show('json');
1728         }
1729
1730         /**
1731          * Test the api_statuses_repeat() function.
1732          * @return void
1733          * @expectedException Friendica\Network\HTTPException\ForbiddenException
1734          */
1735         public function testApiStatusesRepeat()
1736         {
1737                 api_statuses_repeat('json');
1738         }
1739
1740         /**
1741          * Test the api_statuses_repeat() function without an authenticated user.
1742          * @return void
1743          * @expectedException Friendica\Network\HTTPException\ForbiddenException
1744          */
1745         public function testApiStatusesRepeatWithoutAuthenticatedUser()
1746         {
1747                 $_SESSION['authenticated'] = false;
1748                 api_statuses_repeat('json');
1749         }
1750
1751         /**
1752          * Test the api_statuses_repeat() function with an ID.
1753          * @return void
1754          */
1755         public function testApiStatusesRepeatWithId()
1756         {
1757                 $this->app->argv[3] = 1;
1758                 $result = api_statuses_repeat('json');
1759                 $this->assertStatus($result['status']);
1760
1761                 // Also test with a shared status
1762                 $this->app->argv[3] = 5;
1763                 $result = api_statuses_repeat('json');
1764                 $this->assertStatus($result['status']);
1765         }
1766
1767         /**
1768          * Test the api_statuses_destroy() function.
1769          * @return void
1770          * @expectedException Friendica\Network\HTTPException\BadRequestException
1771          */
1772         public function testApiStatusesDestroy()
1773         {
1774                 api_statuses_destroy('json');
1775         }
1776
1777         /**
1778          * Test the api_statuses_destroy() function without an authenticated user.
1779          * @return void
1780          * @expectedException Friendica\Network\HTTPException\ForbiddenException
1781          */
1782         public function testApiStatusesDestroyWithoutAuthenticatedUser()
1783         {
1784                 $_SESSION['authenticated'] = false;
1785                 api_statuses_destroy('json');
1786         }
1787
1788         /**
1789          * Test the api_statuses_destroy() function with an ID.
1790          * @return void
1791          */
1792         public function testApiStatusesDestroyWithId()
1793         {
1794                 $this->app->argv[3] = 1;
1795                 $result = api_statuses_destroy('json');
1796                 $this->assertStatus($result['status']);
1797         }
1798
1799         /**
1800          * Test the api_statuses_mentions() function.
1801          * @return void
1802          */
1803         public function testApiStatusesMentions()
1804         {
1805                 $this->app->user = ['nickname' => $this->selfUser['nick']];
1806                 $_REQUEST['max_id'] = 10;
1807                 $result = api_statuses_mentions('json');
1808                 $this->assertEmpty($result['status']);
1809                 // We should test with mentions in the database.
1810         }
1811
1812         /**
1813          * Test the api_statuses_mentions() function with a negative page parameter.
1814          * @return void
1815          */
1816         public function testApiStatusesMentionsWithNegativePage()
1817         {
1818                 $_REQUEST['page'] = -2;
1819                 $result = api_statuses_mentions('json');
1820                 $this->assertEmpty($result['status']);
1821         }
1822
1823         /**
1824          * Test the api_statuses_mentions() function with an unallowed user.
1825          * @return void
1826          * @expectedException Friendica\Network\HTTPException\ForbiddenException
1827          */
1828         public function testApiStatusesMentionsWithUnallowedUser()
1829         {
1830                 $_SESSION['allow_api'] = false;
1831                 $_GET['screen_name'] = $this->selfUser['nick'];
1832                 api_statuses_mentions('json');
1833         }
1834
1835         /**
1836          * Test the api_statuses_mentions() function with an RSS result.
1837          * @return void
1838          */
1839         public function testApiStatusesMentionsWithRss()
1840         {
1841                 $result = api_statuses_mentions('rss');
1842                 $this->assertXml($result, 'statuses');
1843         }
1844
1845         /**
1846          * Test the api_statuses_user_timeline() function.
1847          * @return void
1848          */
1849         public function testApiStatusesUserTimeline()
1850         {
1851                 $_REQUEST['max_id'] = 10;
1852                 $_REQUEST['exclude_replies'] = true;
1853                 $_REQUEST['conversation_id'] = 1;
1854                 $result = api_statuses_user_timeline('json');
1855                 $this->assertNotEmpty($result['status']);
1856                 foreach ($result['status'] as $status) {
1857                         $this->assertStatus($status);
1858                 }
1859         }
1860
1861         /**
1862          * Test the api_statuses_user_timeline() function with a negative page parameter.
1863          * @return void
1864          */
1865         public function testApiStatusesUserTimelineWithNegativePage()
1866         {
1867                 $_REQUEST['page'] = -2;
1868                 $result = api_statuses_user_timeline('json');
1869                 $this->assertNotEmpty($result['status']);
1870                 foreach ($result['status'] as $status) {
1871                         $this->assertStatus($status);
1872                 }
1873         }
1874
1875         /**
1876          * Test the api_statuses_user_timeline() function with an RSS result.
1877          * @return void
1878          */
1879         public function testApiStatusesUserTimelineWithRss()
1880         {
1881                 $result = api_statuses_user_timeline('rss');
1882                 $this->assertXml($result, 'statuses');
1883         }
1884
1885         /**
1886          * Test the api_statuses_user_timeline() function with an unallowed user.
1887          * @return void
1888          * @expectedException Friendica\Network\HTTPException\ForbiddenException
1889          */
1890         public function testApiStatusesUserTimelineWithUnallowedUser()
1891         {
1892                 $_SESSION['allow_api'] = false;
1893                 $_GET['screen_name'] = $this->selfUser['nick'];
1894                 api_statuses_user_timeline('json');
1895         }
1896
1897         /**
1898          * Test the api_favorites_create_destroy() function.
1899          * @return void
1900          * @expectedException Friendica\Network\HTTPException\BadRequestException
1901          */
1902         public function testApiFavoritesCreateDestroy()
1903         {
1904                 $this->app->argv = ['api', '1.1', 'favorites', 'create'];
1905                 $this->app->argc = count($this->app->argv);
1906                 api_favorites_create_destroy('json');
1907         }
1908
1909         /**
1910          * Test the api_favorites_create_destroy() function with an invalid ID.
1911          * @return void
1912          * @expectedException Friendica\Network\HTTPException\BadRequestException
1913          */
1914         public function testApiFavoritesCreateDestroyWithInvalidId()
1915         {
1916                 $this->app->argv = ['api', '1.1', 'favorites', 'create', '12.json'];
1917                 $this->app->argc = count($this->app->argv);
1918                 api_favorites_create_destroy('json');
1919         }
1920
1921         /**
1922          * Test the api_favorites_create_destroy() function with an invalid action.
1923          * @return void
1924          * @expectedException Friendica\Network\HTTPException\BadRequestException
1925          */
1926         public function testApiFavoritesCreateDestroyWithInvalidAction()
1927         {
1928                 $this->app->argv = ['api', '1.1', 'favorites', 'change.json'];
1929                 $this->app->argc = count($this->app->argv);
1930                 $_REQUEST['id'] = 1;
1931                 api_favorites_create_destroy('json');
1932         }
1933
1934         /**
1935          * Test the api_favorites_create_destroy() function with the create action.
1936          * @return void
1937          */
1938         public function testApiFavoritesCreateDestroyWithCreateAction()
1939         {
1940                 $this->app->argv = ['api', '1.1', 'favorites', 'create.json'];
1941                 $this->app->argc = count($this->app->argv);
1942                 $_REQUEST['id'] = 3;
1943                 $result = api_favorites_create_destroy('json');
1944                 $this->assertStatus($result['status']);
1945         }
1946
1947         /**
1948          * Test the api_favorites_create_destroy() function with the create action and an RSS result.
1949          * @return void
1950          */
1951         public function testApiFavoritesCreateDestroyWithCreateActionAndRss()
1952         {
1953                 $this->app->argv = ['api', '1.1', 'favorites', 'create.rss'];
1954                 $this->app->argc = count($this->app->argv);
1955                 $_REQUEST['id'] = 3;
1956                 $result = api_favorites_create_destroy('rss');
1957                 $this->assertXml($result, 'status');
1958         }
1959
1960         /**
1961          * Test the api_favorites_create_destroy() function with the destroy action.
1962          * @return void
1963          */
1964         public function testApiFavoritesCreateDestroyWithDestroyAction()
1965         {
1966                 $this->app->argv = ['api', '1.1', 'favorites', 'destroy.json'];
1967                 $this->app->argc = count($this->app->argv);
1968                 $_REQUEST['id'] = 3;
1969                 $result = api_favorites_create_destroy('json');
1970                 $this->assertStatus($result['status']);
1971         }
1972
1973         /**
1974          * Test the api_favorites_create_destroy() function without an authenticated user.
1975          * @return void
1976          * @expectedException Friendica\Network\HTTPException\ForbiddenException
1977          */
1978         public function testApiFavoritesCreateDestroyWithoutAuthenticatedUser()
1979         {
1980                 $this->app->argv = ['api', '1.1', 'favorites', 'create.json'];
1981                 $this->app->argc = count($this->app->argv);
1982                 $_SESSION['authenticated'] = false;
1983                 api_favorites_create_destroy('json');
1984         }
1985
1986         /**
1987          * Test the api_favorites() function.
1988          * @return void
1989          */
1990         public function testApiFavorites()
1991         {
1992                 $_REQUEST['page'] = -1;
1993                 $_REQUEST['max_id'] = 10;
1994                 $result = api_favorites('json');
1995                 foreach ($result['status'] as $status) {
1996                         $this->assertStatus($status);
1997                 }
1998         }
1999
2000         /**
2001          * Test the api_favorites() function with an RSS result.
2002          * @return void
2003          */
2004         public function testApiFavoritesWithRss()
2005         {
2006                 $result = api_favorites('rss');
2007                 $this->assertXml($result, 'statuses');
2008         }
2009
2010         /**
2011          * Test the api_favorites() function with an unallowed user.
2012          * @return void
2013          * @expectedException Friendica\Network\HTTPException\ForbiddenException
2014          */
2015         public function testApiFavoritesWithUnallowedUser()
2016         {
2017                 $_SESSION['allow_api'] = false;
2018                 $_GET['screen_name'] = $this->selfUser['nick'];
2019                 api_favorites('json');
2020         }
2021
2022         /**
2023          * Test the api_format_messages() function.
2024          * @return void
2025          */
2026         public function testApiFormatMessages()
2027         {
2028                 $result = api_format_messages(
2029                         ['id' => 1, 'title' => 'item_title', 'body' => '[b]item_body[/b]'],
2030                         ['id' => 2, 'screen_name' => 'recipient_name'],
2031                         ['id' => 3, 'screen_name' => 'sender_name']
2032                 );
2033                 $this->assertEquals('item_title'."\n".'item_body', $result['text']);
2034                 $this->assertEquals(1, $result['id']);
2035                 $this->assertEquals(2, $result['recipient_id']);
2036                 $this->assertEquals(3, $result['sender_id']);
2037                 $this->assertEquals('recipient_name', $result['recipient_screen_name']);
2038                 $this->assertEquals('sender_name', $result['sender_screen_name']);
2039         }
2040
2041         /**
2042          * Test the api_format_messages() function with HTML.
2043          * @return void
2044          */
2045         public function testApiFormatMessagesWithHtmlText()
2046         {
2047                 $_GET['getText'] = 'html';
2048                 $result = api_format_messages(
2049                         ['id' => 1, 'title' => 'item_title', 'body' => '[b]item_body[/b]'],
2050                         ['id' => 2, 'screen_name' => 'recipient_name'],
2051                         ['id' => 3, 'screen_name' => 'sender_name']
2052                 );
2053                 $this->assertEquals('item_title', $result['title']);
2054                 $this->assertEquals('<strong>item_body</strong>', $result['text']);
2055         }
2056
2057         /**
2058          * Test the api_format_messages() function with plain text.
2059          * @return void
2060          */
2061         public function testApiFormatMessagesWithPlainText()
2062         {
2063                 $_GET['getText'] = 'plain';
2064                 $result = api_format_messages(
2065                         ['id' => 1, 'title' => 'item_title', 'body' => '[b]item_body[/b]'],
2066                         ['id' => 2, 'screen_name' => 'recipient_name'],
2067                         ['id' => 3, 'screen_name' => 'sender_name']
2068                 );
2069                 $this->assertEquals('item_title', $result['title']);
2070                 $this->assertEquals('item_body', $result['text']);
2071         }
2072
2073         /**
2074          * Test the api_format_messages() function with the getUserObjects GET parameter set to false.
2075          * @return void
2076          */
2077         public function testApiFormatMessagesWithoutUserObjects()
2078         {
2079                 $_GET['getUserObjects'] = 'false';
2080                 $result = api_format_messages(
2081                         ['id' => 1, 'title' => 'item_title', 'body' => '[b]item_body[/b]'],
2082                         ['id' => 2, 'screen_name' => 'recipient_name'],
2083                         ['id' => 3, 'screen_name' => 'sender_name']
2084                 );
2085                 $this->assertTrue(!isset($result['sender']));
2086                 $this->assertTrue(!isset($result['recipient']));
2087         }
2088
2089         /**
2090          * Test the api_convert_item() function.
2091          * @return void
2092          */
2093         public function testApiConvertItem()
2094         {
2095                 $result = api_convert_item(
2096                         [
2097                                 'network' => 'feed',
2098                                 'title' => 'item_title',
2099                                 // We need a long string to test that it is correctly cut
2100                                 'body' => 'perspiciatis impedit voluptatem quis molestiae ea qui '.
2101                                 'reiciendis dolorum aut ducimus sunt consequatur inventore dolor '.
2102                                 'officiis pariatur doloremque nemo culpa aut quidem qui dolore '.
2103                                 'laudantium atque commodi alias voluptatem non possimus aperiam '.
2104                                 'ipsum rerum consequuntur aut amet fugit quia aliquid praesentium '.
2105                                 'repellendus quibusdam et et inventore mollitia rerum sit autem '.
2106                                 'pariatur maiores ipsum accusantium perferendis vel sit possimus '.
2107                                 'veritatis nihil distinctio qui eum repellat officia illum quos '.
2108                                 'impedit quam iste esse unde qui suscipit aut facilis ut inventore '.
2109                                 'omnis exercitationem quo magnam consequatur maxime aut illum '.
2110                                 'soluta quaerat natus unde aspernatur et sed beatae nihil ullam '.
2111                                 'temporibus corporis ratione blanditiis perspiciatis impedit '.
2112                                 'voluptatem quis molestiae ea qui reiciendis dolorum aut ducimus '.
2113                                 'sunt consequatur inventore dolor officiis pariatur doloremque '.
2114                                 'nemo culpa aut quidem qui dolore laudantium atque commodi alias '.
2115                                 'voluptatem non possimus aperiam ipsum rerum consequuntur aut '.
2116                                 'amet fugit quia aliquid praesentium repellendus quibusdam et et '.
2117                                 'inventore mollitia rerum sit autem pariatur maiores ipsum accusantium '.
2118                                 'perferendis vel sit possimus veritatis nihil distinctio qui eum '.
2119                                 'repellat officia illum quos impedit quam iste esse unde qui '.
2120                                 'suscipit aut facilis ut inventore omnis exercitationem quo magnam '.
2121                                 'consequatur maxime aut illum soluta quaerat natus unde aspernatur '.
2122                                 'et sed beatae nihil ullam temporibus corporis ratione blanditiis',
2123                                 'plink' => 'item_plink'
2124                         ]
2125                 );
2126                 $this->assertStringStartsWith('item_title', $result['text']);
2127                 $this->assertStringStartsWith('<h4>item_title</h4><br>perspiciatis impedit voluptatem', $result['html']);
2128         }
2129
2130         /**
2131          * Test the api_convert_item() function with an empty item body.
2132          * @return void
2133          */
2134         public function testApiConvertItemWithoutBody()
2135         {
2136                 $result = api_convert_item(
2137                         [
2138                                 'network' => 'feed',
2139                                 'title' => 'item_title',
2140                                 'body' => '',
2141                                 'plink' => 'item_plink'
2142                         ]
2143                 );
2144                 $this->assertEquals('item_title', $result['text']);
2145                 $this->assertEquals('<h4>item_title</h4><br>item_plink', $result['html']);
2146         }
2147
2148         /**
2149          * Test the api_convert_item() function with the title in the body.
2150          * @return void
2151          */
2152         public function testApiConvertItemWithTitleInBody()
2153         {
2154                 $result = api_convert_item(
2155                         [
2156                                 'title' => 'item_title',
2157                                 'body' => 'item_title item_body'
2158                         ]
2159                 );
2160                 $this->assertEquals('item_title item_body', $result['text']);
2161                 $this->assertEquals('<h4>item_title</h4><br>item_title item_body', $result['html']);
2162         }
2163
2164         /**
2165          * Test the api_get_attachments() function.
2166          * @return void
2167          */
2168         public function testApiGetAttachments()
2169         {
2170                 $body = 'body';
2171                 $this->assertEmpty(api_get_attachments($body));
2172         }
2173
2174         /**
2175          * Test the api_get_attachments() function with an img tag.
2176          * @return void
2177          */
2178         public function testApiGetAttachmentsWithImage()
2179         {
2180                 $body = '[img]http://via.placeholder.com/1x1.png[/img]';
2181                 $this->assertInternalType('array', api_get_attachments($body));
2182         }
2183
2184         /**
2185          * Test the api_get_attachments() function with an img tag and an AndStatus user agent.
2186          * @return void
2187          */
2188         public function testApiGetAttachmentsWithImageAndAndStatus()
2189         {
2190                 $_SERVER['HTTP_USER_AGENT'] = 'AndStatus';
2191                 $body = '[img]http://via.placeholder.com/1x1.png[/img]';
2192                 $this->assertInternalType('array', api_get_attachments($body));
2193         }
2194
2195         /**
2196          * Test the api_get_entitities() function.
2197          * @return void
2198          */
2199         public function testApiGetEntitities()
2200         {
2201                 $text = 'text';
2202                 $this->assertInternalType('array', api_get_entitities($text, 'bbcode'));
2203         }
2204
2205         /**
2206          * Test the api_get_entitities() function with the include_entities parameter.
2207          * @return void
2208          */
2209         public function testApiGetEntititiesWithIncludeEntities()
2210         {
2211                 $_REQUEST['include_entities'] = 'true';
2212                 $text = 'text';
2213                 $result = api_get_entitities($text, 'bbcode');
2214                 $this->assertInternalType('array', $result['hashtags']);
2215                 $this->assertInternalType('array', $result['symbols']);
2216                 $this->assertInternalType('array', $result['urls']);
2217                 $this->assertInternalType('array', $result['user_mentions']);
2218         }
2219
2220         /**
2221          * Test the api_format_items_embeded_images() function.
2222          * @return void
2223          */
2224         public function testApiFormatItemsEmbededImages()
2225         {
2226                 $this->assertEquals(
2227                         'text ' . System::baseUrl() . '/display/item_guid',
2228                         api_format_items_embeded_images(['guid' => 'item_guid'], 'text data:image/foo')
2229                 );
2230         }
2231
2232         /**
2233          * Test the api_contactlink_to_array() function.
2234          * @return void
2235          */
2236         public function testApiContactlinkToArray()
2237         {
2238                 $this->assertEquals(
2239                         [
2240                                 'name' => 'text',
2241                                 'url' => '',
2242                         ],
2243                         api_contactlink_to_array('text')
2244                 );
2245         }
2246
2247         /**
2248          * Test the api_contactlink_to_array() function with an URL.
2249          * @return void
2250          */
2251         public function testApiContactlinkToArrayWithUrl()
2252         {
2253                 $this->assertEquals(
2254                         [
2255                                 'name' => ['link_text'],
2256                                 'url' => ['url'],
2257                         ],
2258                         api_contactlink_to_array('text <a href="url">link_text</a>')
2259                 );
2260         }
2261
2262         /**
2263          * Test the api_format_items_activities() function.
2264          * @return void
2265          */
2266         public function testApiFormatItemsActivities()
2267         {
2268                 $item = ['uid' => 0, 'uri' => ''];
2269                 $result = api_format_items_activities($item);
2270                 $this->assertArrayHasKey('like', $result);
2271                 $this->assertArrayHasKey('dislike', $result);
2272                 $this->assertArrayHasKey('attendyes', $result);
2273                 $this->assertArrayHasKey('attendno', $result);
2274                 $this->assertArrayHasKey('attendmaybe', $result);
2275         }
2276
2277         /**
2278          * Test the api_format_items_activities() function with an XML result.
2279          * @return void
2280          */
2281         public function testApiFormatItemsActivitiesWithXml()
2282         {
2283                 $item = ['uid' => 0, 'uri' => ''];
2284                 $result = api_format_items_activities($item, 'xml');
2285                 $this->assertArrayHasKey('friendica:like', $result);
2286                 $this->assertArrayHasKey('friendica:dislike', $result);
2287                 $this->assertArrayHasKey('friendica:attendyes', $result);
2288                 $this->assertArrayHasKey('friendica:attendno', $result);
2289                 $this->assertArrayHasKey('friendica:attendmaybe', $result);
2290         }
2291
2292         /**
2293          * Test the api_format_items_profiles() function.
2294          * @return void
2295          */
2296         public function testApiFormatItemsProfiles()
2297         {
2298                 $profile_row = [
2299                         'id' => 'profile_id',
2300                         'profile-name' => 'profile_name',
2301                         'is-default' => true,
2302                         'hide-friends' => true,
2303                         'photo' => 'profile_photo',
2304                         'thumb' => 'profile_thumb',
2305                         'publish' => true,
2306                         'net-publish' => true,
2307                         'pdesc' => 'description',
2308                         'dob' => 'date_of_birth',
2309                         'address' => 'address',
2310                         'locality' => 'city',
2311                         'region' => 'region',
2312                         'postal-code' => 'postal_code',
2313                         'country-name' => 'country',
2314                         'hometown' => 'hometown',
2315                         'gender' => 'gender',
2316                         'marital' => 'marital',
2317                         'with' => 'marital_with',
2318                         'howlong' => 'marital_since',
2319                         'sexual' => 'sexual',
2320                         'politic' => 'politic',
2321                         'religion' => 'religion',
2322                         'pub_keywords' => 'public_keywords',
2323                         'prv_keywords' => 'private_keywords',
2324
2325                         'likes' => 'likes',
2326                         'dislikes' => 'dislikes',
2327                         'about' => 'about',
2328                         'music' => 'music',
2329                         'book' => 'book',
2330                         'tv' => 'tv',
2331                         'film' => 'film',
2332                         'interest' => 'interest',
2333                         'romance' => 'romance',
2334                         'work' => 'work',
2335                         'education' => 'education',
2336                         'contact' => 'social_networks',
2337                         'homepage' => 'homepage'
2338                 ];
2339                 $result = api_format_items_profiles($profile_row);
2340                 $this->assertEquals(
2341                         [
2342                                 'profile_id' => 'profile_id',
2343                                 'profile_name' => 'profile_name',
2344                                 'is_default' => true,
2345                                 'hide_friends' => true,
2346                                 'profile_photo' => 'profile_photo',
2347                                 'profile_thumb' => 'profile_thumb',
2348                                 'publish' => true,
2349                                 'net_publish' => true,
2350                                 'description' => 'description',
2351                                 'date_of_birth' => 'date_of_birth',
2352                                 'address' => 'address',
2353                                 'city' => 'city',
2354                                 'region' => 'region',
2355                                 'postal_code' => 'postal_code',
2356                                 'country' => 'country',
2357                                 'hometown' => 'hometown',
2358                                 'gender' => 'gender',
2359                                 'marital' => 'marital',
2360                                 'marital_with' => 'marital_with',
2361                                 'marital_since' => 'marital_since',
2362                                 'sexual' => 'sexual',
2363                                 'politic' => 'politic',
2364                                 'religion' => 'religion',
2365                                 'public_keywords' => 'public_keywords',
2366                                 'private_keywords' => 'private_keywords',
2367
2368                                 'likes' => 'likes',
2369                                 'dislikes' => 'dislikes',
2370                                 'about' => 'about',
2371                                 'music' => 'music',
2372                                 'book' => 'book',
2373                                 'tv' => 'tv',
2374                                 'film' => 'film',
2375                                 'interest' => 'interest',
2376                                 'romance' => 'romance',
2377                                 'work' => 'work',
2378                                 'education' => 'education',
2379                                 'social_networks' => 'social_networks',
2380                                 'homepage' => 'homepage',
2381                                 'users' => null
2382                         ],
2383                         $result
2384                 );
2385         }
2386
2387         /**
2388          * Test the api_format_items() function.
2389          * @return void
2390          */
2391         public function testApiFormatItems()
2392         {
2393                 $items = [
2394                         [
2395                                 'item_network' => 'item_network',
2396                                 'source' => 'web',
2397                                 'coord' => '5 7',
2398                                 'body' => '',
2399                                 'verb' => '',
2400                                 'author-id' => 43,
2401                                 'author-network' => Protocol::DFRN,
2402                                 'author-link' => 'http://localhost/profile/othercontact',
2403                                 'plink' => '',
2404                         ]
2405                 ];
2406                 $result = api_format_items($items, ['id' => 0], true);
2407                 foreach ($result as $status) {
2408                         $this->assertStatus($status);
2409                 }
2410         }
2411
2412         /**
2413          * Test the api_format_items() function with an XML result.
2414          * @return void
2415          */
2416         public function testApiFormatItemsWithXml()
2417         {
2418                 $items = [
2419                         [
2420                                 'coord' => '5 7',
2421                                 'body' => '',
2422                                 'verb' => '',
2423                                 'author-id' => 43,
2424                                 'author-network' => Protocol::DFRN,
2425                                 'author-link' => 'http://localhost/profile/othercontact',
2426                                 'plink' => '',
2427                         ]
2428                 ];
2429                 $result = api_format_items($items, ['id' => 0], true, 'xml');
2430                 foreach ($result as $status) {
2431                         $this->assertStatus($status);
2432                 }
2433         }
2434
2435         /**
2436          * Test the api_format_items() function.
2437          * @return void
2438          */
2439         public function testApiAccountRateLimitStatus()
2440         {
2441                 $result = api_account_rate_limit_status('json');
2442                 $this->assertEquals(150, $result['hash']['remaining_hits']);
2443                 $this->assertEquals(150, $result['hash']['hourly_limit']);
2444                 $this->assertInternalType('int', $result['hash']['reset_time_in_seconds']);
2445         }
2446
2447         /**
2448          * Test the api_format_items() function with an XML result.
2449          * @return void
2450          */
2451         public function testApiAccountRateLimitStatusWithXml()
2452         {
2453                 $result = api_account_rate_limit_status('xml');
2454                 $this->assertXml($result, 'hash');
2455         }
2456
2457         /**
2458          * Test the api_help_test() function.
2459          * @return void
2460          */
2461         public function testApiHelpTest()
2462         {
2463                 $result = api_help_test('json');
2464                 $this->assertEquals(['ok' => 'ok'], $result);
2465         }
2466
2467         /**
2468          * Test the api_help_test() function with an XML result.
2469          * @return void
2470          */
2471         public function testApiHelpTestWithXml()
2472         {
2473                 $result = api_help_test('xml');
2474                 $this->assertXml($result, 'ok');
2475         }
2476
2477         /**
2478          * Test the api_lists_list() function.
2479          * @return void
2480          */
2481         public function testApiListsList()
2482         {
2483                 $result = api_lists_list('json');
2484                 $this->assertEquals(['lists_list' => []], $result);
2485         }
2486
2487         /**
2488          * Test the api_lists_ownerships() function.
2489          * @return void
2490          */
2491         public function testApiListsOwnerships()
2492         {
2493                 $result = api_lists_ownerships('json');
2494                 foreach ($result['lists']['lists'] as $list) {
2495                         $this->assertList($list);
2496                 }
2497         }
2498
2499         /**
2500          * Test the api_lists_ownerships() function without an authenticated user.
2501          * @return void
2502          * @expectedException Friendica\Network\HTTPException\ForbiddenException
2503          */
2504         public function testApiListsOwnershipsWithoutAuthenticatedUser()
2505         {
2506                 $_SESSION['authenticated'] = false;
2507                 api_lists_ownerships('json');
2508         }
2509
2510         /**
2511          * Test the api_lists_statuses() function.
2512          * @expectedException Friendica\Network\HTTPException\BadRequestException
2513          * @return void
2514          */
2515         public function testApiListsStatuses()
2516         {
2517                 api_lists_statuses('json');
2518         }
2519
2520         /**
2521          * Test the api_lists_statuses() function with a list ID.
2522          * @return void
2523          */
2524         public function testApiListsStatusesWithListId()
2525         {
2526                 $_REQUEST['list_id'] = 1;
2527                 $_REQUEST['page'] = -1;
2528                 $_REQUEST['max_id'] = 10;
2529                 $result = api_lists_statuses('json');
2530                 foreach ($result['status'] as $status) {
2531                         $this->assertStatus($status);
2532                 }
2533         }
2534
2535         /**
2536          * Test the api_lists_statuses() function with a list ID and a RSS result.
2537          * @return void
2538          */
2539         public function testApiListsStatusesWithListIdAndRss()
2540         {
2541                 $_REQUEST['list_id'] = 1;
2542                 $result = api_lists_statuses('rss');
2543                 $this->assertXml($result, 'statuses');
2544         }
2545
2546         /**
2547          * Test the api_lists_statuses() function with an unallowed user.
2548          * @return void
2549          * @expectedException Friendica\Network\HTTPException\ForbiddenException
2550          */
2551         public function testApiListsStatusesWithUnallowedUser()
2552         {
2553                 $_SESSION['allow_api'] = false;
2554                 $_GET['screen_name'] = $this->selfUser['nick'];
2555                 api_lists_statuses('json');
2556         }
2557
2558         /**
2559          * Test the api_statuses_f() function.
2560          * @return void
2561          */
2562         public function testApiStatusesFWithFriends()
2563         {
2564                 $_GET['page'] = -1;
2565                 $result = api_statuses_f('friends');
2566                 $this->assertArrayHasKey('user', $result);
2567         }
2568
2569         /**
2570          * Test the api_statuses_f() function.
2571          * @return void
2572          */
2573         public function testApiStatusesFWithFollowers()
2574         {
2575                 $result = api_statuses_f('followers');
2576                 $this->assertArrayHasKey('user', $result);
2577         }
2578
2579         /**
2580          * Test the api_statuses_f() function.
2581          * @return void
2582          */
2583         public function testApiStatusesFWithBlocks()
2584         {
2585                 $result = api_statuses_f('blocks');
2586                 $this->assertArrayHasKey('user', $result);
2587         }
2588
2589         /**
2590          * Test the api_statuses_f() function.
2591          * @return void
2592          */
2593         public function testApiStatusesFWithIncoming()
2594         {
2595                 $result = api_statuses_f('incoming');
2596                 $this->assertArrayHasKey('user', $result);
2597         }
2598
2599         /**
2600          * Test the api_statuses_f() function an undefined cursor GET variable.
2601          * @return void
2602          */
2603         public function testApiStatusesFWithUndefinedCursor()
2604         {
2605                 $_GET['cursor'] = 'undefined';
2606                 $this->assertFalse(api_statuses_f('friends'));
2607         }
2608
2609         /**
2610          * Test the api_statuses_friends() function.
2611          * @return void
2612          */
2613         public function testApiStatusesFriends()
2614         {
2615                 $result = api_statuses_friends('json');
2616                 $this->assertArrayHasKey('user', $result);
2617         }
2618
2619         /**
2620          * Test the api_statuses_friends() function an undefined cursor GET variable.
2621          * @return void
2622          */
2623         public function testApiStatusesFriendsWithUndefinedCursor()
2624         {
2625                 $_GET['cursor'] = 'undefined';
2626                 $this->assertFalse(api_statuses_friends('json'));
2627         }
2628
2629         /**
2630          * Test the api_statuses_followers() function.
2631          * @return void
2632          */
2633         public function testApiStatusesFollowers()
2634         {
2635                 $result = api_statuses_followers('json');
2636                 $this->assertArrayHasKey('user', $result);
2637         }
2638
2639         /**
2640          * Test the api_statuses_followers() function an undefined cursor GET variable.
2641          * @return void
2642          */
2643         public function testApiStatusesFollowersWithUndefinedCursor()
2644         {
2645                 $_GET['cursor'] = 'undefined';
2646                 $this->assertFalse(api_statuses_followers('json'));
2647         }
2648
2649         /**
2650          * Test the api_blocks_list() function.
2651          * @return void
2652          */
2653         public function testApiBlocksList()
2654         {
2655                 $result = api_blocks_list('json');
2656                 $this->assertArrayHasKey('user', $result);
2657         }
2658
2659         /**
2660          * Test the api_blocks_list() function an undefined cursor GET variable.
2661          * @return void
2662          */
2663         public function testApiBlocksListWithUndefinedCursor()
2664         {
2665                 $_GET['cursor'] = 'undefined';
2666                 $this->assertFalse(api_blocks_list('json'));
2667         }
2668
2669         /**
2670          * Test the api_friendships_incoming() function.
2671          * @return void
2672          */
2673         public function testApiFriendshipsIncoming()
2674         {
2675                 $result = api_friendships_incoming('json');
2676                 $this->assertArrayHasKey('id', $result);
2677         }
2678
2679         /**
2680          * Test the api_friendships_incoming() function an undefined cursor GET variable.
2681          * @return void
2682          */
2683         public function testApiFriendshipsIncomingWithUndefinedCursor()
2684         {
2685                 $_GET['cursor'] = 'undefined';
2686                 $this->assertFalse(api_friendships_incoming('json'));
2687         }
2688
2689         /**
2690          * Test the api_statusnet_config() function.
2691          * @return void
2692          */
2693         public function testApiStatusnetConfig()
2694         {
2695                 $result = api_statusnet_config('json');
2696                 $this->assertEquals('localhost', $result['config']['site']['server']);
2697                 $this->assertEquals('default', $result['config']['site']['theme']);
2698                 $this->assertEquals(System::baseUrl() . '/images/friendica-64.png', $result['config']['site']['logo']);
2699                 $this->assertTrue($result['config']['site']['fancy']);
2700                 $this->assertEquals('en', $result['config']['site']['language']);
2701                 $this->assertEquals('UTC', $result['config']['site']['timezone']);
2702                 $this->assertEquals(200000, $result['config']['site']['textlimit']);
2703                 $this->assertEquals('false', $result['config']['site']['private']);
2704                 $this->assertEquals('false', $result['config']['site']['ssl']);
2705                 $this->assertEquals(30, $result['config']['site']['shorturllength']);
2706         }
2707
2708         /**
2709          * Test the api_statusnet_version() function.
2710          * @return void
2711          */
2712         public function testApiStatusnetVersion()
2713         {
2714                 $result = api_statusnet_version('json');
2715                 $this->assertEquals('0.9.7', $result['version']);
2716         }
2717
2718         /**
2719          * Test the api_ff_ids() function.
2720          * @return void
2721          */
2722         public function testApiFfIds()
2723         {
2724                 $result = api_ff_ids('json');
2725                 $this->assertNull($result);
2726         }
2727
2728         /**
2729          * Test the api_ff_ids() function with a result.
2730          * @return void
2731          */
2732         public function testApiFfIdsWithResult()
2733         {
2734                 $this->markTestIncomplete();
2735         }
2736
2737         /**
2738          * Test the api_ff_ids() function without an authenticated user.
2739          * @return void
2740          * @expectedException Friendica\Network\HTTPException\ForbiddenException
2741          */
2742         public function testApiFfIdsWithoutAuthenticatedUser()
2743         {
2744                 $_SESSION['authenticated'] = false;
2745                 api_ff_ids('json');
2746         }
2747
2748         /**
2749          * Test the api_friends_ids() function.
2750          * @return void
2751          */
2752         public function testApiFriendsIds()
2753         {
2754                 $result = api_friends_ids('json');
2755                 $this->assertNull($result);
2756         }
2757
2758         /**
2759          * Test the api_followers_ids() function.
2760          * @return void
2761          */
2762         public function testApiFollowersIds()
2763         {
2764                 $result = api_followers_ids('json');
2765                 $this->assertNull($result);
2766         }
2767
2768         /**
2769          * Test the api_direct_messages_new() function.
2770          * @return void
2771          */
2772         public function testApiDirectMessagesNew()
2773         {
2774                 $result = api_direct_messages_new('json');
2775                 $this->assertNull($result);
2776         }
2777
2778         /**
2779          * Test the api_direct_messages_new() function without an authenticated user.
2780          * @return void
2781          * @expectedException Friendica\Network\HTTPException\ForbiddenException
2782          */
2783         public function testApiDirectMessagesNewWithoutAuthenticatedUser()
2784         {
2785                 $_SESSION['authenticated'] = false;
2786                 api_direct_messages_new('json');
2787         }
2788
2789         /**
2790          * Test the api_direct_messages_new() function with an user ID.
2791          * @return void
2792          */
2793         public function testApiDirectMessagesNewWithUserId()
2794         {
2795                 $_POST['text'] = 'message_text';
2796                 $_POST['user_id'] = $this->otherUser['id'];
2797                 $result = api_direct_messages_new('json');
2798                 $this->assertEquals(['direct_message' => ['error' => -1]], $result);
2799         }
2800
2801         /**
2802          * Test the api_direct_messages_new() function with a screen name.
2803          * @return void
2804          */
2805         public function testApiDirectMessagesNewWithScreenName()
2806         {
2807                 $_POST['text'] = 'message_text';
2808                 $_POST['screen_name'] = $this->friendUser['nick'];
2809                 $result = api_direct_messages_new('json');
2810                 $this->assertEquals(1, $result['direct_message']['id']);
2811                 $this->assertContains('message_text', $result['direct_message']['text']);
2812                 $this->assertEquals('selfcontact', $result['direct_message']['sender_screen_name']);
2813                 $this->assertEquals(1, $result['direct_message']['friendica_seen']);
2814         }
2815
2816         /**
2817          * Test the api_direct_messages_new() function with a title.
2818          * @return void
2819          */
2820         public function testApiDirectMessagesNewWithTitle()
2821         {
2822                 $_POST['text'] = 'message_text';
2823                 $_POST['screen_name'] = $this->friendUser['nick'];
2824                 $_REQUEST['title'] = 'message_title';
2825                 $result = api_direct_messages_new('json');
2826                 $this->assertEquals(1, $result['direct_message']['id']);
2827                 $this->assertContains('message_text', $result['direct_message']['text']);
2828                 $this->assertContains('message_title', $result['direct_message']['text']);
2829                 $this->assertEquals('selfcontact', $result['direct_message']['sender_screen_name']);
2830                 $this->assertEquals(1, $result['direct_message']['friendica_seen']);
2831         }
2832
2833         /**
2834          * Test the api_direct_messages_new() function with an RSS result.
2835          * @return void
2836          */
2837         public function testApiDirectMessagesNewWithRss()
2838         {
2839                 $_POST['text'] = 'message_text';
2840                 $_POST['screen_name'] = $this->friendUser['nick'];
2841                 $result = api_direct_messages_new('rss');
2842                 $this->assertXml($result, 'direct-messages');
2843         }
2844
2845         /**
2846          * Test the api_direct_messages_destroy() function.
2847          * @return void
2848          * @expectedException Friendica\Network\HTTPException\BadRequestException
2849          */
2850         public function testApiDirectMessagesDestroy()
2851         {
2852                 api_direct_messages_destroy('json');
2853         }
2854
2855         /**
2856          * Test the api_direct_messages_destroy() function with the friendica_verbose GET param.
2857          * @return void
2858          */
2859         public function testApiDirectMessagesDestroyWithVerbose()
2860         {
2861                 $_GET['friendica_verbose'] = 'true';
2862                 $result = api_direct_messages_destroy('json');
2863                 $this->assertEquals(
2864                         [
2865                                 '$result' => [
2866                                         'result' => 'error',
2867                                         'message' => 'message id or parenturi not specified'
2868                                 ]
2869                         ],
2870                         $result
2871                 );
2872         }
2873
2874         /**
2875          * Test the api_direct_messages_destroy() function without an authenticated user.
2876          * @return void
2877          * @expectedException Friendica\Network\HTTPException\ForbiddenException
2878          */
2879         public function testApiDirectMessagesDestroyWithoutAuthenticatedUser()
2880         {
2881                 $_SESSION['authenticated'] = false;
2882                 api_direct_messages_destroy('json');
2883         }
2884
2885         /**
2886          * Test the api_direct_messages_destroy() function with a non-zero ID.
2887          * @return void
2888          * @expectedException Friendica\Network\HTTPException\BadRequestException
2889          */
2890         public function testApiDirectMessagesDestroyWithId()
2891         {
2892                 $_REQUEST['id'] = 1;
2893                 api_direct_messages_destroy('json');
2894         }
2895
2896         /**
2897          * Test the api_direct_messages_destroy() with a non-zero ID and the friendica_verbose GET param.
2898          * @return void
2899          */
2900         public function testApiDirectMessagesDestroyWithIdAndVerbose()
2901         {
2902                 $_REQUEST['id'] = 1;
2903                 $_REQUEST['friendica_parenturi'] = 'parent_uri';
2904                 $_GET['friendica_verbose'] = 'true';
2905                 $result = api_direct_messages_destroy('json');
2906                 $this->assertEquals(
2907                         [
2908                                 '$result' => [
2909                                         'result' => 'error',
2910                                         'message' => 'message id not in database'
2911                                 ]
2912                         ],
2913                         $result
2914                 );
2915         }
2916
2917         /**
2918          * Test the api_direct_messages_destroy() function with a non-zero ID.
2919          * @return void
2920          */
2921         public function testApiDirectMessagesDestroyWithCorrectId()
2922         {
2923                 $this->markTestIncomplete('We need to add a dataset for this.');
2924         }
2925
2926         /**
2927          * Test the api_direct_messages_box() function.
2928          * @return void
2929          */
2930         public function testApiDirectMessagesBoxWithSentbox()
2931         {
2932                 $_REQUEST['page'] = -1;
2933                 $_REQUEST['max_id'] = 10;
2934                 $result = api_direct_messages_box('json', 'sentbox', 'false');
2935                 $this->assertArrayHasKey('direct_message', $result);
2936         }
2937
2938         /**
2939          * Test the api_direct_messages_box() function.
2940          * @return void
2941          */
2942         public function testApiDirectMessagesBoxWithConversation()
2943         {
2944                 $result = api_direct_messages_box('json', 'conversation', 'false');
2945                 $this->assertArrayHasKey('direct_message', $result);
2946         }
2947
2948         /**
2949          * Test the api_direct_messages_box() function.
2950          * @return void
2951          */
2952         public function testApiDirectMessagesBoxWithAll()
2953         {
2954                 $result = api_direct_messages_box('json', 'all', 'false');
2955                 $this->assertArrayHasKey('direct_message', $result);
2956         }
2957
2958         /**
2959          * Test the api_direct_messages_box() function.
2960          * @return void
2961          */
2962         public function testApiDirectMessagesBoxWithInbox()
2963         {
2964                 $result = api_direct_messages_box('json', 'inbox', 'false');
2965                 $this->assertArrayHasKey('direct_message', $result);
2966         }
2967
2968         /**
2969          * Test the api_direct_messages_box() function.
2970          * @return void
2971          */
2972         public function testApiDirectMessagesBoxWithVerbose()
2973         {
2974                 $result = api_direct_messages_box('json', 'sentbox', 'true');
2975                 $this->assertEquals(
2976                         [
2977                                 '$result' => [
2978                                         'result' => 'error',
2979                                         'message' => 'no mails available'
2980                                 ]
2981                         ],
2982                         $result
2983                 );
2984         }
2985
2986         /**
2987          * Test the api_direct_messages_box() function with a RSS result.
2988          * @return void
2989          */
2990         public function testApiDirectMessagesBoxWithRss()
2991         {
2992                 $result = api_direct_messages_box('rss', 'sentbox', 'false');
2993                 $this->assertXml($result, 'direct-messages');
2994         }
2995
2996         /**
2997          * Test the api_direct_messages_box() function without an authenticated user.
2998          * @return void
2999          * @expectedException Friendica\Network\HTTPException\ForbiddenException
3000          */
3001         public function testApiDirectMessagesBoxWithUnallowedUser()
3002         {
3003                 $_SESSION['allow_api'] = false;
3004                 $_GET['screen_name'] = $this->selfUser['nick'];
3005                 api_direct_messages_box('json', 'sentbox', 'false');
3006         }
3007
3008         /**
3009          * Test the api_direct_messages_sentbox() function.
3010          * @return void
3011          */
3012         public function testApiDirectMessagesSentbox()
3013         {
3014                 $result = api_direct_messages_sentbox('json');
3015                 $this->assertArrayHasKey('direct_message', $result);
3016         }
3017
3018         /**
3019          * Test the api_direct_messages_inbox() function.
3020          * @return void
3021          */
3022         public function testApiDirectMessagesInbox()
3023         {
3024                 $result = api_direct_messages_inbox('json');
3025                 $this->assertArrayHasKey('direct_message', $result);
3026         }
3027
3028         /**
3029          * Test the api_direct_messages_all() function.
3030          * @return void
3031          */
3032         public function testApiDirectMessagesAll()
3033         {
3034                 $result = api_direct_messages_all('json');
3035                 $this->assertArrayHasKey('direct_message', $result);
3036         }
3037
3038         /**
3039          * Test the api_direct_messages_conversation() function.
3040          * @return void
3041          */
3042         public function testApiDirectMessagesConversation()
3043         {
3044                 $result = api_direct_messages_conversation('json');
3045                 $this->assertArrayHasKey('direct_message', $result);
3046         }
3047
3048         /**
3049          * Test the api_oauth_request_token() function.
3050          * @return void
3051          */
3052         public function testApiOauthRequestToken()
3053         {
3054                 $this->markTestIncomplete('killme() kills phpunit as well');
3055         }
3056
3057         /**
3058          * Test the api_oauth_access_token() function.
3059          * @return void
3060          */
3061         public function testApiOauthAccessToken()
3062         {
3063                 $this->markTestIncomplete('killme() kills phpunit as well');
3064         }
3065
3066         /**
3067          * Test the api_fr_photoalbum_delete() function.
3068          * @return void
3069          * @expectedException Friendica\Network\HTTPException\BadRequestException
3070          */
3071         public function testApiFrPhotoalbumDelete()
3072         {
3073                 api_fr_photoalbum_delete('json');
3074         }
3075
3076         /**
3077          * Test the api_fr_photoalbum_delete() function with an album name.
3078          * @return void
3079          * @expectedException Friendica\Network\HTTPException\BadRequestException
3080          */
3081         public function testApiFrPhotoalbumDeleteWithAlbum()
3082         {
3083                 $_REQUEST['album'] = 'album_name';
3084                 api_fr_photoalbum_delete('json');
3085         }
3086
3087         /**
3088          * Test the api_fr_photoalbum_delete() function with an album name.
3089          * @return void
3090          */
3091         public function testApiFrPhotoalbumDeleteWithValidAlbum()
3092         {
3093                 $this->markTestIncomplete('We need to add a dataset for this.');
3094         }
3095
3096         /**
3097          * Test the api_fr_photoalbum_delete() function.
3098          * @return void
3099          * @expectedException Friendica\Network\HTTPException\BadRequestException
3100          */
3101         public function testApiFrPhotoalbumUpdate()
3102         {
3103                 api_fr_photoalbum_update('json');
3104         }
3105
3106         /**
3107          * Test the api_fr_photoalbum_delete() function with an album name.
3108          * @return void
3109          * @expectedException Friendica\Network\HTTPException\BadRequestException
3110          */
3111         public function testApiFrPhotoalbumUpdateWithAlbum()
3112         {
3113                 $_REQUEST['album'] = 'album_name';
3114                 api_fr_photoalbum_update('json');
3115         }
3116
3117         /**
3118          * Test the api_fr_photoalbum_delete() function with an album name.
3119          * @return void
3120          * @expectedException Friendica\Network\HTTPException\BadRequestException
3121          */
3122         public function testApiFrPhotoalbumUpdateWithAlbumAndNewAlbum()
3123         {
3124                 $_REQUEST['album'] = 'album_name';
3125                 $_REQUEST['album_new'] = 'album_name';
3126                 api_fr_photoalbum_update('json');
3127         }
3128
3129         /**
3130          * Test the api_fr_photoalbum_update() function without an authenticated user.
3131          * @return void
3132          * @expectedException Friendica\Network\HTTPException\ForbiddenException
3133          */
3134         public function testApiFrPhotoalbumUpdateWithoutAuthenticatedUser()
3135         {
3136                 $_SESSION['authenticated'] = false;
3137                 api_fr_photoalbum_update('json');
3138         }
3139
3140         /**
3141          * Test the api_fr_photoalbum_delete() function with an album name.
3142          * @return void
3143          */
3144         public function testApiFrPhotoalbumUpdateWithValidAlbum()
3145         {
3146                 $this->markTestIncomplete('We need to add a dataset for this.');
3147         }
3148
3149         /**
3150          * Test the api_fr_photos_list() function.
3151          * @return void
3152          */
3153         public function testApiFrPhotosList()
3154         {
3155                 $result = api_fr_photos_list('json');
3156                 $this->assertArrayHasKey('photo', $result);
3157         }
3158
3159         /**
3160          * Test the api_fr_photos_list() function without an authenticated user.
3161          * @return void
3162          * @expectedException Friendica\Network\HTTPException\ForbiddenException
3163          */
3164         public function testApiFrPhotosListWithoutAuthenticatedUser()
3165         {
3166                 $_SESSION['authenticated'] = false;
3167                 api_fr_photos_list('json');
3168         }
3169
3170         /**
3171          * Test the api_fr_photo_create_update() function.
3172          * @return void
3173          * @expectedException Friendica\Network\HTTPException\BadRequestException
3174          */
3175         public function testApiFrPhotoCreateUpdate()
3176         {
3177                 api_fr_photo_create_update('json');
3178         }
3179
3180         /**
3181          * Test the api_fr_photo_create_update() function without an authenticated user.
3182          * @return void
3183          * @expectedException Friendica\Network\HTTPException\ForbiddenException
3184          */
3185         public function testApiFrPhotoCreateUpdateWithoutAuthenticatedUser()
3186         {
3187                 $_SESSION['authenticated'] = false;
3188                 api_fr_photo_create_update('json');
3189         }
3190
3191         /**
3192          * Test the api_fr_photo_create_update() function with an album name.
3193          * @return void
3194          * @expectedException Friendica\Network\HTTPException\BadRequestException
3195          */
3196         public function testApiFrPhotoCreateUpdateWithAlbum()
3197         {
3198                 $_REQUEST['album'] = 'album_name';
3199                 api_fr_photo_create_update('json');
3200         }
3201
3202         /**
3203          * Test the api_fr_photo_create_update() function with the update mode.
3204          * @return void
3205          */
3206         public function testApiFrPhotoCreateUpdateWithUpdate()
3207         {
3208                 $this->markTestIncomplete('We need to create a dataset for this');
3209         }
3210
3211         /**
3212          * Test the api_fr_photo_create_update() function with an uploaded file.
3213          * @return void
3214          */
3215         public function testApiFrPhotoCreateUpdateWithFile()
3216         {
3217                 $this->markTestIncomplete();
3218         }
3219
3220         /**
3221          * Test the api_fr_photo_delete() function.
3222          * @return void
3223          * @expectedException Friendica\Network\HTTPException\BadRequestException
3224          */
3225         public function testApiFrPhotoDelete()
3226         {
3227                 api_fr_photo_delete('json');
3228         }
3229
3230         /**
3231          * Test the api_fr_photo_delete() function without an authenticated user.
3232          * @return void
3233          * @expectedException Friendica\Network\HTTPException\ForbiddenException
3234          */
3235         public function testApiFrPhotoDeleteWithoutAuthenticatedUser()
3236         {
3237                 $_SESSION['authenticated'] = false;
3238                 api_fr_photo_delete('json');
3239         }
3240
3241         /**
3242          * Test the api_fr_photo_delete() function with a photo ID.
3243          * @return void
3244          * @expectedException Friendica\Network\HTTPException\BadRequestException
3245          */
3246         public function testApiFrPhotoDeleteWithPhotoId()
3247         {
3248                 $_REQUEST['photo_id'] = 1;
3249                 api_fr_photo_delete('json');
3250         }
3251
3252         /**
3253          * Test the api_fr_photo_delete() function with a correct photo ID.
3254          * @return void
3255          */
3256         public function testApiFrPhotoDeleteWithCorrectPhotoId()
3257         {
3258                 $this->markTestIncomplete('We need to create a dataset for this.');
3259         }
3260
3261         /**
3262          * Test the api_fr_photo_detail() function.
3263          * @return void
3264          * @expectedException Friendica\Network\HTTPException\BadRequestException
3265          */
3266         public function testApiFrPhotoDetail()
3267         {
3268                 api_fr_photo_detail('json');
3269         }
3270
3271         /**
3272          * Test the api_fr_photo_detail() function without an authenticated user.
3273          * @return void
3274          * @expectedException Friendica\Network\HTTPException\ForbiddenException
3275          */
3276         public function testApiFrPhotoDetailWithoutAuthenticatedUser()
3277         {
3278                 $_SESSION['authenticated'] = false;
3279                 api_fr_photo_detail('json');
3280         }
3281
3282         /**
3283          * Test the api_fr_photo_detail() function with a photo ID.
3284          * @return void
3285          * @expectedException Friendica\Network\HTTPException\NotFoundException
3286          */
3287         public function testApiFrPhotoDetailWithPhotoId()
3288         {
3289                 $_REQUEST['photo_id'] = 1;
3290                 api_fr_photo_detail('json');
3291         }
3292
3293         /**
3294          * Test the api_fr_photo_detail() function with a correct photo ID.
3295          * @return void
3296          */
3297         public function testApiFrPhotoDetailCorrectPhotoId()
3298         {
3299                 $this->markTestIncomplete('We need to create a dataset for this.');
3300         }
3301
3302         /**
3303          * Test the api_account_update_profile_image() function.
3304          * @return void
3305          * @expectedException Friendica\Network\HTTPException\BadRequestException
3306          */
3307         public function testApiAccountUpdateProfileImage()
3308         {
3309                 api_account_update_profile_image('json');
3310         }
3311
3312         /**
3313          * Test the api_account_update_profile_image() function without an authenticated user.
3314          * @return void
3315          * @expectedException Friendica\Network\HTTPException\ForbiddenException
3316          */
3317         public function testApiAccountUpdateProfileImageWithoutAuthenticatedUser()
3318         {
3319                 $_SESSION['authenticated'] = false;
3320                 api_account_update_profile_image('json');
3321         }
3322
3323         /**
3324          * Test the api_account_update_profile_image() function with an uploaded file.
3325          * @return void
3326          * @expectedException Friendica\Network\HTTPException\BadRequestException
3327          */
3328         public function testApiAccountUpdateProfileImageWithUpload()
3329         {
3330                 $this->markTestIncomplete();
3331         }
3332
3333
3334         /**
3335          * Test the api_account_update_profile() function.
3336          * @return void
3337          */
3338         public function testApiAccountUpdateProfile()
3339         {
3340                 $_POST['name'] = 'new_name';
3341                 $_POST['description'] = 'new_description';
3342                 $result = api_account_update_profile('json');
3343                 // We can't use assertSelfUser() here because the user object is missing some properties.
3344                 $this->assertEquals($this->selfUser['id'], $result['user']['cid']);
3345                 $this->assertEquals('DFRN', $result['user']['location']);
3346                 $this->assertEquals($this->selfUser['nick'], $result['user']['screen_name']);
3347                 $this->assertEquals('dfrn', $result['user']['network']);
3348                 $this->assertEquals('new_name', $result['user']['name']);
3349                 $this->assertEquals('new_description', $result['user']['description']);
3350         }
3351
3352         /**
3353          * Test the check_acl_input() function.
3354          * @return void
3355          */
3356         public function testCheckAclInput()
3357         {
3358                 $result = check_acl_input('<aclstring>');
3359                 // Where does this result come from?
3360                 $this->assertEquals(1, $result);
3361         }
3362
3363         /**
3364          * Test the check_acl_input() function with an empty ACL string.
3365          * @return void
3366          */
3367         public function testCheckAclInputWithEmptyAclString()
3368         {
3369                 $result = check_acl_input(' ');
3370                 $this->assertFalse($result);
3371         }
3372
3373         /**
3374          * Test the save_media_to_database() function.
3375          * @return void
3376          */
3377         public function testSaveMediaToDatabase()
3378         {
3379                 $this->markTestIncomplete();
3380         }
3381
3382         /**
3383          * Test the post_photo_item() function.
3384          * @return void
3385          */
3386         public function testPostPhotoItem()
3387         {
3388                 $this->markTestIncomplete();
3389         }
3390
3391         /**
3392          * Test the prepare_photo_data() function.
3393          * @return void
3394          */
3395         public function testPreparePhotoData()
3396         {
3397                 $this->markTestIncomplete();
3398         }
3399
3400         /**
3401          * Test the api_friendica_remoteauth() function.
3402          * @return void
3403          * @expectedException Friendica\Network\HTTPException\BadRequestException
3404          */
3405         public function testApiFriendicaRemoteauth()
3406         {
3407                 api_friendica_remoteauth();
3408         }
3409
3410         /**
3411          * Test the api_friendica_remoteauth() function with an URL.
3412          * @return void
3413          * @expectedException Friendica\Network\HTTPException\BadRequestException
3414          */
3415         public function testApiFriendicaRemoteauthWithUrl()
3416         {
3417                 $_GET['url'] = 'url';
3418                 $_GET['c_url'] = 'url';
3419                 api_friendica_remoteauth();
3420         }
3421
3422         /**
3423          * Test the api_friendica_remoteauth() function with a correct URL.
3424          * @return void
3425          */
3426         public function testApiFriendicaRemoteauthWithCorrectUrl()
3427         {
3428                 $this->markTestIncomplete("We can't use an assertion here because of App->redirect().");
3429                 $_GET['url'] = 'url';
3430                 $_GET['c_url'] = $this->selfUser['nurl'];
3431                 api_friendica_remoteauth();
3432         }
3433
3434         /**
3435          * Test the api_share_as_retweet() function.
3436          * @return void
3437          */
3438         public function testApiShareAsRetweet()
3439         {
3440                 $item = ['body' => '', 'author-id' => 1, 'owner-id' => 1];
3441                 $result = api_share_as_retweet($item);
3442                 $this->assertFalse($result);
3443         }
3444
3445         /**
3446          * Test the api_share_as_retweet() function with a valid item.
3447          * @return void
3448          */
3449         public function testApiShareAsRetweetWithValidItem()
3450         {
3451                 $this->markTestIncomplete();
3452         }
3453
3454         /**
3455          * Test the api_get_nick() function.
3456          * @return void
3457          */
3458         public function testApiGetNick()
3459         {
3460                 $result = api_get_nick($this->otherUser['nurl']);
3461                 $this->assertEquals('othercontact', $result);
3462         }
3463
3464         /**
3465          * Test the api_get_nick() function with a wrong URL.
3466          * @return void
3467          */
3468         public function testApiGetNickWithWrongUrl()
3469         {
3470                 $result = api_get_nick('wrong_url');
3471                 $this->assertFalse($result);
3472         }
3473
3474         /**
3475          * Test the api_in_reply_to() function.
3476          * @return void
3477          */
3478         public function testApiInReplyTo()
3479         {
3480                 $result = api_in_reply_to(['id' => 0, 'parent' => 0, 'uri' => '', 'thr-parent' => '']);
3481                 $this->assertArrayHasKey('status_id', $result);
3482                 $this->assertArrayHasKey('user_id', $result);
3483                 $this->assertArrayHasKey('status_id_str', $result);
3484                 $this->assertArrayHasKey('user_id_str', $result);
3485                 $this->assertArrayHasKey('screen_name', $result);
3486         }
3487
3488         /**
3489          * Test the api_in_reply_to() function with a valid item.
3490          * @return void
3491          */
3492         public function testApiInReplyToWithValidItem()
3493         {
3494                 $this->markTestIncomplete();
3495         }
3496
3497         /**
3498          * Test the api_clean_plain_items() function.
3499          * @return void
3500          */
3501         public function testApiCleanPlainItems()
3502         {
3503                 $_REQUEST['include_entities'] = 'true';
3504                 $result = api_clean_plain_items('some_text [url="some_url"]some_text[/url]');
3505                 $this->assertEquals('some_text [url="some_url"]"some_url"[/url]', $result);
3506         }
3507
3508         /**
3509          * Test the api_clean_attachments() function.
3510          * @return void
3511          */
3512         public function testApiCleanAttachments()
3513         {
3514                 $this->markTestIncomplete();
3515         }
3516
3517         /**
3518          * Test the api_best_nickname() function.
3519          * @return void
3520          */
3521         public function testApiBestNickname()
3522         {
3523                 $contacts = [];
3524                 $result = api_best_nickname($contacts);
3525                 $this->assertNull($result);
3526         }
3527
3528         /**
3529          * Test the api_best_nickname() function with contacts.
3530          * @return void
3531          */
3532         public function testApiBestNicknameWithContacts()
3533         {
3534                 $this->markTestIncomplete();
3535         }
3536
3537         /**
3538          * Test the api_friendica_group_show() function.
3539          * @return void
3540          */
3541         public function testApiFriendicaGroupShow()
3542         {
3543                 $this->markTestIncomplete();
3544         }
3545
3546         /**
3547          * Test the api_friendica_group_delete() function.
3548          * @return void
3549          */
3550         public function testApiFriendicaGroupDelete()
3551         {
3552                 $this->markTestIncomplete();
3553         }
3554
3555         /**
3556          * Test the api_lists_destroy() function.
3557          * @return void
3558          */
3559         public function testApiListsDestroy()
3560         {
3561                 $this->markTestIncomplete();
3562         }
3563
3564         /**
3565          * Test the group_create() function.
3566          * @return void
3567          */
3568         public function testGroupCreate()
3569         {
3570                 $this->markTestIncomplete();
3571         }
3572
3573         /**
3574          * Test the api_friendica_group_create() function.
3575          * @return void
3576          */
3577         public function testApiFriendicaGroupCreate()
3578         {
3579                 $this->markTestIncomplete();
3580         }
3581
3582         /**
3583          * Test the api_lists_create() function.
3584          * @return void
3585          */
3586         public function testApiListsCreate()
3587         {
3588                 $this->markTestIncomplete();
3589         }
3590
3591         /**
3592          * Test the api_friendica_group_update() function.
3593          * @return void
3594          */
3595         public function testApiFriendicaGroupUpdate()
3596         {
3597                 $this->markTestIncomplete();
3598         }
3599
3600         /**
3601          * Test the api_lists_update() function.
3602          * @return void
3603          */
3604         public function testApiListsUpdate()
3605         {
3606                 $this->markTestIncomplete();
3607         }
3608
3609         /**
3610          * Test the api_friendica_activity() function.
3611          * @return void
3612          */
3613         public function testApiFriendicaActivity()
3614         {
3615                 $this->markTestIncomplete();
3616         }
3617
3618         /**
3619          * Test the api_friendica_notification() function.
3620          * @return void
3621          * @expectedException Friendica\Network\HTTPException\BadRequestException
3622          */
3623         public function testApiFriendicaNotification()
3624         {
3625                 api_friendica_notification('json');
3626         }
3627
3628         /**
3629          * Test the api_friendica_notification() function without an authenticated user.
3630          * @return void
3631          * @expectedException Friendica\Network\HTTPException\ForbiddenException
3632          */
3633         public function testApiFriendicaNotificationWithoutAuthenticatedUser()
3634         {
3635                 $_SESSION['authenticated'] = false;
3636                 api_friendica_notification('json');
3637         }
3638
3639         /**
3640          * Test the api_friendica_notification() function with an argument count.
3641          * @return void
3642          */
3643         public function testApiFriendicaNotificationWithArgumentCount()
3644         {
3645                 $this->app->argv = ['api', 'friendica', 'notification'];
3646                 $this->app->argc = count($this->app->argv);
3647                 $result = api_friendica_notification('json');
3648                 $this->assertEquals(['note' => false], $result);
3649         }
3650
3651         /**
3652          * Test the api_friendica_notification() function with an XML result.
3653          * @return void
3654          */
3655         public function testApiFriendicaNotificationWithXmlResult()
3656         {
3657                 $this->app->argv = ['api', 'friendica', 'notification'];
3658                 $this->app->argc = count($this->app->argv);
3659                 $result = api_friendica_notification('xml');
3660                 $this->assertXml($result, 'notes');
3661         }
3662
3663         /**
3664          * Test the api_friendica_notification_seen() function.
3665          * @return void
3666          */
3667         public function testApiFriendicaNotificationSeen()
3668         {
3669                 $this->markTestIncomplete();
3670         }
3671
3672         /**
3673          * Test the api_friendica_direct_messages_setseen() function.
3674          * @return void
3675          */
3676         public function testApiFriendicaDirectMessagesSetseen()
3677         {
3678                 $this->markTestIncomplete();
3679         }
3680
3681         /**
3682          * Test the api_friendica_direct_messages_search() function.
3683          * @return void
3684          */
3685         public function testApiFriendicaDirectMessagesSearch()
3686         {
3687                 $this->markTestIncomplete();
3688         }
3689
3690         /**
3691          * Test the api_friendica_profile_show() function.
3692          * @return void
3693          */
3694         public function testApiFriendicaProfileShow()
3695         {
3696                 $result = api_friendica_profile_show('json');
3697                 // We can't use assertSelfUser() here because the user object is missing some properties.
3698                 $this->assertEquals($this->selfUser['id'], $result['$result']['friendica_owner']['cid']);
3699                 $this->assertEquals('DFRN', $result['$result']['friendica_owner']['location']);
3700                 $this->assertEquals($this->selfUser['name'], $result['$result']['friendica_owner']['name']);
3701                 $this->assertEquals($this->selfUser['nick'], $result['$result']['friendica_owner']['screen_name']);
3702                 $this->assertEquals('dfrn', $result['$result']['friendica_owner']['network']);
3703                 $this->assertTrue($result['$result']['friendica_owner']['verified']);
3704                 $this->assertFalse($result['$result']['multi_profiles']);
3705         }
3706
3707         /**
3708          * Test the api_friendica_profile_show() function with a profile ID.
3709          * @return void
3710          */
3711         public function testApiFriendicaProfileShowWithProfileId()
3712         {
3713                 $this->markTestIncomplete('We need to add a dataset for this.');
3714         }
3715
3716         /**
3717          * Test the api_friendica_profile_show() function with a wrong profile ID.
3718          * @return void
3719          * @expectedException Friendica\Network\HTTPException\BadRequestException
3720          */
3721         public function testApiFriendicaProfileShowWithWrongProfileId()
3722         {
3723                 $_REQUEST['profile_id'] = 666;
3724                 api_friendica_profile_show('json');
3725         }
3726
3727         /**
3728          * Test the api_friendica_profile_show() function without an authenticated user.
3729          * @return void
3730          * @expectedException Friendica\Network\HTTPException\ForbiddenException
3731          */
3732         public function testApiFriendicaProfileShowWithoutAuthenticatedUser()
3733         {
3734                 $_SESSION['authenticated'] = false;
3735                 api_friendica_profile_show('json');
3736         }
3737
3738         /**
3739          * Test the api_saved_searches_list() function.
3740          * @return void
3741          */
3742         public function testApiSavedSearchesList()
3743         {
3744                 $result = api_saved_searches_list('json');
3745                 $this->assertEquals(1, $result['terms'][0]['id']);
3746                 $this->assertEquals(1, $result['terms'][0]['id_str']);
3747                 $this->assertEquals('Saved search', $result['terms'][0]['name']);
3748                 $this->assertEquals('Saved search', $result['terms'][0]['query']);
3749         }
3750 }