Cleanup API

This commit is contained in:
Romain Neutron
2014-02-24 23:38:20 +01:00
parent 2df0f9d659
commit 08efd8ff72
43 changed files with 2676 additions and 5127 deletions

View File

@@ -16,7 +16,6 @@ main:
driver: pdo_sqlite driver: pdo_sqlite
path: '/tmp/db.sqlite' path: '/tmp/db.sqlite'
charset: UTF8 charset: UTF8
api-timers: false
cache: cache:
type: MemcacheCache type: MemcacheCache
options: options:

View File

@@ -12,17 +12,18 @@
namespace Alchemy\Phrasea\Application; namespace Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Application as PhraseaApplication; use Alchemy\Phrasea\Application as PhraseaApplication;
use Alchemy\Phrasea\Core\PhraseaEvents;
use Alchemy\Phrasea\Controller\Api\Oauth2; use Alchemy\Phrasea\Controller\Api\Oauth2;
use Alchemy\Phrasea\Controller\Api\Result;
use Alchemy\Phrasea\Controller\Api\V1; use Alchemy\Phrasea\Controller\Api\V1;
use Alchemy\Phrasea\Core\Event\ApiLoadEndEvent; use Alchemy\Phrasea\Core\Event\ApiResultEvent;
use Alchemy\Phrasea\Core\Event\ApiLoadStartEvent;
use Alchemy\Phrasea\Core\Event\Subscriber\ApiOauth2ErrorsSubscriber; use Alchemy\Phrasea\Core\Event\Subscriber\ApiOauth2ErrorsSubscriber;
use Alchemy\Phrasea\Core\Event\Subscriber\ApiExceptionHandlerSubscriber; use Alchemy\Phrasea\Core\Event\Subscriber\ApiExceptionHandlerSubscriber;
use Alchemy\Phrasea\Core\PhraseaEvents;
use Monolog\Logger; use Monolog\Logger;
use Monolog\Processor\WebProcessor; use Monolog\Processor\WebProcessor;
use Silex\Application as SilexApplication; use Silex\Application as SilexApplication;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
return call_user_func(function ($environment = PhraseaApplication::ENV_PROD) { return call_user_func(function ($environment = PhraseaApplication::ENV_PROD) {
@@ -38,22 +39,15 @@ return call_user_func(function ($environment = PhraseaApplication::ENV_PROD) {
return $monolog; return $monolog;
})); }));
$app->register(new \API_V1_Timer());
$app['dispatcher']->dispatch(PhraseaEvents::API_LOAD_START, new ApiLoadStartEvent());
$app->get('/api/', function (Request $request, SilexApplication $app) { $app->get('/api/', function (Request $request, SilexApplication $app) {
$apiAdapter = new \API_V1_adapter($app); return Result::create($request, [
$result = new \API_V1_result($app, $request, $apiAdapter);
return $result->set_datas([
'name' => $app['conf']->get(['registry', 'general', 'title']), 'name' => $app['conf']->get(['registry', 'general', 'title']),
'type' => 'phraseanet', 'type' => 'phraseanet',
'description' => $app['conf']->get(['registry', 'general', 'description']), 'description' => $app['conf']->get(['registry', 'general', 'description']),
'documentation' => 'https://docs.phraseanet.com/Devel', 'documentation' => 'https://docs.phraseanet.com/Devel',
'versions' => [ 'versions' => [
'1' => [ '1' => [
'number' => $apiAdapter->get_version(), 'number' => V1::VERSION,
'uri' => '/api/v1/', 'uri' => '/api/v1/',
'authenticationProtocol' => 'OAuth2', 'authenticationProtocol' => 'OAuth2',
'authenticationVersion' => 'draft#v9', 'authenticationVersion' => 'draft#v9',
@@ -63,14 +57,20 @@ return call_user_func(function ($environment = PhraseaApplication::ENV_PROD) {
] ]
] ]
] ]
])->get_response(); ])->createResponse();
}); });
$app->mount('/api/oauthv2', new Oauth2()); $app->mount('/api/oauthv2', new Oauth2());
$app->mount('/api/v1', new V1()); $app->mount('/api/v1', new V1());
$app['dispatcher']->addSubscriber(new ApiOauth2ErrorsSubscriber($app['phraseanet.exception_handler'], $app['translator'])); $app['dispatcher'] = $app->share($app->extend('dispatcher', function ($dispatcher, PhraseaApplication $app) {
$app['dispatcher']->dispatch(PhraseaEvents::API_LOAD_END, new ApiLoadEndEvent()); $dispatcher->addSubscriber(new ApiOauth2ErrorsSubscriber($app['phraseanet.exception_handler'], $app['translator']));
return $dispatcher;
}));
$app->after(function (Request $request, Response $response) use ($app) {
$app['dispatcher']->dispatch(PhraseaEvents::API_RESULT, new ApiResultEvent($request, $response));
});
return $app; return $app;
}, isset($environment) ? $environment : PhraseaApplication::ENV_PROD); }, isset($environment) ? $environment : PhraseaApplication::ENV_PROD);

View File

@@ -9,80 +9,82 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
namespace Alchemy\Phrasea\Controller\Api;
use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Application;
class API_V1_Log class Logger
{ {
const DATABOXES_RESSOURCE = 'databoxes'; const DATABOXES_RESOURCE = 'databoxes';
const RECORDS_RESSOURCE = 'record'; const RECORDS_RESOURCE = 'record';
const BASKETS_RESSOURCE = 'baskets'; const BASKETS_RESOURCE = 'baskets';
const FEEDS_RESSOURCE = 'feeds'; const FEEDS_RESOURCE = 'feeds';
/** /**
* *
* @var int * @var int
*/ */
protected $id; private $id;
/** /**
* *
* @var int * @var int
*/ */
protected $account_id; private $account_id;
/** /**
* *
* @var DateTime * @var DateTime
*/ */
protected $date; private $date;
/** /**
* *
* @var int * @var int
*/ */
protected $status_code; private $status_code;
/** /**
* *
* @var string * @var string
*/ */
protected $format; private $format;
/** /**
* *
* @var string * @var string
*/ */
protected $ressource; private $resource;
/** /**
* *
* @var string * @var string
*/ */
protected $general; private $general;
/** /**
* *
* @var string * @var string
*/ */
protected $aspect; private $aspect;
/** /**
* *
* @var string * @var string
*/ */
protected $action; private $action;
/** /**
* *
* @var API_OAuth2_Account * @var API_OAuth2_Account
*/ */
protected $account; private $account;
/** /**
* *
* @var Application * @var Application
*/ */
protected $app; private $app;
/** /**
* *
@@ -102,7 +104,7 @@ class API_V1_Log
api_log_date, api_log_date,
api_log_status_code, api_log_status_code,
api_log_format, api_log_format,
api_log_ressource, api_log_resource,
api_log_general, api_log_general,
api_log_aspect, api_log_aspect,
api_log_action api_log_action
@@ -113,16 +115,16 @@ class API_V1_Log
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql); $stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
$stmt->execute([':log_id' => $this->id]); $stmt->execute([':log_id' => $this->id]);
$row = $stmt->fetch(PDO::FETCH_ASSOC); $row = $stmt->fetch(\PDO::FETCH_ASSOC);
$stmt->closeCursor(); $stmt->closeCursor();
$this->account_id = $row['api_account_id']; $this->account_id = $row['api_account_id'];
$this->account = new API_OAuth2_Account($this->app, (int) $row['api_account_id']); $this->account = new \API_OAuth2_Account($this->app, (int) $row['api_account_id']);
$this->aspect = $row['api_log_aspect']; $this->aspect = $row['api_log_aspect'];
$this->date = new DateTime($row['api_log_date']); $this->date = new \DateTime($row['api_log_date']);
$this->format = $row['api_log_format']; $this->format = $row['api_log_format'];
$this->general = $row['api_log_general']; $this->general = $row['api_log_general'];
$this->ressource = $row['api_log_ressource']; $this->resource = $row['api_log_resource'];
$this->status_code = (int) $row['api_log_status_code']; $this->status_code = (int) $row['api_log_status_code'];
return $this; return $this;
@@ -212,7 +214,7 @@ class API_V1_Log
{ {
if ( ! in_array($format, ['json', 'jsonp', 'yaml', 'unknow'])) if ( ! in_array($format, ['json', 'jsonp', 'yaml', 'unknow']))
throw new Exception_InvalidArgument(); throw new \Exception_InvalidArgument();
$this->format = $format; $this->format = $format;
@@ -232,25 +234,25 @@ class API_V1_Log
return $this; return $this;
} }
public function get_ressource() public function get_resource()
{ {
return $this->ressource; return $this->resource;
} }
public function set_ressource($ressource) public function set_resource($resource)
{ {
if ( ! in_array($format, [self::DATABOXES_RESSOURCE, self::BASKETS_RESSOURCE, self::FEEDS_RESSOURCE, self::RECORDS_RESSOURCE])) if ( ! in_array($resource, [self::DATABOXES_RESOURCE, self::BASKETS_RESOURCE, self::FEEDS_RESOURCE, self::RECORDS_RESOURCE]))
throw new Exception_InvalidArgument(); throw new \Exception_InvalidArgument();
$this->ressource = $ressource; $this->resource = $resource;
$sql = 'UPDATE api_log $sql = 'UPDATE api_log
SET api_log_ressource = :ressource SET api_log_resource = :resource
WHERE api_log_id = :log_id'; WHERE api_log_id = :log_id';
$params = [ $params = [
':ressource' => $this->ressource ':resource' => $this->resource,
, ':log_id' => $this->id ':log_id' => $this->id,
]; ];
$stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql); $stmt = $this->app['phraseanet.appbox']->get_connection()->prepare($sql);
@@ -340,7 +342,7 @@ class API_V1_Log
return $this->account; return $this->account;
} }
public static function create(Application $app, API_OAuth2_Account $account, $route, $status_code, $format, $ressource, $general = null, $aspect = null, $action = null) public static function create(Application $app, \API_OAuth2_Account $account, $route, $status_code, $format, $resource, $general = null, $aspect = null, $action = null)
{ {
$sql = ' $sql = '
INSERT INTO INSERT INTO
@@ -351,7 +353,7 @@ class API_V1_Log
api_log_date, api_log_date,
api_log_status_code, api_log_status_code,
api_log_format, api_log_format,
api_log_ressource, api_log_resource,
api_log_general, api_log_general,
api_log_aspect, api_log_aspect,
api_log_action api_log_action
@@ -363,7 +365,7 @@ class API_V1_Log
NOW(), NOW(),
:status_code, :status_code,
:format, :format,
:ressource, :resource,
:general, :general,
:aspect, :aspect,
:action :action
@@ -374,7 +376,7 @@ class API_V1_Log
':route' => $route, ':route' => $route,
':status_code' => $status_code, ':status_code' => $status_code,
':format' => $format, ':format' => $format,
':ressource' => $ressource, ':resource' => $resource,
':general' => $general, ':general' => $general,
':aspect' => $aspect, ':aspect' => $aspect,
':action' => $action ':action' => $action

View File

@@ -0,0 +1,267 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Controller\Api;
use Silex\Application;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Yaml\Dumper;
class Result
{
/** @var string */
private $responseTime;
/** @var integer */
private $code = 200;
/** @var string */
private $errorType;
/** @var string */
private $errorMessage;
/** @var string */
private $errorDetails;
/** @var Request */
private $request;
/** @var mixed */
private $data;
/** @var string */
private $responseType;
const FORMAT_JSON = 'json';
const FORMAT_YAML = 'yaml';
const FORMAT_JSONP = 'jsonp';
const ERROR_BAD_REQUEST = 'Bad Request';
const ERROR_UNAUTHORIZED = 'Unauthorized';
const ERROR_FORBIDDEN = 'Forbidden';
const ERROR_NOTFOUND = 'Not Found';
const ERROR_MAINTENANCE = 'Service Temporarily Unavailable';
const ERROR_METHODNOTALLOWED = 'Method Not Allowed';
const ERROR_INTERNALSERVERERROR = 'Internal Server Error';
public function __construct(Request $request, array $data = null, $code = 200, $errorType = null, $errorMessage = null, $errorDetails = null)
{
$date = new \DateTime();
$this->request = $request;
$this->responseTime = $date->format(DATE_ATOM);
$this->data = new \stdClass();
$this->parseResponseType();
$this->setData($data);
$this->code = $code;
$this->errorType = $errorType;
$this->errorMessage = $errorMessage;
$this->errorDetails = $errorDetails;
return $this;
}
/**
* Creates a Symfony Response
*
* @return Response
*/
public function createResponse()
{
$response = new Response($this->format(), $this->getStatusCode(), ['Content-Type' => $this->getContentType()]);
$response->setCharset('UTF-8');
return $response;
}
/**
* @param Request $request
* @param $data
*
* @return Result
*/
public static function create(Request $request, $data)
{
return new static($request, $data);
}
/**
* @param Request $request
* @param $code
* @param $message
*
* @return Result
*
* @throws InvalidArgumentException
*/
public static function createError(Request $request, $code, $message)
{
$errorDetails = $message;
switch ($code) {
case 400:
$errorType = self::ERROR_BAD_REQUEST;
$errorMessage = 'Parameter is invalid or missing';
break;
case 401:
$errorType = self::ERROR_UNAUTHORIZED;
$errorMessage = 'The OAuth token was provided but was invalid.';
break;
case 403:
$errorType = self::ERROR_FORBIDDEN;
$errorMessage = 'Access to the requested resource is forbidden';
break;
case 404:
$errorType = self::ERROR_NOTFOUND;
$errorMessage = 'Requested resource is not found';
break;
case 405:
$errorType = self::ERROR_METHODNOTALLOWED;
$errorMessage = 'Attempting to use POST with a GET-only endpoint, or vice-versa';
break;
case 500:
$errorType = self::ERROR_INTERNALSERVERERROR;
$errorMessage = 'Internal Server Error';
break;
case 503:
$errorType = self::ERROR_MAINTENANCE;
$errorMessage = 'Server is offline for maintenance, try again soon.';
break;
default:
throw new \InvalidArgumentException('Unable to generate a response.');
}
return new static($request, null, $code, $errorType, $errorMessage, $errorDetails);
}
private function parseResponseType()
{
if (trim($this->request->get('callback')) !== '') {
return $this->responseType = self::FORMAT_JSONP;
}
$responseTypes = array_map('strtolower', $this->request->getAcceptableContentTypes());
if (in_array('application/json', $responseTypes)) {
return $this->responseType = self::FORMAT_JSON;
}
if (in_array('application/yaml', $responseTypes)) {
return $this->responseType = self::FORMAT_YAML;
}
if (in_array('text/yaml', $responseTypes)) {
return $this->responseType = self::FORMAT_YAML;
}
return $this->responseType = self::FORMAT_JSON;
}
/**
* Sets data to the response.
*
* If no datas provided, a stdClass if set,
* so the serialized datas will be objects
*
* @param array $datas
*
* @return Result
*/
private function setData(array $data = null)
{
if (null === $data || count($data) === 0) {
$data = new \stdClass();
}
$this->data = $data;
return $this;
}
/**
* Formats the data and return serialized string
*
* @return string
*/
private function format()
{
$request_uri = sprintf('%s %s', $this->request->getMethod(), $this->request->getBasePath().$this->request->getPathInfo());
$ret = [
'meta' => [
'api_version' => V1::VERSION,
'request' => $request_uri,
'response_time' => $this->responseTime,
'http_code' => $this->code,
'error_type' => $this->errorType,
'error_message' => $this->errorMessage,
'error_details' => $this->errorDetails,
'charset' => 'UTF-8',
],
'response' => $this->data,
];
switch ($this->responseType) {
case self::FORMAT_JSON:
default:
$return_value = \p4string::jsonencode($ret);
break;
case self::FORMAT_YAML:
if ($ret['response'] instanceof \stdClass) {
$ret['response'] = [];
}
$dumper = new Dumper();
$return_value = $dumper->dump($ret, 8);
break;
case self::FORMAT_JSONP:
$callback = trim($this->request->get('callback'));
$return_value = $callback . '(' . \p4string::jsonencode($ret) . ')';
break;
}
return $return_value;
}
/**
* Returns serialized data content type
*
* @return string
*/
private function getContentType()
{
switch ($this->responseType) {
case self::FORMAT_JSON:
default:
return 'application/json';
case self::FORMAT_YAML:
return 'application/yaml';
case self::FORMAT_JSONP:
return 'text/javascript';
}
}
/**
* Returns the correct http code depending on the errors
*
* @return integer
*/
private function getStatusCode()
{
if ($this->responseType == self::FORMAT_JSONP && $this->code != 500) {
return 200;
}
return $this->code;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,23 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Core\Event;
use Alchemy\Phrasea\Core\PhraseaEvents;
use Symfony\Component\EventDispatcher\Event as SfEvent;
class ApiLoadEndEvent extends SfEvent
{
public function getName()
{
return PhraseaEvents::API_LOAD_END;
}
}

View File

@@ -1,23 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Core\Event;
use Alchemy\Phrasea\Core\PhraseaEvents;
use Symfony\Component\EventDispatcher\Event as SfEvent;
class ApiLoadStartEvent extends SfEvent
{
public function getName()
{
return PhraseaEvents::API_LOAD_START;
}
}

View File

@@ -13,9 +13,39 @@ namespace Alchemy\Phrasea\Core\Event;
use Alchemy\Phrasea\Core\PhraseaEvents; use Alchemy\Phrasea\Core\PhraseaEvents;
use Symfony\Component\EventDispatcher\Event as SfEvent; use Symfony\Component\EventDispatcher\Event as SfEvent;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class ApiResultEvent extends SfEvent class ApiResultEvent extends SfEvent
{ {
private $request;
private $response;
public function __construct(Request $request, Response $response)
{
$this->request = $request;
$this->response = $response;
}
/**
* @return Request
*/
public function getRequest()
{
return $this->request;
}
/**
* @return Response
*/
public function getResponse()
{
return $this->response;
}
/**
* @return string
*/
public function getName() public function getName()
{ {
return PhraseaEvents::API_RESULT; return PhraseaEvents::API_RESULT;

View File

@@ -12,6 +12,7 @@
namespace Alchemy\Phrasea\Core\Event\Subscriber; namespace Alchemy\Phrasea\Core\Event\Subscriber;
use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Controller\Api\Result;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface;
@@ -43,43 +44,32 @@ class ApiExceptionHandlerSubscriber implements EventSubscriberInterface
$headers = []; $headers = [];
$e = $event->getException(); $e = $event->getException();
if ($e instanceof \API_V1_exception_methodnotallowed) { if ($e instanceof MethodNotAllowedHttpException) {
$code = \API_V1_result::ERROR_METHODNOTALLOWED; $code = 405;
} elseif ($e instanceof MethodNotAllowedHttpException) {
$code = \API_V1_result::ERROR_METHODNOTALLOWED;
} elseif ($e instanceof BadRequestHttpException) { } elseif ($e instanceof BadRequestHttpException) {
$code = \API_V1_result::ERROR_BAD_REQUEST; $code = 400;
} elseif ($e instanceof \API_V1_exception_badrequest) {
$code = \API_V1_result::ERROR_BAD_REQUEST;
} elseif ($e instanceof \API_V1_exception_forbidden) {
$code = \API_V1_result::ERROR_FORBIDDEN;
} elseif ($e instanceof \API_V1_exception_unauthorized) {
$code = \API_V1_result::ERROR_UNAUTHORIZED;
} elseif ($e instanceof \API_V1_exception_internalservererror) {
$code = \API_V1_result::ERROR_INTERNALSERVERERROR;
} elseif ($e instanceof AccessDeniedHttpException) { } elseif ($e instanceof AccessDeniedHttpException) {
$code = \API_V1_result::ERROR_FORBIDDEN; $code = 403;
} elseif ($e instanceof UnauthorizedHttpException) { } elseif ($e instanceof UnauthorizedHttpException) {
$code = \API_V1_result::ERROR_UNAUTHORIZED; $code = 401;
} elseif ($e instanceof NotFoundHttpException) { } elseif ($e instanceof NotFoundHttpException) {
$code = \API_V1_result::ERROR_NOTFOUND; $code = 404;
} elseif ($e instanceof HttpExceptionInterface) { } elseif ($e instanceof HttpExceptionInterface) {
if (503 === $e->getStatusCode()) { if (503 === $e->getStatusCode()) {
$code = \API_V1_result::ERROR_MAINTENANCE; $code = 503;
} else { } else {
$code = \API_V1_result::ERROR_INTERNALSERVERERROR; $code = 500;
} }
} else { } else {
$code = \API_V1_result::ERROR_INTERNALSERVERERROR; $code = 500;
} }
if ($e instanceof HttpExceptionInterface) { if ($e instanceof HttpExceptionInterface) {
$headers = $e->getHeaders(); $headers = $e->getHeaders();
} }
$result = $this->app['api']->get_error_message($event->getRequest(), $code, $e->getMessage()); $response = Result::createError($event->getRequest(), $code, $e->getMessage())->createResponse();
$response = $result->get_response(); $response->headers->set('X-Status-Code', $response->getStatusCode());
$response->headers->set('X-Status-Code', $result->get_http_code());
foreach ($headers as $key => $value) { foreach ($headers as $key => $value) {
$response->headers->set($key, $value); $response->headers->set($key, $value);

View File

@@ -276,12 +276,11 @@ class API_OAuth2_Token
$row = $stmt->fetch(PDO::FETCH_ASSOC); $row = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor(); $stmt->closeCursor();
if ( ! $row) if (!$row) {
throw new NotFoundHttpException('Account not found'); throw new NotFoundHttpException('Account not found');
}
$account = new API_OAuth2_Account($app, $row['api_account_id']); return new self($app['phraseanet.appbox'], new API_OAuth2_Account($app, $row['api_account_id']));
return new self($app['phraseanet.appbox'], $account);
} }
/** /**

View File

@@ -1,15 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
abstract class API_V1_Abstract implements API_V1_Interface
{
}

View File

@@ -1,309 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Alchemy\Phrasea\Model\Entities\Basket;
use Alchemy\Phrasea\Model\Entities\User;
use Symfony\Component\HttpFoundation\Request;
use Silex\Application;
interface API_V1_Interface
{
public function get_version();
/**
* Route : /databoxes/list/FORMAT/
*
* Method : GET
*
* Parameters :
*
*/
public function get_databoxes(Request $request);
/**
* Route /databoxes/DATABOX_ID/collections/FORMAT/
*
* Method : GET
*
* Parameters ;
* DATABOX_ID : required INT
*/
public function get_databox_collections(Request $request, $databox_id);
/**
* Route /databoxes/DATABOX_ID/status/FORMAT/
*
* Method : GET
*
* Parameters ;
* DATABOX_ID : required INT
*/
public function get_databox_status(Request $request, $databox_id);
/**
* Route /databoxes/DATABOX_ID/metadatas/FORMAT/
*
* Method : GET
*
* Parameters ;
* DATABOX_ID : required INT
*/
public function get_databox_metadatas(Request $request, $databox_id);
/**
* Route /databoxes/DATABOX_ID/termsOfUse/FORMAT/
*
* Method : GET
*
* Parameters ;
* DATABOX_ID : required INT
*/
public function get_databox_terms(Request $request, $databox_id);
/**
* Route : /records/search/FORMAT/
*
* Method : GET or POST
*
* Parameters :
* bases[] : array
* status[] : array
* fields[] : array
* record_type : boolean
* media_type : string
*
* Response :
* Array of record objects
*
*/
public function search_records(Request $request);
/**
* Route : /records/DATABOX_ID/RECORD_ID/related/FORMAT/
*
* Method : GET
*
* Parameters :
* DATABOX_ID : required INT
* RECORD_ID : required INT
*
*/
public function get_record_related(Request $request, $databox_id, $record_id);
/**
* Route : /records/DATABOX_ID/RECORD_ID/metadatas/FORMAT/
*
* Method : GET
*
* Parameters :
* DATABOX_ID : required INT
* RECORD_ID : required INT
*
*/
public function get_record_metadatas(Request $request, $databox_id, $record_id);
/**
* Route : /records/DATABOX_ID/RECORD_ID/status/FORMAT/
*
* Method : GET
*
* Parameters :
* DATABOX_ID : required INT
* RECORD_ID : required INT
*
*/
public function get_record_status(Request $request, $databox_id, $record_id);
/**
* Route : /records/DATABOX_ID/RECORD_ID/embed/FORMAT/
*
* Method : GET
*
* Parameters :
* DATABOX_ID : required INT
* RECORD_ID : required INT
*
*/
public function get_record_embed(Request $request, $databox_id, $record_id);
/**
* Route : /records/DATABOX_ID/RECORD_ID/setmetadatas/FORMAT/
*
* Method : POST
*
* Parameters :
* DATABOX_ID : required INT
* RECORD_ID : required INT
*
*/
public function set_record_metadatas(Request $request, $databox_id, $record_id);
/**
* Route : /records/DATABOX_ID/RECORD_ID/setstatus/FORMAT/
*
* Method : POST
*
* Parameters :
* DATABOX_ID : required INT
* RECORD_ID : required INT
*
*/
public function set_record_status(Request $request, $databox_id, $record_id);
/**
* Route : /records/DATABOX_ID/RECORD_ID/setcollection/FORMAT/
*
* Method : POST
*
* Parameters :
* DATABOX_ID : required INT
* RECORD_ID : required INT
*
*/
public function set_record_collection(Request $request, $databox_id, $record_id);
/**
* Route : /baskets/list/FORMAT/
*
* Method : POST
*
* Parameters :
*
*/
public function search_baskets(Request $request);
/**
* Route : /baskets/add/FORMAT/
*
* Method : POST
*
* Parameters :
*
*/
public function create_basket(Request $request);
/**
* Route : /baskets/BASKET_ID/delete/FORMAT/
*
* Method : POST
*
* Parameters :
* BASKET_ID : required INT
*
*/
public function delete_basket(Request $request, Basket $basket);
/**
* Route : /baskets/BASKET_ID/content/FORMAT/
*
* Method : POST
*
* Parameters :
* BASKET_ID : required INT
*
*/
public function get_basket(Request $request, Basket $basket);
/**
* Route : /baskets/BASKET_ID/title/FORMAT/
*
* Method : GET
*
* Parameters :
* BASKET_ID : required INT
*
*/
public function set_basket_title(Request $request, Basket $basket);
/**
* Route : /baskets/BASKET_ID/description/FORMAT/
*
* Method : POST
*
* Parameters :
* BASKET_ID : required INT
*
*/
public function set_basket_description(Request $request, Basket $basket);
/**
* Route : /publications/list/FORMAT/
*
* Method : POST
*
* Parameters :
*
*/
public function search_publications(Request $request, User $user);
/**
* Route : /publications/PUBLICATION_ID/remove/FORMAT/
*
* Method : GET
*
* Parameters :
* PUBLICATION_ID : required INT
*
*/
public function remove_publications(Request $request, $publication_id);
/**
* Route : /publications/PUBLICATION_ID/content/FORMAT/
*
* Method : GET
*
* Parameters :
* PUBLICATION_ID : required INT
*
*/
public function get_publication(Request $request, $publication_id, User $user);
public function get_publications(Request $request, User $user);
public function get_feed_entry(Request $request, $entry, User $user);
/**
* Route : /users/search/FORMAT/
*
* Method : POST-GET
*
* Parameters :
*
*/
public function search_users(Request $request);
/**
* Route : /users/USER_ID/access/FORMAT/
*
* Method : GET
*
* Parameters :
* USER_ID : required INT
*
*/
public function get_user_acces(Request $request, $usr_id);
public function add_record(Application $app, Request $request);
/**
* Route : /users/add/FORMAT/
*
* Method : POST
*
* Parameters :
*
*/
public function add_user(Request $request);
public function get_error_message(Request $request, $error, $message);
public function get_error_code(Request $request, $code);
}

View File

@@ -1,61 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Silex\Application;
use Silex\ServiceProviderInterface;
use Alchemy\Phrasea\Core\PhraseaEvents;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\HttpKernel\KernelEvents;
class API_V1_Timer implements ServiceProviderInterface
{
private $starting;
public function __construct()
{
$this->starting = microtime(true);
}
public function register(Application $app)
{
$app['api.timers'] = new ArrayCollection();
$app['api.timers.start'] = $this->starting;
$callback = function (Event $event) use ($app) {
$name = $event->getName();
$n = 1;
while (isset($app['api.timers']->{$name})) {
$n++;
$name = $event->getName() . '#' . $n;
}
$app['api.timers']->add([
'name' => $name,
'memory' => memory_get_usage(),
'time' => microtime(true) - $app['api.timers.start'],
]);
};
$app['dispatcher']->addListener(KernelEvents::CONTROLLER, $callback, -999999);
$app['dispatcher']->addListener(KernelEvents::REQUEST, $callback, 999999);
$app['dispatcher']->addListener(KernelEvents::REQUEST, $callback, -999999);
$app['dispatcher']->addListener(KernelEvents::RESPONSE, $callback, -999999);
$app['dispatcher']->addListener(KernelEvents::EXCEPTION, $callback, 999999);
$app['dispatcher']->addListener(PhraseaEvents::API_OAUTH2_START, $callback);
$app['dispatcher']->addListener(PhraseaEvents::API_OAUTH2_END, $callback);
$app['dispatcher']->addListener(PhraseaEvents::API_LOAD_END, $callback);
$app['dispatcher']->addListener(PhraseaEvents::API_RESULT, $callback);
}
public function boot(Application $app)
{
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,20 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
abstract class API_V1_exception_abstract extends Exception
{
protected static $details;
public static function get_details()
{
return static::$details;
}
}

View File

@@ -1,16 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class API_V1_exception_badrequest extends API_V1_exception_abstract
{
protected static $details = 'Parameter is invalid or missing';
}

View File

@@ -1,16 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class API_V1_exception_forbidden extends API_V1_exception_abstract
{
protected static $details = 'Access to the requested ressource is forbidden';
}

View File

@@ -1,16 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class API_V1_exception_internalservererror extends API_V1_exception_abstract
{
protected static $details = 'Internal Server Error';
}

View File

@@ -1,15 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class API_V1_exception_maintenance extends API_V1_exception_abstract
{
protected static $details = 'Server is offline for maintenance, try again soon.';
}

View File

@@ -1,16 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class API_V1_exception_methodnotallowed extends API_V1_exception_abstract
{
protected static $details = 'Attempting to use POST with a GET-only endpoint, or vice-versa';
}

View File

@@ -1,16 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class API_V1_exception_notfound extends API_V1_exception_abstract
{
protected static $details = 'Requested ressource is not found';
}

View File

@@ -1,16 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
class API_V1_exception_unauthorized extends API_V1_exception_abstract
{
protected static $details = 'The OAuth token was provided but was invalid.';
}

View File

@@ -1,393 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Alchemy\Phrasea\Core\Event\ApiResultEvent;
use Alchemy\Phrasea\Core\PhraseaEvents;
use Silex\Application;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class API_V1_result
{
protected $app;
/**
*
* @var string
*/
protected $api_version;
/**
*
* @var string
*/
protected $response_time;
/**
*
* @var int
*/
protected $http_code = 200;
/**
*
* @var string
*/
protected $error_type;
/**
*
* @var string
*/
protected $error_message;
/**
*
* @var string
*/
protected $error_details;
/**
*
* @var string
*/
protected $request;
/**
*
* @var mixed
*/
protected $response;
/**
*
* @var string
*/
protected $response_type;
/**
* Constant for responsetype json
*/
const FORMAT_JSON = 'json';
/**
* Constant for responsetype yaml
*/
const FORMAT_YAML = 'yaml';
/**
* Constant for responsetype jsonp
*/
const FORMAT_JSONP = 'jsonp';
const ERROR_BAD_REQUEST = 'Bad Request';
const ERROR_UNAUTHORIZED = 'Unauthorized';
const ERROR_FORBIDDEN = 'Forbidden';
const ERROR_NOTFOUND = 'Not Found';
const ERROR_MAINTENANCE = 'Service Temporarily Unavailable';
const ERROR_METHODNOTALLOWED = 'Method Not Allowed';
const ERROR_INTERNALSERVERERROR = 'Internal Server Error';
/**
* API v1 Result constructor
*
* @param Application $app
* @param Request $request
* @param API_V1_adapter $api
*
* @return API_V1_result
*/
public function __construct(Application $app, Request $request, API_V1_adapter $api)
{
$date = new DateTime();
$this->app = $app;
$this->request = $request;
$this->api_version = $api->get_version();
$this->response_time = $date->format(DATE_ATOM);
$this->response = new stdClass();
$this->parse_response_type();
return $this;
}
protected function parse_response_type()
{
if (trim($this->request->get('callback')) !== '') {
return $this->response_type = self::FORMAT_JSONP;
}
$accept = $this->request->getAcceptableContentTypes();
$response_types = [];
foreach ($accept as $key => $app_type) {
$response_types[strtolower($app_type)] = true;
}
if (array_key_exists('application/json', $response_types)) {
return $this->response_type = self::FORMAT_JSON;
}
if (array_key_exists('application/yaml', $response_types)) {
return $this->response_type = self::FORMAT_YAML;
}
if (array_key_exists('text/yaml', $response_types)) {
return $this->response_type = self::FORMAT_YAML;
}
return $this->response_type = self::FORMAT_JSON;
}
/**
* Set datas to the response
* If no datas provided (aka empty array), a stdClass if set,
* so the serialized datas will be objects
*
* @param array $datas
* @return API_V1_result
*/
public function set_datas(array $datas)
{
if (count($datas) === 0)
$datas = new stdClass ();
$this->response = $datas;
return $this;
}
/**
* Return response data
*
* @return array
*/
public function get_datas()
{
return (array) $this->response;
}
/**
* Format the data and return serialized string
*
* @return string
*/
public function format()
{
$request_uri = sprintf('%s %s'
, $this->request->getMethod()
, $this->request->getBasePath()
. $this->request->getPathInfo()
);
$ret = [
'meta' => [
'api_version' => $this->api_version
, 'request' => $request_uri
, 'response_time' => $this->response_time
, 'http_code' => $this->http_code
, 'error_type' => $this->error_type
, 'error_message' => $this->error_message
, 'error_details' => $this->error_details
, 'charset' => 'UTF-8'
]
, 'response' => $this->response
];
$this->app['dispatcher']->dispatch(PhraseaEvents::API_RESULT, new ApiResultEvent());
if ($this->app['conf']->get(['main', 'api-timers'], false)) {
$ret['timers'] = $this->app['api.timers']->toArray();
}
switch ($this->response_type) {
case self::FORMAT_JSON:
default:
$return_value = p4string::jsonencode($ret);
break;
case self::FORMAT_YAML:
if ($ret['response'] instanceof stdClass)
$ret['response'] = [];
$dumper = new Symfony\Component\Yaml\Dumper();
$return_value = $dumper->dump($ret, 8);
break;
case self::FORMAT_JSONP:
$callback = trim($this->request->get('callback'));
$return_value = $callback . '(' . p4string::jsonencode($ret) . ')';
break;
}
return $return_value;
}
/**
* Return serailized datas content type
*
* @return string
*/
public function get_content_type()
{
switch ($this->response_type) {
case self::FORMAT_JSON:
default:
$return_value = 'application/json';
break;
case self::FORMAT_YAML:
$return_value = 'application/yaml';
break;
case self::FORMAT_JSONP:
$return_value = 'text/javascript';
break;
}
return $return_value;
}
/**
* Set the API_V1_result http_code, error_type, error_message and error_details
* with the appropriate datas
*
* @param string $const
* @param string $message
*
* @return API_V1_result
*/
public function set_error_message($const, $message)
{
$this->error_details = $message;
switch ($const) {
case self::ERROR_BAD_REQUEST:
$this->http_code = 400;
$this->error_type = $const;
$this->error_message = API_V1_exception_badrequest::get_details();
break;
case self::ERROR_UNAUTHORIZED:
$this->http_code = 401;
$this->error_type = $const;
$this->error_message = API_V1_exception_unauthorized::get_details();
break;
case self::ERROR_FORBIDDEN:
$this->http_code = 403;
$this->error_type = $const;
$this->error_message = API_V1_exception_forbidden::get_details();
break;
case self::ERROR_NOTFOUND:
$this->http_code = 404;
$this->error_type = $const;
$this->error_message = API_V1_exception_notfound::get_details();
break;
case self::ERROR_METHODNOTALLOWED:
$this->http_code = 405;
$this->error_type = $const;
$this->error_message = API_V1_exception_methodnotallowed::get_details();
break;
case self::ERROR_INTERNALSERVERERROR:
$this->http_code = 500;
$this->error_type = $const;
$this->error_message = API_V1_exception_internalservererror::get_details();
break;
case self::ERROR_MAINTENANCE:
$this->http_code = 503;
$this->error_type = $const;
$this->error_message = API_V1_exception_maintenance::get_details();
break;
case OAUTH2_ERROR_INVALID_REQUEST:
$this->error_type = $const;
break;
}
return $this;
}
/**
* Set the API_V1_result http_code, error_message and error_details
* with the appropriate datas
*
* @param integer $code
*
* @return API_V1_result
*/
public function set_error_code($code)
{
switch ($code = (int) $code) {
case 400:
$this->http_code = $code;
$this->error_type = self::ERROR_BAD_REQUEST;
$this->error_message = API_V1_exception_badrequest::get_details();
break;
case 401:
$this->http_code = $code;
$this->error_type = self::ERROR_UNAUTHORIZED;
$this->error_message = API_V1_exception_unauthorized::get_details();
break;
case 403:
$this->http_code = $code;
$this->error_type = self::ERROR_FORBIDDEN;
$this->error_message = API_V1_exception_forbidden::get_details();
break;
case 404:
$this->http_code = $code;
$this->error_type = self::ERROR_NOTFOUND;
$this->error_message = API_V1_exception_notfound::get_details();
break;
case 405:
$this->http_code = $code;
$this->error_type = self::ERROR_METHODNOTALLOWED;
$this->error_message = API_V1_exception_methodnotallowed::get_details();
break;
case 500:
$this->http_code = $code;
$this->error_type = self::ERROR_INTERNALSERVERERROR;
$this->error_message = API_V1_exception_internalservererror::get_details();
break;
}
return $this;
}
/**
* Returns the correct http code depending on the errors
*
* @return int
*/
public function get_http_code()
{
if ($this->response_type == self::FORMAT_JSONP && $this->http_code != 500) {
return 200;
} else {
return $this->http_code;
}
}
/**
*
* @param int $code
*/
public function set_http_code($code)
{
$this->http_code = (int) $code;
}
/**
* Return a Symfony Response
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function get_response()
{
$response = new Response(
$this->format(),
$this->get_http_code(),
['Content-Type' => $this->get_content_type()]
);
$response->setCharset('UTF-8');
return $response;
}
}

View File

@@ -0,0 +1,68 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Alchemy\Phrasea\Application;
class patch_390alpha14a extends patchAbstract
{
/** @var string */
private $release = '3.9.0-alpha.14';
/** @var array */
private $concern = [base::APPLICATION_BOX];
/**
* {@inheritdoc}
*/
public function get_release()
{
return $this->release;
}
/**
* {@inheritdoc}
*/
public function require_all_upgrades()
{
return false;
}
/**
* {@inheritdoc}
*/
public function concern()
{
return $this->concern;
}
/**
* {@inheritdoc}
*/
public function getDoctrineMigrations()
{
return [];
}
/**
* {@inheritdoc}
*/
public function apply(base $appbox, Application $app)
{
$app['conf']->remove(['main', 'api-timers']);
if ($this->tableHasField($appbox, 'api_logs', 'api_log_ressource')) {
$sql = 'UPDATE api_logs SET api_log_resource = api_log_ressource';
$app['phraseanet.appbox']->get_connection()->executeUpdate($sql);
}
return true;
}
}

View File

@@ -9,6 +9,7 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
use Alchemy\Phrasea\Application;
use Doctrine\ORM\NoResultException; use Doctrine\ORM\NoResultException;
use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManager;
@@ -25,4 +26,25 @@ abstract class patchAbstract implements patchInterface
} }
} }
protected function tableExists(base $base, $tableName)
{
return $base
->get_connection()
->getSchemaManager()
->tablesExist([$tableName]);
}
protected function tableHasField(base $base, $tableName, $fieldName)
{
if (!$this->tableExists($base, $tableName)) {
return false;
}
return $base
->get_connection()
->getSchemaManager()
->listTableDetails($tableName)
->hasColumn($fieldName);
}
} }

View File

@@ -383,7 +383,7 @@
<comment></comment> <comment></comment>
</field> </field>
<field> <field>
<name>api_log_ressource</name> <name>api_log_resource</name>
<type>varchar(64)</type> <type>varchar(64)</type>
<null>YES</null> <null>YES</null>
<extra></extra> <extra></extra>

View File

@@ -16,7 +16,6 @@ main:
driver: pdo_sqlite driver: pdo_sqlite
path: '/tmp/db.sqlite' path: '/tmp/db.sqlite'
charset: UTF8 charset: UTF8
api-timers: false
cache: cache:
type: MemcacheCache type: MemcacheCache
options: options:

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace Alchemy\Tests\Phrasea\Application; namespace Alchemy\Tests\Phrasea\Controller\Api;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace Alchemy\Tests\Phrasea\Application; namespace Alchemy\Tests\Phrasea\Controller\Api;
class ApiJsonTest extends ApiTestCase class ApiJsonTest extends ApiTestCase
{ {

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace Alchemy\Tests\Phrasea\Application; namespace Alchemy\Tests\Phrasea\Controller\Api;
use Symfony\Component\HttpKernel\Client; use Symfony\Component\HttpKernel\Client;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;

View File

@@ -1,9 +1,10 @@
<?php <?php
namespace Alchemy\Tests\Phrasea\Application; namespace Alchemy\Tests\Phrasea\Controller\Api;
use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Border\File; use Alchemy\Phrasea\Border\File;
use Alchemy\Phrasea\Controller\Api\V1;
use Alchemy\Phrasea\Core\PhraseaEvents; use Alchemy\Phrasea\Core\PhraseaEvents;
use Alchemy\Phrasea\Authentication\Context; use Alchemy\Phrasea\Authentication\Context;
use Alchemy\Phrasea\Model\Entities\Task; use Alchemy\Phrasea\Model\Entities\Task;
@@ -132,11 +133,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$this->evaluateMetaNotFound($content); $this->evaluateMetaNotFound($content);
} }
/**
* @covers \API_V1_adapter::get_databoxes
* @covers \API_V1_adapter::list_databoxes
* @covers \API_V1_adapter::list_databox
*/
public function testDataboxListRoute() public function testDataboxListRoute()
{ {
$this->setToken(self::$token); $this->setToken(self::$token);
@@ -231,8 +227,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
/** /**
* Route GET /API/V1/monitor/task * Route GET /API/V1/monitor/task
* @covers API_V1_adapter::get_task_list
* @covers API_V1_adapter::list_task
*/ */
public function testGetMonitorTasks() public function testGetMonitorTasks()
{ {
@@ -261,7 +255,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
/** /**
* Route GET /API/V1/monitor/scheduler * Route GET /API/V1/monitor/scheduler
* @covers API_V1_adapter::get_scheduler
*/ */
public function testGetScheduler() public function testGetScheduler()
{ {
@@ -340,11 +333,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
} }
} }
/**
* Route GET /API/V1/monitor/task{idTask}
* @covers API_V1_adapter::get_task
* @covers API_V1_adapter::list_task
*/
public function testGetMonitorTaskById() public function testGetMonitorTaskById()
{ {
$tasks = self::$DI['app']['manipulator.task']->getRepository()->findAll(); $tasks = self::$DI['app']['manipulator.task']->getRepository()->findAll();
@@ -372,10 +360,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$this->evaluateGoodTask($content['response']['task']); $this->evaluateGoodTask($content['response']['task']);
} }
/**
* Route POST /API/V1/monitor/task{idTask}
* @covers API_V1_adapter::set_task_property
*/
public function testPostMonitorTaskById() public function testPostMonitorTaskById()
{ {
$tasks = self::$DI['app']['manipulator.task']->getRepository()->findAll(); $tasks = self::$DI['app']['manipulator.task']->getRepository()->findAll();
@@ -406,10 +390,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$this->assertEquals($title, $content['response']['task']['title']); $this->assertEquals($title, $content['response']['task']['title']);
} }
/**
* Route GET /API/V1/monitor/task/{idTask}/
* @covers API_V1_adapter::get_task
*/
public function testUnknowGetMonitorTaskById() public function testUnknowGetMonitorTaskById()
{ {
if (null === self::$adminToken) { if (null === self::$adminToken) {
@@ -422,10 +402,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$this->evaluateMetaNotFound($content); $this->evaluateMetaNotFound($content);
} }
/**
* Route POST /API/V1/monitor/task/{idTask}/start
* @covers API_V1_adapter::start_task
*/
public function testPostMonitorStartTask() public function testPostMonitorStartTask()
{ {
if (null === self::$adminToken) { if (null === self::$adminToken) {
@@ -456,10 +432,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$this->assertEquals(Task::STATUS_STARTED, $task->getStatus()); $this->assertEquals(Task::STATUS_STARTED, $task->getStatus());
} }
/**
* Route POST /API/V1/monitor/task/{idTask}/stop
* @covers API_V1_adapter::stop_task
*/
public function testPostMonitorStopTask() public function testPostMonitorStopTask()
{ {
$tasks = self::$DI['app']['manipulator.task']->getRepository()->findAll(); $tasks = self::$DI['app']['manipulator.task']->getRepository()->findAll();
@@ -490,13 +462,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$this->assertEquals(Task::STATUS_STOPPED, $task->getStatus()); $this->assertEquals(Task::STATUS_STOPPED, $task->getStatus());
} }
/**
* Route GET /API/V1/monitor/phraseanet
* @covers API_V1_adapter::get_phraseanet_monitor
* @covers API_V1_adapter::get_config_info
* @covers API_V1_adapter::get_cache_info
* @covers API_V1_adapter::get_gv_info
*/
public function testgetMonitorPhraseanet() public function testgetMonitorPhraseanet()
{ {
if (null === self::$adminToken) { if (null === self::$adminToken) {
@@ -519,10 +484,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$this->assertInternalType('array', $content['response']['phraseanet']); $this->assertInternalType('array', $content['response']['phraseanet']);
} }
/**
* @covers \API_V1_adapter::get_record
* @covers \API_V1_adapter::list_record
*/
public function testRecordRoute() public function testRecordRoute()
{ {
$this->setToken(self::$token); $this->setToken(self::$token);
@@ -545,10 +506,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']); $this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']);
} }
/**
* @covers \API_V1_adapter::get_story
* @covers \API_V1_adapter::list_story
*/
public function testStoryRoute() public function testStoryRoute()
{ {
$this->setToken(self::$token); $this->setToken(self::$token);
@@ -580,11 +537,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
self::$DI['record_story_1']->removeChild(self::$DI['record_1']); self::$DI['record_story_1']->removeChild(self::$DI['record_1']);
} }
/**
* @covers \API_V1_adapter::get_databox_collections
* @covers \API_V1_adapter::list_databox_collections
* @covers \API_V1_adapter::list_collection
*/
public function testDataboxCollectionRoute() public function testDataboxCollectionRoute()
{ {
$this->setToken(self::$token); $this->setToken(self::$token);
@@ -625,10 +577,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']); $this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']);
} }
/**
* @covers \API_V1_adapter::get_databox_status
* @covers \API_V1_adapter::list_databox_status
*/
public function testDataboxStatusRoute() public function testDataboxStatusRoute()
{ {
$this->setToken(self::$token); $this->setToken(self::$token);
@@ -678,11 +626,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']); $this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']);
} }
/**
* @covers \API_V1_adapter::get_databox_metadatas
* @covers \API_V1_adapter::list_databox_metadatas_fields
* @covers \API_V1_adapter::list_databox_metadata_field_properties
*/
public function testDataboxMetadatasRoute() public function testDataboxMetadatasRoute()
{ {
$this->setToken(self::$token); $this->setToken(self::$token);
@@ -766,11 +709,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']); $this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']);
} }
/**
* @covers \API_V1_adapter::get_databox_terms
* @covers \API_V1_adapter::list_databox_terms
*
*/
public function testDataboxTermsOfUseRoute() public function testDataboxTermsOfUseRoute()
{ {
$this->setToken(self::$token); $this->setToken(self::$token);
@@ -799,11 +737,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']); $this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']);
} }
/**
* @covers \API_V1_adapter::search
* @covers \API_V1_adapter::list_record
* @covers \API_V1_adapter::list_story
*/
public function testSearchRoute() public function testSearchRoute()
{ {
$this->setToken(self::$token); $this->setToken(self::$token);
@@ -833,11 +766,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
} }
} }
/**
* @covers \API_V1_adapter::search
* @covers \API_V1_adapter::list_record
* @covers \API_V1_adapter::list_story
*/
public function testSearchRouteWithStories() public function testSearchRouteWithStories()
{ {
$this->setToken(self::$token); $this->setToken(self::$token);
@@ -870,10 +798,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
} }
} }
/**
* @covers \API_V1_adapter::search_records
* @covers \API_V1_adapter::list_record
*/
public function testRecordsSearchRoute() public function testRecordsSearchRoute()
{ {
$this->setToken(self::$token); $this->setToken(self::$token);
@@ -925,9 +849,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
return [['POST'], ['GET']]; return [['POST'], ['GET']];
} }
/**
* @covers \API_V1_adapter::caption_records
*/
public function testRecordsCaptionRoute() public function testRecordsCaptionRoute()
{ {
$this->setToken(self::$token); $this->setToken(self::$token);
@@ -953,10 +874,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']); $this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']);
} }
/**
* @covers \API_V1_adapter::get_record_metadatas
* @covers \API_V1_adapter::list_record_caption
*/
public function testRecordsMetadatasRoute() public function testRecordsMetadatasRoute()
{ {
$this->setToken(self::$token); $this->setToken(self::$token);
@@ -980,9 +897,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']); $this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']);
} }
/**
* @covers \API_V1_adapter::get_record_status
*/
public function testRecordsStatusRoute() public function testRecordsStatusRoute()
{ {
$this->setToken(self::$token); $this->setToken(self::$token);
@@ -1006,11 +920,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']); $this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']);
} }
/**
* @covers \API_V1_adapter::get_record_embed
* @covers \API_V1_adapter::list_embedable_media
* @covers \API_V1_adapter::list_permalink
*/
public function testRecordsEmbedRoute() public function testRecordsEmbedRoute()
{ {
$this->setToken(self::$token); $this->setToken(self::$token);
@@ -1037,11 +946,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']); $this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']);
} }
/**
* @covers \API_V1_adapter::get_record_embed
* @covers \API_V1_adapter::list_embedable_media
* @covers \API_V1_adapter::list_permalink
*/
public function testStoriesEmbedRoute() public function testStoriesEmbedRoute()
{ {
$this->setToken(self::$token); $this->setToken(self::$token);
@@ -1069,9 +973,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']); $this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']);
} }
/**
* @covers \API_V1_adapter::get_record_embed
*/
public function testRecordsEmbedRouteMimeType() public function testRecordsEmbedRouteMimeType()
{ {
$this->setToken(self::$token); $this->setToken(self::$token);
@@ -1086,9 +987,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$this->assertEquals(0, count($content['response']['embed'])); $this->assertEquals(0, count($content['response']['embed']));
} }
/**
* @covers \API_V1_adapter::get_record_related
*/
public function testRecordsEmbedRouteDevices() public function testRecordsEmbedRouteDevices()
{ {
$this->setToken(self::$token); $this->setToken(self::$token);
@@ -1101,9 +999,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$this->assertEquals(0, count($content['response']['embed'])); $this->assertEquals(0, count($content['response']['embed']));
} }
/**
* @covers \API_V1_adapter::get_record_related
*/
public function testRecordsRelatedRoute() public function testRecordsRelatedRoute()
{ {
$this->setToken(self::$token); $this->setToken(self::$token);
@@ -1130,11 +1025,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']); $this->evaluateMethodNotAllowedRoute($route, ['POST', 'PUT', 'DELETE']);
} }
/**
* @covers \API_V1_adapter::set_record_metadatas
* @covers \API_V1_adapter::list_record_caption
* @covers \API_V1_adapter::list_record_caption_field
*/
public function testRecordsSetMetadatas() public function testRecordsSetMetadatas()
{ {
$this->setToken(self::$token); $this->setToken(self::$token);
@@ -1192,10 +1082,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
} }
} }
/**
* @covers \API_V1_adapter::set_record_status
* @covers \API_V1_adapter::list_record_status
*/
public function testRecordsSetStatus() public function testRecordsSetStatus()
{ {
$this->setToken(self::$token); $this->setToken(self::$token);
@@ -1254,12 +1140,9 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
self::$DI['record_1']->set_binary_status(str_repeat('0', 32)); self::$DI['record_1']->set_binary_status(str_repeat('0', 32));
} }
/**
* @covers \API_V1_adapter::set_record_collection
*/
public function testMoveRecordToCollection() public function testMoveRecordToCollection()
{ {
$file = new File(self::$DI['app'], self::$DI['app']['mediavorus']->guess(__DIR__ . '/../../../../files/test001.jpg'), self::$DI['collection']); $file = new File(self::$DI['app'], self::$DI['app']['mediavorus']->guess(__DIR__ . '/../../../../../files/test001.jpg'), self::$DI['collection']);
$record = \record_adapter::createFromFile($file, self::$DI['app']); $record = \record_adapter::createFromFile($file, self::$DI['app']);
$this->setToken(self::$token); $this->setToken(self::$token);
@@ -1288,11 +1171,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$record->delete(); $record->delete();
} }
/**
* @covers \API_V1_adapter::search_baskets
* @covers \API_V1_adapter::list_baskets
* @covers \API_V1_adapter::list_basket
*/
public function testSearchBaskets() public function testSearchBaskets()
{ {
self::$DI['client'] = new Client(self::$DI['app'], []); self::$DI['client'] = new Client(self::$DI['app'], []);
@@ -1313,10 +1191,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
} }
} }
/**
* @covers \API_V1_adapter::create_basket
* @covers \API_V1_adapter::list_basket
*/
public function testAddBasket() public function testAddBasket()
{ {
$this->setToken(self::$token); $this->setToken(self::$token);
@@ -1337,11 +1211,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$this->assertEquals('un Joli Nom', $content['response']['basket']['name']); $this->assertEquals('un Joli Nom', $content['response']['basket']['name']);
} }
/**
* @covers \API_V1_adapter::get_basket
* @covers \API_V1_adapter::list_basket_content
* @covers \API_V1_adapter::list_basket_element
*/
public function testBasketContent() public function testBasketContent()
{ {
$this->setToken(self::$adminToken); $this->setToken(self::$adminToken);
@@ -1377,11 +1246,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
} }
} }
/**
* @covers \API_V1_adapter::set_basket_title
* @covers \API_V1_adapter::list_basket_content
* @covers \API_V1_adapter::list_basket_element
*/
public function testSetBasketTitle() public function testSetBasketTitle()
{ {
$this->setToken(self::$adminToken); $this->setToken(self::$adminToken);
@@ -1430,11 +1294,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$this->assertEquals($content['response']['basket']['name'], '<strong>aéaa'); $this->assertEquals($content['response']['basket']['name'], '<strong>aéaa');
} }
/**
* @covers \API_V1_adapter::set_basket_description
* @covers \API_V1_adapter::list_basket_content
* @covers \API_V1_adapter::list_basket_element
*/
public function testSetBasketDescription() public function testSetBasketDescription()
{ {
$this->setToken(self::$adminToken); $this->setToken(self::$adminToken);
@@ -1458,9 +1317,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$this->assertEquals($content['response']['basket']['description'], 'une belle desc'); $this->assertEquals($content['response']['basket']['description'], 'une belle desc');
} }
/**
* @covers \API_V1_adapter::delete_basket
*/
public function testDeleteBasket() public function testDeleteBasket()
{ {
$this->setToken(self::$adminToken); $this->setToken(self::$adminToken);
@@ -1486,10 +1342,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
} }
} }
/**
* @covers \API_V1_adapter::add_record
* @covers \API_V1_adapter::list_record
*/
public function testAddRecord() public function testAddRecord()
{ {
$this->setToken(self::$token); $this->setToken(self::$token);
@@ -1509,10 +1361,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$this->assertArrayHasKey('url', $datas); $this->assertArrayHasKey('url', $datas);
} }
/**
* @covers \API_V1_adapter::add_record
* @covers \API_V1_adapter::list_record
*/
public function testAddRecordForceRecord() public function testAddRecordForceRecord()
{ {
$this->setToken(self::$token); $this->setToken(self::$token);
@@ -1538,10 +1386,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$this->assertEquals('0', $datas['entity']); $this->assertEquals('0', $datas['entity']);
} }
/**
* @covers \API_V1_adapter::add_record
* @covers \API_V1_adapter::list_quarantine_item
*/
public function testAddRecordForceLazaret() public function testAddRecordForceLazaret()
{ {
$this->setToken(self::$token); $this->setToken(self::$token);
@@ -1566,9 +1410,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$this->assertEquals('1', $datas['entity']); $this->assertEquals('1', $datas['entity']);
} }
/**
* @covers \API_V1_adapter::add_record
*/
public function testAddRecordWrongBehavior() public function testAddRecordWrongBehavior()
{ {
$this->setToken(self::$token); $this->setToken(self::$token);
@@ -1584,9 +1425,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$this->evaluateMetaBadRequest($content); $this->evaluateMetaBadRequest($content);
} }
/**
* @covers \API_V1_adapter::add_record
*/
public function testAddRecordWrongBaseId() public function testAddRecordWrongBaseId()
{ {
$this->setToken(self::$adminToken); $this->setToken(self::$adminToken);
@@ -1602,9 +1440,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$this->evaluateMetaForbidden($content); $this->evaluateMetaForbidden($content);
} }
/**
* @covers \API_V1_adapter::add_record
*/
public function testAddRecordNoBaseId() public function testAddRecordNoBaseId()
{ {
$this->setToken(self::$token); $this->setToken(self::$token);
@@ -1620,9 +1455,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$this->evaluateMetaBadRequest($content); $this->evaluateMetaBadRequest($content);
} }
/**
* @covers \API_V1_adapter::add_record
*/
public function testAddRecordMultipleFiles() public function testAddRecordMultipleFiles()
{ {
$this->setToken(self::$token); $this->setToken(self::$token);
@@ -1652,10 +1484,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$this->evaluateMetaBadRequest($content); $this->evaluateMetaBadRequest($content);
} }
/**
* @covers \API_V1_adapter::search_publications
* @covers \API_V1_adapter::list_publication
*/
public function testFeedList() public function testFeedList()
{ {
$created_feed = self::$DI['app']['EM']->find('Phraseanet:Feed', 1); $created_feed = self::$DI['app']['EM']->find('Phraseanet:Feed', 1);
@@ -1690,13 +1518,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
} }
} }
/**
* @covers \API_V1_adapter::get_publications
* @covers \API_V1_adapter::list_publications_entries
* @covers \API_V1_adapter::list_publication_entry
* @covers \API_V1_adapter::list_publication_entry_item
* @covers \API_V1_adapter::list_record
*/
public function testFeedsContent() public function testFeedsContent()
{ {
self::$DI['app']['notification.deliverer'] = $this->getMockBuilder('Alchemy\Phrasea\Notification\Deliverer') self::$DI['app']['notification.deliverer'] = $this->getMockBuilder('Alchemy\Phrasea\Notification\Deliverer')
@@ -1754,10 +1575,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
} }
} }
/**
* @covers \API_V1_adapter::get_feed_entry
* @covers \API_V1_adapter::list_publication_entry
*/
public function testFeedEntry() public function testFeedEntry()
{ {
self::$DI['app']['notification.deliverer'] = $this->getMockBuilder('Alchemy\Phrasea\Notification\Deliverer') self::$DI['app']['notification.deliverer'] = $this->getMockBuilder('Alchemy\Phrasea\Notification\Deliverer')
@@ -1785,10 +1602,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
} }
/**
* @covers \API_V1_adapter::get_feed_entry
* @covers \API_V1_adapter::list_publication_entry
*/
public function testFeedEntryNoAccess() public function testFeedEntryNoAccess()
{ {
self::$DI['app']['notification.deliverer'] = $this->getMockBuilder('Alchemy\Phrasea\Notification\Deliverer') self::$DI['app']['notification.deliverer'] = $this->getMockBuilder('Alchemy\Phrasea\Notification\Deliverer')
@@ -1812,13 +1625,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$this->evaluateMetaForbidden($content); $this->evaluateMetaForbidden($content);
} }
/**
* @covers \API_V1_adapter::get_publication
* @covers \API_V1_adapter::list_publications_entries
* @covers \API_V1_adapter::list_publication_entry
* @covers \API_V1_adapter::list_publication_entry_item
* @covers \API_V1_adapter::list_record
*/
public function testFeedContent() public function testFeedContent()
{ {
self::$DI['app']['notification.deliverer'] = $this->getMockBuilder('Alchemy\Phrasea\Notification\Deliverer') self::$DI['app']['notification.deliverer'] = $this->getMockBuilder('Alchemy\Phrasea\Notification\Deliverer')
@@ -1869,10 +1675,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
} }
} }
/**
* @covers list_quarantine
* @covers list_quarantine_item
*/
public function testQuarantineList() public function testQuarantineList()
{ {
$this->setToken(self::$token); $this->setToken(self::$token);
@@ -1904,9 +1706,6 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
} }
} }
/**
* @covers list_quarantine_item
*/
public function testQuarantineContent() public function testQuarantineContent()
{ {
$this->setToken(self::$token); $this->setToken(self::$token);
@@ -1936,7 +1735,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
}; };
$tmpname = tempnam(sys_get_temp_dir(), 'test_quarantine'); $tmpname = tempnam(sys_get_temp_dir(), 'test_quarantine');
copy(__DIR__ . '/../../../../files/iphone_pic.jpg', $tmpname); copy(__DIR__ . '/../../../../../files/iphone_pic.jpg', $tmpname);
$file = File::buildFromPathfile($tmpname, self::$DI['collection'], self::$DI['app']); $file = File::buildFromPathfile($tmpname, self::$DI['collection'], self::$DI['app']);
self::$DI['app']['border-manager']->process($lazaretSession, $file, $callback, Manager::FORCE_LAZARET); self::$DI['app']['border-manager']->process($lazaretSession, $file, $callback, Manager::FORCE_LAZARET);
@@ -2030,7 +1829,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
protected function getAddRecordFile() protected function getAddRecordFile()
{ {
$file = tempnam(sys_get_temp_dir(), 'upload'); $file = tempnam(sys_get_temp_dir(), 'upload');
copy(__DIR__ . '/../../../../files/iphone_pic.jpg', $file); copy(__DIR__ . '/../../../../../files/iphone_pic.jpg', $file);
return [ return [
'file' => new \Symfony\Component\HttpFoundation\File\UploadedFile($file, 'upload.jpg') 'file' => new \Symfony\Component\HttpFoundation\File\UploadedFile($file, 'upload.jpg')
@@ -2430,7 +2229,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
$this->assertArrayHasKey('thumbnail', $story); $this->assertArrayHasKey('thumbnail', $story);
$this->assertArrayHasKey('uuid', $story); $this->assertArrayHasKey('uuid', $story);
$this->assertArrayHasKey('@entity@', $story); $this->assertArrayHasKey('@entity@', $story);
$this->assertEquals(\API_V1_adapter::OBJECT_TYPE_STORY, $story['@entity@']); $this->assertEquals(V1::OBJECT_TYPE_STORY, $story['@entity@']);
$this->assertTrue(\uuid::is_valid($story['uuid'])); $this->assertTrue(\uuid::is_valid($story['uuid']));
if ( ! is_null($story['thumbnail'])) { if ( ! is_null($story['thumbnail'])) {
@@ -2463,7 +2262,7 @@ abstract class ApiTestCase extends \PhraseanetWebTestCase
} }
$this->assertArrayHasKey('@entity@', $story['metadatas']); $this->assertArrayHasKey('@entity@', $story['metadatas']);
$this->assertEquals(\API_V1_adapter::OBJECT_TYPE_STORY_METADATA_BAG, $story['metadatas']['@entity@']); $this->assertEquals(V1::OBJECT_TYPE_STORY_METADATA_BAG, $story['metadatas']['@entity@']);
foreach ($story['records'] as $record) { foreach ($story['records'] as $record) {
$this->evaluateGoodRecord($record); $this->evaluateGoodRecord($record);

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace Alchemy\Tests\Phrasea\Application; namespace Alchemy\Tests\Phrasea\Controller\Api;
use Symfony\Component\Yaml\Yaml; use Symfony\Component\Yaml\Yaml;

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace Alchemy\Tests\Phrasea\Application; namespace Alchemy\Tests\Phrasea\Controller\Api;
use Alchemy\Phrasea\Core\PhraseaEvents; use Alchemy\Phrasea\Core\PhraseaEvents;
use Alchemy\Phrasea\Authentication\Context; use Alchemy\Phrasea\Authentication\Context;

View File

@@ -0,0 +1,245 @@
<?php
namespace Alchemy\Tests\Phrasea\Controller\Api;
use Alchemy\Phrasea\Controller\Api\Result;
use Alchemy\Phrasea\Controller\Api\V1;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Yaml\Parser;
class ResultTest extends \PhraseanetAuthenticatedTestCase
{
public function testFormatJson()
{
$server = [
'HTTP_ACCEPT' => 'application/json',
'REQUEST_METHOD' => 'GET',
'SCRIPT_FILENAME' => 'my/base/path/my/request/uri/filename',
'REQUEST_URI' => 'my/base/path/my/request/uri',
'PHP_SELF' => 'my/base/path',
];
$request = new Request(["callback" => ""], [], [], [], [], $server);
$apiResult = new Result($request);
$return = $apiResult->createResponse()->getContent();
$this->assertInternalType(\PHPUnit_Framework_Constraint_IsType::TYPE_STRING, $return);
$response = json_decode($return);
$this->assertInternalType(\PHPUnit_Framework_Constraint_IsType::TYPE_OBJECT, $response);
$this->assertObjectHasAttribute("meta", $response);
$this->assertInternalType(\PHPUnit_Framework_Constraint_IsType::TYPE_OBJECT, $response->meta);
$this->assertObjectHasAttribute("response", $response);
$this->assertInternalType(\PHPUnit_Framework_Constraint_IsType::TYPE_OBJECT, $response->response);
$this->assertEquals(0, sizeof(get_object_vars($response->response)));
$this->assertEquals(0, sizeof(get_class_methods($response->response)));
$this->checkResponseFieldMeta($response, "api_version", V1::VERSION, \PHPUnit_Framework_Constraint_IsType::TYPE_STRING);
$this->checkResponseFieldMeta($response, "request", "GET my/base/path/my/request/uri", \PHPUnit_Framework_Constraint_IsType::TYPE_STRING);
$date = new \DateTime();
$now = $date->format('U');
$dateQuery = \DateTime::createFromFormat(DATE_ATOM, $response->meta->response_time);
$nowQuery = $dateQuery->format('U');
$this->assertLessThan(1, $nowQuery - $now);
$this->assertDateAtom($response->meta->response_time);
$date = new \DateTime();
$nowU = $date->format('U');
$dateResp = \DateTime::createFromFormat(DATE_ATOM, $response->meta->response_time);
$respU = $dateResp->format('U');
$this->assertLessThan(3, abs($respU - $nowU), 'No more than 3sec between now and the query');
$this->checkResponseFieldMeta($response, "http_code", 200, \PHPUnit_Framework_Constraint_IsType::TYPE_INT);
$this->checkResponseFieldMeta($response, "charset", "UTF-8", \PHPUnit_Framework_Constraint_IsType::TYPE_STRING);
$this->assertObjectHasAttribute("error_message", $response->meta);
$this->assertNull($response->meta->error_message);
$this->assertObjectHasAttribute("error_details", $response->meta);
$this->assertNull($response->meta->error_details);
}
public function testFormatYaml()
{
$server = [
'HTTP_ACCEPT' => 'application/yaml',
'REQUEST_METHOD' => 'GET',
'SCRIPT_FILENAME' => 'my/base/path/my/request/uri/filename',
'REQUEST_URI' => 'my/base/path/my/request/uri',
'PHP_SELF' => 'my/base/path',
];
$request = new Request(["callback" => ""], [], [], [], [], $server);
$apiResult = new Result($request);
$response = (new Parser())->parse($apiResult->createResponse()->getContent());
$this->assertInternalType(\PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY, $response);
$this->assertArrayHasKey("meta", $response);
$this->assertInternalType(\PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY, $response["meta"]);
$this->assertArrayHasKey("response", $response);
$this->assertInternalType(\PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY, $response["response"]);
$this->assertEquals(0, count($response["response"]));
$this->assertArrayHasKey("api_version", $response["meta"]);
$this->assertInternalType(\PHPUnit_Framework_Constraint_IsType::TYPE_STRING, $response["meta"]["api_version"]);
$this->assertEquals(V1::VERSION, $response["meta"]["api_version"]);
$this->assertArrayHasKey("request", $response["meta"]);
$this->assertInternalType(\PHPUnit_Framework_Constraint_IsType::TYPE_STRING, $response["meta"]["request"]);
$this->assertEquals("GET my/base/path/my/request/uri", $response["meta"]["request"]);
$this->assertArrayHasKey("response_time", $response["meta"]);
$this->assertInternalType(\PHPUnit_Framework_Constraint_IsType::TYPE_STRING, $response["meta"]["response_time"]);
$this->assertDateAtom($response["meta"]["response_time"]);
$dateObj1 = \DateTime::createFromFormat(DATE_ATOM, $response["meta"]["response_time"]);
$dateObj2 = new \DateTime();
$this->assertLessThan(3, abs($dateObj1->format('U') - $dateObj2->format('U')), 'No more than 3sec between now and the query');
$this->assertArrayHasKey("http_code", $response["meta"]);
$this->assertInternalType(\PHPUnit_Framework_Constraint_IsType::TYPE_INT, $response["meta"]["http_code"]);
$this->assertEquals(200, $response["meta"]["http_code"]);
$this->assertArrayHasKey("error_message", $response["meta"]);
$this->assertNull($response["meta"]["error_message"]);
$this->assertArrayHasKey("error_details", $response["meta"]);
$this->assertNull($response["meta"]["error_details"]);
$this->assertArrayHasKey("charset", $response["meta"]);
$this->assertInternalType(\PHPUnit_Framework_Constraint_IsType::TYPE_STRING, $response["meta"]["charset"]);
$this->assertEquals("UTF-8", $response["meta"]["charset"]);
}
public function testFormatJsonP()
{
$request = new Request(["callback" => "my_callback_function"], [], [], [], [], ["HTTP_ACCEPT" => "application/yaml"]);
$apiResult = new Result($request);
$return = $apiResult->createResponse()->getContent();
$this->assertInternalType(\PHPUnit_Framework_Constraint_IsType::TYPE_STRING, $return);
$this->assertRegexp("/my_callback_function\\(\\{.+\\}\\)/", $return);
$response = json_decode(substr($return, 21, strlen($return) - 22), true);
$this->assertSame([], $response['response']);
}
public function testData()
{
$apiResult = new Result(new Request(), ["pirouette" => "cacahuete", "black" => true, "bob" => ["bob"]]);
$response = json_decode($apiResult->createResponse()->getContent());
$this->checkResponseFieldResponse($response, "pirouette", "cacahuete", \PHPUnit_Framework_Constraint_IsType::TYPE_STRING);
$this->checkResponseFieldResponse($response, "black", true, \PHPUnit_Framework_Constraint_IsType::TYPE_BOOL);
$this->checkResponseFieldResponse($response, "bob", ["bob"], \PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY);
}
public function testEmptyData()
{
$apiResult = new Result(new Request(), []);
$content = json_decode($apiResult->createResponse()->getContent(), true);
$this->assertSame(array(), $content['response']);
}
public function testContentType()
{
$server = ["HTTP_ACCEPT" => "application/json"];
$request = new Request(["callback" => ""], [], [], [], [], $server);
$apiResult = new Result($request);
$this->assertEquals("application/json", $apiResult->createResponse()->headers->get('content-type'));
$server = ["HTTP_ACCEPT" => "application/yaml"];
$request = new Request(["callback" => ""], [], [], [], [], $server);
$apiResult = new Result($request);
$this->assertEquals('application/yaml', $apiResult->createResponse()->headers->get('content-type'));
$server = ["HTTP_ACCEPT" => "text/yaml"];
$request = new Request(["callback" => ""], [], [], [], [], $server);
$apiResult = new Result($request);
$this->assertEquals('application/yaml', $apiResult->createResponse()->headers->get('content-type'));
$server = ["HTTP_ACCEPT" => ""];
$request = new Request(["callback" => "hello"], [], [], [], [], $server);
$apiResult = new Result($request);
$this->assertEquals('text/javascript', $apiResult->createResponse()->headers->get('content-type'));
$server = ["HTTP_ACCEPT" => "unknow"];
$request = new Request(["callback" => ""], [], [], [], [], $server);
$apiResult = new Result($request);
$this->assertEquals("application/json", $apiResult->createResponse()->headers->get('content-type'));
}
public function testConstructor()
{
$apiResult = new Result(new Request(), [], 400, 'type', Result::ERROR_BAD_REQUEST, 'details');
$this->assertErrorMessage($apiResult, 400, 'type', Result::ERROR_BAD_REQUEST, 'details');
$apiResult = new Result(new Request(), [], 401, 'type', Result::ERROR_UNAUTHORIZED, 'details');
$this->assertErrorMessage($apiResult, 401, 'type', Result::ERROR_UNAUTHORIZED, 'details');
$apiResult = new Result(new Request(), [], 403, 'type', Result::ERROR_FORBIDDEN, 'details');
$this->assertErrorMessage($apiResult, 403, 'type', Result::ERROR_FORBIDDEN, 'details');
$apiResult = new Result(new Request(), [], 404, 'type', Result::ERROR_NOTFOUND, 'details');
$this->assertErrorMessage($apiResult, 404, 'type', Result::ERROR_NOTFOUND, 'details');
$apiResult = new Result(new Request(), [], 405, 'type', Result::ERROR_METHODNOTALLOWED, 'details');
$this->assertErrorMessage($apiResult, 405, 'type', Result::ERROR_METHODNOTALLOWED, 'details');
$apiResult = new Result(new Request(), [], 500, 'type', Result::ERROR_INTERNALSERVERERROR, 'details');
$this->assertErrorMessage($apiResult, 500, 'type', Result::ERROR_INTERNALSERVERERROR, 'details');
}
public function testCreateError()
{
$apiResult = Result::createError(new Request(), 400, 'detaillage');
$this->assertErrorMessage($apiResult, 400, Result::ERROR_BAD_REQUEST, 'Parameter is invalid or missing', 'detaillage');
$apiResult = Result::createError(new Request(), 401, 'detaillage');
$this->assertErrorMessage($apiResult, 401, Result::ERROR_UNAUTHORIZED, 'The OAuth token was provided but was invalid.', 'detaillage');
$apiResult = Result::createError(new Request(), 403, 'detaillage');
$this->assertErrorMessage($apiResult, 403, Result::ERROR_FORBIDDEN, 'Access to the requested resource is forbidden', 'detaillage');
$apiResult = Result::createError(new Request(), 404, 'detaillage');
$this->assertErrorMessage($apiResult, 404, Result::ERROR_NOTFOUND, 'Requested resource is not found', 'detaillage');
$apiResult = Result::createError(new Request(), 405, 'detaillage');
$this->assertErrorMessage($apiResult, 405, Result::ERROR_METHODNOTALLOWED, 'Attempting to use POST with a GET-only endpoint, or vice-versa', 'detaillage');
$apiResult = Result::createError(new Request(), 500, 'detaillage');
$this->assertErrorMessage($apiResult, 500, Result::ERROR_INTERNALSERVERERROR, 'Internal Server Error', 'detaillage');
}
private function checkResponseFieldMeta(\stdClass $response, $field, $expectedValue, $type)
{
$this->assertObjectHasAttribute($field, $response->meta);
$this->assertInternalType($type, $response->meta->$field);
$this->assertEquals($expectedValue, $response->meta->$field);
}
private function checkResponseFieldResponse(\stdClass $response, $field, $expectedValue, $type)
{
$this->assertObjectHasAttribute($field, $response->response);
$this->assertInternalType($type, $response->response->$field);
$this->assertEquals($expectedValue, $response->response->$field);
}
private function assertErrorMessage(Result $apiResult, $code, $type, $message, $detail)
{
$response = json_decode($apiResult->createResponse()->getContent());
$this->checkResponseFieldMeta($response, 'http_code', $code, \PHPUnit_Framework_Constraint_IsType::TYPE_INT);
if (is_null($type)) {
$this->assertObjectHasAttribute('error_type', $response->meta);
$this->assertNull($response->meta->error_type);
} else {
$this->checkResponseFieldMeta($response, 'error_type', $type, \PHPUnit_Framework_Constraint_IsType::TYPE_STRING);
}
if (is_null($message)) {
$this->assertObjectHasAttribute('error_message', $response->meta);
$this->assertNull($response->meta->error_message);
} else {
$this->checkResponseFieldMeta($response, 'error_message', $message, \PHPUnit_Framework_Constraint_IsType::TYPE_STRING);
}
if (is_null($detail)) {
$this->assertObjectHasAttribute('error_details', $response->meta);
$this->assertNull($response->meta->error_details);
} else {
$this->checkResponseFieldMeta($response, 'error_details', $detail, \PHPUnit_Framework_Constraint_IsType::TYPE_STRING);
}
}
}

View File

@@ -16,7 +16,6 @@ main:
driver: pdo_sqlite driver: pdo_sqlite
path: '/tmp/db.sqlite' path: '/tmp/db.sqlite'
charset: UTF8 charset: UTF8
api-timers: false
cache: cache:
type: MemcacheCache type: MemcacheCache
options: options:

View File

@@ -16,7 +16,6 @@ main:
driver: pdo_sqlite driver: pdo_sqlite
path: '/tmp/db.sqlite' path: '/tmp/db.sqlite'
charset: UTF8 charset: UTF8
api-timers: false
cache: cache:
type: MemcacheCache type: MemcacheCache
options: options:

View File

@@ -5,8 +5,11 @@ namespace Alchemy\Tests\Phrasea\Core\Event\Subscriber;
use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Core\Event\Subscriber\ApiExceptionHandlerSubscriber; use Alchemy\Phrasea\Core\Event\Subscriber\ApiExceptionHandlerSubscriber;
use Symfony\Component\HttpKernel\Client; use Symfony\Component\HttpKernel\Client;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException; use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
class ApiExceptionHandlerSubscriberTest extends \PhraseanetTestCase class ApiExceptionHandlerSubscriberTest extends \PhraseanetTestCase
{ {
@@ -16,10 +19,6 @@ class ApiExceptionHandlerSubscriberTest extends \PhraseanetTestCase
public function testError($exception, $code) public function testError($exception, $code)
{ {
$app = new Application('test'); $app = new Application('test');
$app['api'] = function () use ($app) {
return new \API_V1_adapter($app);
};
$app->register(new \API_V1_Timer());
$app['dispatcher']->addSubscriber(new ApiExceptionHandlerSubscriber($app)); $app['dispatcher']->addSubscriber(new ApiExceptionHandlerSubscriber($app));
$app->get('/', function () use ($exception) { $app->get('/', function () use ($exception) {
throw $exception; throw $exception;
@@ -35,13 +34,11 @@ class ApiExceptionHandlerSubscriberTest extends \PhraseanetTestCase
public function provideExceptionsAndCode() public function provideExceptionsAndCode()
{ {
return [ return [
[new \API_V1_exception_methodnotallowed(), 405],
[new MethodNotAllowedHttpException(['PUT', 'HEAD']), 405], [new MethodNotAllowedHttpException(['PUT', 'HEAD']), 405],
[new \API_V1_exception_badrequest(), 400],
[new \API_V1_exception_forbidden(), 403],
[new \API_V1_exception_unauthorized(), 401],
[new \API_V1_exception_internalservererror(), 500],
[new NotFoundHttpException(), 404], [new NotFoundHttpException(), 404],
[new BadRequestHttpException(), 400],
[new AccessDeniedHttpException(), 403],
[new UnauthorizedHttpException('challenge'), 401],
[new \Exception(), 500], [new \Exception(), 500],
]; ];
} }

View File

@@ -18,10 +18,6 @@ class ApiOauth2ErrorsSubscriberTest extends \PhraseanetTestCase
public function testError($exception, $code, $contentType) public function testError($exception, $code, $contentType)
{ {
$app = new Application('test'); $app = new Application('test');
$app['api'] = function () use ($app) {
return new \API_V1_adapter($app);
};
$app->register(new \API_V1_Timer());
$app['dispatcher']->addSubscriber(new ApiOauth2ErrorsSubscriber(PhraseaExceptionHandler::register(), $this->createTranslatorMock())); $app['dispatcher']->addSubscriber(new ApiOauth2ErrorsSubscriber(PhraseaExceptionHandler::register(), $this->createTranslatorMock()));
$app->get('/api/oauthv2', function () use ($exception) { $app->get('/api/oauthv2', function () use ($exception) {
throw $exception; throw $exception;
@@ -41,10 +37,6 @@ class ApiOauth2ErrorsSubscriberTest extends \PhraseanetTestCase
{ {
$app = new Application('test'); $app = new Application('test');
unset($app['exception_handler']); unset($app['exception_handler']);
$app['api'] = function () use ($app) {
return new \API_V1_adapter($app);
};
$app->register(new \API_V1_Timer());
$app['dispatcher']->addSubscriber(new ApiOauth2ErrorsSubscriber(PhraseaExceptionHandler::register(), $this->createTranslatorMock())); $app['dispatcher']->addSubscriber(new ApiOauth2ErrorsSubscriber(PhraseaExceptionHandler::register(), $this->createTranslatorMock()));
$app->get('/', function () use ($exception) { $app->get('/', function () use ($exception) {
throw $exception; throw $exception;

View File

@@ -1,6 +1,6 @@
<?php <?php
class Session_LoggerTest extends \PhraseanetTestCase class Session_LoggerTest extends \PhraseanetAuthenticatedTestCase
{ {
/** /**
* @var Session_Logger * @var Session_Logger

View File

@@ -1,44 +0,0 @@
<?php
use Alchemy\Phrasea\Core\PhraseaEvents;
use Symfony\Component\EventDispatcher\Event;
class api_v1_TimerTest extends \PhraseanetTestCase
{
public function testRegister()
{
$start = microtime(true);
$app = $this->loadApp();
$dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
$dispatcher->expects($this->exactly(9))
->method('addListener');
$app['dispatcher'] = $dispatcher;
$app->register(new API_V1_Timer());
$this->assertInstanceOf('Doctrine\Common\Collections\ArrayCollection', $app['api.timers']);
$this->assertGreaterThan($start, $app['api.timers.start']);
}
public function testTriggerEvent()
{
$app = $this->loadApp();
$app->register(new API_V1_Timer());
$app['dispatcher']->dispatch(PhraseaEvents::API_RESULT, new Event());
$timers = $app['api.timers']->toArray();
$this->assertCount(1, $timers);
$timer = array_pop($timers);
$this->assertArrayHasKey('name', $timer);
$this->assertArrayHasKey('memory', $timer);
$this->assertArrayHasKey('time', $timer);
$this->assertEquals(PhraseaEvents::API_RESULT, $timer['name']);
$this->assertGreaterThan(0, $timer['time']);
$this->assertGreaterThan(400000, $timer['memory']);
}
}

View File

@@ -1,656 +0,0 @@
<?php
use Alchemy\Phrasea\Border\File as BorderFile;
use Symfony\Component\HttpFoundation\Request;
class api_v1_adapterTest extends \PhraseanetAuthenticatedTestCase
{
/**
* @var API_V1_adapter
*/
protected $object;
public function setUp()
{
parent::setUp();
self::$DI['app']->register(new \API_V1_Timer());
$this->object = new API_V1_adapter(self::$DI['app']);
}
public function testGet_error_code()
{
$request = new Request([], [], [], [], [], ['HTTP_Accept' => 'application/json']);
$result = $this->object->get_error_code($request, 400);
$this->assertTrue(is_array(json_decode($result->format(), true)));
$this->assertEquals(400, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$result = $this->object->get_error_code($request, 403);
$this->assertTrue(is_array(json_decode($result->format(), true)));
$this->assertEquals(403, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$result = $this->object->get_error_code($request, 500);
$this->assertTrue(is_array(json_decode($result->format(), true)));
$this->assertEquals(500, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$result = $this->object->get_error_code($request, 405);
$this->assertTrue(is_array(json_decode($result->format(), true)));
$this->assertEquals(405, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$result = $this->object->get_error_code($request, 404);
$this->assertTrue(is_array(json_decode($result->format(), true)));
$this->assertEquals(404, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$result = $this->object->get_error_code($request, 401);
$this->assertTrue(is_array(json_decode($result->format(), true)));
$this->assertEquals(401, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
}
public function testGet_error_message()
{
$request = new Request([], [], [], [], [], ['HTTP_Accept' => 'application/json']);
$result = $this->object->get_error_message($request, API_V1_result::ERROR_BAD_REQUEST, 'detaillage');
$this->assertTrue(is_array(json_decode($result->format(), true)));
$this->assertEquals(400, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$result = $this->object->get_error_message($request, API_V1_result::ERROR_FORBIDDEN, 'detaillage');
$this->assertTrue(is_array(json_decode($result->format(), true)));
$this->assertEquals(403, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$result = $this->object->get_error_message($request, API_V1_result::ERROR_INTERNALSERVERERROR, 'detaillage');
$this->assertTrue(is_array(json_decode($result->format(), true)));
$this->assertEquals(500, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$result = $this->object->get_error_message($request, API_V1_result::ERROR_METHODNOTALLOWED, 'detaillage');
$this->assertTrue(is_array(json_decode($result->format(), true)));
$this->assertEquals(405, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$result = $this->object->get_error_message($request, API_V1_result::ERROR_NOTFOUND, 'detaillage');
$this->assertTrue(is_array(json_decode($result->format(), true)));
$this->assertEquals(404, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$result = $this->object->get_error_message($request, API_V1_result::ERROR_UNAUTHORIZED, 'detaillage');
$this->assertTrue(is_array(json_decode($result->format(), true)));
$this->assertEquals(401, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
}
public function testGet_version()
{
$this->assertEquals('1.3', $this->object->get_version());
}
public function testGet_databoxes()
{
$request = new Request([], [], [], [], [], ['HTTP_Accept' => 'application/json']);
$result = $this->object->get_databoxes($request);
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
}
public function testGet_databox_collections()
{
$request = new Request();
foreach (self::$DI['app']['phraseanet.appbox']->get_databoxes() as $databox) {
$result = $this->object->get_databox_collections($request, $databox->get_sbas_id());
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
}
}
public function testGet_record()
{
$request = new Request([], [], [], [], [], ['HTTP_Accept' => 'application/json']);
$result = $this->object->get_record($request, self::$DI['record_1']->get_sbas_id(), "-40");
$this->assertEquals(400, $result->get_http_code());
$request = new Request([], [], [], [], [], ['HTTP_Accept' => 'application/json']);
$result = $this->object->get_record($request, self::$DI['record_1']->get_sbas_id(), self::$DI['record_1']->get_record_id());
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
}
public function testGet_databox_status()
{
$request = new Request([], [], [], [], [], ['HTTP_Accept' => 'application/json']);
foreach (self::$DI['app']['phraseanet.appbox']->get_databoxes() as $databox) {
$result = $this->object->get_databox_status($request, $databox->get_sbas_id());
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
}
}
public function testGet_databox_metadatas()
{
$request = new Request([], [], [], [], [], ['HTTP_Accept' => 'application/json']);
foreach (self::$DI['app']['phraseanet.appbox']->get_databoxes() as $databox) {
$result = $this->object->get_databox_metadatas($request, $databox->get_sbas_id());
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
}
}
public function testGet_databox_terms()
{
$request = new Request([], [], [], [], [], ['HTTP_Accept' => 'application/json']);
foreach (self::$DI['app']['phraseanet.appbox']->get_databoxes() as $databox) {
$result = $this->object->get_databox_terms($request, $databox->get_sbas_id());
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
}
}
public function testSearch_recordsWithRecords()
{
$this->authenticate(self::$DI['app']);
$record = \record_adapter::createFromFile(BorderFile::buildFromPathfile(__DIR__ . '/../../../files/cestlafete.jpg', self::$DI['collection'], self::$DI['app']), self::$DI['app']);
$request = new Request(['record_type' => "image", 'search_type' => 0], [], [], [], [], ['HTTP_Accept' => 'application/json']);
$result = $this->object->search_records($request);
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
$data = json_decode($result->format(), true);
$found = false;
foreach ($data['response']['results'] as $retRecord) {
if ($retRecord['record_id'] == $record->get_record_id() && $retRecord['databox_id'] == $record->get_sbas_id()) {
$found = true;
break;
}
}
if (!$found) {
$this->fail('unable to find the record back');
}
}
public function testSearch_withOffset()
{
$request = new Request([], [], [], [], [], ['HTTP_Accept' => 'application/json']);
$result = $this->object->search_records($request);
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
$data = json_decode($result->format(), true);
if ($data['response']['total_results'] < 2) {
$this->markTestSkipped('Not enough data to test');
}
$total = $data['response']['total_results'];
$request = new Request([
'offset_start' => 0,
'per_page' => 1,
], [], [], [], [], ['HTTP_Accept' => 'application/json']);
$resultData1 = $this->object->search_records($request);
$data = json_decode($resultData1->format(), true);
$this->assertCount(1, $data['response']['results']);
$result1 = array_pop($data['response']['results']);
$request = new Request([
'offset_start' => 1,
'per_page' => 1,
], [], [], [], [], ['HTTP_Accept' => 'application/json']);
$resultData2 = $this->object->search_records($request);
$data = json_decode($resultData2->format(), true);
$this->assertCount(1, $data['response']['results']);
$result2 = array_pop($data['response']['results']);
// item at offset #0 is different than offset at item #1
$this->assertNotEquals($result1['record_id'], $result2['record_id']);
// last item is last item
$request = new Request([
'offset_start' => $total - 1,
'per_page' => 10,
], [], [], [], [], ['HTTP_Accept' => 'application/json']);
$resultData = $this->object->search_records($request);
$data = json_decode($resultData->format(), true);
$this->assertCount(1, $data['response']['results']);
}
public function testSearch_recordsWithStories()
{
$this->authenticate(self::$DI['app']);
$story = \record_adapter::createStory(self::$DI['app'], self::$DI['collection']);
if (!$story->hasChild(self::$DI['record_1'])) {
$story->appendChild(self::$DI['record_1']);
}
$request = new Request(['search_type' => 1], [], [], [], [], ['HTTP_Accept' => 'application/json']);
$result = $this->object->search_records($request);
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
$data = json_decode($result->format(), true);
$found = false;
foreach ($data['response']['results'] as $retStory) {
if ($retStory['record_id'] == $story->get_record_id() && $retStory['databox_id'] == $story->get_sbas_id()) {
$found = true;
break;
}
}
if (!$found) {
$this->fail('unable to find the story back');
}
}
public function testSearchWithStories()
{
$this->authenticate(self::$DI['app']);
$story = \record_adapter::createStory(self::$DI['app'], self::$DI['collection']);
if (!$story->hasChild(self::$DI['record_1'])) {
$story->appendChild(self::$DI['record_1']);
}
$request = new Request(['search_type' => 1], [], [], [], [], ['HTTP_Accept' => 'application/json']);
$result = $this->object->search($request);
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
$data = json_decode($result->format(), true);
$this->assertArrayHasKey('records', $data['response']['results']);
$this->assertArrayHasKey('stories', $data['response']['results']);
$found = false;
foreach ($data['response']['results']['stories'] as $retStory) {
if ($retStory['story_id'] == $story->get_record_id() && $retStory['databox_id'] == $story->get_sbas_id()) {
$found = true;
break;
}
}
if (!$found) {
$this->fail('unable to find the story back');
}
}
public function testSearchWithRecords()
{
$this->authenticate(self::$DI['app']);
$record = \record_adapter::createFromFile(BorderFile::buildFromPathfile(__DIR__ . '/../../../files/cestlafete.jpg', self::$DI['collection'], self::$DI['app']), self::$DI['app']);
$request = new Request(['search_type' => 0], [], [], [], [], ['HTTP_Accept' => 'application/json']);
$result = $this->object->search($request);
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
$data = json_decode($result->format(), true);
$this->assertArrayHasKey('records', $data['response']['results']);
$this->assertArrayHasKey('stories', $data['response']['results']);
$found = false;
foreach ($data['response']['results']['records'] as $retRecord) {
if ($retRecord['record_id'] == $record->get_record_id() && $retRecord['databox_id'] == $record->get_sbas_id()) {
$found = true;
break;
}
}
if (!$found) {
$this->fail('unable to find the record back');
}
}
public function testGet_record_related()
{
$basketElement = self::$DI['app']['EM']->find('Phraseanet:BasketElement', 1);
$story = self::$DI['record_story_1'];
if (false === $story->hasChild(self::$DI['record_1'])) {
$story->appendChild(self::$DI['record_1']);
}
$request = new Request([], [], [], [], [], ['HTTP_Accept' => 'application/json']);
$result = $this->object->get_record_related($request, self::$DI['record_1']->get_sbas_id(), self::$DI['record_1']->get_record_id());
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
$data = json_decode($result->format(), true);
$this->assertArrayHasKey('baskets', $data['response']);
$this->assertArrayHasKey('stories', $data['response']);
$found = false;
foreach ($data['response']['baskets'] as $bask) {
if ($bask['basket_id'] == $basketElement->getBasket()->getId()) {
$found = true;
break;
}
}
if (!$found) {
$this->fail('unable to find the basket back');
}
$found = false;
foreach ($data['response']['stories'] as $retStory) {
if ($retStory['story_id'] == $story->get_record_id() && $retStory['databox_id'] == $story->get_sbas_id()) {
$found = true;
break;
}
}
if (!$found) {
$this->fail('unable to find the story back');
}
}
public function testGet_record_metadatas()
{
$request = new Request([], [], [], [], [], ['HTTP_Accept' => 'application/json']);
$result = $this->object->get_record_metadatas($request, self::$DI['record_1']->get_sbas_id(), self::$DI['record_1']->get_record_id());
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
}
public function testGet_record_status()
{
$request = new Request();
$request = new Request([], [], [], [], [], ['HTTP_Accept' => 'application/json']);
$result = $this->object->get_record_status($request, self::$DI['record_1']->get_sbas_id(), self::$DI['record_1']->get_record_id());
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
}
public function testGet_record_embed()
{
$request = new Request([], [], [], [], [], ['HTTP_Accept' => 'application/json']);
$result = $this->object->get_record_embed($request, self::$DI['record_1']->get_sbas_id(), self::$DI['record_1']->get_record_id());
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
}
public function testSet_record_metadatas()
{
$databox = self::$DI['record_1']->get_databox();
$request = new Request(["salut" => "salut c'est la fete"], [], [], [], [], ['HTTP_Accept' => 'application/json']);
$result = $this->object->set_record_metadatas($request, self::$DI['record_1']->get_sbas_id(), self::$DI['record_1']->get_record_id());
$this->assertEquals(400, $result->get_http_code());
$request = new Request(["metadatas" => "salut c'est la fete"], [], [], [], [], ['HTTP_Accept' => 'application/json']);
$this->object->set_record_metadatas($request, self::$DI['record_1']->get_sbas_id(), self::$DI['record_1']->get_record_id());
$this->assertEquals(400, $result->get_http_code());
if (sizeof(self::$DI['record_1']->get_caption()->get_fields()) == 0) {
$caption_field_value = caption_Field_Value::create(self::$DI['app'], databox_field::get_instance(self::$DI['app'], $databox, 1), self::$DI['record_1'], 'my value');
}
$metadatas = [];
foreach (self::$DI['record_1']->get_databox()->get_meta_structure()->get_elements() as $field) {
try {
$values = self::$DI['record_1']->get_caption()->get_field($field->get_name())->get_values();
$value = array_pop($values);
$meta_id = $value->getId();
} catch (\Exception $e) {
$meta_id = null;
}
$metadatas[] = [
'meta_id' => $meta_id
, 'meta_struct_id' => $field->get_id()
, 'value' => 'poOM POOM TCHOK ' . $field->get_id()
];
}
$request = new Request(["metadatas" => $metadatas], [], [], [], [], ['HTTP_Accept' => 'application/json']);
$result = $this->object->set_record_metadatas($request, self::$DI['record_1']->get_sbas_id(), self::$DI['record_1']->get_record_id());
$response = json_decode($result->format(), true);
$this->assertEquals($response['meta']['http_code'], 200);
$this->checkResponseField($result, "record_metadatas", 'array');
}
public function testSet_record_status()
{
$app = self::$DI['app'];
$stub = $this->getMock("API_V1_adapter", ["list_record_status"], [$app]);
$databox = self::$DI['record_1']->get_databox();
$statusbit = null;
foreach ($databox->get_statusbits() as $key => $value) {
$statusbit = $key;
break;
}
if (null === $statusbit) {
$this->markTestSkipped('No status bit defined in databox');
}
$request = new Request(["salut" => "salut c'est la fete"], [], [], [], [], ['HTTP_Accept' => 'application/json']);
$result = $stub->set_record_status($request, self::$DI['record_1']->get_sbas_id(), self::$DI['record_1']->get_record_id());
$this->assertEquals(400, $result->get_http_code());
$request = new Request(["status" => "salut c'est la fete"], [], [], [], [], ['HTTP_Accept' => 'application/json']);
$stub->set_record_status($request, self::$DI['record_1']->get_sbas_id(), self::$DI['record_1']->get_record_id());
$this->assertEquals(400, $result->get_http_code());
$status = [$statusbit => '1'];
$request = new Request(["status" => $status], [], [], [], [], ['HTTP_Accept' => 'application/json']);
//check method use record->get_caption
$stub->expects($this->once())
->method("list_record_status")
->will($this->returnValue(new stdClass()));
//check for metadas fiels in response
$result = $stub->set_record_status($request, self::$DI['record_1']->get_sbas_id(), self::$DI['record_1']->get_record_id());
$this->checkResponseField($result, "status", 'array');
}
public function testSet_record_collection()
{
$app = self::$DI['app'];
$stub = $this->getMock("API_V1_adapter", ["list_record"], [$app]);
$databox = self::$DI['record_1']->get_databox();
$request = new Request(["salut" => "salut c'est la fete"], [], [], [], [], ['HTTP_Accept' => 'application/json']);
$result = $stub->set_record_collection($request, self::$DI['record_1']->get_sbas_id(), self::$DI['record_1']->get_record_id());
$this->assertEquals(400, $result->get_http_code());
foreach ($app['phraseanet.appbox']->get_databoxes() as $databox) {
$collections = $databox->get_collections();
break;
}
$collection = array_shift($collections);
$request = new Request(["base_id" => $collection->get_base_id()], [], [], [], [], ['HTTP_Accept' => 'application/json']);
//check method use record->get_caption
$stub->expects($this->once())
->method("list_record")
->will($this->returnValue(new stdClass()));
//check for metadas fiels in response
$result = $stub->set_record_collection($request, self::$DI['record_1']->get_sbas_id(), self::$DI['record_1']->get_record_id());
$this->checkResponseField($result, "record", 'array');
}
/**
* @todo Implement testAdd_record_tobasket().
*/
public function testAdd_record_tobasket()
{
// Remove the following lines when you implement this test.
$this->markTestIncomplete(
'This test has not been implemented yet.'
);
}
public function testSearch_baskets()
{
$request = new Request([], [], [], [], [], ['HTTP_Accept' => 'application/json']);
$result = $this->object->search_baskets($request);
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
}
public function testCreate_basket()
{
$request = new Request([], [], ['name' => 'BIG BASKET'], [], [], ['HTTP_Accept' => 'application/json']);
$result = $this->object->create_basket($request);
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
$n = 0;
$response = json_decode($result->format(), true);
$this->assertArrayHasKey('basket', $response['response']);
$basket = self::$DI['app']['converter.basket']->convert($response['response']['basket']['basket_id']);
self::$DI['app']['acl.basket']->isOwner($basket, self::$DI['app']['authentication']->getUser());
}
public function testDelete_basket()
{
$Basket = self::$DI['app']['EM']->find('Phraseanet:Basket', 1);
$request = new Request([], [], [], [], [], ['HTTP_Accept' => 'application/json']);
$result = $this->object->delete_basket($request, $Basket);
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
$this->setExpectedException('Symfony\Component\HttpKernel\Exception\NotFoundHttpException');
self::$DI['app']['converter.basket']->convert($Basket->getId());
}
public function testGet_basket()
{
$basket = self::$DI['app']['EM']->find('Phraseanet:Basket', 1);
$request = new Request([], [], [], [], [], ['HTTP_Accept' => 'application/json']);
$result = $this->object->get_basket($request, $basket);
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
}
public function testSet_basket_title()
{
$basket = self::$DI['app']['EM']->find('Phraseanet:Basket', 1);
$request = new Request([], [], ['name' => 'PROUTO'], [], [], ['HTTP_Accept' => 'application/json']);
$result = $this->object->set_basket_title($request, $basket);
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
$repository = self::$DI['app']['EM']->getRepository('Phraseanet:Basket');
$ret_bask = $repository->find($basket->getId());
$this->assertEquals('PROUTO', $ret_bask->getName());
}
public function testSet_basket_description()
{
$basket = self::$DI['app']['EM']->find('Phraseanet:Basket', 1);
$request = new Request([], [], ['description' => 'une belle description'], [], [], ['HTTP_Accept' => 'application/json']);
$result = $this->object->set_basket_description($request, $basket);
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
$repository = self::$DI['app']['EM']->getRepository('Phraseanet:Basket');
$ret_bask = $repository->find($basket->getId());
$this->assertEquals('une belle description', $ret_bask->getDescription());
}
public function testSearch_publications()
{
$request = new Request([], [], [], [], [], ['HTTP_Accept' => 'application/json']);
$feed = self::$DI['app']['EM']->find('Phraseanet:Feed', 1);
$result = $this->object->search_publications($request, self::$DI['user']);
$this->checkResponseField($result, "feeds", 'array');
}
public function testRemove_publications()
{
// Remove the following lines when you implement this test.
$this->markTestIncomplete(
'This test has not been implemented yet.'
);
}
public function testGet_publication()
{
self::$DI['app']['notification.deliverer'] = $this->getMockBuilder('Alchemy\Phrasea\Notification\Deliverer')
->disableOriginalConstructor()
->getMock();
$date = new DateTime();
$request = new Request([], [], [], [], [], ['HTTP_Accept' => 'application/json']);
$feeds = self::$DI['app']['EM']->getRepository('Phraseanet:Feed')->getAllForUser(self::$DI['app']['acl']->get(self::$DI['user']));
foreach ($feeds as $feed) {
$result = $this->object->get_publication($request, $feed->getId(), self::$DI['user']);
$this->checkResponseField($result, "feed", 'array');
$this->checkResponseField($result, "entries", 'array');
$this->checkResponseField($result, "offset_start", 'integer');
$this->checkResponseField($result, "per_page", 'integer');
}
}
private function checkResponseField(API_V1_result $result, $field, $type)
{
$response = json_decode($result->format(), true);
$this->assertArrayHasKey($field, $response['response']);
$this->assertInternalType($type, $response['response'][$field]);
}
}

View File

@@ -1,428 +0,0 @@
<?php
require_once __DIR__ . '/../../../../vendor/alchemy/oauth2php/lib/OAuth2.php';
use Symfony\Component\HttpFoundation\Request;
class api_v1_resultTest extends \PhraseanetAuthenticatedTestCase
{
/**
* @var API_V1_result
*/
protected $api;
public function setUp()
{
parent::setUp();
self::$DI['app']->register(new \API_V1_Timer());
self::$DI['app']['conf']->set(['main', 'api-timers'], true);
$this->api = $this->getMock("API_V1_adapter", ["get_version"], [], "", false);
$this->api->expects($this->any())->method("get_version")->will($this->returnValue("my_super_version1.0"));
}
private function assertIsTimer($timer)
{
$this->assertObjectHasAttribute('name', $timer);
$this->assertObjectHasAttribute('memory', $timer);
$this->assertObjectHasAttribute('time', $timer);
}
public function testFormatJson()
{
$server = [
"HTTP_ACCEPT" => "application/json"
, 'REQUEST_METHOD' => 'GET'
, 'SCRIPT_FILENAME' => 'my/base/path/my/request/uri/filename'
, "REQUEST_URI" => "my/base/path/my/request/uri"
, 'PHP_SELF' => 'my/base/path'
];
$request = new Request(["callback" => ""], [], [], [], [], $server);
$api_result = new API_V1_result(self::$DI['app'], $request, $this->api);
$return = $api_result->format();
$this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_STRING, $return);
$response = json_decode($return);
$this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_OBJECT, $response);
$this->assertObjectHasAttribute("meta", $response);
$this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_OBJECT, $response->meta);
$this->assertObjectHasAttribute("response", $response);
$this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_OBJECT, $response->response);
$this->assertEquals(0, sizeof(get_object_vars($response->response)));
$this->assertEquals(0, sizeof(get_class_methods($response->response)));
$this->checkResponseFieldMeta($response, "api_version", "my_super_version1.0", PHPUnit_Framework_Constraint_IsType::TYPE_STRING);
$this->checkResponseFieldMeta($response, "request", "GET my/base/path/my/request/uri", PHPUnit_Framework_Constraint_IsType::TYPE_STRING);
$this->assertObjectHasAttribute("timers", $response);
$this->assertCount(1, $response->timers);
foreach ($response->timers as $timer) {
$this->assertIsTimer($timer);
}
$date = new \DateTime();
$now = $date->format('U');
$date_query = \DateTime::createFromFormat(DATE_ATOM, $response->meta->response_time);
$now_query = $date_query->format('U');
$this->assertLessThan(1, $now_query - $now);
$this->assertDateAtom($response->meta->response_time);
$date = new DateTime();
$now_U = $date->format('U');
$date_resp = DateTime::createFromFormat(DATE_ATOM, $response->meta->response_time);
$resp_U = $date_resp->format('U');
$this->assertLessThan(3, abs($resp_U - $now_U), 'No more than 3sec between now and the query');
$this->checkResponseFieldMeta($response, "http_code", 200, PHPUnit_Framework_Constraint_IsType::TYPE_INT);
$this->checkResponseFieldMeta($response, "charset", "UTF-8", PHPUnit_Framework_Constraint_IsType::TYPE_STRING);
$this->assertObjectHasAttribute("error_message", $response->meta);
$this->assertNull($response->meta->error_message);
$this->assertObjectHasAttribute("error_details", $response->meta);
$this->assertNull($response->meta->error_details);
$this->assertObjectHasAttribute("timers", $response);
$this->assertCount(1, $response->timers);
foreach ($response->timers as $timer) {
$this->assertIsTimer($timer);
}
}
public function testFormatYaml()
{
$server = [
"HTTP_ACCEPT" => "application/yaml"
, 'REQUEST_METHOD' => 'GET'
, 'SCRIPT_FILENAME' => 'my/base/path/my/request/uri/filename'
, "REQUEST_URI" => "my/base/path/my/request/uri"
, 'PHP_SELF' => 'my/base/path'
];
$request = new Request(["callback" => ""], [], [], [], [], $server);
$api_result = new API_V1_result(self::$DI['app'], $request, $this->api);
$return = $api_result->format();
$sfYaml = new Symfony\Component\Yaml\Parser();
$response = $sfYaml->parse($return);
$this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY, $response);
$this->assertArrayHasKey("meta", $response);
$this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY, $response["meta"]);
$this->assertArrayHasKey("response", $response);
$this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY, $response["response"]);
$this->assertEquals(0, count($response["response"]));
$this->assertArrayHasKey("api_version", $response["meta"]);
$this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_STRING, $response["meta"]["api_version"]);
$this->assertEquals("my_super_version1.0", $response["meta"]["api_version"]);
$this->assertArrayHasKey("request", $response["meta"]);
$this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_STRING, $response["meta"]["request"]);
$this->assertEquals("GET my/base/path/my/request/uri", $response["meta"]["request"]);
$this->assertArrayHasKey("response_time", $response["meta"]);
$this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_STRING, $response["meta"]["response_time"]);
$this->assertDateAtom($response["meta"]["response_time"]);
$date_obj1 = DateTime::createFromFormat(DATE_ATOM, $response["meta"]["response_time"]);
$date_obj2 = new DateTime();
$this->assertLessThan(3, abs($date_obj1->format('U') - $date_obj2->format('U')), 'No more than 3sec between now and the query');
$this->assertArrayHasKey("http_code", $response["meta"]);
$this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_INT, $response["meta"]["http_code"]);
$this->assertEquals(200, $response["meta"]["http_code"]);
$this->assertArrayHasKey("error_message", $response["meta"]);
$this->assertNull($response["meta"]["error_message"]);
$this->assertArrayHasKey("error_details", $response["meta"]);
$this->assertNull($response["meta"]["error_details"]);
$this->assertArrayHasKey("charset", $response["meta"]);
$this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_STRING, $response["meta"]["charset"]);
$this->assertEquals("UTF-8", $response["meta"]["charset"]);
$this->assertArrayHasKey("timers", $response);
$this->assertCount(1, $response['timers']);
}
public function testFormatJsonP()
{
$server = [
"HTTP_ACCEPT" => "application/yaml"
, 'REQUEST_METHOD' => 'GET'
, 'SCRIPT_FILENAME' => 'my/base/path/my/request/uri/filename'
, "REQUEST_URI" => "my/base/path/my/request/uri"
, 'PHP_SELF' => 'my/base/path'
];
$request = new Request(["callback" => "my_callback_function"], [], [], [], [], $server);
$api_result = new API_V1_result(self::$DI['app'], $request, $this->api);
$return = $api_result->format();
$this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_STRING, $return);
$this->assertRegexp("/my_callback_function\(\{.+\}\)/", $return);
$response = json_decode(substr($return, 21, strlen($return) - 22));
$this->assertObjectHasAttribute("timers", $response);
$this->assertCount(1, $response->timers);
foreach ($response->timers as $timer) {
$this->assertIsTimer($timer);
}
}
/**
* @depends testFormatJson
*/
public function testSet_datas()
{
$server = [
"HTTP_ACCEPT" => "application/json"
, 'REQUEST_METHOD' => 'GET'
, 'SCRIPT_FILENAME' => 'my/base/path/my/request/uri/filename'
, "REQUEST_URI" => "my/base/path/my/request/uri"
, 'PHP_SELF' => 'my/base/path'
];
$request = new Request(["callback" => ""], [], [], [], [], $server);
$api_result = new API_V1_result(self::$DI['app'], $request, $this->api);
$api_result->set_datas(["pirouette" => "cacahuete", "black" => true, "bob" => ["bob"]]);
$response = json_decode($api_result->format());
$this->checkResponseFieldResponse($response, "pirouette", "cacahuete", PHPUnit_Framework_Constraint_IsType::TYPE_STRING);
$this->checkResponseFieldResponse($response, "black", true, PHPUnit_Framework_Constraint_IsType::TYPE_BOOL);
$this->checkResponseFieldResponse($response, "bob", ["bob"], PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY);
}
public function testGet_datas()
{
$server = [
"HTTP_ACCEPT" => "application/json"
, 'REQUEST_METHOD' => 'GET'
, 'SCRIPT_FILENAME' => 'my/base/path/my/request/uri/filename'
, "REQUEST_URI" => "my/base/path/my/request/uri"
, 'PHP_SELF' => 'my/base/path'
];
$request = new Request(["callback" => ""], [], [], [], [], $server);
$data = ["pirouette" => "cacahuete", "black" => true, "bob" => ["bob"]];
$api_result = new API_V1_result(self::$DI['app'], $request, $this->api);
$api_result->set_datas($data);
$this->assertEquals($data, $api_result->get_datas());
}
public function testGet_Emptydatas()
{
$server = [
"HTTP_ACCEPT" => "application/json"
, 'REQUEST_METHOD' => 'GET'
, 'SCRIPT_FILENAME' => 'my/base/path/my/request/uri/filename'
, "REQUEST_URI" => "my/base/path/my/request/uri"
, 'PHP_SELF' => 'my/base/path'
];
$request = new Request(["callback" => ""], [], [], [], [], $server);
$data = [];
$api_result = new API_V1_result(self::$DI['app'], $request, $this->api);
$api_result->set_datas($data);
$this->assertEquals($data, $api_result->get_datas());
}
private function checkResponseFieldMeta(stdClass $response, $field, $expected_value, $type)
{
$this->assertObjectHasAttribute($field, $response->meta);
$this->assertInternalType($type, $response->meta->$field);
$this->assertEquals($expected_value, $response->meta->$field);
}
private function checkResponseFieldResponse(stdClass $response, $field, $expected_value, $type)
{
$this->assertObjectHasAttribute($field, $response->response);
$this->assertInternalType($type, $response->response->$field);
$this->assertEquals($expected_value, $response->response->$field);
}
public function testGet_content_type()
{
$server = ["HTTP_ACCEPT" => "application/json"];
$request = new Request(["callback" => ""], [], [], [], [], $server);
$api_result = new API_V1_result(self::$DI['app'], $request, $this->api);
$this->assertEquals("application/json", $api_result->get_content_type());
$server = ["HTTP_ACCEPT" => "application/yaml"];
$request = new Request(["callback" => ""], [], [], [], [], $server);
$api_result = new API_V1_result(self::$DI['app'], $request, $this->api);
$this->assertEquals('application/yaml', $api_result->get_content_type());
$server = ["HTTP_ACCEPT" => "text/yaml"];
$request = new Request(["callback" => ""], [], [], [], [], $server);
$api_result = new API_V1_result(self::$DI['app'], $request, $this->api);
$this->assertEquals('application/yaml', $api_result->get_content_type());
$server = ["HTTP_ACCEPT" => ""];
$request = new Request(["callback" => "hello"], [], [], [], [], $server);
$api_result = new API_V1_result(self::$DI['app'], $request, $this->api);
$this->assertEquals('text/javascript', $api_result->get_content_type());
$server = ["HTTP_ACCEPT" => "unknow"];
$request = new Request(["callback" => ""], [], [], [], [], $server);
$api_result = new API_V1_result(self::$DI['app'], $request, $this->api);
$this->assertEquals("application/json", $api_result->get_content_type());
}
/**
* @depends testFormatJson
*/
public function testSet_error_message()
{
$api_result = new API_V1_result(self::$DI['app'], new Request(), $this->api);
$api_result->set_error_message(API_V1_result::ERROR_BAD_REQUEST, 'detaillage');
$this->assertErrorMessage($api_result, 400, API_V1_result::ERROR_BAD_REQUEST, API_V1_exception_badrequest::get_details(), 'detaillage');
$api_result = new API_V1_result(self::$DI['app'], new Request(), $this->api);
$api_result->set_error_message(API_V1_result::ERROR_UNAUTHORIZED, 'detaillage');
$this->assertErrorMessage($api_result, 401, API_V1_result::ERROR_UNAUTHORIZED, API_V1_exception_unauthorized::get_details(), 'detaillage');
$api_result = new API_V1_result(self::$DI['app'], new Request(), $this->api);
$api_result->set_error_message(API_V1_result::ERROR_FORBIDDEN, 'detaillage');
$this->assertErrorMessage($api_result, 403, API_V1_result::ERROR_FORBIDDEN, API_V1_exception_forbidden::get_details(), 'detaillage');
$api_result = new API_V1_result(self::$DI['app'], new Request(), $this->api);
$api_result->set_error_message(API_V1_result::ERROR_NOTFOUND, 'detaillage');
$this->assertErrorMessage($api_result, 404, API_V1_result::ERROR_NOTFOUND, API_V1_exception_notfound::get_details(), 'detaillage');
$api_result = new API_V1_result(self::$DI['app'], new Request(), $this->api);
$api_result->set_error_message(API_V1_result::ERROR_METHODNOTALLOWED, 'detaillage');
$this->assertErrorMessage($api_result, 405, API_V1_result::ERROR_METHODNOTALLOWED, API_V1_exception_methodnotallowed::get_details(), 'detaillage');
$api_result = new API_V1_result(self::$DI['app'], new Request(), $this->api);
$api_result->set_error_message(API_V1_result::ERROR_INTERNALSERVERERROR, 'detaillage');
$this->assertErrorMessage($api_result, 500, API_V1_result::ERROR_INTERNALSERVERERROR, API_V1_exception_internalservererror::get_details(), 'detaillage');
$api_result = new API_V1_result(self::$DI['app'], new Request(), $this->api);
$api_result->set_error_message(OAUTH2_ERROR_INVALID_REQUEST, 'detaillage');
$this->assertErrorMessage($api_result, 200, OAUTH2_ERROR_INVALID_REQUEST, NULL, 'detaillage');
}
private function assertErrorMessage(API_V1_result $api_result, $code, $type, $message, $detail)
{
$response = json_decode($api_result->format());
$this->checkResponseFieldMeta($response, 'http_code', $code, PHPUnit_Framework_Constraint_IsType::TYPE_INT);
if (is_null($type)) {
$this->assertObjectHasAttribute('error_type', $response->meta);
$this->assertNull($response->meta->error_type);
} else {
$this->checkResponseFieldMeta($response, 'error_type', $type, PHPUnit_Framework_Constraint_IsType::TYPE_STRING);
}
if (is_null($message)) {
$this->assertObjectHasAttribute('error_message', $response->meta);
$this->assertNull($response->meta->error_message);
} else {
$this->checkResponseFieldMeta($response, 'error_message', $message, PHPUnit_Framework_Constraint_IsType::TYPE_STRING);
}
if (is_null($detail)) {
$this->assertObjectHasAttribute('error_details', $response->meta);
$this->assertNull($response->meta->error_details);
} else {
$this->checkResponseFieldMeta($response, 'error_details', $detail, PHPUnit_Framework_Constraint_IsType::TYPE_STRING);
}
}
/**
* @depends testFormatJson
*/
public function testSet_error_code()
{
$api_result = new API_V1_result(self::$DI['app'], new Request(), $this->api);
$api_result->set_error_code(400);
$this->assertErrorMessage($api_result, 400, API_V1_result::ERROR_BAD_REQUEST, API_V1_exception_badrequest::get_details(), null);
$api_result = new API_V1_result(self::$DI['app'], new Request(), $this->api);
$api_result->set_error_code(401);
$this->assertErrorMessage($api_result, 401, API_V1_result::ERROR_UNAUTHORIZED, API_V1_exception_unauthorized::get_details(), null);
$api_result = new API_V1_result(self::$DI['app'], new Request(), $this->api);
$api_result->set_error_code(403);
$this->assertErrorMessage($api_result, 403, API_V1_result::ERROR_FORBIDDEN, API_V1_exception_forbidden::get_details(), null);
$api_result = new API_V1_result(self::$DI['app'], new Request(), $this->api);
$api_result->set_error_code(404);
$this->assertErrorMessage($api_result, 404, API_V1_result::ERROR_NOTFOUND, API_V1_exception_notfound::get_details(), null);
$api_result = new API_V1_result(self::$DI['app'], new Request(), $this->api);
$api_result->set_error_code(405);
$this->assertErrorMessage($api_result, 405, API_V1_result::ERROR_METHODNOTALLOWED, API_V1_exception_methodnotallowed::get_details(), null);
$api_result = new API_V1_result(self::$DI['app'], new Request(), $this->api);
$api_result->set_error_code(500);
$this->assertErrorMessage($api_result, 500, API_V1_result::ERROR_INTERNALSERVERERROR, API_V1_exception_internalservererror::get_details(), null);
}
public function testGet_http_code()
{
$api_result = new API_V1_result(self::$DI['app'], new Request(), $this->api);
$api_result->set_error_code(400);
$this->assertEquals(400, $api_result->get_http_code());
$api_result = new API_V1_result(self::$DI['app'], new Request(), $this->api);
$api_result->set_error_code(401);
$this->assertEquals(401, $api_result->get_http_code());
$api_result = new API_V1_result(self::$DI['app'], new Request(), $this->api);
$api_result->set_error_code(403);
$this->assertEquals(403, $api_result->get_http_code());
$api_result = new API_V1_result(self::$DI['app'], new Request(), $this->api);
$api_result->set_error_code(404);
$this->assertEquals(404, $api_result->get_http_code());
$api_result = new API_V1_result(self::$DI['app'], new Request(), $this->api);
$api_result->set_error_code(405);
$this->assertEquals(405, $api_result->get_http_code());
$api_result = new API_V1_result(self::$DI['app'], new Request(), $this->api);
$api_result->set_error_code(500);
$this->assertEquals(500, $api_result->get_http_code());
$api_result = new API_V1_result(self::$DI['app'], new Request(["callback" => "my_callback"]), $this->api);
$api_result->set_error_code(400);
$this->assertEquals(200, $api_result->get_http_code());
$api_result = new API_V1_result(self::$DI['app'], new Request(["callback" => "my_callback"]), $this->api);
$api_result->set_error_code(500);
$this->assertEquals(500, $api_result->get_http_code());
}
public function testSet_http_code()
{
$api_result = new API_V1_result(self::$DI['app'], new Request(), $this->api);
$api_result->set_http_code(500);
$this->assertEquals(500, $api_result->get_http_code());
$api_result->set_http_code(400);
$this->assertEquals(400, $api_result->get_http_code());
$api_result->set_http_code(401);
$this->assertEquals(401, $api_result->get_http_code());
$api_result->set_http_code(403);
$this->assertEquals(403, $api_result->get_http_code());
$api_result = new API_V1_result(self::$DI['app'], new Request(["callback" => "my_callback"]), $this->api);
$api_result->set_http_code(500);
$this->assertEquals(500, $api_result->get_http_code());
$api_result->set_http_code(400);
$this->assertEquals(200, $api_result->get_http_code());
$api_result->set_http_code(401);
$this->assertEquals(200, $api_result->get_http_code());
$api_result->set_http_code(403);
$this->assertEquals(200, $api_result->get_http_code());
$api_result->set_http_code(404);
$this->assertEquals(200, $api_result->get_http_code());
$api_result->set_http_code(405);
$this->assertEquals(200, $api_result->get_http_code());
}
}

View File

@@ -16,7 +16,7 @@ require_once __DIR__ . '/../lib/autoload.php';
ErrorHandler::register(); ErrorHandler::register();
$environment = Application::ENV_PROD; $environment = Application::ENV_DEV;
$app = require __DIR__ . '/../lib/Alchemy/Phrasea/Application/Api.php'; $app = require __DIR__ . '/../lib/Alchemy/Phrasea/Application/Api.php';
$app->run(); $app->run();