]> git.mxchange.org Git - friendica.git/blob - tests/legacy/ApiTest.php
Merge remote-tracking branch 'upstream/2021.12-rc' into api-fixes
[friendica.git] / tests / legacy / ApiTest.php
1 <?php
2 /**
3  * ApiTest class.
4  */
5
6 namespace Friendica\Test\legacy;
7
8 use Friendica\App;
9 use Friendica\App\Router;
10 use Friendica\Core\Config\Capability\IManageConfigValues;
11 use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
12 use Friendica\Core\Protocol;
13 use Friendica\DI;
14 use Friendica\Model\Post;
15 use Friendica\Module\Api\ApiResponse;
16 use Friendica\Module\Api\Twitter\Media\Upload;
17 use Friendica\Module\BaseApi;
18 use Friendica\Network\HTTPException;
19 use Friendica\Security\BasicAuth;
20 use Friendica\Test\FixtureTest;
21 use Friendica\Util\Arrays;
22 use Friendica\Util\DateTimeFormat;
23 use Friendica\Util\Temporal;
24 use Monolog\Handler\TestHandler;
25
26 require_once __DIR__ . '/../../include/api.php';
27
28 /**
29  * Tests for the API functions.
30  *
31  * Functions that use header() need to be tested in a separate process.
32  * @see https://phpunit.de/manual/5.7/en/appendixes.annotations.html#appendixes.annotations.runTestsInSeparateProcesses
33  *
34  * @backupGlobals enabled
35  */
36 class ApiTest extends FixtureTest
37 {
38         /**
39          * @var TestHandler Can handle log-outputs
40          */
41         protected $logOutput;
42
43         /** @var array */
44         protected $selfUser;
45         /** @var array */
46         protected $friendUser;
47         /** @var array */
48         protected $otherUser;
49
50         protected $wrongUserId;
51
52         /** @var App */
53         protected $app;
54
55         /** @var IManageConfigValues */
56         protected $config;
57
58         /**
59          * Create variables used by tests.
60          */
61         protected function setUp() : void
62         {
63                 global $API, $called_api;
64                 $API = [];
65                 $called_api = [];
66
67                 parent::setUp();
68
69                 /** @var IManageConfigValues $config */
70                 $this->config = $this->dice->create(IManageConfigValues::class);
71
72                 $this->config->set('system', 'url', 'http://localhost');
73                 $this->config->set('system', 'hostname', 'localhost');
74                 $this->config->set('system', 'worker_dont_fork', true);
75
76                 // Default config
77                 $this->config->set('config', 'hostname', 'localhost');
78                 $this->config->set('system', 'throttle_limit_day', 100);
79                 $this->config->set('system', 'throttle_limit_week', 100);
80                 $this->config->set('system', 'throttle_limit_month', 100);
81                 $this->config->set('system', 'theme', 'system_theme');
82
83
84                 /** @var App app */
85                 $this->app = DI::app();
86
87                 DI::args()->setArgc(1);
88
89                 // User data that the test database is populated with
90                 $this->selfUser   = [
91                         'id'   => 42,
92                         'name' => 'Self contact',
93                         'nick' => 'selfcontact',
94                         'nurl' => 'http://localhost/profile/selfcontact'
95                 ];
96                 $this->friendUser = [
97                         'id'   => 44,
98                         'name' => 'Friend contact',
99                         'nick' => 'friendcontact',
100                         'nurl' => 'http://localhost/profile/friendcontact'
101                 ];
102                 $this->otherUser  = [
103                         'id'   => 43,
104                         'name' => 'othercontact',
105                         'nick' => 'othercontact',
106                         'nurl' => 'http://localhost/profile/othercontact'
107                 ];
108
109                 // User ID that we know is not in the database
110                 $this->wrongUserId = 666;
111
112                 DI::session()->start();
113
114                 // Most API require login so we force the session
115                 $_SESSION = [
116                         'authenticated' => true,
117                         'uid'           => $this->selfUser['id']
118                 ];
119                 BasicAuth::setCurrentUserID($this->selfUser['id']);
120         }
121
122         /**
123          * Assert that an user array contains expected keys.
124          *
125          * @param array $user User array
126          *
127          * @return void
128          */
129         private function assertSelfUser(array $user)
130         {
131                 self::assertEquals($this->selfUser['id'], $user['uid']);
132                 self::assertEquals($this->selfUser['id'], $user['cid']);
133                 self::assertEquals(1, $user['self']);
134                 self::assertEquals('DFRN', $user['location']);
135                 self::assertEquals($this->selfUser['name'], $user['name']);
136                 self::assertEquals($this->selfUser['nick'], $user['screen_name']);
137                 self::assertEquals('dfrn', $user['network']);
138                 self::assertTrue($user['verified']);
139         }
140
141         /**
142          * Assert that an user array contains expected keys.
143          *
144          * @param array $user User array
145          *
146          * @return void
147          */
148         private function assertOtherUser(array $user = [])
149         {
150                 self::assertEquals($this->otherUser['id'], $user['id']);
151                 self::assertEquals($this->otherUser['id'], $user['id_str']);
152                 self::assertEquals($this->otherUser['name'], $user['name']);
153                 self::assertEquals($this->otherUser['nick'], $user['screen_name']);
154                 self::assertFalse($user['verified']);
155         }
156
157         /**
158          * Assert that a status array contains expected keys.
159          *
160          * @param array $status Status array
161          *
162          * @return void
163          */
164         private function assertStatus(array $status = [])
165         {
166                 self::assertIsString($status['text'] ?? '');
167                 self::assertIsInt($status['id'] ?? '');
168                 // We could probably do more checks here.
169         }
170
171         /**
172          * Assert that a list array contains expected keys.
173          *
174          * @param array $list List array
175          *
176          * @return void
177          */
178         private function assertList(array $list = [])
179         {
180                 self::assertIsString($list['name']);
181                 self::assertIsInt($list['id']);
182                 self::assertIsString('string', $list['id_str']);
183                 self::assertContains($list['mode'], ['public', 'private']);
184                 // We could probably do more checks here.
185         }
186
187         /**
188          * Assert that the string is XML and contain the root element.
189          *
190          * @param string $result       XML string
191          * @param string $root_element Root element name
192          *
193          * @return void
194          */
195         private function assertXml($result = '', $root_element = '')
196         {
197                 self::assertStringStartsWith('<?xml version="1.0"?>', $result);
198                 self::assertStringContainsString('<' . $root_element, $result);
199                 // We could probably do more checks here.
200         }
201
202         /**
203          * Get the path to a temporary empty PNG image.
204          *
205          * @return string Path
206          */
207         private function getTempImage()
208         {
209                 $tmpFile = tempnam(sys_get_temp_dir(), 'tmp_file');
210                 file_put_contents(
211                         $tmpFile,
212                         base64_decode(
213                         // Empty 1x1 px PNG image
214                                 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg=='
215                         )
216                 );
217
218                 return $tmpFile;
219         }
220
221         /**
222          * Test the api_user() function.
223          *
224          * @return void
225          */
226         public function testApiUser()
227         {
228                 self::assertEquals($this->selfUser['id'], BaseApi::getCurrentUserID());
229         }
230
231         /**
232          * Test the api_user() function with an unallowed user.
233          *
234          * @return void
235          */
236         public function testApiUserWithUnallowedUser()
237         {
238                 // self::assertEquals(false, api_user());
239         }
240
241         /**
242          * Test the api_source() function.
243          *
244          * @return void
245          */
246         public function testApiSource()
247         {
248                 self::assertEquals('api', BasicAuth::getCurrentApplicationToken()['name']);
249         }
250
251         /**
252          * Test the api_source() function with a Twidere user agent.
253          *
254          * @return void
255          */
256         public function testApiSourceWithTwidere()
257         {
258                 $_SERVER['HTTP_USER_AGENT'] = 'Twidere';
259                 self::assertEquals('Twidere', BasicAuth::getCurrentApplicationToken()['name']);
260         }
261
262         /**
263          * Test the api_source() function with a GET parameter.
264          *
265          * @return void
266          */
267         public function testApiSourceWithGet()
268         {
269                 $_REQUEST['source'] = 'source_name';
270                 self::assertEquals('source_name', BasicAuth::getCurrentApplicationToken()['name']);
271         }
272
273         /**
274          * Test the api_date() function.
275          *
276          * @return void
277          */
278         public function testApiDate()
279         {
280                 self::assertEquals('Wed Oct 10 00:00:00 +0000 1990', DateTimeFormat::utc('1990-10-10', DateTimeFormat::API));
281         }
282
283         /**
284          * Test the api_register_func() function.
285          *
286          * @return void
287          */
288         public function testApiRegisterFunc()
289         {
290                 global $API;
291                 self::assertNull(
292                         api_register_func(
293                                 'api_path',
294                                 function () {
295                                 },
296                                 true,
297                                 'method'
298                         )
299                 );
300                 self::assertTrue(is_callable($API['api_path']['func']));
301         }
302
303         /**
304          * Test the BasicAuth::getCurrentUserID() function without any login.
305          *
306          * @runInSeparateProcess
307          * @preserveGlobalState disabled
308          * @preserveGlobalState disabled
309          */
310         public function testApiLoginWithoutLogin()
311         {
312                 BasicAuth::setCurrentUserID();
313                 $this->expectException(\Friendica\Network\HTTPException\UnauthorizedException::class);
314                 BasicAuth::getCurrentUserID(true);
315         }
316
317         /**
318          * Test the BasicAuth::getCurrentUserID() function with a bad login.
319          *
320          * @runInSeparateProcess
321          * @preserveGlobalState disabled
322          * @preserveGlobalState disabled
323          */
324         public function testApiLoginWithBadLogin()
325         {
326                 BasicAuth::setCurrentUserID();
327                 $this->expectException(\Friendica\Network\HTTPException\UnauthorizedException::class);
328                 $_SERVER['PHP_AUTH_USER'] = 'user@server';
329                 BasicAuth::getCurrentUserID(true);
330         }
331
332         /**
333          * Test the BasicAuth::getCurrentUserID() function with oAuth.
334          *
335          * @return void
336          */
337         public function testApiLoginWithOauth()
338         {
339                 $this->markTestIncomplete('Can we test this easily?');
340         }
341
342         /**
343          * Test the BasicAuth::getCurrentUserID() function with authentication provided by an addon.
344          *
345          * @return void
346          */
347         public function testApiLoginWithAddonAuth()
348         {
349                 $this->markTestIncomplete('Can we test this easily?');
350         }
351
352         /**
353          * Test the BasicAuth::getCurrentUserID() function with a correct login.
354          *
355          * @runInSeparateProcess
356          * @preserveGlobalState disabled
357          * @doesNotPerformAssertions
358          */
359         public function testApiLoginWithCorrectLogin()
360         {
361                 BasicAuth::setCurrentUserID();
362                 $_SERVER['PHP_AUTH_USER'] = 'Test user';
363                 $_SERVER['PHP_AUTH_PW']   = 'password';
364                 BasicAuth::getCurrentUserID(true);
365         }
366
367         /**
368          * Test the BasicAuth::getCurrentUserID() function with a remote user.
369          *
370          * @runInSeparateProcess
371          * @preserveGlobalState disabled
372          */
373         public function testApiLoginWithRemoteUser()
374         {
375                 BasicAuth::setCurrentUserID();
376                 $this->expectException(\Friendica\Network\HTTPException\UnauthorizedException::class);
377                 $_SERVER['REDIRECT_REMOTE_USER'] = '123456dXNlcjpwYXNzd29yZA==';
378                 BasicAuth::getCurrentUserID(true);
379         }
380
381         /**
382          * Test the api_call() function.
383          *
384          * @runInSeparateProcess
385          * @preserveGlobalState disabled
386          */
387         public function testApiCall()
388         {
389                 global $API;
390                 $API['api_path']           = [
391                         'method' => 'method',
392                         'func'   => function () {
393                                 return ['data' => ['some_data']];
394                         }
395                 ];
396                 $_SERVER['REQUEST_METHOD'] = 'method';
397                 $_SERVER['QUERY_STRING'] = 'pagename=api_path';
398                 $_GET['callback']          = 'callback_name';
399
400                 self::assertEquals(
401                         'callback_name(["some_data"])',
402                         api_call('api_path', 'json')
403                 );
404         }
405
406         /**
407          * Test the api_call() function with the profiled enabled.
408          *
409          * @runInSeparateProcess
410          * @preserveGlobalState disabled
411          */
412         public function testApiCallWithProfiler()
413         {
414                 global $API;
415                 $API['api_path']           = [
416                         'method' => 'method',
417                         'func'   => function () {
418                                 return ['data' => ['some_data']];
419                         }
420                 ];
421
422                 $_SERVER['REQUEST_METHOD'] = 'method';
423                 $_SERVER['QUERY_STRING'] = 'pagename=api_path';
424
425                 $this->config->set('system', 'profiler', true);
426                 $this->config->set('rendertime', 'callstack', true);
427                 $this->app->callstack = [
428                         'database'       => ['some_function' => 200],
429                         'database_write' => ['some_function' => 200],
430                         'cache'          => ['some_function' => 200],
431                         'cache_write'    => ['some_function' => 200],
432                         'network'        => ['some_function' => 200]
433                 ];
434
435                 self::assertEquals(
436                         '["some_data"]',
437                         api_call('api_path', 'json')
438                 );
439         }
440
441         /**
442          * Test the api_call() function with a JSON result.
443          *
444          * @runInSeparateProcess
445          * @preserveGlobalState disabled
446          */
447         public function testApiCallWithJson()
448         {
449                 global $API;
450                 $API['api_path']           = [
451                         'method' => 'method',
452                         'func'   => function () {
453                                 return ['data' => ['some_data']];
454                         }
455                 ];
456                 $_SERVER['REQUEST_METHOD'] = 'method';
457                 $_SERVER['QUERY_STRING'] = 'pagename=api_path.json';
458
459                 self::assertEquals(
460                         '["some_data"]',
461                         api_call('api_path.json', 'json')
462                 );
463         }
464
465         /**
466          * Test the api_call() function with an XML result.
467          *
468          * @runInSeparateProcess
469          * @preserveGlobalState disabled
470          */
471         public function testApiCallWithXml()
472         {
473                 global $API;
474                 $API['api_path']           = [
475                         'method' => 'method',
476                         'func'   => function () {
477                                 return 'some_data';
478                         }
479                 ];
480                 $_SERVER['REQUEST_METHOD'] = 'method';
481                 $_SERVER['QUERY_STRING'] = 'pagename=api_path.xml';
482
483                 $args = DI::args()->determine($_SERVER, $_GET);
484
485                 self::assertEquals(
486                         'some_data',
487                         api_call('api_path.xml', 'xml')
488                 );
489         }
490
491         /**
492          * Test the api_call() function with an RSS result.
493          *
494          * @runInSeparateProcess
495          * @preserveGlobalState disabled
496          */
497         public function testApiCallWithRss()
498         {
499                 global $API;
500                 $API['api_path']           = [
501                         'method' => 'method',
502                         'func'   => function () {
503                                 return 'some_data';
504                         }
505                 ];
506                 $_SERVER['REQUEST_METHOD'] = 'method';
507                 $_SERVER['QUERY_STRING'] = 'pagename=api_path.rss';
508
509                 self::assertEquals(
510                         '<?xml version="1.0" encoding="UTF-8"?>' . "\n" .
511                         'some_data',
512                         api_call('api_path.rss', 'rss')
513                 );
514         }
515
516         /**
517          * Test the api_call() function with an Atom result.
518          *
519          * @runInSeparateProcess
520          * @preserveGlobalState disabled
521          */
522         public function testApiCallWithAtom()
523         {
524                 global $API;
525                 $API['api_path']           = [
526                         'method' => 'method',
527                         'func'   => function () {
528                                 return 'some_data';
529                         }
530                 ];
531                 $_SERVER['REQUEST_METHOD'] = 'method';
532                 $_SERVER['QUERY_STRING'] = 'pagename=api_path.atom';
533
534                 self::assertEquals(
535                         '<?xml version="1.0" encoding="UTF-8"?>' . "\n" .
536                         'some_data',
537                         api_call('api_path.atom', 'atom')
538                 );
539         }
540
541         /**
542          * Test the api_rss_extra() function.
543          *
544          * @return void
545          */
546         public function testApiRssExtra()
547         {
548                 /*
549                 $user_info = ['url' => 'user_url', 'lang' => 'en'];
550                 $result    = api_rss_extra([], $user_info);
551                 self::assertEquals($user_info, $result['$user']);
552                 self::assertEquals($user_info['url'], $result['$rss']['alternate']);
553                 self::assertArrayHasKey('self', $result['$rss']);
554                 self::assertArrayHasKey('base', $result['$rss']);
555                 self::assertArrayHasKey('updated', $result['$rss']);
556                 self::assertArrayHasKey('atom_updated', $result['$rss']);
557                 self::assertArrayHasKey('language', $result['$rss']);
558                 self::assertArrayHasKey('logo', $result['$rss']);
559                 */
560         }
561
562         /**
563          * Test the api_rss_extra() function without any user info.
564          *
565          * @return void
566          */
567         public function testApiRssExtraWithoutUserInfo()
568         {
569                 /*
570                 $result = api_rss_extra([], null);
571                 self::assertIsArray($result['$user']);
572                 self::assertArrayHasKey('alternate', $result['$rss']);
573                 self::assertArrayHasKey('self', $result['$rss']);
574                 self::assertArrayHasKey('base', $result['$rss']);
575                 self::assertArrayHasKey('updated', $result['$rss']);
576                 self::assertArrayHasKey('atom_updated', $result['$rss']);
577                 self::assertArrayHasKey('language', $result['$rss']);
578                 self::assertArrayHasKey('logo', $result['$rss']);
579                 */
580         }
581
582         /**
583          * Test the api_get_user() function.
584          *
585          * @return void
586          */
587         public function testApiGetUser()
588         {
589                 // $user = api_get_user();
590                 // self::assertSelfUser($user);
591                 // self::assertEquals('708fa0', $user['profile_sidebar_fill_color']);
592                 // self::assertEquals('6fdbe8', $user['profile_link_color']);
593                 // self::assertEquals('ededed', $user['profile_background_color']);
594         }
595
596         /**
597          * Test the api_get_user() function with a Frio schema.
598          *
599          * @return void
600          */
601         public function testApiGetUserWithFrioSchema()
602         {
603                 // $pConfig = $this->dice->create(IManagePersonalConfigValues::class);
604                 // $pConfig->set($this->selfUser['id'], 'frio', 'schema', 'red');
605                 // $user = api_get_user();
606                 // self::assertSelfUser($user);
607                 // self::assertEquals('708fa0', $user['profile_sidebar_fill_color']);
608                 // self::assertEquals('6fdbe8', $user['profile_link_color']);
609                 // self::assertEquals('ededed', $user['profile_background_color']);
610         }
611
612         /**
613          * Test the api_get_user() function with an empty Frio schema.
614          *
615          * @return void
616          */
617         public function testApiGetUserWithEmptyFrioSchema()
618         {
619                 // $pConfig = $this->dice->create(IManagePersonalConfigValues::class);
620                 // $pConfig->set($this->selfUser['id'], 'frio', 'schema', '---');
621                 // $user = api_get_user();
622                 // self::assertSelfUser($user);
623                 // self::assertEquals('708fa0', $user['profile_sidebar_fill_color']);
624                 // self::assertEquals('6fdbe8', $user['profile_link_color']);
625                 // self::assertEquals('ededed', $user['profile_background_color']);
626         }
627
628         /**
629          * Test the api_get_user() function with a custom Frio schema.
630          *
631          * @return void
632          */
633         public function testApiGetUserWithCustomFrioSchema()
634         {
635                 // $pConfig = $this->dice->create(IManagePersonalConfigValues::class);
636                 // $pConfig->set($this->selfUser['id'], 'frio', 'schema', '---');
637                 // $pConfig->set($this->selfUser['id'], 'frio', 'nav_bg', '#123456');
638                 // $pConfig->set($this->selfUser['id'], 'frio', 'link_color', '#123456');
639                 // $pConfig->set($this->selfUser['id'], 'frio', 'background_color', '#123456');
640                 // $user = api_get_user();
641                 // self::assertSelfUser($user);
642                 // self::assertEquals('123456', $user['profile_sidebar_fill_color']);
643                 // self::assertEquals('123456', $user['profile_link_color']);
644                 // self::assertEquals('123456', $user['profile_background_color']);
645         }
646
647         /**
648          * Test the api_get_user() function with an user that is not allowed to use the API.
649          *
650          * @runInSeparateProcess
651          * @preserveGlobalState disabled
652          */
653         public function testApiGetUserWithoutApiUser()
654         {
655                 // api_get_user() with empty parameters is not used anymore
656                 /*
657                 $_SERVER['PHP_AUTH_USER'] = 'Test user';
658                 $_SERVER['PHP_AUTH_PW']   = 'password';
659                 BasicAuth::setCurrentUserID();
660                 self::assertFalse(api_get_user());
661                 */
662         }
663
664         /**
665          * Test the api_get_user() function with an user ID in a GET parameter.
666          *
667          * @return void
668          */
669         public function testApiGetUserWithGetId()
670         {
671                 // self::assertOtherUser(api_get_user());
672         }
673
674         /**
675          * Test the api_get_user() function with a wrong user ID in a GET parameter.
676          *
677          * @return void
678          */
679         public function testApiGetUserWithWrongGetId()
680         {
681                 // $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
682                 // self::assertOtherUser(api_get_user());
683         }
684
685         /**
686          * Test the api_get_user() function with an user name in a GET parameter.
687          *
688          * @return void
689          */
690         public function testApiGetUserWithGetName()
691         {
692                 // self::assertSelfUser(api_get_user());
693         }
694
695         /**
696          * Test the api_get_user() function with a profile URL in a GET parameter.
697          *
698          * @return void
699          */
700         public function testApiGetUserWithGetUrl()
701         {
702                 // self::assertSelfUser(api_get_user());
703         }
704
705         /**
706          * Test the api_get_user() function with an user ID in the API path.
707          *
708          * @return void
709          */
710         public function testApiGetUserWithNumericCalledApi()
711         {
712                 // global $called_api;
713                 // $called_api         = ['api_path'];
714                 // DI::args()->setArgv(['', $this->otherUser['id'] . '.json']);
715                 // self::assertOtherUser(api_get_user());
716         }
717
718         /**
719          * Test the api_get_user() function with the $called_api global variable.
720          *
721          * @return void
722          */
723         public function testApiGetUserWithCalledApi()
724         {
725                 // global $called_api;
726                 // $called_api = ['api', 'api_path'];
727                 // self::assertSelfUser(api_get_user());
728         }
729
730         /**
731          * Test the Arrays::walkRecursive() function.
732          *
733          * @return void
734          */
735         public function testApiWalkRecursive()
736         {
737                 $array = ['item1'];
738                 self::assertEquals(
739                         $array,
740                         Arrays::walkRecursive(
741                                 $array,
742                                 function () {
743                                         // Should we test this with a callback that actually does something?
744                                         return true;
745                                 }
746                         )
747                 );
748         }
749
750         /**
751          * Test the Arrays::walkRecursive() function with an array.
752          *
753          * @return void
754          */
755         public function testApiWalkRecursiveWithArray()
756         {
757                 $array = [['item1'], ['item2']];
758                 self::assertEquals(
759                         $array,
760                         Arrays::walkRecursive(
761                                 $array,
762                                 function () {
763                                         // Should we test this with a callback that actually does something?
764                                         return true;
765                                 }
766                         )
767                 );
768         }
769
770         /**
771          * Test the BaseApi::reformatXML() function.
772          *
773          * @return void
774          */
775         public function testApiReformatXml()
776         {
777                 $item = true;
778                 $key  = '';
779                 self::assertTrue(ApiResponse::reformatXML($item, $key));
780                 self::assertEquals('true', $item);
781         }
782
783         /**
784          * Test the BaseApi::reformatXML() function with a statusnet_api key.
785          *
786          * @return void
787          */
788         public function testApiReformatXmlWithStatusnetKey()
789         {
790                 $item = '';
791                 $key  = 'statusnet_api';
792                 self::assertTrue(ApiResponse::reformatXML($item, $key));
793                 self::assertEquals('statusnet:api', $key);
794         }
795
796         /**
797          * Test the BaseApi::reformatXML() function with a friendica_api key.
798          *
799          * @return void
800          */
801         public function testApiReformatXmlWithFriendicaKey()
802         {
803                 $item = '';
804                 $key  = 'friendica_api';
805                 self::assertTrue(ApiResponse::reformatXML($item, $key));
806                 self::assertEquals('friendica:api', $key);
807         }
808
809         /**
810          * Test the BaseApi::createXML() function.
811          *
812          * @return void
813          */
814         public function testApiCreateXml()
815         {
816                 self::assertEquals(
817                         '<?xml version="1.0"?>' . "\n" .
818                         '<root_element xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" ' .
819                         'xmlns:friendica="http://friendi.ca/schema/api/1/" ' .
820                         'xmlns:georss="http://www.georss.org/georss">' . "\n" .
821                         '  <data>some_data</data>' . "\n" .
822                         '</root_element>' . "\n",
823                         DI::apiResponse()->createXML(['data' => ['some_data']], 'root_element')
824                 );
825         }
826
827         /**
828          * Test the BaseApi::createXML() function without any XML namespace.
829          *
830          * @return void
831          */
832         public function testApiCreateXmlWithoutNamespaces()
833         {
834                 self::assertEquals(
835                         '<?xml version="1.0"?>' . "\n" .
836                         '<ok>' . "\n" .
837                         '  <data>some_data</data>' . "\n" .
838                         '</ok>' . "\n",
839                         DI::apiResponse()->createXML(['data' => ['some_data']], 'ok')
840                 );
841         }
842
843         /**
844          * Test the BaseApi::formatData() function.
845          *
846          * @return void
847          */
848         public function testApiFormatData()
849         {
850                 $data = ['some_data'];
851                 self::assertEquals($data, DI::apiResponse()->formatData('root_element', 'json', $data));
852         }
853
854         /**
855          * Test the BaseApi::formatData() function with an XML result.
856          *
857          * @return void
858          */
859         public function testApiFormatDataWithXml()
860         {
861                 self::assertEquals(
862                         '<?xml version="1.0"?>' . "\n" .
863                         '<root_element xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" ' .
864                         'xmlns:friendica="http://friendi.ca/schema/api/1/" ' .
865                         'xmlns:georss="http://www.georss.org/georss">' . "\n" .
866                         '  <data>some_data</data>' . "\n" .
867                         '</root_element>' . "\n",
868                         DI::apiResponse()->formatData('root_element', 'xml', ['data' => ['some_data']])
869                 );
870         }
871
872         /**
873          * Test the api_statuses_mediap() function.
874          *
875          * @return void
876          */
877         public function testApiStatusesMediap()
878         {
879                 /*
880                 DI::args()->setArgc(2);
881
882                 $_FILES         = [
883                         'media' => [
884                                 'id'       => 666,
885                                 'size'     => 666,
886                                 'width'    => 666,
887                                 'height'   => 666,
888                                 'tmp_name' => $this->getTempImage(),
889                                 'name'     => 'spacer.png',
890                                 'type'     => 'image/png'
891                         ]
892                 ];
893                 $_GET['status'] = '<b>Status content</b>';
894
895                 $result = api_statuses_mediap('json');
896                 self::assertStatus($result['status']);
897                 */
898         }
899
900         /**
901          * Test the api_statuses_mediap() function without an authenticated user.
902          *
903          * @return void
904          */
905         public function testApiStatusesMediapWithoutAuthenticatedUser()
906         {
907                 // $this->expectException(\Friendica\Network\HTTPException\UnauthorizedException::class);
908                 // BasicAuth::setCurrentUserID();
909                 // $_SESSION['authenticated'] = false;
910                 // api_statuses_mediap('json');
911         }
912
913         /**
914          * Test the api_statuses_update() function.
915          *
916          * @return void
917          */
918         public function testApiStatusesUpdate()
919         {
920                 /*
921                 $_REQUEST['status']                = 'Status content #friendica';
922                 $_REQUEST['in_reply_to_status_id'] = -1;
923                 $_REQUEST['lat']                   = 48;
924                 $_REQUEST['long']                  = 7;
925                 $_FILES                            = [
926                         'media' => [
927                                 'id'       => 666,
928                                 'size'     => 666,
929                                 'width'    => 666,
930                                 'height'   => 666,
931                                 'tmp_name' => $this->getTempImage(),
932                                 'name'     => 'spacer.png',
933                                 'type'     => 'image/png'
934                         ]
935                 ];
936
937                 $result = api_statuses_update('json');
938                 self::assertStatus($result['status']);
939                 */
940         }
941
942         /**
943          * Test the api_statuses_update() function with an HTML status.
944          *
945          * @return void
946          */
947         public function testApiStatusesUpdateWithHtml()
948         {
949                 /*
950                 $_REQUEST['htmlstatus'] = '<b>Status content</b>';
951
952                 $result = api_statuses_update('json');
953                 self::assertStatus($result['status']);
954                 */
955         }
956
957         /**
958          * Test the api_statuses_update() function without an authenticated user.
959          *
960          * @return void
961          */
962         public function testApiStatusesUpdateWithoutAuthenticatedUser()
963         {
964                 /*
965                 $this->expectException(\Friendica\Network\HTTPException\UnauthorizedException::class);
966                 BasicAuth::setCurrentUserID();
967                 $_SESSION['authenticated'] = false;
968                 api_statuses_update('json');
969                 */
970         }
971
972         /**
973          * Test the api_statuses_update() function with a parent status.
974          *
975          * @return void
976          */
977         public function testApiStatusesUpdateWithParent()
978         {
979                 $this->markTestIncomplete('This triggers an exit() somewhere and kills PHPUnit.');
980         }
981
982         /**
983          * Test the api_statuses_update() function with a media_ids parameter.
984          *
985          * @return void
986          */
987         public function testApiStatusesUpdateWithMediaIds()
988         {
989                 $this->markTestIncomplete();
990         }
991
992         /**
993          * Test the api_statuses_update() function with the throttle limit reached.
994          *
995          * @return void
996          */
997         public function testApiStatusesUpdateWithDayThrottleReached()
998         {
999                 $this->markTestIncomplete();
1000         }
1001
1002         /**
1003          * Test the \Friendica\Module\Api\Twitter\Media\Upload module.
1004          * @runInSeparateProcess
1005          * @preserveGlobalState disabled
1006          */
1007         public function testApiMediaUpload()
1008         {
1009                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
1010                 (new Upload(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), ['REQUEST_METHOD' => Router::POST]))->run();
1011         }
1012
1013         /**
1014          * Test the \Friendica\Module\Api\Twitter\Media\Upload module without an authenticated user.
1015          *
1016          * @return void
1017          */
1018         public function testApiMediaUploadWithoutAuthenticatedUser()
1019         {
1020                 $this->expectException(\Friendica\Network\HTTPException\UnauthorizedException::class);
1021                 BasicAuth::setCurrentUserID();
1022                 $_SESSION['authenticated'] = false;
1023                 (new Upload(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), ['REQUEST_METHOD' => Router::POST]))->run();
1024         }
1025
1026         /**
1027          * Test the \Friendica\Module\Api\Twitter\Media\Upload module with an invalid uploaded media.
1028          *
1029          * @return void
1030          */
1031         public function testApiMediaUploadWithMedia()
1032         {
1033                 $this->expectException(\Friendica\Network\HTTPException\InternalServerErrorException::class);
1034                 $_FILES = [
1035                         'media' => [
1036                                 'id'       => 666,
1037                                 'tmp_name' => 'tmp_name'
1038                         ]
1039                 ];
1040                 (new Upload(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), ['REQUEST_METHOD' => Router::POST]))->run();
1041         }
1042
1043         /**
1044          * Test the \Friendica\Module\Api\Twitter\Media\Upload module with an valid uploaded media.
1045          *
1046          * @return void
1047          */
1048         public function testApiMediaUploadWithValidMedia()
1049         {
1050                 $_FILES    = [
1051                         'media' => [
1052                                 'id'       => 666,
1053                                 'size'     => 666,
1054                                 'width'    => 666,
1055                                 'height'   => 666,
1056                                 'tmp_name' => $this->getTempImage(),
1057                                 'name'     => 'spacer.png',
1058                                 'type'     => 'image/png'
1059                         ]
1060                 ];
1061
1062                 $response = (new Upload(DI::app(), DI::l10n(), DI::baseUrl(), DI::args(), DI::logger(), DI::profiler(), DI::apiResponse(), ['REQUEST_METHOD' => Router::POST]))->run();
1063                 $media = json_decode($response->getBody(), true);
1064
1065                 self::assertEquals('image/png', $media['image']['image_type']);
1066                 self::assertEquals(1, $media['image']['w']);
1067                 self::assertEquals(1, $media['image']['h']);
1068                 self::assertNotEmpty($media['image']['friendica_preview_url']);
1069         }
1070
1071         /**
1072          * Test the api_statuses_repeat() function.
1073          *
1074          * @return void
1075          */
1076         public function testApiStatusesRepeat()
1077         {
1078                 // $this->expectException(\Friendica\Network\HTTPException\ForbiddenException::class);
1079                 // api_statuses_repeat('json');
1080         }
1081
1082         /**
1083          * Test the api_statuses_repeat() function without an authenticated user.
1084          *
1085          * @return void
1086          */
1087         public function testApiStatusesRepeatWithoutAuthenticatedUser()
1088         {
1089                 // $this->expectException(\Friendica\Network\HTTPException\UnauthorizedException::class);
1090                 // BasicAuth::setCurrentUserID();
1091                 // $_SESSION['authenticated'] = false;
1092                 // api_statuses_repeat('json');
1093         }
1094
1095         /**
1096          * Test the api_statuses_repeat() function with an ID.
1097          *
1098          * @return void
1099          */
1100         public function testApiStatusesRepeatWithId()
1101         {
1102                 // DI::args()->setArgv(['', '', '', 1]);
1103                 // $result = api_statuses_repeat('json');
1104                 // self::assertStatus($result['status']);
1105
1106                 // Also test with a shared status
1107                 // DI::args()->setArgv(['', '', '', 5]);
1108                 // $result = api_statuses_repeat('json');
1109                 // self::assertStatus($result['status']);
1110         }
1111
1112         /**
1113          * Test the api_favorites_create_destroy() function.
1114          *
1115          * @return void
1116          */
1117         public function testApiFavoritesCreateDestroy()
1118         {
1119                 // $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
1120                 // DI::args()->setArgv(['api', '1.1', 'favorites', 'create']);
1121                 // api_favorites_create_destroy('json');
1122         }
1123
1124         /**
1125          * Test the api_favorites_create_destroy() function with an invalid ID.
1126          *
1127          * @return void
1128          */
1129         public function testApiFavoritesCreateDestroyWithInvalidId()
1130         {
1131                 // $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
1132                 // DI::args()->setArgv(['api', '1.1', 'favorites', 'create', '12.json']);
1133                 // api_favorites_create_destroy('json');
1134         }
1135
1136         /**
1137          * Test the api_favorites_create_destroy() function with an invalid action.
1138          *
1139          * @return void
1140          */
1141         public function testApiFavoritesCreateDestroyWithInvalidAction()
1142         {
1143                 // $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
1144                 // DI::args()->setArgv(['api', '1.1', 'favorites', 'change.json']);
1145                 // $_REQUEST['id'] = 1;
1146                 // api_favorites_create_destroy('json');
1147         }
1148
1149         /**
1150          * Test the api_favorites_create_destroy() function with the create action.
1151          *
1152          * @return void
1153          */
1154         public function testApiFavoritesCreateDestroyWithCreateAction()
1155         {
1156                 // DI::args()->setArgv(['api', '1.1', 'favorites', 'create.json']);
1157                 // $_REQUEST['id'] = 3;
1158                 // $result         = api_favorites_create_destroy('json');
1159                 // self::assertStatus($result['status']);
1160         }
1161
1162         /**
1163          * Test the api_favorites_create_destroy() function with the create action and an RSS result.
1164          *
1165          * @return void
1166          */
1167         public function testApiFavoritesCreateDestroyWithCreateActionAndRss()
1168         {
1169                 // DI::args()->setArgv(['api', '1.1', 'favorites', 'create.rss']);
1170                 // $_REQUEST['id'] = 3;
1171                 // $result         = api_favorites_create_destroy('rss');
1172                 // self::assertXml($result, 'status');
1173         }
1174
1175         /**
1176          * Test the api_favorites_create_destroy() function with the destroy action.
1177          *
1178          * @return void
1179          */
1180         public function testApiFavoritesCreateDestroyWithDestroyAction()
1181         {
1182                 // DI::args()->setArgv(['api', '1.1', 'favorites', 'destroy.json']);
1183                 // $_REQUEST['id'] = 3;
1184                 // $result         = api_favorites_create_destroy('json');
1185                 // self::assertStatus($result['status']);
1186         }
1187
1188         /**
1189          * Test the api_favorites_create_destroy() function without an authenticated user.
1190          *
1191          * @return void
1192          */
1193         public function testApiFavoritesCreateDestroyWithoutAuthenticatedUser()
1194         {
1195                 /*
1196                 $this->expectException(\Friendica\Network\HTTPException\UnauthorizedException::class);
1197                 DI::args()->setArgv(['api', '1.1', 'favorites', 'create.json']);
1198                 BasicAuth::setCurrentUserID();
1199                 $_SESSION['authenticated'] = false;
1200                 api_favorites_create_destroy('json');
1201                 */
1202         }
1203
1204
1205
1206         /**
1207          * Test the api_format_messages() function.
1208          *
1209          * @return void
1210          */
1211         public function testApiFormatMessages()
1212         {
1213                 $result = api_format_messages(
1214                         ['id' => 1, 'uri-id' => 1, 'title' => 'item_title', 'body' => '[b]item_body[/b]'],
1215                         ['id' => 2, 'uri-id' => 2, 'screen_name' => 'recipient_name'],
1216                         ['id' => 3, 'uri-id' => 2, 'screen_name' => 'sender_name']
1217                 );
1218                 self::assertEquals('item_title' . "\n" . 'item_body', $result['text']);
1219                 self::assertEquals(1, $result['id']);
1220                 self::assertEquals(2, $result['recipient_id']);
1221                 self::assertEquals(3, $result['sender_id']);
1222                 self::assertEquals('recipient_name', $result['recipient_screen_name']);
1223                 self::assertEquals('sender_name', $result['sender_screen_name']);
1224         }
1225
1226         /**
1227          * Test the api_format_messages() function with HTML.
1228          *
1229          * @return void
1230          */
1231         public function testApiFormatMessagesWithHtmlText()
1232         {
1233                 $_GET['getText'] = 'html';
1234                 $result          = api_format_messages(
1235                         ['id' => 1, 'uri-id' => 1, 'title' => 'item_title', 'body' => '[b]item_body[/b]'],
1236                         ['id' => 2, 'uri-id' => 2, 'screen_name' => 'recipient_name'],
1237                         ['id' => 3, 'uri-id' => 3, 'screen_name' => 'sender_name']
1238                 );
1239                 self::assertEquals('item_title', $result['title']);
1240                 self::assertEquals('<strong>item_body</strong>', $result['text']);
1241         }
1242
1243         /**
1244          * Test the api_format_messages() function with plain text.
1245          *
1246          * @return void
1247          */
1248         public function testApiFormatMessagesWithPlainText()
1249         {
1250                 $_GET['getText'] = 'plain';
1251                 $result          = api_format_messages(
1252                         ['id' => 1, 'uri-id' => 1, 'title' => 'item_title', 'body' => '[b]item_body[/b]'],
1253                         ['id' => 2, 'uri-id' => 2, 'screen_name' => 'recipient_name'],
1254                         ['id' => 3, 'uri-id' => 3, 'screen_name' => 'sender_name']
1255                 );
1256                 self::assertEquals('item_title', $result['title']);
1257                 self::assertEquals('item_body', $result['text']);
1258         }
1259
1260         /**
1261          * Test the api_format_messages() function with the getUserObjects GET parameter set to false.
1262          *
1263          * @return void
1264          */
1265         public function testApiFormatMessagesWithoutUserObjects()
1266         {
1267                 $_GET['getUserObjects'] = 'false';
1268                 $result                 = api_format_messages(
1269                         ['id' => 1, 'uri-id' => 1, 'title' => 'item_title', 'body' => '[b]item_body[/b]'],
1270                         ['id' => 2, 'uri-id' => 2, 'screen_name' => 'recipient_name'],
1271                         ['id' => 3, 'uri-id' => 3, 'screen_name' => 'sender_name']
1272                 );
1273                 self::assertTrue(!isset($result['sender']));
1274                 self::assertTrue(!isset($result['recipient']));
1275         }
1276
1277         /**
1278          * Test the api_convert_item() function.
1279          *
1280          * @return void
1281          */
1282         public function testApiConvertItem()
1283         {
1284                 /*
1285                 $result = api_convert_item(
1286                         [
1287                                 'network' => 'feed',
1288                                 'title'   => 'item_title',
1289                                 'uri-id'  => 1,
1290                                 // We need a long string to test that it is correctly cut
1291                                 'body'    => 'perspiciatis impedit voluptatem quis molestiae ea qui ' .
1292                                                          'reiciendis dolorum aut ducimus sunt consequatur inventore dolor ' .
1293                                                          'officiis pariatur doloremque nemo culpa aut quidem qui dolore ' .
1294                                                          'laudantium atque commodi alias voluptatem non possimus aperiam ' .
1295                                                          'ipsum rerum consequuntur aut amet fugit quia aliquid praesentium ' .
1296                                                          'repellendus quibusdam et et inventore mollitia rerum sit autem ' .
1297                                                          'pariatur maiores ipsum accusantium perferendis vel sit possimus ' .
1298                                                          'veritatis nihil distinctio qui eum repellat officia illum quos ' .
1299                                                          'impedit quam iste esse unde qui suscipit aut facilis ut inventore ' .
1300                                                          'omnis exercitationem quo magnam consequatur maxime aut illum ' .
1301                                                          'soluta quaerat natus unde aspernatur et sed beatae nihil ullam ' .
1302                                                          'temporibus corporis ratione blanditiis perspiciatis impedit ' .
1303                                                          'voluptatem quis molestiae ea qui reiciendis dolorum aut ducimus ' .
1304                                                          'sunt consequatur inventore dolor officiis pariatur doloremque ' .
1305                                                          'nemo culpa aut quidem qui dolore laudantium atque commodi alias ' .
1306                                                          'voluptatem non possimus aperiam ipsum rerum consequuntur aut ' .
1307                                                          'amet fugit quia aliquid praesentium repellendus quibusdam et et ' .
1308                                                          'inventore mollitia rerum sit autem pariatur maiores ipsum accusantium ' .
1309                                                          'perferendis vel sit possimus veritatis nihil distinctio qui eum ' .
1310                                                          'repellat officia illum quos impedit quam iste esse unde qui ' .
1311                                                          'suscipit aut facilis ut inventore omnis exercitationem quo magnam ' .
1312                                                          'consequatur maxime aut illum soluta quaerat natus unde aspernatur ' .
1313                                                          'et sed beatae nihil ullam temporibus corporis ratione blanditiis',
1314                                 'plink'   => 'item_plink'
1315                         ]
1316                 );
1317                 self::assertStringStartsWith('item_title', $result['text']);
1318                 self::assertStringStartsWith('<h4>item_title</h4><br>perspiciatis impedit voluptatem', $result['html']);
1319                 */
1320         }
1321
1322         /**
1323          * Test the api_convert_item() function with an empty item body.
1324          *
1325          * @return void
1326          */
1327         public function testApiConvertItemWithoutBody()
1328         {
1329                 /*
1330                 $result = api_convert_item(
1331                         [
1332                                 'network' => 'feed',
1333                                 'title'   => 'item_title',
1334                                 'uri-id'  => -1,
1335                                 'body'    => '',
1336                                 'plink'   => 'item_plink'
1337                         ]
1338                 );
1339                 self::assertEquals("item_title", $result['text']);
1340                 self::assertEquals('<h4>item_title</h4><br>item_plink', $result['html']);
1341                 */
1342         }
1343
1344         /**
1345          * Test the api_convert_item() function with the title in the body.
1346          *
1347          * @return void
1348          */
1349         public function testApiConvertItemWithTitleInBody()
1350         {
1351                 /*
1352                 $result = api_convert_item(
1353                         [
1354                                 'title'  => 'item_title',
1355                                 'body'   => 'item_title item_body',
1356                                 'uri-id' => 1,
1357                         ]
1358                 );
1359                 self::assertEquals('item_title item_body', $result['text']);
1360                 self::assertEquals('<h4>item_title</h4><br>item_title item_body', $result['html']);
1361                 */
1362         }
1363
1364         /**
1365          * Test the api_get_attachments() function.
1366          *
1367          * @return void
1368          */
1369         public function testApiGetAttachments()
1370         {
1371                 // $body = 'body';
1372                 // self::assertEmpty(api_get_attachments($body, 0));
1373         }
1374
1375         /**
1376          * Test the api_get_attachments() function with an img tag.
1377          *
1378          * @return void
1379          */
1380         public function testApiGetAttachmentsWithImage()
1381         {
1382                 // $body = '[img]http://via.placeholder.com/1x1.png[/img]';
1383                 // self::assertIsArray(api_get_attachments($body, 0));
1384         }
1385
1386         /**
1387          * Test the api_get_attachments() function with an img tag and an AndStatus user agent.
1388          *
1389          * @return void
1390          */
1391         public function testApiGetAttachmentsWithImageAndAndStatus()
1392         {
1393                 // $_SERVER['HTTP_USER_AGENT'] = 'AndStatus';
1394                 // $body                       = '[img]http://via.placeholder.com/1x1.png[/img]';
1395                 // self::assertIsArray(api_get_attachments($body, 0));
1396         }
1397
1398         /**
1399          * Test the api_get_entitities() function.
1400          *
1401          * @return void
1402          */
1403         public function testApiGetEntitities()
1404         {
1405                 // $text = 'text';
1406                 // self::assertIsArray(api_get_entitities($text, 'bbcode', 0));
1407         }
1408
1409         /**
1410          * Test the api_get_entitities() function with the include_entities parameter.
1411          *
1412          * @return void
1413          */
1414         public function testApiGetEntititiesWithIncludeEntities()
1415         {
1416                 /*
1417                 $_REQUEST['include_entities'] = 'true';
1418                 $text                         = 'text';
1419                 $result                       = api_get_entitities($text, 'bbcode', 0);
1420                 self::assertIsArray($result['hashtags']);
1421                 self::assertIsArray($result['symbols']);
1422                 self::assertIsArray($result['urls']);
1423                 self::assertIsArray($result['user_mentions']);
1424                 */
1425         }
1426
1427         /**
1428          * Test the api_format_items_embeded_images() function.
1429          *
1430          * @return void
1431          */
1432         public function testApiFormatItemsEmbededImages()
1433         {
1434                 /*
1435                 self::assertEquals(
1436                         'text ' . DI::baseUrl() . '/display/item_guid',
1437                         api_format_items_embeded_images(['guid' => 'item_guid'], 'text data:image/foo')
1438                 );
1439                 */
1440         }
1441
1442         /**
1443          * Test the api_format_items_activities() function.
1444          *
1445          * @return void
1446          */
1447         public function testApiFormatItemsActivities()
1448         {
1449                 $item   = ['uid' => 0, 'uri-id' => 1];
1450                 $result = DI::friendicaActivities()->createFromUriId($item['uri-id'], $item['uid']);
1451                 self::assertArrayHasKey('like', $result);
1452                 self::assertArrayHasKey('dislike', $result);
1453                 self::assertArrayHasKey('attendyes', $result);
1454                 self::assertArrayHasKey('attendno', $result);
1455                 self::assertArrayHasKey('attendmaybe', $result);
1456         }
1457
1458         /**
1459          * Test the api_format_items_activities() function with an XML result.
1460          *
1461          * @return void
1462          */
1463         public function testApiFormatItemsActivitiesWithXml()
1464         {
1465                 $item   = ['uid' => 0, 'uri-id' => 1];
1466                 $result = DI::friendicaActivities()->createFromUriId($item['uri-id'], $item['uid'], 'xml');
1467                 self::assertArrayHasKey('friendica:like', $result);
1468                 self::assertArrayHasKey('friendica:dislike', $result);
1469                 self::assertArrayHasKey('friendica:attendyes', $result);
1470                 self::assertArrayHasKey('friendica:attendno', $result);
1471                 self::assertArrayHasKey('friendica:attendmaybe', $result);
1472         }
1473
1474         /**
1475          * Test the api_format_items() function.
1476          * @doesNotPerformAssertions
1477          */
1478         public function testApiFormatItems()
1479         {
1480                 /*
1481                 $items = Post::selectToArray([], ['uid' => 42]);
1482                 foreach ($items as $item) {
1483                         $status = api_format_item($item);
1484                         self::assertStatus($status);
1485                 }
1486                 */
1487         }
1488
1489         /**
1490          * Test the api_format_items() function with an XML result.
1491          * @doesNotPerformAssertions
1492          */
1493         public function testApiFormatItemsWithXml()
1494         {
1495                 /*
1496                 $items = Post::selectToArray([], ['uid' => 42]);
1497                 foreach ($items as $item) {
1498                         $status = api_format_item($item, 'xml');
1499                         self::assertStatus($status);
1500                 }
1501                 */
1502         }
1503
1504         /**
1505          * Test the api_lists_list() function.
1506          *
1507          * @return void
1508          */
1509         public function testApiListsList()
1510         {
1511                 $result = api_lists_list('json');
1512                 self::assertEquals(['lists_list' => []], $result);
1513         }
1514
1515         /**
1516          * Test the api_lists_ownerships() function.
1517          *
1518          * @return void
1519          */
1520         public function testApiListsOwnerships()
1521         {
1522                 $result = api_lists_ownerships('json');
1523                 foreach ($result['lists']['lists'] as $list) {
1524                         self::assertList($list);
1525                 }
1526         }
1527
1528         /**
1529          * Test the api_lists_ownerships() function without an authenticated user.
1530          *
1531          * @return void
1532          */
1533         public function testApiListsOwnershipsWithoutAuthenticatedUser()
1534         {
1535                 $this->expectException(\Friendica\Network\HTTPException\UnauthorizedException::class);
1536                 BasicAuth::setCurrentUserID();
1537                 $_SESSION['authenticated'] = false;
1538                 api_lists_ownerships('json');
1539         }
1540
1541         /**
1542          * Test the api_statuses_f() function.
1543          *
1544          * @return void
1545          */
1546         public function testApiStatusesFWithIncoming()
1547         {
1548                 // $result = api_statuses_f('incoming');
1549                 // self::assertArrayHasKey('user', $result);
1550         }
1551
1552
1553         /**
1554          * Test the api_direct_messages_new() function.
1555          *
1556          * @return void
1557          */
1558         public function testApiDirectMessagesNew()
1559         {
1560                 $result = api_direct_messages_new('json');
1561                 self::assertNull($result);
1562         }
1563
1564         /**
1565          * Test the api_direct_messages_new() function without an authenticated user.
1566          *
1567          * @return void
1568          */
1569         public function testApiDirectMessagesNewWithoutAuthenticatedUser()
1570         {
1571                 $this->expectException(\Friendica\Network\HTTPException\UnauthorizedException::class);
1572                 BasicAuth::setCurrentUserID();
1573                 $_SESSION['authenticated'] = false;
1574                 api_direct_messages_new('json');
1575         }
1576
1577         /**
1578          * Test the api_direct_messages_new() function with an user ID.
1579          *
1580          * @return void
1581          */
1582         public function testApiDirectMessagesNewWithUserId()
1583         {
1584                 $_POST['text']       = 'message_text';
1585                 $_REQUEST['user_id'] = $this->otherUser['id'];
1586                 $result           = api_direct_messages_new('json');
1587                 self::assertEquals(['direct_message' => ['error' => -1]], $result);
1588         }
1589
1590         /**
1591          * Test the api_direct_messages_new() function with a screen name.
1592          *
1593          * @return void
1594          */
1595         public function testApiDirectMessagesNewWithScreenName()
1596         {
1597                 $this->app->setLoggedInUserNickname($this->selfUser['nick']);
1598                 $_POST['text']       = 'message_text';
1599                 $_REQUEST['user_id'] = $this->friendUser['id'];
1600                 $result              = api_direct_messages_new('json');
1601                 self::assertStringContainsString('message_text', $result['direct_message']['text']);
1602                 self::assertEquals('selfcontact', $result['direct_message']['sender_screen_name']);
1603                 self::assertEquals(1, $result['direct_message']['friendica_seen']);
1604         }
1605
1606         /**
1607          * Test the api_direct_messages_new() function with a title.
1608          *
1609          * @return void
1610          */
1611         public function testApiDirectMessagesNewWithTitle()
1612         {
1613                 $this->app->setLoggedInUserNickname($this->selfUser['nick']);
1614                 $_POST['text']        = 'message_text';
1615                 $_REQUEST['user_id']  = $this->friendUser['id'];
1616                 $_REQUEST['title']    = 'message_title';
1617                 $result            = api_direct_messages_new('json');
1618                 self::assertStringContainsString('message_text', $result['direct_message']['text']);
1619                 self::assertStringContainsString('message_title', $result['direct_message']['text']);
1620                 self::assertEquals('selfcontact', $result['direct_message']['sender_screen_name']);
1621                 self::assertEquals(1, $result['direct_message']['friendica_seen']);
1622         }
1623
1624         /**
1625          * Test the api_direct_messages_new() function with an RSS result.
1626          *
1627          * @return void
1628          */
1629         public function testApiDirectMessagesNewWithRss()
1630         {
1631                 $this->app->setLoggedInUserNickname($this->selfUser['nick']);
1632                 $_POST['text']       = 'message_text';
1633                 $_REQUEST['user_id'] = $this->friendUser['id'];
1634                 $result              = api_direct_messages_new('rss');
1635                 self::assertXml($result, 'direct-messages');
1636         }
1637
1638         /**
1639          * Test the api_direct_messages_destroy() function.
1640          *
1641          * @return void
1642          */
1643         public function testApiDirectMessagesDestroy()
1644         {
1645                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
1646                 api_direct_messages_destroy('json');
1647         }
1648
1649         /**
1650          * Test the api_direct_messages_destroy() function with the friendica_verbose GET param.
1651          *
1652          * @return void
1653          */
1654         public function testApiDirectMessagesDestroyWithVerbose()
1655         {
1656                 $_GET['friendica_verbose'] = 'true';
1657                 $result                    = api_direct_messages_destroy('json');
1658                 self::assertEquals(
1659                         [
1660                                 '$result' => [
1661                                         'result'  => 'error',
1662                                         'message' => 'message id or parenturi not specified'
1663                                 ]
1664                         ],
1665                         $result
1666                 );
1667         }
1668
1669         /**
1670          * Test the api_direct_messages_destroy() function without an authenticated user.
1671          *
1672          * @return void
1673          */
1674         public function testApiDirectMessagesDestroyWithoutAuthenticatedUser()
1675         {
1676                 $this->expectException(\Friendica\Network\HTTPException\UnauthorizedException::class);
1677                 BasicAuth::setCurrentUserID();
1678                 $_SESSION['authenticated'] = false;
1679                 api_direct_messages_destroy('json');
1680         }
1681
1682         /**
1683          * Test the api_direct_messages_destroy() function with a non-zero ID.
1684          *
1685          * @return void
1686          */
1687         public function testApiDirectMessagesDestroyWithId()
1688         {
1689                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
1690                 $_REQUEST['id'] = 1;
1691                 api_direct_messages_destroy('json');
1692         }
1693
1694         /**
1695          * Test the api_direct_messages_destroy() with a non-zero ID and the friendica_verbose GET param.
1696          *
1697          * @return void
1698          */
1699         public function testApiDirectMessagesDestroyWithIdAndVerbose()
1700         {
1701                 $_REQUEST['id']                  = 1;
1702                 $_REQUEST['friendica_parenturi'] = 'parent_uri';
1703                 $_GET['friendica_verbose']       = 'true';
1704                 $result                          = api_direct_messages_destroy('json');
1705                 self::assertEquals(
1706                         [
1707                                 '$result' => [
1708                                         'result'  => 'error',
1709                                         'message' => 'message id not in database'
1710                                 ]
1711                         ],
1712                         $result
1713                 );
1714         }
1715
1716         /**
1717          * Test the api_direct_messages_destroy() function with a non-zero ID.
1718          *
1719          * @return void
1720          */
1721         public function testApiDirectMessagesDestroyWithCorrectId()
1722         {
1723                 $this->markTestIncomplete('We need to add a dataset for this.');
1724         }
1725
1726         /**
1727          * Test the api_direct_messages_box() function.
1728          *
1729          * @return void
1730          */
1731         public function testApiDirectMessagesBoxWithSentbox()
1732         {
1733                 $_REQUEST['page']   = -1;
1734                 $_REQUEST['max_id'] = 10;
1735                 $result             = api_direct_messages_box('json', 'sentbox', 'false');
1736                 self::assertArrayHasKey('direct_message', $result);
1737         }
1738
1739         /**
1740          * Test the api_direct_messages_box() function.
1741          *
1742          * @return void
1743          */
1744         public function testApiDirectMessagesBoxWithConversation()
1745         {
1746                 $result = api_direct_messages_box('json', 'conversation', 'false');
1747                 self::assertArrayHasKey('direct_message', $result);
1748         }
1749
1750         /**
1751          * Test the api_direct_messages_box() function.
1752          *
1753          * @return void
1754          */
1755         public function testApiDirectMessagesBoxWithAll()
1756         {
1757                 $result = api_direct_messages_box('json', 'all', 'false');
1758                 self::assertArrayHasKey('direct_message', $result);
1759         }
1760
1761         /**
1762          * Test the api_direct_messages_box() function.
1763          *
1764          * @return void
1765          */
1766         public function testApiDirectMessagesBoxWithInbox()
1767         {
1768                 $result = api_direct_messages_box('json', 'inbox', 'false');
1769                 self::assertArrayHasKey('direct_message', $result);
1770         }
1771
1772         /**
1773          * Test the api_direct_messages_box() function.
1774          *
1775          * @return void
1776          */
1777         public function testApiDirectMessagesBoxWithVerbose()
1778         {
1779                 $result = api_direct_messages_box('json', 'sentbox', 'true');
1780                 self::assertEquals(
1781                         [
1782                                 '$result' => [
1783                                         'result'  => 'error',
1784                                         'message' => 'no mails available'
1785                                 ]
1786                         ],
1787                         $result
1788                 );
1789         }
1790
1791         /**
1792          * Test the api_direct_messages_box() function with a RSS result.
1793          *
1794          * @return void
1795          */
1796         public function testApiDirectMessagesBoxWithRss()
1797         {
1798                 $result = api_direct_messages_box('rss', 'sentbox', 'false');
1799                 self::assertXml($result, 'direct-messages');
1800         }
1801
1802         /**
1803          * Test the api_direct_messages_box() function without an authenticated user.
1804          *
1805          * @return void
1806          */
1807         public function testApiDirectMessagesBoxWithUnallowedUser()
1808         {
1809                 $this->expectException(\Friendica\Network\HTTPException\UnauthorizedException::class);
1810                 BasicAuth::setCurrentUserID();
1811                 api_direct_messages_box('json', 'sentbox', 'false');
1812         }
1813
1814         /**
1815          * Test the api_direct_messages_sentbox() function.
1816          *
1817          * @return void
1818          */
1819         public function testApiDirectMessagesSentbox()
1820         {
1821                 $result = api_direct_messages_sentbox('json');
1822                 self::assertArrayHasKey('direct_message', $result);
1823         }
1824
1825         /**
1826          * Test the api_direct_messages_inbox() function.
1827          *
1828          * @return void
1829          */
1830         public function testApiDirectMessagesInbox()
1831         {
1832                 $result = api_direct_messages_inbox('json');
1833                 self::assertArrayHasKey('direct_message', $result);
1834         }
1835
1836         /**
1837          * Test the api_direct_messages_all() function.
1838          *
1839          * @return void
1840          */
1841         public function testApiDirectMessagesAll()
1842         {
1843                 $result = api_direct_messages_all('json');
1844                 self::assertArrayHasKey('direct_message', $result);
1845         }
1846
1847         /**
1848          * Test the api_direct_messages_conversation() function.
1849          *
1850          * @return void
1851          */
1852         public function testApiDirectMessagesConversation()
1853         {
1854                 $result = api_direct_messages_conversation('json');
1855                 self::assertArrayHasKey('direct_message', $result);
1856         }
1857
1858         /**
1859          * Test the api_oauth_request_token() function.
1860          *
1861          * @return void
1862          */
1863         public function testApiOauthRequestToken()
1864         {
1865                 $this->markTestIncomplete('exit() kills phpunit as well');
1866         }
1867
1868         /**
1869          * Test the api_oauth_access_token() function.
1870          *
1871          * @return void
1872          */
1873         public function testApiOauthAccessToken()
1874         {
1875                 $this->markTestIncomplete('exit() kills phpunit as well');
1876         }
1877
1878         /**
1879          * Test the api_fr_photos_list() function.
1880          *
1881          * @return void
1882          */
1883         public function testApiFrPhotosList()
1884         {
1885                 $result = api_fr_photos_list('json');
1886                 self::assertArrayHasKey('photo', $result);
1887         }
1888
1889         /**
1890          * Test the api_fr_photos_list() function without an authenticated user.
1891          *
1892          * @return void
1893          */
1894         public function testApiFrPhotosListWithoutAuthenticatedUser()
1895         {
1896                 $this->expectException(\Friendica\Network\HTTPException\UnauthorizedException::class);
1897                 BasicAuth::setCurrentUserID();
1898                 $_SESSION['authenticated'] = false;
1899                 api_fr_photos_list('json');
1900         }
1901
1902         /**
1903          * Test the api_fr_photo_create_update() function.
1904          */
1905         public function testApiFrPhotoCreateUpdate()
1906         {
1907                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
1908                 api_fr_photo_create_update('json');
1909         }
1910
1911         /**
1912          * Test the api_fr_photo_create_update() function without an authenticated user.
1913          *
1914          * @return void
1915          */
1916         public function testApiFrPhotoCreateUpdateWithoutAuthenticatedUser()
1917         {
1918                 $this->expectException(\Friendica\Network\HTTPException\UnauthorizedException::class);
1919                 BasicAuth::setCurrentUserID();
1920                 $_SESSION['authenticated'] = false;
1921                 api_fr_photo_create_update('json');
1922         }
1923
1924         /**
1925          * Test the api_fr_photo_create_update() function with an album name.
1926          *
1927          * @return void
1928          */
1929         public function testApiFrPhotoCreateUpdateWithAlbum()
1930         {
1931                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
1932                 $_REQUEST['album'] = 'album_name';
1933                 api_fr_photo_create_update('json');
1934         }
1935
1936         /**
1937          * Test the api_fr_photo_create_update() function with the update mode.
1938          *
1939          * @return void
1940          */
1941         public function testApiFrPhotoCreateUpdateWithUpdate()
1942         {
1943                 $this->markTestIncomplete('We need to create a dataset for this');
1944         }
1945
1946         /**
1947          * Test the api_fr_photo_create_update() function with an uploaded file.
1948          *
1949          * @return void
1950          */
1951         public function testApiFrPhotoCreateUpdateWithFile()
1952         {
1953                 $this->markTestIncomplete();
1954         }
1955
1956         /**
1957          * Test the api_fr_photo_detail() function.
1958          *
1959          * @return void
1960          */
1961         public function testApiFrPhotoDetail()
1962         {
1963                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
1964                 api_fr_photo_detail('json');
1965         }
1966
1967         /**
1968          * Test the api_fr_photo_detail() function without an authenticated user.
1969          *
1970          * @return void
1971          */
1972         public function testApiFrPhotoDetailWithoutAuthenticatedUser()
1973         {
1974                 $this->expectException(\Friendica\Network\HTTPException\UnauthorizedException::class);
1975                 BasicAuth::setCurrentUserID();
1976                 $_SESSION['authenticated'] = false;
1977                 api_fr_photo_detail('json');
1978         }
1979
1980         /**
1981          * Test the api_fr_photo_detail() function with a photo ID.
1982          *
1983          * @return void
1984          */
1985         public function testApiFrPhotoDetailWithPhotoId()
1986         {
1987                 $this->expectException(\Friendica\Network\HTTPException\NotFoundException::class);
1988                 $_REQUEST['photo_id'] = 1;
1989                 api_fr_photo_detail('json');
1990         }
1991
1992         /**
1993          * Test the api_fr_photo_detail() function with a correct photo ID.
1994          *
1995          * @return void
1996          */
1997         public function testApiFrPhotoDetailCorrectPhotoId()
1998         {
1999                 $this->markTestIncomplete('We need to create a dataset for this.');
2000         }
2001
2002         /**
2003          * Test the api_account_update_profile_image() function.
2004          *
2005          * @return void
2006          */
2007         public function testApiAccountUpdateProfileImage()
2008         {
2009                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
2010                 api_account_update_profile_image('json');
2011         }
2012
2013         /**
2014          * Test the api_account_update_profile_image() function without an authenticated user.
2015          *
2016          * @return void
2017          */
2018         public function testApiAccountUpdateProfileImageWithoutAuthenticatedUser()
2019         {
2020                 $this->expectException(\Friendica\Network\HTTPException\UnauthorizedException::class);
2021                 BasicAuth::setCurrentUserID();
2022                 $_SESSION['authenticated'] = false;
2023                 api_account_update_profile_image('json');
2024         }
2025
2026         /**
2027          * Test the api_account_update_profile_image() function with an uploaded file.
2028          *
2029          * @return void
2030          */
2031         public function testApiAccountUpdateProfileImageWithUpload()
2032         {
2033                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
2034                 $this->markTestIncomplete();
2035         }
2036
2037         /**
2038          * Test the check_acl_input() function.
2039          *
2040          * @return void
2041          */
2042         public function testCheckAclInput()
2043         {
2044                 $result = check_acl_input('<aclstring>', BaseApi::getCurrentUserID());
2045                 // Where does this result come from?
2046                 self::assertEquals(1, $result);
2047         }
2048
2049         /**
2050          * Test the check_acl_input() function with an empty ACL string.
2051          *
2052          * @return void
2053          */
2054         public function testCheckAclInputWithEmptyAclString()
2055         {
2056                 $result = check_acl_input(' ', BaseApi::getCurrentUserID());
2057                 self::assertFalse($result);
2058         }
2059
2060         /**
2061          * Test the save_media_to_database() function.
2062          *
2063          * @return void
2064          */
2065         public function testSaveMediaToDatabase()
2066         {
2067                 $this->markTestIncomplete();
2068         }
2069
2070         /**
2071          * Test the post_photo_item() function.
2072          *
2073          * @return void
2074          */
2075         public function testPostPhotoItem()
2076         {
2077                 $this->markTestIncomplete();
2078         }
2079
2080         /**
2081          * Test the prepare_photo_data() function.
2082          *
2083          * @return void
2084          */
2085         public function testPreparePhotoData()
2086         {
2087                 $this->markTestIncomplete();
2088         }
2089
2090         /**
2091          * Test the api_share_as_retweet() function with a valid item.
2092          *
2093          * @return void
2094          */
2095         public function testApiShareAsRetweetWithValidItem()
2096         {
2097                 $this->markTestIncomplete();
2098         }
2099
2100         /**
2101          * Test the api_in_reply_to() function with a valid item.
2102          *
2103          * @return void
2104          */
2105         public function testApiInReplyToWithValidItem()
2106         {
2107                 $this->markTestIncomplete();
2108         }
2109
2110         /**
2111          * Test the api_clean_plain_items() function.
2112          *
2113          * @return void
2114          */
2115         public function testApiCleanPlainItems()
2116         {
2117                 $_REQUEST['include_entities'] = 'true';
2118                 $result                       = api_clean_plain_items('some_text [url="some_url"]some_text[/url]');
2119                 self::assertEquals('some_text [url="some_url"]"some_url"[/url]', $result);
2120         }
2121
2122         /**
2123          * Test the api_best_nickname() function with contacts.
2124          *
2125          * @return void
2126          */
2127         public function testApiBestNicknameWithContacts()
2128         {
2129                 $this->markTestIncomplete();
2130         }
2131
2132         /**
2133          * Test the api_friendica_group_show() function.
2134          *
2135          * @return void
2136          */
2137         public function testApiFriendicaGroupShow()
2138         {
2139                 $this->markTestIncomplete();
2140         }
2141
2142         /**
2143          * Test the api_friendica_group_delete() function.
2144          *
2145          * @return void
2146          */
2147         public function testApiFriendicaGroupDelete()
2148         {
2149                 $this->markTestIncomplete();
2150         }
2151
2152         /**
2153          * Test the api_lists_destroy() function.
2154          *
2155          * @return void
2156          */
2157         public function testApiListsDestroy()
2158         {
2159                 $this->markTestIncomplete();
2160         }
2161
2162         /**
2163          * Test the group_create() function.
2164          *
2165          * @return void
2166          */
2167         public function testGroupCreate()
2168         {
2169                 $this->markTestIncomplete();
2170         }
2171
2172         /**
2173          * Test the api_friendica_group_create() function.
2174          *
2175          * @return void
2176          */
2177         public function testApiFriendicaGroupCreate()
2178         {
2179                 $this->markTestIncomplete();
2180         }
2181
2182         /**
2183          * Test the api_lists_create() function.
2184          *
2185          * @return void
2186          */
2187         public function testApiListsCreate()
2188         {
2189                 $this->markTestIncomplete();
2190         }
2191
2192         /**
2193          * Test the api_friendica_group_update() function.
2194          *
2195          * @return void
2196          */
2197         public function testApiFriendicaGroupUpdate()
2198         {
2199                 $this->markTestIncomplete();
2200         }
2201
2202         /**
2203          * Test the api_lists_update() function.
2204          *
2205          * @return void
2206          */
2207         public function testApiListsUpdate()
2208         {
2209                 $this->markTestIncomplete();
2210         }
2211
2212         /**
2213          * Test the api_friendica_activity() function.
2214          *
2215          * @return void
2216          */
2217         public function testApiFriendicaActivity()
2218         {
2219                 $this->markTestIncomplete();
2220         }
2221
2222         /**
2223          * Test the api_friendica_notification_seen() function.
2224          *
2225          * @return void
2226          */
2227         public function testApiFriendicaNotificationSeen()
2228         {
2229                 $this->markTestIncomplete();
2230         }
2231
2232         /**
2233          * Test the api_friendica_direct_messages_setseen() function.
2234          *
2235          * @return void
2236          */
2237         public function testApiFriendicaDirectMessagesSetseen()
2238         {
2239                 $this->markTestIncomplete();
2240         }
2241
2242         /**
2243          * Test the api_friendica_direct_messages_search() function.
2244          *
2245          * @return void
2246          */
2247         public function testApiFriendicaDirectMessagesSearch()
2248         {
2249                 $this->markTestIncomplete();
2250         }
2251 }