ServerTest.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Json_Server
  17. * @subpackage UnitTests
  18. * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. * @version $Id$
  21. */
  22. // Call Zend_Json_ServerTest::main() if this source file is executed directly.
  23. if (!defined("PHPUnit_MAIN_METHOD")) {
  24. define("PHPUnit_MAIN_METHOD", "Zend_Json_ServerTest::main");
  25. }
  26. require_once 'Zend/Json/Server.php';
  27. require_once 'Zend/Json/Server/Request.php';
  28. require_once 'Zend/Json/Server/Response.php';
  29. require_once 'Zend/Json.php';
  30. require_once 'Zend/Server/Exception.php';
  31. /**
  32. * Test class for Zend_Json_Server
  33. *
  34. * @category Zend
  35. * @package Zend_Json_Server
  36. * @subpackage UnitTests
  37. * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
  38. * @license http://framework.zend.com/license/new-bsd New BSD License
  39. * @group Zend_Json
  40. * @group Zend_Json_Server
  41. */
  42. class Zend_Json_ServerTest extends PHPUnit_Framework_TestCase
  43. {
  44. /**
  45. * Runs the test methods of this class.
  46. *
  47. * @return void
  48. */
  49. public static function main()
  50. {
  51. $suite = new PHPUnit_Framework_TestSuite("Zend_Json_ServerTest");
  52. $result = PHPUnit_TextUI_TestRunner::run($suite);
  53. }
  54. /**
  55. * Sets up the fixture, for example, open a network connection.
  56. * This method is called before a test is executed.
  57. *
  58. * @return void
  59. */
  60. public function setUp()
  61. {
  62. $this->server = new Zend_Json_Server();
  63. }
  64. /**
  65. * Tears down the fixture, for example, close a network connection.
  66. * This method is called after a test is executed.
  67. *
  68. * @return void
  69. */
  70. public function tearDown()
  71. {
  72. }
  73. public function testShouldBeAbleToBindFunctionToServer()
  74. {
  75. $this->server->addFunction('strtolower');
  76. $methods = $this->server->getFunctions();
  77. $this->assertTrue($methods->hasMethod('strtolower'));
  78. }
  79. public function testShouldBeAbleToBindCallback1ToServer()
  80. {
  81. $this->server->addFunction(array('Zend_Json_ServerTest_Foo', 'staticBar'));
  82. $methods = $this->server->getFunctions();
  83. $this->assertTrue($methods->hasMethod('staticBar'));
  84. }
  85. public function testShouldBeAbleToBindCallback2ToServer()
  86. {
  87. $this->server->addFunction(array(new Zend_Json_ServerTest_Foo, 'bar'));
  88. $methods = $this->server->getFunctions();
  89. $this->assertTrue($methods->hasMethod('bar'));
  90. }
  91. public function testShouldBeAbleToBindClassToServer()
  92. {
  93. $this->server->setClass('Zend_Json_Server');
  94. $test = $this->server->getFunctions();
  95. $this->assertTrue(0 < count($test));
  96. }
  97. public function testBindingClassToServerShouldRegisterAllPublicMethods()
  98. {
  99. $this->server->setClass('Zend_Json_Server');
  100. $test = $this->server->getFunctions();
  101. $methods = get_class_methods('Zend_Json_Server');
  102. foreach ($methods as $method) {
  103. if ('_' == $method[0]) {
  104. continue;
  105. }
  106. $this->assertTrue($test->hasMethod($method), 'Testing for method ' . $method . ' against ' . var_export($test, 1));
  107. }
  108. }
  109. public function testShouldBeAbleToBindObjectToServer()
  110. {
  111. $object = new Zend_Json_Server();
  112. $this->server->setClass($object);
  113. $test = $this->server->getFunctions();
  114. $this->assertTrue(0 < count($test));
  115. }
  116. public function testBindingObjectToServerShouldRegisterAllPublicMethods()
  117. {
  118. $object = new Zend_Json_Server();
  119. $this->server->setClass($object);
  120. $test = $this->server->getFunctions();
  121. $methods = get_class_methods($object);
  122. foreach ($methods as $method) {
  123. if ('_' == $method[0]) {
  124. continue;
  125. }
  126. $this->assertTrue($test->hasMethod($method), 'Testing for method ' . $method . ' against ' . var_export($test, 1));
  127. }
  128. }
  129. public function testShouldBeAbleToBindMultipleClassesAndObjectsToServer()
  130. {
  131. $this->server->setClass('Zend_Json_Server')
  132. ->setClass(new Zend_Json());
  133. $methods = $this->server->getFunctions();
  134. $zjsMethods = get_class_methods('Zend_Json_Server');
  135. $zjMethods = get_class_methods('Zend_Json');
  136. $this->assertTrue(count($zjsMethods) < count($methods));
  137. $this->assertTrue(count($zjMethods) < count($methods));
  138. }
  139. public function testNamingCollisionsShouldResolveToLastRegisteredMethod()
  140. {
  141. $this->server->setClass('Zend_Json_Server_Request')
  142. ->setClass('Zend_Json_Server_Response');
  143. $methods = $this->server->getFunctions();
  144. $this->assertTrue($methods->hasMethod('toJson'));
  145. $toJson = $methods->getMethod('toJson');
  146. $this->assertEquals('Zend_Json_Server_Response', $toJson->getCallback()->getClass());
  147. }
  148. public function testGetRequestShouldInstantiateRequestObjectByDefault()
  149. {
  150. $request = $this->server->getRequest();
  151. $this->assertTrue($request instanceof Zend_Json_Server_Request);
  152. }
  153. public function testShouldAllowSettingRequestObjectManually()
  154. {
  155. $orig = $this->server->getRequest();
  156. $new = new Zend_Json_Server_Request();
  157. $this->server->setRequest($new);
  158. $test = $this->server->getRequest();
  159. $this->assertSame($new, $test);
  160. $this->assertNotSame($orig, $test);
  161. }
  162. public function testGetResponseShouldInstantiateResponseObjectByDefault()
  163. {
  164. $response = $this->server->getResponse();
  165. $this->assertTrue($response instanceof Zend_Json_Server_Response);
  166. }
  167. public function testShouldAllowSettingResponseObjectManually()
  168. {
  169. $orig = $this->server->getResponse();
  170. $new = new Zend_Json_Server_Response();
  171. $this->server->setResponse($new);
  172. $test = $this->server->getResponse();
  173. $this->assertSame($new, $test);
  174. $this->assertNotSame($orig, $test);
  175. }
  176. public function testFaultShouldCreateErrorResponse()
  177. {
  178. $response = $this->server->getResponse();
  179. $this->assertFalse($response->isError());
  180. $this->server->fault('error condition', -32000);
  181. $this->assertTrue($response->isError());
  182. $error = $response->getError();
  183. $this->assertEquals(-32000, $error->getCode());
  184. $this->assertEquals('error condition', $error->getMessage());
  185. }
  186. public function testResponseShouldBeEmittedAutomaticallyByDefault()
  187. {
  188. $this->assertTrue($this->server->autoEmitResponse());
  189. }
  190. public function testShouldBeAbleToDisableAutomaticResponseEmission()
  191. {
  192. $this->testResponseShouldBeEmittedAutomaticallyByDefault();
  193. $this->server->setAutoEmitResponse(false);
  194. $this->assertFalse($this->server->autoEmitResponse());
  195. }
  196. public function testShouldBeAbleToRetrieveSmdObject()
  197. {
  198. $smd = $this->server->getServiceMap();
  199. $this->assertTrue($smd instanceof Zend_Json_Server_Smd);
  200. }
  201. public function testShouldBeAbleToSetArbitrarySmdMetadata()
  202. {
  203. $this->server->setTransport('POST')
  204. ->setEnvelope('JSON-RPC-1.0')
  205. ->setContentType('application/x-json')
  206. ->setTarget('/foo/bar')
  207. ->setId('foobar')
  208. ->setDescription('This is a test service');
  209. $this->assertEquals('POST', $this->server->getTransport());
  210. $this->assertEquals('JSON-RPC-1.0', $this->server->getEnvelope());
  211. $this->assertEquals('application/x-json', $this->server->getContentType());
  212. $this->assertEquals('/foo/bar', $this->server->getTarget());
  213. $this->assertEquals('foobar', $this->server->getId());
  214. $this->assertEquals('This is a test service', $this->server->getDescription());
  215. }
  216. public function testSmdObjectRetrievedFromServerShouldReflectServerState()
  217. {
  218. $this->server->addFunction('strtolower')
  219. ->setClass('Zend_Json_Server')
  220. ->setTransport('POST')
  221. ->setEnvelope('JSON-RPC-1.0')
  222. ->setContentType('application/x-json')
  223. ->setTarget('/foo/bar')
  224. ->setId('foobar')
  225. ->setDescription('This is a test service');
  226. $smd = $this->server->getServiceMap();
  227. $this->assertEquals('POST', $this->server->getTransport());
  228. $this->assertEquals('JSON-RPC-1.0', $this->server->getEnvelope());
  229. $this->assertEquals('application/x-json', $this->server->getContentType());
  230. $this->assertEquals('/foo/bar', $this->server->getTarget());
  231. $this->assertEquals('foobar', $this->server->getId());
  232. $this->assertEquals('This is a test service', $this->server->getDescription());
  233. $services = $smd->getServices();
  234. $this->assertTrue(is_array($services));
  235. $this->assertTrue(0 < count($services));
  236. $this->assertTrue(array_key_exists('strtolower', $services));
  237. $methods = get_class_methods('Zend_Json_Server');
  238. foreach ($methods as $method) {
  239. if ('_' == $method[0]) {
  240. continue;
  241. }
  242. $this->assertTrue(array_key_exists($method, $services));
  243. }
  244. }
  245. public function testHandleValidMethodShouldWork()
  246. {
  247. $this->server->setClass('Zend_Json_ServerTest_Foo')
  248. ->addFunction('Zend_Json_ServerTest_FooFunc')
  249. ->setAutoEmitResponse(false);
  250. $request = $this->server->getRequest();
  251. $request->setMethod('bar')
  252. ->setParams(array(true, 'foo', 'bar'))
  253. ->setId('foo');
  254. $response = $this->server->handle();
  255. $this->assertTrue($response instanceof Zend_Json_Server_Response);
  256. $this->assertFalse($response->isError());
  257. $request->setMethod('Zend_Json_ServerTest_FooFunc')
  258. ->setId('foo');
  259. $response = $this->server->handle();
  260. $this->assertTrue($response instanceof Zend_Json_Server_Response);
  261. $this->assertFalse($response->isError());
  262. }
  263. public function testHandleValidMethodWithTooFewParamsShouldPassDefaultsOrNullsForMissingParams()
  264. {
  265. $this->server->setClass('Zend_Json_ServerTest_Foo')
  266. ->setAutoEmitResponse(false);
  267. $request = $this->server->getRequest();
  268. $request->setMethod('bar')
  269. ->setParams(array(true))
  270. ->setId('foo');
  271. $response = $this->server->handle();
  272. $this->assertTrue($response instanceof Zend_Json_Server_Response);
  273. $this->assertFalse($response->isError());
  274. $result = $response->getResult();
  275. $this->assertTrue(is_array($result));
  276. $this->assertTrue(3 == count($result));
  277. $this->assertEquals('two', $result[1], var_export($result, 1));
  278. $this->assertNull($result[2]);
  279. }
  280. public function testHandleValidMethodWithMissingParamsShouldThrowException()
  281. {
  282. $this->server->setClass('Zend_Json_ServerTest_Foo')
  283. ->setAutoEmitResponse(false);
  284. $request = $this->server->getRequest();
  285. $request->setMethod('bar')
  286. ->setParams(array('one' => null))
  287. ->setId('foo');
  288. try {
  289. $response = $this->server->handle();
  290. } catch (Exception $e) {
  291. $this->assertTrue($e instanceof Zend_Server_Exception);
  292. $this->assertEquals('Method bar is missing required parameter: one', $e->getMessage());
  293. }
  294. }
  295. public function testHandleValidMethodWithTooManyParamsShouldWork()
  296. {
  297. $this->server->setClass('Zend_Json_ServerTest_Foo')
  298. ->setAutoEmitResponse(false);
  299. $request = $this->server->getRequest();
  300. $request->setMethod('bar')
  301. ->setParams(array(true, 'foo', 'bar', 'baz'))
  302. ->setId('foo');
  303. $response = $this->server->handle();
  304. $this->assertTrue($response instanceof Zend_Json_Server_Response);
  305. $this->assertFalse($response->isError());
  306. $result = $response->getResult();
  307. $this->assertTrue(is_array($result));
  308. $this->assertTrue(3 == count($result));
  309. $this->assertEquals('foo', $result[1]);
  310. $this->assertEquals('bar', $result[2]);
  311. }
  312. public function testHandleShouldAllowNamedParamsInAnyOrder1()
  313. {
  314. $this->server->setClass('Zend_Json_ServerTest_Foo')
  315. ->setAutoEmitResponse( false );
  316. $request = $this->server->getRequest();
  317. $request->setMethod('bar')
  318. ->setParams( array(
  319. 'three' => 3,
  320. 'two' => 2,
  321. 'one' => 1
  322. ))
  323. ->setId( 'foo' );
  324. $response = $this->server->handle();
  325. $result = $response->getResult();
  326. $this->assertTrue( is_array( $result ) );
  327. $this->assertEquals( 1, $result[0] );
  328. $this->assertEquals( 2, $result[1] );
  329. $this->assertEquals( 3, $result[2] );
  330. }
  331. public function testHandleShouldAllowNamedParamsInAnyOrder2()
  332. {
  333. $this->server->setClass('Zend_Json_ServerTest_Foo')
  334. ->setAutoEmitResponse( false );
  335. $request = $this->server->getRequest();
  336. $request->setMethod('bar')
  337. ->setParams( array(
  338. 'three' => 3,
  339. 'one' => 1,
  340. 'two' => 2,
  341. ) )
  342. ->setId( 'foo' );
  343. $response = $this->server->handle();
  344. $result = $response->getResult();
  345. $this->assertTrue( is_array( $result ) );
  346. $this->assertEquals( 1, $result[0] );
  347. $this->assertEquals( 2, $result[1] );
  348. $this->assertEquals( 3, $result[2] );
  349. }
  350. public function testHandleRequestWithErrorsShouldReturnErrorResponse()
  351. {
  352. $this->server->setClass('Zend_Json_ServerTest_Foo')
  353. ->setAutoEmitResponse(false);
  354. $response = $this->server->handle();
  355. $this->assertTrue($response instanceof Zend_Json_Server_Response);
  356. $this->assertTrue($response->isError());
  357. $this->assertEquals(Zend_Json_Server_Error::ERROR_INVALID_REQUEST, $response->getError()->getCode());
  358. }
  359. public function testHandleRequestWithInvalidMethodShouldReturnErrorResponse()
  360. {
  361. $this->server->setClass('Zend_Json_ServerTest_Foo')
  362. ->setAutoEmitResponse(false);
  363. $request = $this->server->getRequest();
  364. $request->setMethod('bogus')
  365. ->setId('foo');
  366. $response = $this->server->handle();
  367. $this->assertTrue($response instanceof Zend_Json_Server_Response);
  368. $this->assertTrue($response->isError());
  369. $this->assertEquals(Zend_Json_Server_Error::ERROR_INVALID_METHOD, $response->getError()->getCode());
  370. }
  371. public function testHandleRequestWithExceptionShouldReturnErrorResponse()
  372. {
  373. $this->server->setClass('Zend_Json_ServerTest_Foo')
  374. ->setAutoEmitResponse(false);
  375. $request = $this->server->getRequest();
  376. $request->setMethod('baz')
  377. ->setId('foo');
  378. $response = $this->server->handle();
  379. $this->assertTrue($response instanceof Zend_Json_Server_Response);
  380. $this->assertTrue($response->isError());
  381. $this->assertEquals(Zend_Json_Server_Error::ERROR_OTHER, $response->getError()->getCode());
  382. $this->assertEquals('application error', $response->getError()->getMessage());
  383. }
  384. public function testHandleShouldEmitResponseByDefault()
  385. {
  386. $this->server->setClass('Zend_Json_ServerTest_Foo');
  387. $request = $this->server->getRequest();
  388. $request->setMethod('bar')
  389. ->setParams(array(true, 'foo', 'bar'))
  390. ->setId('foo');
  391. ob_start();
  392. $this->server->handle();
  393. $buffer = ob_get_clean();
  394. $decoded = Zend_Json::decode($buffer);
  395. $this->assertTrue(is_array($decoded));
  396. $this->assertTrue(array_key_exists('result', $decoded));
  397. $this->assertTrue(array_key_exists('id', $decoded));
  398. $response = $this->server->getResponse();
  399. $this->assertEquals($response->getResult(), $decoded['result']);
  400. $this->assertEquals($response->getId(), $decoded['id']);
  401. }
  402. public function testResponseShouldBeEmptyWhenRequestHasNoId()
  403. {
  404. $this->server->setClass('Zend_Json_ServerTest_Foo');
  405. $request = $this->server->getRequest();
  406. $request->setMethod('bar')
  407. ->setParams(array(true, 'foo', 'bar'));
  408. ob_start();
  409. $this->server->handle();
  410. $buffer = ob_get_clean();
  411. $this->assertTrue(empty($buffer));
  412. }
  413. public function testLoadFunctionsShouldLoadResultOfGetFunctions()
  414. {
  415. $this->server->setClass('Zend_Json_ServerTest_Foo');
  416. $functions = $this->server->getFunctions();
  417. $server = new Zend_Json_Server();
  418. $server->loadFunctions($functions);
  419. $this->assertEquals($functions->toArray(), $server->getFunctions()->toArray());
  420. }
  421. }
  422. /**
  423. * Class for testing JSON-RPC server
  424. */
  425. class Zend_Json_ServerTest_Foo
  426. {
  427. /**
  428. * Bar
  429. *
  430. * @param bool $one
  431. * @param string $two
  432. * @param mixed $three
  433. * @return array
  434. */
  435. static public function staticBar($one, $two = 'two', $three = null)
  436. {
  437. return array($one, $two, $three);
  438. }
  439. /**
  440. * Bar
  441. *
  442. * @param bool $one
  443. * @param string $two
  444. * @param mixed $three
  445. * @return array
  446. */
  447. public function bar($one, $two = 'two', $three = null)
  448. {
  449. return array($one, $two, $three);
  450. }
  451. /**
  452. * Baz
  453. *
  454. * @return void
  455. */
  456. public function baz()
  457. {
  458. throw new Exception('application error');
  459. }
  460. }
  461. /**
  462. * Test function for JSON-RPC server
  463. *
  464. * @return bool
  465. */
  466. function Zend_Json_ServerTest_FooFunc()
  467. {
  468. return true;
  469. }
  470. // Call Zend_Json_ServerTest::main() if this source file is executed directly.
  471. if (PHPUnit_MAIN_METHOD == "Zend_Json_ServerTest::main") {
  472. Zend_Json_ServerTest::main();
  473. }