diff --git a/config/config.sample.yml b/config/config.sample.yml index 51db7023b4..ff5f0e326b 100644 --- a/config/config.sample.yml +++ b/config/config.sample.yml @@ -21,6 +21,7 @@ dev: #Assign your phraseanet application connection #Connections are defined in connexions.yml configuration file database: main_connexion + api-timers: true #Assign your template engine service & ORM service #Services are defined in service.yml configuration file diff --git a/lib/Alchemy/Phrasea/Application/Api.php b/lib/Alchemy/Phrasea/Application/Api.php index b59685c505..6b40c37243 100644 --- a/lib/Alchemy/Phrasea/Application/Api.php +++ b/lib/Alchemy/Phrasea/Application/Api.php @@ -11,6 +11,11 @@ namespace Alchemy\Phrasea\Application; +use Alchemy\Phrasea\Core\PhraseaEvents; +use Alchemy\Phrasea\Core\Event\ApiLoadEndEvent; +use Alchemy\Phrasea\Core\Event\ApiLoadStartEvent; +use Alchemy\Phrasea\Core\Event\ApiOAuth2StartEvent; +use Alchemy\Phrasea\Core\Event\ApiOAuth2EndEvent; use Silex\Application; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Request; @@ -25,6 +30,10 @@ return call_user_func(function() { $app = new \Silex\Application(); + $app->register(new \API_V1_Timer()); + + $app['dispatcher']->dispatch(PhraseaEvents::API_LOAD_START, new ApiLoadStartEvent()); + /** * @var Alchemy\Phrasea\Core */ @@ -45,7 +54,7 @@ return call_user_func(function() { * @var Closure */ $app['api'] = function () use ($app) { - return new \API_V1_adapter(false, $app["appbox"], $app["Core"]); + return new \API_V1_adapter($app, false, $app["appbox"], $app["Core"]); }; /** @@ -59,6 +68,7 @@ return call_user_func(function() { * @ throws \API_V1_exception_forbidden */ $app->before(function($request) use ($app) { + $app['dispatcher']->dispatch(PhraseaEvents::API_OAUTH2_START, new ApiOAuth2StartEvent()); $session = $app["appbox"]->get_session(); $registry = $app['Core']->getRegistry(); $oauth2_adapter = new \API_OAuth2_Adapter($app["appbox"]); @@ -76,12 +86,14 @@ return call_user_func(function() { } if ($session->is_authenticated()) { + $app['dispatcher']->dispatch(PhraseaEvents::API_OAUTH2_END, new ApiOAuth2EndEvent()); return; } if ($oauth2_adapter->has_ses_id()) { try { $session->restore($user, $oauth2_adapter->get_ses_id()); + $app['dispatcher']->dispatch(PhraseaEvents::API_OAUTH2_END, new ApiOAuth2EndEvent()); return; } catch (\Exception $e) { @@ -91,6 +103,7 @@ return call_user_func(function() { $auth = new \Session_Authentication_None($user); $session->authenticate($auth); $oauth2_adapter->remember_this_ses_id($session->get_ses_id()); + $app['dispatcher']->dispatch(PhraseaEvents::API_OAUTH2_END, new ApiOAuth2EndEvent()); return; }); @@ -891,5 +904,7 @@ return call_user_func(function() { return $response; }); + $app['dispatcher']->dispatch(PhraseaEvents::API_LOAD_END, new ApiLoadEndEvent()); + return $app; }); diff --git a/lib/Alchemy/Phrasea/Application/ApiVersion.php b/lib/Alchemy/Phrasea/Application/ApiVersion.php index 6addb702fd..11549c4166 100644 --- a/lib/Alchemy/Phrasea/Application/ApiVersion.php +++ b/lib/Alchemy/Phrasea/Application/ApiVersion.php @@ -11,6 +11,9 @@ namespace Alchemy\Phrasea\Application; +use Alchemy\Phrasea\Core\PhraseaEvents; +use Alchemy\Phrasea\Core\Event\ApiLoadEndEvent; +use Alchemy\Phrasea\Core\Event\ApiLoadStartEvent; use Symfony\Component\HttpFoundation\Request; /** @@ -23,15 +26,19 @@ return call_user_func(function() { $app = new \Silex\Application(); + $app->register(new \API_V1_Timer()); + + $app['dispatcher']->dispatch(PhraseaEvents::API_LOAD_START, new ApiLoadStartEvent()); + $app["Core"] = \bootstrap::getCore(); $app->get( '/', function(Request $request) use ($app) { $registry = $app["Core"]->getRegistry(); - $apiAdapter = new \API_V1_adapter(false, \appbox::get_instance($app['Core']), $app["Core"]); + $apiAdapter = new \API_V1_adapter($app, false, \appbox::get_instance($app['Core']), $app["Core"]); - $result = new \API_V1_result($request, $apiAdapter); + $result = new \API_V1_result($app, $request, $apiAdapter); $result->set_datas( array( @@ -57,6 +64,8 @@ return call_user_func(function() { return $result->get_response(); }); + $app['dispatcher']->dispatch(PhraseaEvents::API_LOAD_END, new ApiLoadEndEvent()); + return $app; }); diff --git a/lib/Alchemy/Phrasea/Core/Event/ApiLoadEndEvent.php b/lib/Alchemy/Phrasea/Core/Event/ApiLoadEndEvent.php new file mode 100644 index 0000000000..304bbf5e9b --- /dev/null +++ b/lib/Alchemy/Phrasea/Core/Event/ApiLoadEndEvent.php @@ -0,0 +1,23 @@ +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(array( + '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) + { + } +} \ No newline at end of file diff --git a/lib/classes/API/V1/adapter.class.php b/lib/classes/API/V1/adapter.class.php index cd0f17e7a6..eeaff46b31 100644 --- a/lib/classes/API/V1/adapter.class.php +++ b/lib/classes/API/V1/adapter.class.php @@ -20,6 +20,8 @@ use Silex\Application; */ class API_V1_adapter extends API_V1_Abstract { + protected $app; + /** * API Version * @@ -51,8 +53,9 @@ class API_V1_adapter extends API_V1_Abstract * @param appbox $appbox Appbox object * @return API_V1_adapter */ - public function __construct($auth_token, appbox &$appbox, Alchemy\Phrasea\Core $core) + public function __construct(Application $app, $auth_token, appbox &$appbox, Alchemy\Phrasea\Core $core) { + $this->app = $app; $this->appbox = $appbox; $this->core = $core; @@ -67,7 +70,7 @@ class API_V1_adapter extends API_V1_Abstract */ public function get_error_message(Request $request, $error, $message) { - $result = new API_V1_result($request, $this); + $result = new API_V1_result($this->app, $request, $this); $result->set_error_message($error, $message); return $result; @@ -81,7 +84,7 @@ class API_V1_adapter extends API_V1_Abstract */ public function get_error_code(Request $request, $code) { - $result = new API_V1_result($request, $this); + $result = new API_V1_result($this->app, $request, $this); $result->set_error_code($code); return $result; @@ -105,7 +108,7 @@ class API_V1_adapter extends API_V1_Abstract */ public function get_scheduler(Application $app) { - $result = new \API_V1_result($app['request'], $this); + $result = new \API_V1_result($app, $app['request'], $this); $appbox = \appbox::get_instance($app['Core']); $taskManager = new \task_manager($appbox); @@ -132,7 +135,7 @@ class API_V1_adapter extends API_V1_Abstract */ public function get_task_list(Application $app) { - $result = new \API_V1_result($app['request'], $this); + $result = new \API_V1_result($app, $app['request'], $this); $appbox = \appbox::get_instance($app['Core']); $taskManager = new \task_manager($appbox); @@ -172,7 +175,7 @@ class API_V1_adapter extends API_V1_Abstract */ public function get_task(Application $app, $taskId) { - $result = new \API_V1_result($app['request'], $this); + $result = new \API_V1_result($app, $app['request'], $this); $appbox = \appbox::get_instance($app['Core']); $taskManager = new task_manager($appbox); @@ -195,7 +198,7 @@ class API_V1_adapter extends API_V1_Abstract */ public function start_task(Application $app, $taskId) { - $result = new \API_V1_result($app['request'], $this); + $result = new \API_V1_result($app, $app['request'], $this); $appbox = \appbox::get_instance($app['Core']); $taskManager = new \task_manager($appbox); @@ -219,7 +222,7 @@ class API_V1_adapter extends API_V1_Abstract */ public function stop_task(Application $app, $taskId) { - $result = new API_V1_result($app['request'], $this); + $result = new API_V1_result($app, $app['request'], $this); $appbox = \appbox::get_instance($app['Core']); $taskManager = new \task_manager($appbox); @@ -245,7 +248,7 @@ class API_V1_adapter extends API_V1_Abstract */ public function set_task_property(Application $app, $taskId) { - $result = new API_V1_result($app['request'], $this); + $result = new API_V1_result($app, $app['request'], $this); $title = $app['request']->get('title'); $autostart = $app['request']->get('autostart'); @@ -511,7 +514,7 @@ class API_V1_adapter extends API_V1_Abstract */ public function get_phraseanet_monitor(Application $app) { - $result = new API_V1_result($app['request'], $this); + $result = new API_V1_result($app, $app['request'], $this); $ret = array_merge( $this->get_config_info($app), $this->get_cache_info($app), $this->get_gv_info($app) @@ -531,7 +534,7 @@ class API_V1_adapter extends API_V1_Abstract */ public function get_databoxes(Request $request) { - $result = new API_V1_result($request, $this); + $result = new API_V1_result($this->app, $request, $this); $result->set_datas(array("databoxes" => $this->list_databoxes())); @@ -548,7 +551,7 @@ class API_V1_adapter extends API_V1_Abstract */ public function get_databox_collections(Request $request, $databox_id) { - $result = new API_V1_result($request, $this); + $result = new API_V1_result($this->app, $request, $this); $result->set_datas( array( @@ -571,7 +574,7 @@ class API_V1_adapter extends API_V1_Abstract */ public function get_databox_status(Request $request, $databox_id) { - $result = new API_V1_result($request, $this); + $result = new API_V1_result($this->app, $request, $this); $result->set_datas( array( @@ -595,7 +598,7 @@ class API_V1_adapter extends API_V1_Abstract */ public function get_databox_metadatas(Request $request, $databox_id) { - $result = new API_V1_result($request, $this); + $result = new API_V1_result($this->app, $request, $this); $result->set_datas( array( @@ -620,7 +623,7 @@ class API_V1_adapter extends API_V1_Abstract */ public function get_databox_terms(Request $request, $databox_id) { - $result = new API_V1_result($request, $this); + $result = new API_V1_result($this->app, $request, $this); $result->set_datas( array( @@ -634,7 +637,7 @@ class API_V1_adapter extends API_V1_Abstract public function caption_records(Request $request, $databox_id, $record_id) { - $result = new API_V1_result($request, $this); + $result = new API_V1_result($this->app, $request, $this); $record = $this->appbox->get_databox($databox_id)->get_record($record_id); $fields = $record->get_caption()->get_fields(); @@ -739,7 +742,7 @@ class API_V1_adapter extends API_V1_Abstract $ret['url'] = '/quarantine/item/' . $output->getId() . '/'; } - $result = new API_V1_result($request, $this); + $result = new API_V1_result($this->app, $request, $this); $result->set_datas($ret); @@ -772,7 +775,7 @@ class API_V1_adapter extends API_V1_Abstract $ret[] = $this->list_lazaret_file($lazaretFile); } - $result = new API_V1_result($request, $this); + $result = new API_V1_result($this->app, $request, $this); $result->set_datas(array( 'offset_start' => $offset_start, @@ -798,7 +801,7 @@ class API_V1_adapter extends API_V1_Abstract $ret = array('quarantine_item' => $this->list_lazaret_file($lazaretFile)); - $result = new API_V1_result($request, $this); + $result = new API_V1_result($this->app, $request, $this); $result->set_datas($ret); @@ -848,7 +851,7 @@ class API_V1_adapter extends API_V1_Abstract */ public function search(Request $request) { - $result = new API_V1_result($request, $this); + $result = new API_V1_result($this->app, $request, $this); list($ret, $search_result) = $this->prepare_search_request($request); @@ -882,7 +885,7 @@ class API_V1_adapter extends API_V1_Abstract */ public function search_records(Request $request) { - $result = new API_V1_result($request, $this); + $result = new API_V1_result($this->app, $request, $this); list($ret, $search_result) = $this->prepare_search_request($request); @@ -1014,7 +1017,7 @@ class API_V1_adapter extends API_V1_Abstract */ public function get_record_related(Request $request, $databox_id, $record_id) { - $result = new API_V1_result($request, $this); + $result = new API_V1_result($this->app, $request, $this); $that = $this; $baskets = array_map(function ($basket) use ($that) { @@ -1050,7 +1053,7 @@ class API_V1_adapter extends API_V1_Abstract */ public function get_record_metadatas(Request $request, $databox_id, $record_id) { - $result = new API_V1_result($request, $this); + $result = new API_V1_result($this->app, $request, $this); $record = $this->appbox->get_databox($databox_id)->get_record($record_id); @@ -1074,7 +1077,7 @@ class API_V1_adapter extends API_V1_Abstract */ public function get_record_status(Request $request, $databox_id, $record_id) { - $result = new API_V1_result($request, $this); + $result = new API_V1_result($this->app, $request, $this); $record = $this->appbox ->get_databox($databox_id) @@ -1105,7 +1108,7 @@ class API_V1_adapter extends API_V1_Abstract public function get_record_embed(Request $request, $databox_id, $record_id) { - $result = new API_V1_result($request, $this); + $result = new API_V1_result($this->app, $request, $this); $record = $this->appbox->get_databox($databox_id)->get_record($record_id); @@ -1135,7 +1138,7 @@ class API_V1_adapter extends API_V1_Abstract public function get_story_embed(Request $request, $databox_id, $record_id) { - $result = new API_V1_result($request, $this); + $result = new API_V1_result($this->app, $request, $this); $record = $this->appbox->get_databox($databox_id)->get_record($record_id); @@ -1155,7 +1158,7 @@ class API_V1_adapter extends API_V1_Abstract public function set_record_metadatas(Request $request, $databox_id, $record_id) { - $result = new API_V1_result($request, $this); + $result = new API_V1_result($this->app, $request, $this); $record = $this->appbox->get_databox($databox_id)->get_record($record_id); try { @@ -1182,7 +1185,7 @@ class API_V1_adapter extends API_V1_Abstract public function set_record_status(Request $request, $databox_id, $record_id) { - $result = new API_V1_result($request, $this); + $result = new API_V1_result($this->app, $request, $this); $databox = $this->appbox->get_databox($databox_id); $record = $databox->get_record($record_id); $status_bits = $databox->get_statusbits(); @@ -1233,7 +1236,7 @@ class API_V1_adapter extends API_V1_Abstract */ public function set_record_collection(Request $request, $databox_id, $record_id) { - $result = new API_V1_result($request, $this); + $result = new API_V1_result($this->app, $request, $this); $databox = $this->appbox->get_databox($databox_id); $record = $databox->get_record($record_id); @@ -1259,7 +1262,7 @@ class API_V1_adapter extends API_V1_Abstract */ public function get_record(Request $request, $databox_id, $record_id) { - $result = new API_V1_result($request, $this); + $result = new API_V1_result($this->app, $request, $this); $databox = $this->appbox->get_databox($databox_id); try { $record = $databox->get_record($record_id); @@ -1283,7 +1286,7 @@ class API_V1_adapter extends API_V1_Abstract */ public function get_story(Request $request, $databox_id, $story_id) { - $result = new API_V1_result($request, $this); + $result = new API_V1_result($this->app, $request, $this); $databox = $this->appbox->get_databox($databox_id); try { $story = $databox->get_record($story_id); @@ -1305,7 +1308,7 @@ class API_V1_adapter extends API_V1_Abstract */ public function search_baskets(Request $request) { - $result = new API_V1_result($request, $this); + $result = new API_V1_result($this->app, $request, $this); $usr_id = $session = $this->appbox->get_session()->get_usr_id(); @@ -1344,7 +1347,7 @@ class API_V1_adapter extends API_V1_Abstract */ public function create_basket(Request $request) { - $result = new API_V1_result($request, $this); + $result = new API_V1_result($this->app, $request, $this); $name = $request->get('name'); @@ -1397,7 +1400,7 @@ class API_V1_adapter extends API_V1_Abstract */ public function get_basket(Request $request, $basket_id) { - $result = new API_V1_result($request, $this); + $result = new API_V1_result($this->app, $request, $this); $em = $this->core->getEntityManager(); $repository = $em->getRepository('\Entities\Basket'); @@ -1495,7 +1498,7 @@ class API_V1_adapter extends API_V1_Abstract */ public function set_basket_title(Request $request, $basket_id) { - $result = new API_V1_result($request, $this); + $result = new API_V1_result($this->app, $request, $this); $name = $request->get('name'); @@ -1524,7 +1527,7 @@ class API_V1_adapter extends API_V1_Abstract */ public function set_basket_description(Request $request, $basket_id) { - $result = new API_V1_result($request, $this); + $result = new API_V1_result($this->app, $request, $this); $desc = $request->get('description'); @@ -1553,7 +1556,7 @@ class API_V1_adapter extends API_V1_Abstract */ public function search_publications(Request $request, User_Adapter &$user) { - $result = new API_V1_result($request, $this); + $result = new API_V1_result($this->app, $request, $this); $coll = Feed_Collection::load_all($this->appbox, $user); @@ -1588,7 +1591,7 @@ class API_V1_adapter extends API_V1_Abstract */ public function get_publication(Request $request, $publication_id, User_Adapter &$user) { - $result = new API_V1_result($request, $this); + $result = new API_V1_result($this->app, $request, $this); $feed = Feed_Adapter::load_with_user($this->appbox, $user, $publication_id); @@ -1611,7 +1614,7 @@ class API_V1_adapter extends API_V1_Abstract public function get_publications(Request $request, User_Adapter &$user) { - $result = new API_V1_result($request, $this); + $result = new API_V1_result($this->app, $request, $this); $feed = Feed_Aggregate::load_with_user($this->appbox, $user); @@ -1634,7 +1637,7 @@ class API_V1_adapter extends API_V1_Abstract public function get_feed_entry(Request $request, $entry_id, User_Adapter &$user) { - $result = new API_V1_result($request, $this); + $result = new API_V1_result($this->app, $request, $this); $entry = Feed_Entry_Adapter::load_from_id($this->appbox, $entry_id); diff --git a/lib/classes/API/V1/result.class.php b/lib/classes/API/V1/result.class.php index decc2e6130..d71a3831f1 100644 --- a/lib/classes/API/V1/result.class.php +++ b/lib/classes/API/V1/result.class.php @@ -9,18 +9,15 @@ * file that was distributed with this source code. */ -/** - * - * - * - * @package APIv1 - * @license http://opensource.org/licenses/gpl-3.0 GPLv3 - * @link www.phraseanet.com - */ -use \Symfony\Component\HttpFoundation\Request; +use Alchemy\Phrasea\Core\Event\ApiResultEvent; +use Alchemy\Phrasea\Core\PhraseaEvents; +use Silex\Application; +use Symfony\Component\HttpFoundation\Request; class API_V1_result { + protected $app; + /** * * @var string @@ -102,10 +99,11 @@ class API_V1_result * @param string $response_type One of the API_V1_result 'FORMAT_*' constants * @return API_V1_result */ - public function __construct(Request $request, API_V1_adapter $api) + 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); @@ -196,6 +194,14 @@ class API_V1_result , 'response' => $this->response ); + $this->app['dispatcher']->dispatch(PhraseaEvents::API_RESULT, new ApiResultEvent()); + + $conf = $this->app['Core']->getConfiguration()->getPhraseanet(); + + if ($conf->has('api-timers') && true === $conf->get('api-timers')) { + $ret['timers'] = $this->app['api.timers']->toArray(); + } + $return_value = false; switch ($this->response_type) { diff --git a/tests/api/v1/api_v1_TimerTest.php b/tests/api/v1/api_v1_TimerTest.php new file mode 100644 index 0000000000..1baa8aced9 --- /dev/null +++ b/tests/api/v1/api_v1_TimerTest.php @@ -0,0 +1,48 @@ +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 = new Application(); + $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']); + } +} diff --git a/tests/api/v1/api_v1_adapterTest.php b/tests/api/v1/api_v1_adapterTest.php index 55c03df74f..acb26f7f4f 100644 --- a/tests/api/v1/api_v1_adapterTest.php +++ b/tests/api/v1/api_v1_adapterTest.php @@ -15,8 +15,9 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract public function setUp() { parent::setUp(); + $app = require __DIR__ . '/../../../lib/Alchemy/Phrasea/Application/Api.php'; $appbox = appbox::get_instance(\bootstrap::getCore()); - $this->object = new API_V1_adapter(FALSE, $appbox, self::$core); + $this->object = new API_V1_adapter($app, FALSE, $appbox, self::$core); } public function testGet_error_code() @@ -466,8 +467,9 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract public function testSet_record_status() { + $app = require __DIR__ . '/../../../lib/Alchemy/Phrasea/Application/Api.php'; $appbox = appbox::get_instance(\bootstrap::getCore()); - $stub = $this->getMock("API_V1_adapter", array("list_record_status"), array(false, &$appbox, bootstrap::getCore())); + $stub = $this->getMock("API_V1_adapter", array("list_record_status"), array($app, false, &$appbox, bootstrap::getCore())); $appbox = appbox::get_instance(\bootstrap::getCore()); $databox = static::$records['record_1']->get_databox(); @@ -504,7 +506,8 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract public function testSet_record_collection() { $appbox = appbox::get_instance(\bootstrap::getCore()); - $stub = $this->getMock("API_V1_adapter", array("list_record"), array(false, &$appbox, bootstrap::getCore())); + $app = require __DIR__ . '/../../../lib/Alchemy/Phrasea/Application/Api.php'; + $stub = $this->getMock("API_V1_adapter", array("list_record"), array($app, false, &$appbox, bootstrap::getCore())); $databox = static::$records['record_1']->get_databox(); $request = new Request(array("salut" => "salut c'est la fete"), array(), array(), array(), array(), array('HTTP_Accept' => 'application/json')); diff --git a/tests/api/v1/api_v1_resultTest.php b/tests/api/v1/api_v1_resultTest.php index 936443a746..57fc003700 100644 --- a/tests/api/v1/api_v1_resultTest.php +++ b/tests/api/v1/api_v1_resultTest.php @@ -12,14 +12,31 @@ class API_V1_resultTest extends PhraseanetPHPUnitAuthenticatedAbstract */ protected $api; + protected $app; + public function setUp() { parent::setUp(); + $this->app = require __DIR__ . '/../../../lib/Alchemy/Phrasea/Application/Api.php'; + + $conf = $this->app['Core']->getConfiguration(); + $confs = $conf->getConfigurations(); + $confs[$conf->getEnvironnement()]['phraseanet']['api-timers'] = true; + + $this->app['Core']->getConfiguration()->setConfigurations($confs); + $this->api = $this->getMock("API_V1_adapter", array("get_version"), array(), "", false); $this->api->expects($this->any())->method("get_version")->will($this->returnValue("my_super_version1.0")); } - public function testFormat() + protected function assertIsTimer($timer) + { + $this->assertObjectHasAttribute('name', $timer); + $this->assertObjectHasAttribute('memory', $timer); + $this->assertObjectHasAttribute('time', $timer); + } + + public function testFormatJson() { $server = array( "HTTP_ACCEPT" => "application/json" @@ -30,7 +47,7 @@ class API_V1_resultTest extends PhraseanetPHPUnitAuthenticatedAbstract ); $request = new Request(array("callback" => ""), array(), array(), array(), array(), $server); - $api_result = new API_V1_result($request, $this->api); + $api_result = new API_V1_result($this->app, $request, $this->api); $return = $api_result->format(); $this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_STRING, $return); $response = json_decode($return); @@ -44,6 +61,13 @@ class API_V1_resultTest extends PhraseanetPHPUnitAuthenticatedAbstract $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(2, $response->timers); + + foreach ($response->timers as $timer) { + $this->assertIsTimer($timer); + } + $date = new \DateTime(); $now = $date->format('U'); @@ -67,6 +91,16 @@ class API_V1_resultTest extends PhraseanetPHPUnitAuthenticatedAbstract $this->assertObjectHasAttribute("error_details", $response->meta); $this->assertNull($response->meta->error_details); + $this->assertObjectHasAttribute("timers", $response); + $this->assertCount(2, $response->timers); + + foreach ($response->timers as $timer) { + $this->assertIsTimer($timer); + } + } + + public function testFormatYaml() + { $server = array( "HTTP_ACCEPT" => "application/yaml" , 'REQUEST_METHOD' => 'GET' @@ -76,7 +110,7 @@ class API_V1_resultTest extends PhraseanetPHPUnitAuthenticatedAbstract ); $request = new Request(array("callback" => ""), array(), array(), array(), array(), $server); - $api_result = new API_V1_result($request, $this->api); + $api_result = new API_V1_result($this->app, $request, $this->api); $return = $api_result->format(); $sfYaml = new Symfony\Component\Yaml\Parser(); $response = $sfYaml->parse($return); @@ -112,7 +146,12 @@ class API_V1_resultTest extends PhraseanetPHPUnitAuthenticatedAbstract $this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_STRING, $response["meta"]["charset"]); $this->assertEquals("UTF-8", $response["meta"]["charset"]); + $this->assertArrayHasKey("timers", $response); + $this->assertCount(2, $response['timers']); + } + public function testFormatJsonP() + { $server = array( "HTTP_ACCEPT" => "application/yaml" , 'REQUEST_METHOD' => 'GET' @@ -122,14 +161,22 @@ class API_V1_resultTest extends PhraseanetPHPUnitAuthenticatedAbstract ); $request = new Request(array("callback" => "my_callback_function"), array(), array(), array(), array(), $server); - $api_result = new API_V1_result($request, $this->api); + $api_result = new API_V1_result($this->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(2, $response->timers); + + foreach ($response->timers as $timer) { + $this->assertIsTimer($timer); + } } /** - * @depends testFormat + * @depends testFormatJson */ public function testSet_datas() { @@ -142,7 +189,7 @@ class API_V1_resultTest extends PhraseanetPHPUnitAuthenticatedAbstract ); $request = new Request(array("callback" => ""), array(), array(), array(), array(), $server); - $api_result = new API_V1_result($request, $this->api); + $api_result = new API_V1_result($this->app, $request, $this->api); $api_result->set_datas(array("pirouette" => "cacahuete", "black" => true, "bob" => array("bob"))); $response = json_decode($api_result->format()); $this->checkResponseFieldResponse($response, "pirouette", "cacahuete", PHPUnit_Framework_Constraint_IsType::TYPE_STRING); @@ -162,7 +209,7 @@ class API_V1_resultTest extends PhraseanetPHPUnitAuthenticatedAbstract $request = new Request(array("callback" => ""), array(), array(), array(), array(), $server); $data = array("pirouette" => "cacahuete", "black" => true, "bob" => array("bob")); - $api_result = new API_V1_result($request, $this->api); + $api_result = new API_V1_result($this->app, $request, $this->api); $api_result->set_datas($data); $this->assertEquals($data, $api_result->get_datas()); @@ -180,7 +227,7 @@ class API_V1_resultTest extends PhraseanetPHPUnitAuthenticatedAbstract $request = new Request(array("callback" => ""), array(), array(), array(), array(), $server); $data = array(); - $api_result = new API_V1_result($request, $this->api); + $api_result = new API_V1_result($this->app, $request, $this->api); $api_result->set_datas($data); $this->assertEquals($data, $api_result->get_datas()); @@ -204,60 +251,60 @@ class API_V1_resultTest extends PhraseanetPHPUnitAuthenticatedAbstract { $server = array("HTTP_ACCEPT" => "application/json"); $request = new Request(array("callback" => ""), array(), array(), array(), array(), $server); - $api_result = new API_V1_result($request, $this->api); + $api_result = new API_V1_result($this->app, $request, $this->api); $this->assertEquals("application/json", $api_result->get_content_type()); $server = array("HTTP_ACCEPT" => "application/yaml"); $request = new Request(array("callback" => ""), array(), array(), array(), array(), $server); - $api_result = new API_V1_result($request, $this->api); + $api_result = new API_V1_result($this->app, $request, $this->api); $this->assertEquals('application/yaml', $api_result->get_content_type()); $server = array("HTTP_ACCEPT" => "text/yaml"); $request = new Request(array("callback" => ""), array(), array(), array(), array(), $server); - $api_result = new API_V1_result($request, $this->api); + $api_result = new API_V1_result($this->app, $request, $this->api); $this->assertEquals('application/yaml', $api_result->get_content_type()); $server = array("HTTP_ACCEPT" => ""); $request = new Request(array("callback" => "hello"), array(), array(), array(), array(), $server); - $api_result = new API_V1_result($request, $this->api); + $api_result = new API_V1_result($this->app, $request, $this->api); $this->assertEquals('text/javascript', $api_result->get_content_type()); $server = array("HTTP_ACCEPT" => "unknow"); $request = new Request(array("callback" => ""), array(), array(), array(), array(), $server); - $api_result = new API_V1_result($request, $this->api); + $api_result = new API_V1_result($this->app, $request, $this->api); $this->assertEquals("application/json", $api_result->get_content_type()); } /** - * @depends testFormat + * @depends testFormatJson */ public function testSet_error_message() { - $api_result = new API_V1_result(new Request(), $this->api); + $api_result = new API_V1_result($this->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(new Request(), $this->api); + $api_result = new API_V1_result($this->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(new Request(), $this->api); + $api_result = new API_V1_result($this->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(new Request(), $this->api); + $api_result = new API_V1_result($this->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(new Request(), $this->api); + $api_result = new API_V1_result($this->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(new Request(), $this->api); + $api_result = new API_V1_result($this->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(new Request(), $this->api); + $api_result = new API_V1_result($this->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'); } @@ -290,73 +337,73 @@ class API_V1_resultTest extends PhraseanetPHPUnitAuthenticatedAbstract } /** - * @depends testFormat + * @depends testFormatJson */ public function testSet_error_code() { - $api_result = new API_V1_result(new Request(), $this->api); + $api_result = new API_V1_result($this->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(new Request(), $this->api); + $api_result = new API_V1_result($this->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(new Request(), $this->api); + $api_result = new API_V1_result($this->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(new Request(), $this->api); + $api_result = new API_V1_result($this->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(new Request(), $this->api); + $api_result = new API_V1_result($this->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(new Request(), $this->api); + $api_result = new API_V1_result($this->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(new Request(), $this->api); + $api_result = new API_V1_result($this->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(new Request(), $this->api); + $api_result = new API_V1_result($this->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(new Request(), $this->api); + $api_result = new API_V1_result($this->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(new Request(), $this->api); + $api_result = new API_V1_result($this->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(new Request(), $this->api); + $api_result = new API_V1_result($this->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(new Request(), $this->api); + $api_result = new API_V1_result($this->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(new Request(array("callback" => "my_callback")), $this->api); + $api_result = new API_V1_result($this->app, new Request(array("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(new Request(array("callback" => "my_callback")), $this->api); + $api_result = new API_V1_result($this->app, new Request(array("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(new Request(), $this->api); + $api_result = new API_V1_result($this->app, new Request(), $this->api); $api_result->set_http_code(500); $this->assertEquals(500, $api_result->get_http_code()); @@ -367,7 +414,7 @@ class API_V1_resultTest extends PhraseanetPHPUnitAuthenticatedAbstract $api_result->set_http_code(403); $this->assertEquals(403, $api_result->get_http_code()); - $api_result = new API_V1_result(new Request(array("callback" => "my_callback")), $this->api); + $api_result = new API_V1_result($this->app, new Request(array("callback" => "my_callback")), $this->api); $api_result->set_http_code(500); $this->assertEquals(500, $api_result->get_http_code());