]> git.mxchange.org Git - friendica.git/blob - tests/legacy/ApiTest.php
Add license check
[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\Core\ACL;
10 use Friendica\Core\Config\Capability\IManageConfigValues;
11 use Friendica\DI;
12 use Friendica\Module\BaseApi;
13 use Friendica\Security\BasicAuth;
14 use Friendica\Test\FixtureTest;
15 use Friendica\Util\Arrays;
16 use Friendica\Util\DateTimeFormat;
17 use Monolog\Handler\TestHandler;
18
19 require_once __DIR__ . '/../../include/api.php';
20
21 /**
22  * Tests for the API functions.
23  *
24  * Functions that use header() need to be tested in a separate process.
25  * @see https://phpunit.de/manual/5.7/en/appendixes.annotations.html#appendixes.annotations.runTestsInSeparateProcesses
26  *
27  * @backupGlobals enabled
28  */
29 class ApiTest extends FixtureTest
30 {
31         /**
32          * @var TestHandler Can handle log-outputs
33          */
34         protected $logOutput;
35
36         /** @var array */
37         protected $selfUser;
38         /** @var array */
39         protected $friendUser;
40         /** @var array */
41         protected $otherUser;
42
43         protected $wrongUserId;
44
45         /** @var App */
46         protected $app;
47
48         /** @var IManageConfigValues */
49         protected $config;
50
51         /**
52          * Create variables used by tests.
53          */
54         protected function setUp() : void
55         {
56                 global $API, $called_api;
57                 $API = [];
58                 $called_api = [];
59
60                 parent::setUp();
61
62                 /** @var IManageConfigValues $config */
63                 $this->config = $this->dice->create(IManageConfigValues::class);
64
65                 $this->config->set('system', 'url', 'http://localhost');
66                 $this->config->set('system', 'hostname', 'localhost');
67                 $this->config->set('system', 'worker_dont_fork', true);
68
69                 // Default config
70                 $this->config->set('config', 'hostname', 'localhost');
71                 $this->config->set('system', 'throttle_limit_day', 100);
72                 $this->config->set('system', 'throttle_limit_week', 100);
73                 $this->config->set('system', 'throttle_limit_month', 100);
74                 $this->config->set('system', 'theme', 'system_theme');
75
76
77                 /** @var App app */
78                 $this->app = DI::app();
79
80                 DI::args()->setArgc(1);
81
82                 // User data that the test database is populated with
83                 $this->selfUser   = [
84                         'id'   => 42,
85                         'name' => 'Self contact',
86                         'nick' => 'selfcontact',
87                         'nurl' => 'http://localhost/profile/selfcontact'
88                 ];
89                 $this->friendUser = [
90                         'id'   => 44,
91                         'name' => 'Friend contact',
92                         'nick' => 'friendcontact',
93                         'nurl' => 'http://localhost/profile/friendcontact'
94                 ];
95                 $this->otherUser  = [
96                         'id'   => 43,
97                         'name' => 'othercontact',
98                         'nick' => 'othercontact',
99                         'nurl' => 'http://localhost/profile/othercontact'
100                 ];
101
102                 // User ID that we know is not in the database
103                 $this->wrongUserId = 666;
104
105                 DI::session()->start();
106
107                 // Most API require login so we force the session
108                 $_SESSION = [
109                         'authenticated' => true,
110                         'uid'           => $this->selfUser['id']
111                 ];
112                 BasicAuth::setCurrentUserID($this->selfUser['id']);
113         }
114
115         /**
116          * Assert that a list array contains expected keys.
117          *
118          * @param array $list List array
119          *
120          * @return void
121          */
122         private function assertList(array $list = [])
123         {
124                 self::assertIsString($list['name']);
125                 self::assertIsInt($list['id']);
126                 self::assertIsString('string', $list['id_str']);
127                 self::assertContains($list['mode'], ['public', 'private']);
128                 // We could probably do more checks here.
129         }
130
131         /**
132          * Assert that the string is XML and contain the root element.
133          *
134          * @param string $result       XML string
135          * @param string $root_element Root element name
136          *
137          * @return void
138          */
139         private function assertXml($result = '', $root_element = '')
140         {
141                 self::assertStringStartsWith('<?xml version="1.0"?>', $result);
142                 self::assertStringContainsString('<' . $root_element, $result);
143                 // We could probably do more checks here.
144         }
145
146         /**
147          * Test the api_user() function.
148          *
149          * @return void
150          */
151         public function testApiUser()
152         {
153                 self::assertEquals($this->selfUser['id'], BaseApi::getCurrentUserID());
154         }
155
156
157
158         /**
159          * Test the api_source() function.
160          *
161          * @return void
162          */
163         public function testApiSource()
164         {
165                 self::assertEquals('api', BasicAuth::getCurrentApplicationToken()['name']);
166         }
167
168         /**
169          * Test the api_source() function with a Twidere user agent.
170          *
171          * @return void
172          */
173         public function testApiSourceWithTwidere()
174         {
175                 $_SERVER['HTTP_USER_AGENT'] = 'Twidere';
176                 self::assertEquals('Twidere', BasicAuth::getCurrentApplicationToken()['name']);
177         }
178
179         /**
180          * Test the api_source() function with a GET parameter.
181          *
182          * @return void
183          */
184         public function testApiSourceWithGet()
185         {
186                 $_REQUEST['source'] = 'source_name';
187                 self::assertEquals('source_name', BasicAuth::getCurrentApplicationToken()['name']);
188         }
189
190         /**
191          * Test the api_date() function.
192          *
193          * @return void
194          */
195         public function testApiDate()
196         {
197                 self::assertEquals('Wed Oct 10 00:00:00 +0000 1990', DateTimeFormat::utc('1990-10-10', DateTimeFormat::API));
198         }
199
200         /**
201          * Test the api_register_func() function.
202          *
203          * @return void
204          */
205         public function testApiRegisterFunc()
206         {
207                 global $API;
208                 self::assertNull(
209                         api_register_func(
210                                 'api_path',
211                                 function () {
212                                 },
213                                 true,
214                                 'method'
215                         )
216                 );
217                 self::assertTrue(is_callable($API['api_path']['func']));
218         }
219
220         /**
221          * Test the BasicAuth::getCurrentUserID() function without any login.
222          *
223          * @runInSeparateProcess
224          * @preserveGlobalState disabled
225          * @preserveGlobalState disabled
226          */
227         public function testApiLoginWithoutLogin()
228         {
229                 BasicAuth::setCurrentUserID();
230                 $this->expectException(\Friendica\Network\HTTPException\UnauthorizedException::class);
231                 BasicAuth::getCurrentUserID(true);
232         }
233
234         /**
235          * Test the BasicAuth::getCurrentUserID() function with a bad login.
236          *
237          * @runInSeparateProcess
238          * @preserveGlobalState disabled
239          * @preserveGlobalState disabled
240          */
241         public function testApiLoginWithBadLogin()
242         {
243                 BasicAuth::setCurrentUserID();
244                 $this->expectException(\Friendica\Network\HTTPException\UnauthorizedException::class);
245                 $_SERVER['PHP_AUTH_USER'] = 'user@server';
246                 BasicAuth::getCurrentUserID(true);
247         }
248
249         /**
250          * Test the BasicAuth::getCurrentUserID() function with oAuth.
251          *
252          * @return void
253          */
254         public function testApiLoginWithOauth()
255         {
256                 $this->markTestIncomplete('Can we test this easily?');
257         }
258
259         /**
260          * Test the BasicAuth::getCurrentUserID() function with authentication provided by an addon.
261          *
262          * @return void
263          */
264         public function testApiLoginWithAddonAuth()
265         {
266                 $this->markTestIncomplete('Can we test this easily?');
267         }
268
269         /**
270          * Test the BasicAuth::getCurrentUserID() function with a correct login.
271          *
272          * @runInSeparateProcess
273          * @preserveGlobalState disabled
274          * @doesNotPerformAssertions
275          */
276         public function testApiLoginWithCorrectLogin()
277         {
278                 BasicAuth::setCurrentUserID();
279                 $_SERVER['PHP_AUTH_USER'] = 'Test user';
280                 $_SERVER['PHP_AUTH_PW']   = 'password';
281                 BasicAuth::getCurrentUserID(true);
282         }
283
284         /**
285          * Test the BasicAuth::getCurrentUserID() function with a remote user.
286          *
287          * @runInSeparateProcess
288          * @preserveGlobalState disabled
289          */
290         public function testApiLoginWithRemoteUser()
291         {
292                 BasicAuth::setCurrentUserID();
293                 $this->expectException(\Friendica\Network\HTTPException\UnauthorizedException::class);
294                 $_SERVER['REDIRECT_REMOTE_USER'] = '123456dXNlcjpwYXNzd29yZA==';
295                 BasicAuth::getCurrentUserID(true);
296         }
297
298         /**
299          * Test the api_call() function.
300          *
301          * @runInSeparateProcess
302          * @preserveGlobalState disabled
303          */
304         public function testApiCall()
305         {
306                 global $API;
307                 $API['api_path']           = [
308                         'method' => 'method',
309                         'func'   => function () {
310                                 return ['data' => ['some_data']];
311                         }
312                 ];
313                 $_SERVER['REQUEST_METHOD'] = 'method';
314                 $_SERVER['QUERY_STRING'] = 'pagename=api_path';
315                 $_GET['callback']          = 'callback_name';
316
317                 self::assertEquals(
318                         'callback_name(["some_data"])',
319                         api_call('api_path', 'json')
320                 );
321         }
322
323         /**
324          * Test the api_call() function with the profiled enabled.
325          *
326          * @runInSeparateProcess
327          * @preserveGlobalState disabled
328          */
329         public function testApiCallWithProfiler()
330         {
331                 global $API;
332                 $API['api_path']           = [
333                         'method' => 'method',
334                         'func'   => function () {
335                                 return ['data' => ['some_data']];
336                         }
337                 ];
338
339                 $_SERVER['REQUEST_METHOD'] = 'method';
340                 $_SERVER['QUERY_STRING'] = 'pagename=api_path';
341
342                 $this->config->set('system', 'profiler', true);
343                 $this->config->set('rendertime', 'callstack', true);
344                 $this->app->callstack = [
345                         'database'       => ['some_function' => 200],
346                         'database_write' => ['some_function' => 200],
347                         'cache'          => ['some_function' => 200],
348                         'cache_write'    => ['some_function' => 200],
349                         'network'        => ['some_function' => 200]
350                 ];
351
352                 self::assertEquals(
353                         '["some_data"]',
354                         api_call('api_path', 'json')
355                 );
356         }
357
358         /**
359          * Test the api_call() function with a JSON result.
360          *
361          * @runInSeparateProcess
362          * @preserveGlobalState disabled
363          */
364         public function testApiCallWithJson()
365         {
366                 global $API;
367                 $API['api_path']           = [
368                         'method' => 'method',
369                         'func'   => function () {
370                                 return ['data' => ['some_data']];
371                         }
372                 ];
373                 $_SERVER['REQUEST_METHOD'] = 'method';
374                 $_SERVER['QUERY_STRING'] = 'pagename=api_path.json';
375
376                 self::assertEquals(
377                         '["some_data"]',
378                         api_call('api_path.json', 'json')
379                 );
380         }
381
382         /**
383          * Test the api_call() function with an XML result.
384          *
385          * @runInSeparateProcess
386          * @preserveGlobalState disabled
387          */
388         public function testApiCallWithXml()
389         {
390                 global $API;
391                 $API['api_path']           = [
392                         'method' => 'method',
393                         'func'   => function () {
394                                 return 'some_data';
395                         }
396                 ];
397                 $_SERVER['REQUEST_METHOD'] = 'method';
398                 $_SERVER['QUERY_STRING'] = 'pagename=api_path.xml';
399
400                 $args = DI::args()->determine($_SERVER, $_GET);
401
402                 self::assertEquals(
403                         'some_data',
404                         api_call('api_path.xml', 'xml')
405                 );
406         }
407
408         /**
409          * Test the api_call() function with an RSS result.
410          *
411          * @runInSeparateProcess
412          * @preserveGlobalState disabled
413          */
414         public function testApiCallWithRss()
415         {
416                 global $API;
417                 $API['api_path']           = [
418                         'method' => 'method',
419                         'func'   => function () {
420                                 return 'some_data';
421                         }
422                 ];
423                 $_SERVER['REQUEST_METHOD'] = 'method';
424                 $_SERVER['QUERY_STRING'] = 'pagename=api_path.rss';
425
426                 self::assertEquals(
427                         '<?xml version="1.0" encoding="UTF-8"?>' . "\n" .
428                         'some_data',
429                         api_call('api_path.rss', 'rss')
430                 );
431         }
432
433         /**
434          * Test the api_call() function with an Atom result.
435          *
436          * @runInSeparateProcess
437          * @preserveGlobalState disabled
438          */
439         public function testApiCallWithAtom()
440         {
441                 global $API;
442                 $API['api_path']           = [
443                         'method' => 'method',
444                         'func'   => function () {
445                                 return 'some_data';
446                         }
447                 ];
448                 $_SERVER['REQUEST_METHOD'] = 'method';
449                 $_SERVER['QUERY_STRING'] = 'pagename=api_path.atom';
450
451                 self::assertEquals(
452                         '<?xml version="1.0" encoding="UTF-8"?>' . "\n" .
453                         'some_data',
454                         api_call('api_path.atom', 'atom')
455                 );
456         }
457
458         /**
459          * Test the Arrays::walkRecursive() function.
460          *
461          * @return void
462          */
463         public function testApiWalkRecursive()
464         {
465                 $array = ['item1'];
466                 self::assertEquals(
467                         $array,
468                         Arrays::walkRecursive(
469                                 $array,
470                                 function () {
471                                         // Should we test this with a callback that actually does something?
472                                         return true;
473                                 }
474                         )
475                 );
476         }
477
478         /**
479          * Test the Arrays::walkRecursive() function with an array.
480          *
481          * @return void
482          */
483         public function testApiWalkRecursiveWithArray()
484         {
485                 $array = [['item1'], ['item2']];
486                 self::assertEquals(
487                         $array,
488                         Arrays::walkRecursive(
489                                 $array,
490                                 function () {
491                                         // Should we test this with a callback that actually does something?
492                                         return true;
493                                 }
494                         )
495                 );
496         }
497
498         /**
499          * Test the api_lists_list() function.
500          *
501          * @return void
502          */
503         public function testApiListsList()
504         {
505                 $result = api_lists_list('json');
506                 self::assertEquals(['lists_list' => []], $result);
507         }
508
509         /**
510          * Test the api_lists_ownerships() function.
511          *
512          * @return void
513          */
514         public function testApiListsOwnerships()
515         {
516                 $result = api_lists_ownerships('json');
517                 foreach ($result['lists']['lists'] as $list) {
518                         self::assertList($list);
519                 }
520         }
521
522         /**
523          * Test the api_lists_ownerships() function without an authenticated user.
524          *
525          * @return void
526          */
527         public function testApiListsOwnershipsWithoutAuthenticatedUser()
528         {
529                 $this->expectException(\Friendica\Network\HTTPException\UnauthorizedException::class);
530                 BasicAuth::setCurrentUserID();
531                 $_SESSION['authenticated'] = false;
532                 api_lists_ownerships('json');
533         }
534
535         /**
536          * Test the api_fr_photos_list() function.
537          *
538          * @return void
539          */
540         public function testApiFrPhotosList()
541         {
542                 $result = api_fr_photos_list('json');
543                 self::assertArrayHasKey('photo', $result);
544         }
545
546         /**
547          * Test the api_fr_photos_list() function without an authenticated user.
548          *
549          * @return void
550          */
551         public function testApiFrPhotosListWithoutAuthenticatedUser()
552         {
553                 $this->expectException(\Friendica\Network\HTTPException\UnauthorizedException::class);
554                 BasicAuth::setCurrentUserID();
555                 $_SESSION['authenticated'] = false;
556                 api_fr_photos_list('json');
557         }
558
559         /**
560          * Test the api_fr_photo_create_update() function.
561          */
562         public function testApiFrPhotoCreateUpdate()
563         {
564                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
565                 api_fr_photo_create_update('json');
566         }
567
568         /**
569          * Test the api_fr_photo_create_update() function without an authenticated user.
570          *
571          * @return void
572          */
573         public function testApiFrPhotoCreateUpdateWithoutAuthenticatedUser()
574         {
575                 $this->expectException(\Friendica\Network\HTTPException\UnauthorizedException::class);
576                 BasicAuth::setCurrentUserID();
577                 $_SESSION['authenticated'] = false;
578                 api_fr_photo_create_update('json');
579         }
580
581         /**
582          * Test the api_fr_photo_create_update() function with an album name.
583          *
584          * @return void
585          */
586         public function testApiFrPhotoCreateUpdateWithAlbum()
587         {
588                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
589                 $_REQUEST['album'] = 'album_name';
590                 api_fr_photo_create_update('json');
591         }
592
593         /**
594          * Test the api_fr_photo_create_update() function with the update mode.
595          *
596          * @return void
597          */
598         public function testApiFrPhotoCreateUpdateWithUpdate()
599         {
600                 $this->markTestIncomplete('We need to create a dataset for this');
601         }
602
603         /**
604          * Test the api_fr_photo_create_update() function with an uploaded file.
605          *
606          * @return void
607          */
608         public function testApiFrPhotoCreateUpdateWithFile()
609         {
610                 $this->markTestIncomplete();
611         }
612
613         /**
614          * Test the api_fr_photo_detail() function.
615          *
616          * @return void
617          */
618         public function testApiFrPhotoDetail()
619         {
620                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
621                 api_fr_photo_detail('json');
622         }
623
624         /**
625          * Test the api_fr_photo_detail() function without an authenticated user.
626          *
627          * @return void
628          */
629         public function testApiFrPhotoDetailWithoutAuthenticatedUser()
630         {
631                 $this->expectException(\Friendica\Network\HTTPException\UnauthorizedException::class);
632                 BasicAuth::setCurrentUserID();
633                 $_SESSION['authenticated'] = false;
634                 api_fr_photo_detail('json');
635         }
636
637         /**
638          * Test the api_fr_photo_detail() function with a photo ID.
639          *
640          * @return void
641          */
642         public function testApiFrPhotoDetailWithPhotoId()
643         {
644                 $this->expectException(\Friendica\Network\HTTPException\NotFoundException::class);
645                 $_REQUEST['photo_id'] = 1;
646                 api_fr_photo_detail('json');
647         }
648
649         /**
650          * Test the api_fr_photo_detail() function with a correct photo ID.
651          *
652          * @return void
653          */
654         public function testApiFrPhotoDetailCorrectPhotoId()
655         {
656                 $this->markTestIncomplete('We need to create a dataset for this.');
657         }
658
659         /**
660          * Test the api_account_update_profile_image() function.
661          *
662          * @return void
663          */
664         public function testApiAccountUpdateProfileImage()
665         {
666                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
667                 api_account_update_profile_image('json');
668         }
669
670         /**
671          * Test the api_account_update_profile_image() function without an authenticated user.
672          *
673          * @return void
674          */
675         public function testApiAccountUpdateProfileImageWithoutAuthenticatedUser()
676         {
677                 $this->expectException(\Friendica\Network\HTTPException\UnauthorizedException::class);
678                 BasicAuth::setCurrentUserID();
679                 $_SESSION['authenticated'] = false;
680                 api_account_update_profile_image('json');
681         }
682
683         /**
684          * Test the api_account_update_profile_image() function with an uploaded file.
685          *
686          * @return void
687          */
688         public function testApiAccountUpdateProfileImageWithUpload()
689         {
690                 $this->expectException(\Friendica\Network\HTTPException\BadRequestException::class);
691                 $this->markTestIncomplete();
692         }
693
694         /**
695          * Test the save_media_to_database() function.
696          *
697          * @return void
698          */
699         public function testSaveMediaToDatabase()
700         {
701                 $this->markTestIncomplete();
702         }
703
704         /**
705          * Test the post_photo_item() function.
706          *
707          * @return void
708          */
709         public function testPostPhotoItem()
710         {
711                 $this->markTestIncomplete();
712         }
713
714         /**
715          * Test the prepare_photo_data() function.
716          *
717          * @return void
718          */
719         public function testPreparePhotoData()
720         {
721                 $this->markTestIncomplete();
722         }
723
724         /**
725          * Test the api_friendica_group_show() function.
726          *
727          * @return void
728          */
729         public function testApiFriendicaGroupShow()
730         {
731                 $this->markTestIncomplete();
732         }
733
734         /**
735          * Test the api_lists_destroy() function.
736          *
737          * @return void
738          */
739         public function testApiListsDestroy()
740         {
741                 $this->markTestIncomplete();
742         }
743
744         /**
745          * Test the group_create() function.
746          *
747          * @return void
748          */
749         public function testGroupCreate()
750         {
751                 $this->markTestIncomplete();
752         }
753
754         /**
755          * Test the api_friendica_group_create() function.
756          *
757          * @return void
758          */
759         public function testApiFriendicaGroupCreate()
760         {
761                 $this->markTestIncomplete();
762         }
763
764         /**
765          * Test the api_lists_create() function.
766          *
767          * @return void
768          */
769         public function testApiListsCreate()
770         {
771                 $this->markTestIncomplete();
772         }
773
774         /**
775          * Test the api_lists_update() function.
776          *
777          * @return void
778          */
779         public function testApiListsUpdate()
780         {
781                 $this->markTestIncomplete();
782         }
783 }