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