Remove dependency on super-globals in Module\Api\ApiResponse
- Updated DI dependencies to reflect the new parameters - Updated tests to reflect the new parameters
This commit is contained in:
parent
d165a96220
commit
960171c4e0
3 changed files with 85 additions and 8 deletions
|
@ -25,6 +25,7 @@ use Friendica\App\Arguments;
|
||||||
use Friendica\App\BaseURL;
|
use Friendica\App\BaseURL;
|
||||||
use Friendica\Core\L10n;
|
use Friendica\Core\L10n;
|
||||||
use Friendica\Module\Response;
|
use Friendica\Module\Response;
|
||||||
|
use Friendica\Network\HTTPException;
|
||||||
use Friendica\Util\Arrays;
|
use Friendica\Util\Arrays;
|
||||||
use Friendica\Util\DateTimeFormat;
|
use Friendica\Util\DateTimeFormat;
|
||||||
use Friendica\Util\XML;
|
use Friendica\Util\XML;
|
||||||
|
@ -46,14 +47,20 @@ class ApiResponse extends Response
|
||||||
protected $baseUrl;
|
protected $baseUrl;
|
||||||
/** @var TwitterUser */
|
/** @var TwitterUser */
|
||||||
protected $twitterUser;
|
protected $twitterUser;
|
||||||
|
/** @var array */
|
||||||
|
protected $server;
|
||||||
|
/** @var string */
|
||||||
|
protected $jsonpCallback;
|
||||||
|
|
||||||
public function __construct(L10n $l10n, Arguments $args, LoggerInterface $logger, BaseURL $baseUrl, TwitterUser $twitterUser)
|
public function __construct(L10n $l10n, Arguments $args, LoggerInterface $logger, BaseURL $baseUrl, TwitterUser $twitterUser, array $server = [], string $jsonpCallback = '')
|
||||||
{
|
{
|
||||||
$this->l10n = $l10n;
|
$this->l10n = $l10n;
|
||||||
$this->args = $args;
|
$this->args = $args;
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
$this->baseUrl = $baseUrl;
|
$this->baseUrl = $baseUrl;
|
||||||
$this->twitterUser = $twitterUser;
|
$this->twitterUser = $twitterUser;
|
||||||
|
$this->server = $server;
|
||||||
|
$this->jsonpCallback = $jsonpCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -63,6 +70,7 @@ class ApiResponse extends Response
|
||||||
* @param string $root_element Name of the root element
|
* @param string $root_element Name of the root element
|
||||||
*
|
*
|
||||||
* @return string The XML data
|
* @return string The XML data
|
||||||
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function createXML(array $data, string $root_element): string
|
public function createXML(array $data, string $root_element): string
|
||||||
{
|
{
|
||||||
|
@ -109,6 +117,7 @@ class ApiResponse extends Response
|
||||||
* @param int $cid Contact ID of template
|
* @param int $cid Contact ID of template
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
|
* @throws HTTPException\InternalServerErrorException
|
||||||
*/
|
*/
|
||||||
private function addRSSValues(array $arr, int $cid): array
|
private function addRSSValues(array $arr, int $cid): array
|
||||||
{
|
{
|
||||||
|
@ -141,6 +150,7 @@ class ApiResponse extends Response
|
||||||
* @param int $cid ID of the contact for RSS
|
* @param int $cid ID of the contact for RSS
|
||||||
*
|
*
|
||||||
* @return array|string (string|array) XML data or JSON data
|
* @return array|string (string|array) XML data or JSON data
|
||||||
|
* @throws HTTPException\InternalServerErrorException
|
||||||
*/
|
*/
|
||||||
public function formatData(string $root_element, string $type, array $data, int $cid = 0)
|
public function formatData(string $root_element, string $type, array $data, int $cid = 0)
|
||||||
{
|
{
|
||||||
|
@ -180,7 +190,7 @@ class ApiResponse extends Response
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exit with error code
|
* Add formatted error message to response
|
||||||
*
|
*
|
||||||
* @param int $code
|
* @param int $code
|
||||||
* @param string $description
|
* @param string $description
|
||||||
|
@ -188,6 +198,7 @@ class ApiResponse extends Response
|
||||||
* @param string|null $format
|
* @param string|null $format
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws HTTPException\InternalServerErrorException
|
||||||
*/
|
*/
|
||||||
public function error(int $code, string $description, string $message, string $format = null)
|
public function error(int $code, string $description, string $message, string $format = null)
|
||||||
{
|
{
|
||||||
|
@ -197,19 +208,21 @@ class ApiResponse extends Response
|
||||||
'request' => $this->args->getQueryString()
|
'request' => $this->args->getQueryString()
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->setHeader(($_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.1') . ' ' . $code . ' ' . $description);
|
$this->setHeader(($this->server['SERVER_PROTOCOL'] ?? 'HTTP/1.1') . ' ' . $code . ' ' . $description);
|
||||||
|
|
||||||
$this->exit('status', ['status' => $error], $format);
|
$this->exit('status', ['status' => $error], $format);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Outputs formatted data according to the data type and then exits the execution.
|
* Add formatted data according to the data type to the response.
|
||||||
*
|
*
|
||||||
* @param string $root_element
|
* @param string $root_element
|
||||||
* @param array $data An array with a single element containing the returned result
|
* @param array $data An array with a single element containing the returned result
|
||||||
* @param string|null $format Output format (xml, json, rss, atom)
|
* @param string|null $format Output format (xml, json, rss, atom)
|
||||||
|
* @param int $cid
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws HTTPException\InternalServerErrorException
|
||||||
*/
|
*/
|
||||||
public function exit(string $root_element, array $data, string $format = null, int $cid = 0)
|
public function exit(string $root_element, array $data, string $format = null, int $cid = 0)
|
||||||
{
|
{
|
||||||
|
@ -226,8 +239,8 @@ class ApiResponse extends Response
|
||||||
$this->setType(static::TYPE_JSON);
|
$this->setType(static::TYPE_JSON);
|
||||||
if (!empty($return)) {
|
if (!empty($return)) {
|
||||||
$json = json_encode(end($return));
|
$json = json_encode(end($return));
|
||||||
if (!empty($_GET['callback'])) {
|
if ($this->jsonpCallback) {
|
||||||
$json = $_GET['callback'] . '(' . $json . ')';
|
$json = $this->jsonpCallback . '(' . $json . ')';
|
||||||
}
|
}
|
||||||
$return = $json;
|
$return = $json;
|
||||||
}
|
}
|
||||||
|
@ -251,6 +264,7 @@ class ApiResponse extends Response
|
||||||
* @param array $data
|
* @param array $data
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws HTTPException\InternalServerErrorException
|
||||||
*/
|
*/
|
||||||
public function exitWithJson(array $data)
|
public function exitWithJson(array $data)
|
||||||
{
|
{
|
||||||
|
@ -273,7 +287,7 @@ class ApiResponse extends Response
|
||||||
[
|
[
|
||||||
'method' => $method,
|
'method' => $method,
|
||||||
'path' => $path,
|
'path' => $path,
|
||||||
'agent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
|
'agent' => $this->server['HTTP_USER_AGENT'] ?? '',
|
||||||
'request' => $request,
|
'request' => $request,
|
||||||
]);
|
]);
|
||||||
$error = $this->l10n->t('API endpoint %s %s is not implemented but might be in the future.', strtoupper($method), $path);
|
$error = $this->l10n->t('API endpoint %s %s is not implemented but might be in the future.', strtoupper($method), $path);
|
||||||
|
|
|
@ -330,4 +330,10 @@ return [
|
||||||
$_SERVER
|
$_SERVER
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
\Friendica\Module\Api\ApiResponse::class => [
|
||||||
|
'constructParams' => [
|
||||||
|
$_SERVER,
|
||||||
|
$_GET['callback'] ?? '',
|
||||||
|
],
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|
|
@ -127,7 +127,30 @@ class ApiResponseTest extends MockedTest
|
||||||
$baseUrl = \Mockery::mock(BaseURL::class);
|
$baseUrl = \Mockery::mock(BaseURL::class);
|
||||||
$twitterUser = \Mockery::mock(User::class);
|
$twitterUser = \Mockery::mock(User::class);
|
||||||
|
|
||||||
$response = new ApiResponse($l10n, $args, new NullLogger(), $baseUrl, $twitterUser);
|
$logger = \Mockery::mock(NullLogger::class);
|
||||||
|
$logger->shouldReceive('info')->withArgs(['Unimplemented API call', ['method' => 'all', 'path' => '', 'agent' => '', 'request' => []]]);
|
||||||
|
|
||||||
|
$response = new ApiResponse($l10n, $args, $logger, $baseUrl, $twitterUser);
|
||||||
|
$response->unsupported();
|
||||||
|
|
||||||
|
self::assertEquals('{"error":"API endpoint %s %s is not implemented but might be in the future.","code":"501 Not Implemented","request":""}', $response->getContent());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUnsupportedUserAgent()
|
||||||
|
{
|
||||||
|
$l10n = \Mockery::mock(L10n::class);
|
||||||
|
$l10n->shouldReceive('t')->andReturnUsing(function ($args) {
|
||||||
|
return $args;
|
||||||
|
});
|
||||||
|
$args = \Mockery::mock(Arguments::class);
|
||||||
|
$args->shouldReceive('getQueryString')->andReturn('');
|
||||||
|
$baseUrl = \Mockery::mock(BaseURL::class);
|
||||||
|
$twitterUser = \Mockery::mock(User::class);
|
||||||
|
|
||||||
|
$logger = \Mockery::mock(NullLogger::class);
|
||||||
|
$logger->shouldReceive('info')->withArgs(['Unimplemented API call', ['method' => 'all', 'path' => '', 'agent' => 'PHPUnit', 'request' => []]]);
|
||||||
|
|
||||||
|
$response = new ApiResponse($l10n, $args, $logger, $baseUrl, $twitterUser, ['HTTP_USER_AGENT' => 'PHPUnit']);
|
||||||
$response->unsupported();
|
$response->unsupported();
|
||||||
|
|
||||||
self::assertEquals('{"error":"API endpoint %s %s is not implemented but might be in the future.","code":"501 Not Implemented","request":""}', $response->getContent());
|
self::assertEquals('{"error":"API endpoint %s %s is not implemented but might be in the future.","code":"501 Not Implemented","request":""}', $response->getContent());
|
||||||
|
@ -250,6 +273,40 @@ class ApiResponseTest extends MockedTest
|
||||||
self::assertEquals($data, $response->formatData('root_element', 'json', $data));
|
self::assertEquals($data, $response->formatData('root_element', 'json', $data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testApiExitWithJson()
|
||||||
|
{
|
||||||
|
$l10n = \Mockery::mock(L10n::class);
|
||||||
|
$l10n->shouldReceive('t')->andReturnUsing(function ($args) {
|
||||||
|
return $args;
|
||||||
|
});
|
||||||
|
$args = \Mockery::mock(Arguments::class);
|
||||||
|
$args->shouldReceive('getQueryString')->andReturn('');
|
||||||
|
$baseUrl = \Mockery::mock(BaseURL::class);
|
||||||
|
$twitterUser = \Mockery::mock(User::class);
|
||||||
|
|
||||||
|
$response = new ApiResponse($l10n, $args, new NullLogger(), $baseUrl, $twitterUser);
|
||||||
|
$response->exitWithJson(['some_data']);
|
||||||
|
|
||||||
|
self::assertEquals('["some_data"]', $response->getContent());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testApiExitWithJsonP()
|
||||||
|
{
|
||||||
|
$l10n = \Mockery::mock(L10n::class);
|
||||||
|
$l10n->shouldReceive('t')->andReturnUsing(function ($args) {
|
||||||
|
return $args;
|
||||||
|
});
|
||||||
|
$args = \Mockery::mock(Arguments::class);
|
||||||
|
$args->shouldReceive('getQueryString')->andReturn('');
|
||||||
|
$baseUrl = \Mockery::mock(BaseURL::class);
|
||||||
|
$twitterUser = \Mockery::mock(User::class);
|
||||||
|
|
||||||
|
$response = new ApiResponse($l10n, $args, new NullLogger(), $baseUrl, $twitterUser, [], 'JsonPCallback');
|
||||||
|
$response->exitWithJson(['some_data']);
|
||||||
|
|
||||||
|
self::assertEquals('JsonPCallback(["some_data"])', $response->getContent());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test the BaseApi::formatData() function with an XML result.
|
* Test the BaseApi::formatData() function with an XML result.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in a new issue