3 * @copyright Copyright (C) 2010-2023, the Friendica project
5 * @license GNU AGPL version 3 or any later version
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as
9 * published by the Free Software Foundation, either version 3 of the
10 * License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 namespace Friendica\Test\src\Module\Api;
24 use Friendica\App\Arguments;
25 use Friendica\App\BaseURL;
26 use Friendica\Core\L10n;
27 use Friendica\Factory\Api\Twitter\User;
28 use Friendica\Module\Api\ApiResponse;
29 use Friendica\Test\MockedTest;
30 use Psr\Log\NullLogger;
32 class ApiResponseTest extends MockedTest
34 public function testErrorWithJson()
36 $l10n = \Mockery::mock(L10n::class);
37 $args = \Mockery::mock(Arguments::class);
38 $args->shouldReceive('getQueryString')->andReturn('');
39 $baseUrl = \Mockery::mock(BaseURL::class);
40 $twitterUser = \Mockery::mock(User::class);
42 $response = new ApiResponse($l10n, $args, new NullLogger(), $baseUrl, $twitterUser);
43 $response->error(200, 'OK', 'error_message', 'json');
45 self::assertEquals('{"error":"error_message","code":"200 OK","request":""}', $response->getContent());
48 public function testErrorWithXml()
50 $l10n = \Mockery::mock(L10n::class);
51 $args = \Mockery::mock(Arguments::class);
52 $args->shouldReceive('getQueryString')->andReturn('');
53 $baseUrl = \Mockery::mock(BaseURL::class);
54 $twitterUser = \Mockery::mock(User::class);
56 $response = new ApiResponse($l10n, $args, new NullLogger(), $baseUrl, $twitterUser);
57 $response->error(200, 'OK', 'error_message', 'xml');
59 self::assertEquals(['Content-type' => 'text/xml', 'HTTP/1.1 200 OK'], $response->getHeaders());
60 self::assertEquals('<?xml version="1.0"?>' . "\n" .
61 '<status xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" ' .
62 'xmlns:friendica="http://friendi.ca/schema/api/1/" ' .
63 'xmlns:georss="http://www.georss.org/georss">' . "\n" .
64 ' <error>error_message</error>' . "\n" .
65 ' <code>200 OK</code>' . "\n" .
66 ' <request/>' . "\n" .
68 $response->getContent());
71 public function testErrorWithRss()
73 $l10n = \Mockery::mock(L10n::class);
74 $args = \Mockery::mock(Arguments::class);
75 $args->shouldReceive('getQueryString')->andReturn('');
76 $baseUrl = \Mockery::mock(BaseURL::class);
77 $twitterUser = \Mockery::mock(User::class);
79 $response = new ApiResponse($l10n, $args, new NullLogger(), $baseUrl, $twitterUser);
80 $response->error(200, 'OK', 'error_message', 'rss');
82 self::assertEquals(['Content-type' => 'application/rss+xml', 'HTTP/1.1 200 OK'], $response->getHeaders());
84 '<?xml version="1.0"?>' . "\n" .
85 '<status xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" ' .
86 'xmlns:friendica="http://friendi.ca/schema/api/1/" ' .
87 'xmlns:georss="http://www.georss.org/georss">' . "\n" .
88 ' <error>error_message</error>' . "\n" .
89 ' <code>200 OK</code>' . "\n" .
90 ' <request/>' . "\n" .
92 $response->getContent());
95 public function testErrorWithAtom()
97 $l10n = \Mockery::mock(L10n::class);
98 $args = \Mockery::mock(Arguments::class);
99 $args->shouldReceive('getQueryString')->andReturn('');
100 $baseUrl = \Mockery::mock(BaseURL::class);
101 $twitterUser = \Mockery::mock(User::class);
103 $response = new ApiResponse($l10n, $args, new NullLogger(), $baseUrl, $twitterUser);
104 $response->error(200, 'OK', 'error_message', 'atom');
106 self::assertEquals(['Content-type' => 'application/atom+xml', 'HTTP/1.1 200 OK'], $response->getHeaders());
108 '<?xml version="1.0"?>' . "\n" .
109 '<status xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" ' .
110 'xmlns:friendica="http://friendi.ca/schema/api/1/" ' .
111 'xmlns:georss="http://www.georss.org/georss">' . "\n" .
112 ' <error>error_message</error>' . "\n" .
113 ' <code>200 OK</code>' . "\n" .
114 ' <request/>' . "\n" .
116 $response->getContent());
119 public function testUnsupported()
121 $l10n = \Mockery::mock(L10n::class);
122 $l10n->shouldReceive('t')->andReturnUsing(function ($args) {
125 $args = \Mockery::mock(Arguments::class);
126 $args->shouldReceive('getQueryString')->andReturn('');
127 $baseUrl = \Mockery::mock(BaseURL::class);
128 $twitterUser = \Mockery::mock(User::class);
130 $response = new ApiResponse($l10n, $args, new NullLogger(), $baseUrl, $twitterUser);
131 $response->unsupported();
133 self::assertEquals('{"error":"API endpoint %s %s is not implemented but might be in the future.","code":"501 Not Implemented","request":""}', $response->getContent());
137 * Test the BaseApi::reformatXML() function.
141 public function testApiReformatXml()
145 self::assertTrue(ApiResponse::reformatXML($item, $key));
146 self::assertEquals('true', $item);
150 * Test the BaseApi::reformatXML() function with a statusnet_api key.
154 public function testApiReformatXmlWithStatusnetKey()
157 $key = 'statusnet_api';
158 self::assertTrue(ApiResponse::reformatXML($item, $key));
159 self::assertEquals('statusnet:api', $key);
163 * Test the BaseApi::reformatXML() function with a friendica_api key.
167 public function testApiReformatXmlWithFriendicaKey()
170 $key = 'friendica_api';
171 self::assertTrue(ApiResponse::reformatXML($item, $key));
172 self::assertEquals('friendica:api', $key);
176 * Test the BaseApi::createXML() function.
180 public function testApiCreateXml()
182 $l10n = \Mockery::mock(L10n::class);
183 $l10n->shouldReceive('t')->andReturnUsing(function ($args) {
186 $args = \Mockery::mock(Arguments::class);
187 $args->shouldReceive('getQueryString')->andReturn('');
188 $baseUrl = \Mockery::mock(BaseURL::class);
189 $twitterUser = \Mockery::mock(User::class);
191 $response = new ApiResponse($l10n, $args, new NullLogger(), $baseUrl, $twitterUser);
194 '<?xml version="1.0"?>' . "\n" .
195 '<root_element xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" ' .
196 'xmlns:friendica="http://friendi.ca/schema/api/1/" ' .
197 'xmlns:georss="http://www.georss.org/georss">' . "\n" .
198 ' <data>some_data</data>' . "\n" .
199 '</root_element>' . "\n",
200 $response->createXML(['data' => ['some_data']], 'root_element')
205 * Test the BaseApi::createXML() function without any XML namespace.
209 public function testApiCreateXmlWithoutNamespaces()
211 $l10n = \Mockery::mock(L10n::class);
212 $l10n->shouldReceive('t')->andReturnUsing(function ($args) {
215 $args = \Mockery::mock(Arguments::class);
216 $args->shouldReceive('getQueryString')->andReturn('');
217 $baseUrl = \Mockery::mock(BaseURL::class);
218 $twitterUser = \Mockery::mock(User::class);
220 $response = new ApiResponse($l10n, $args, new NullLogger(), $baseUrl, $twitterUser);
223 '<?xml version="1.0"?>' . "\n" .
225 ' <data>some_data</data>' . "\n" .
227 $response->createXML(['data' => ['some_data']], 'ok')
232 * Test the BaseApi::formatData() function.
236 public function testApiFormatData()
238 $l10n = \Mockery::mock(L10n::class);
239 $l10n->shouldReceive('t')->andReturnUsing(function ($args) {
242 $args = \Mockery::mock(Arguments::class);
243 $args->shouldReceive('getQueryString')->andReturn('');
244 $baseUrl = \Mockery::mock(BaseURL::class);
245 $twitterUser = \Mockery::mock(User::class);
247 $response = new ApiResponse($l10n, $args, new NullLogger(), $baseUrl, $twitterUser);
249 $data = ['some_data'];
250 self::assertEquals($data, $response->formatData('root_element', 'json', $data));
254 * Test the BaseApi::formatData() function with an XML result.
258 public function testApiFormatDataWithXml()
260 $l10n = \Mockery::mock(L10n::class);
261 $l10n->shouldReceive('t')->andReturnUsing(function ($args) {
264 $args = \Mockery::mock(Arguments::class);
265 $args->shouldReceive('getQueryString')->andReturn('');
266 $baseUrl = \Mockery::mock(BaseURL::class);
267 $twitterUser = \Mockery::mock(User::class);
269 $response = new ApiResponse($l10n, $args, new NullLogger(), $baseUrl, $twitterUser);
272 '<?xml version="1.0"?>' . "\n" .
273 '<root_element xmlns="http://api.twitter.com" xmlns:statusnet="http://status.net/schema/api/1/" ' .
274 'xmlns:friendica="http://friendi.ca/schema/api/1/" ' .
275 'xmlns:georss="http://www.georss.org/georss">' . "\n" .
276 ' <data>some_data</data>' . "\n" .
277 '</root_element>' . "\n",
278 $response->formatData('root_element', 'xml', ['data' => ['some_data']])
283 * Test the api_rss_extra() function.
287 public function testApiRssExtra()
289 self::markTestIncomplete('Cannot mock it yet.');
292 $user_info = ['url' => 'user_url', 'lang' => 'en'];
293 $userMock = \Mockery::mock(\Friendica\Object\Api\Twitter\User::class);
294 $userMock->shouldReceive('toArray')->andReturn($user_info);
296 $l10n = \Mockery::mock(L10n::class);
297 $l10n->shouldReceive('t')->andReturnUsing(function ($args) {
300 $args = \Mockery::mock(Arguments::class);
301 $args->shouldReceive('getQueryString')->andReturn('');
302 $baseUrl = \Mockery::mock(BaseURL::class);
303 $baseUrl->shouldReceive('__toString')->andReturn('https://friendica.local');
304 $twitterUser = \Mockery::mock(User::class);
305 $twitterUser->shouldReceive('createFromContactId')->with(1)->andReturn($userMock);
307 $response = new ApiResponse($l10n, $args, new NullLogger(), $baseUrl, $twitterUser);
309 $result = $response->formatData('root_element', 'rss', ['data' => ['some_data']], 1);
313 self::assertEquals($user_info, $result['$user']);
314 self::assertEquals($user_info['url'], $result['$rss']['alternate']);
315 self::assertArrayHasKey('self', $result['$rss']);
316 self::assertArrayHasKey('base', $result['$rss']);
317 self::assertArrayHasKey('updated', $result['$rss']);
318 self::assertArrayHasKey('atom_updated', $result['$rss']);
319 self::assertArrayHasKey('language', $result['$rss']);
320 self::assertArrayHasKey('logo', $result['$rss']);
325 * Test the api_rss_extra() function without any user info.
329 public function testApiRssExtraWithoutUserInfo()
331 self::markTestIncomplete('Cannot mock it yet.');
334 $result = api_rss_extra([], null);
335 self::assertIsArray($result['$user']);
336 self::assertArrayHasKey('alternate', $result['$rss']);
337 self::assertArrayHasKey('self', $result['$rss']);
338 self::assertArrayHasKey('base', $result['$rss']);
339 self::assertArrayHasKey('updated', $result['$rss']);
340 self::assertArrayHasKey('atom_updated', $result['$rss']);
341 self::assertArrayHasKey('language', $result['$rss']);
342 self::assertArrayHasKey('logo', $result['$rss']);