use Friendica\App\BaseURL;
use Friendica\Core\L10n;
use Friendica\Module\Response;
+use Friendica\Network\HTTPException;
use Friendica\Util\Arrays;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\XML;
protected $baseUrl;
/** @var 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->args = $args;
$this->logger = $logger;
$this->baseUrl = $baseUrl;
$this->twitterUser = $twitterUser;
+ $this->server = $server;
+ $this->jsonpCallback = $jsonpCallback;
}
/**
* @param string $root_element Name of the root element
*
* @return string The XML data
+ * @throws \Exception
*/
public function createXML(array $data, string $root_element): string
{
* @param int $cid Contact ID of template
*
* @return array
+ * @throws HTTPException\InternalServerErrorException
*/
private function addRSSValues(array $arr, int $cid): array
{
* @param int $cid ID of the contact for RSS
*
* @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)
{
}
/**
- * Exit with error code
+ * Add formatted error message to response
*
* @param int $code
* @param string $description
* @param string|null $format
*
* @return void
+ * @throws HTTPException\InternalServerErrorException
*/
public function error(int $code, string $description, string $message, string $format = null)
{
'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);
}
/**
- * 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 array $data An array with a single element containing the returned result
* @param string|null $format Output format (xml, json, rss, atom)
+ * @param int $cid
*
* @return void
+ * @throws HTTPException\InternalServerErrorException
*/
public function exit(string $root_element, array $data, string $format = null, int $cid = 0)
{
$this->setType(static::TYPE_JSON);
if (!empty($return)) {
$json = json_encode(end($return));
- if (!empty($_GET['callback'])) {
- $json = $_GET['callback'] . '(' . $json . ')';
+ if ($this->jsonpCallback) {
+ $json = $this->jsonpCallback . '(' . $json . ')';
}
$return = $json;
}
* @param array $data
*
* @return void
+ * @throws HTTPException\InternalServerErrorException
*/
public function exitWithJson(array $data)
{
[
'method' => $method,
'path' => $path,
- 'agent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
+ 'agent' => $this->server['HTTP_USER_AGENT'] ?? '',
'request' => $request,
]);
$error = $this->l10n->t('API endpoint %s %s is not implemented but might be in the future.', strtoupper($method), $path);
$baseUrl = \Mockery::mock(BaseURL::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();
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($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.
*