summaryrefslogtreecommitdiff
path: root/libs/jsonrpc/tests
diff options
context:
space:
mode:
Diffstat (limited to 'libs/jsonrpc/tests')
-rw-r--r--libs/jsonrpc/tests/ClientTest.php103
-rw-r--r--libs/jsonrpc/tests/HttpClientTest.php220
-rw-r--r--libs/jsonrpc/tests/MiddlewareHandlerTest.php40
-rw-r--r--libs/jsonrpc/tests/ProcedureHandlerTest.php153
-rw-r--r--libs/jsonrpc/tests/Request/RequestBuilderTest.php53
-rw-r--r--libs/jsonrpc/tests/Response/HeaderMockTest.php25
-rw-r--r--libs/jsonrpc/tests/Response/ResponseBuilderTest.php151
-rw-r--r--libs/jsonrpc/tests/Response/ResponseParserTest.php100
-rw-r--r--libs/jsonrpc/tests/ServerProtocolTest.php237
-rw-r--r--libs/jsonrpc/tests/ServerTest.php258
-rw-r--r--libs/jsonrpc/tests/Validator/HostValidatorTest.php32
-rw-r--r--libs/jsonrpc/tests/Validator/JsonEncodingValidatorTest.php22
-rw-r--r--libs/jsonrpc/tests/Validator/JsonFormatValidatorTest.php19
-rw-r--r--libs/jsonrpc/tests/Validator/RpcFormatValidatorTest.php48
-rw-r--r--libs/jsonrpc/tests/Validator/UserValidatorTest.php24
15 files changed, 1485 insertions, 0 deletions
diff --git a/libs/jsonrpc/tests/ClientTest.php b/libs/jsonrpc/tests/ClientTest.php
new file mode 100644
index 00000000..d1f83877
--- /dev/null
+++ b/libs/jsonrpc/tests/ClientTest.php
@@ -0,0 +1,103 @@
+<?php
+
+use JsonRPC\Client;
+
+require_once __DIR__.'/../../../vendor/autoload.php';
+
+class ClientTest extends PHPUnit_Framework_TestCase
+{
+ private $httpClient;
+
+ public function setUp()
+ {
+ $this->httpClient = $this
+ ->getMockBuilder('\JsonRPC\HttpClient')
+ ->setMethods(array('execute'))
+ ->getMock();
+ }
+
+ public function testSendBatch()
+ {
+ $client = new Client('', false, $this->httpClient);
+ $response = array(
+ array(
+ 'jsonrpc' => '2.0',
+ 'result' => 'c',
+ 'id' => 1,
+ ),
+ array(
+ 'jsonrpc' => '2.0',
+ 'result' => 'd',
+ 'id' => 2,
+ )
+ );
+
+ $this->httpClient
+ ->expects($this->once())
+ ->method('execute')
+ ->with($this->stringContains('[{"jsonrpc":"2.0","method":"methodA","id":'))
+ ->will($this->returnValue($response));
+
+
+ $result = $client->batch()
+ ->execute('methodA', array('a' => 'b'))
+ ->execute('methodB', array('a' => 'b'))
+ ->send();
+
+ $this->assertEquals(array('c', 'd'), $result);
+ }
+
+ public function testSendRequest()
+ {
+ $client = new Client('', false, $this->httpClient);
+
+ $this->httpClient
+ ->expects($this->once())
+ ->method('execute')
+ ->with($this->stringContains('{"jsonrpc":"2.0","method":"methodA","id":'))
+ ->will($this->returnValue(array('jsonrpc' => '2.0', 'result' => 'foobar', 'id' => 1)));
+
+ $result = $client->execute('methodA', array('a' => 'b'));
+ $this->assertEquals($result, 'foobar');
+ }
+
+ public function testSendRequestWithError()
+ {
+ $client = new Client('', false, $this->httpClient);
+
+ $this->httpClient
+ ->expects($this->once())
+ ->method('execute')
+ ->with($this->stringContains('{"jsonrpc":"2.0","method":"methodA","id":'))
+ ->will($this->returnValue(array(
+ 'jsonrpc' => '2.0',
+ 'error' => array(
+ 'code' => -32601,
+ 'message' => 'Method not found',
+ ),
+ )));
+
+ $this->setExpectedException('BadFunctionCallException');
+ $client->execute('methodA', array('a' => 'b'));
+ }
+
+ public function testSendRequestWithErrorAndReturnExceptionEnabled()
+ {
+ $client = new Client('', true, $this->httpClient);
+
+ $this->httpClient
+ ->expects($this->once())
+ ->method('execute')
+ ->with($this->stringContains('{"jsonrpc":"2.0","method":"methodA","id":'))
+ ->will($this->returnValue(array(
+ 'jsonrpc' => '2.0',
+ 'error' => array(
+ 'code' => -32601,
+ 'message' => 'Method not found',
+ ),
+ )));
+
+ $result = $client->execute('methodA', array('a' => 'b'));
+ $this->assertInstanceOf('BadFunctionCallException', $result);
+ }
+}
diff --git a/libs/jsonrpc/tests/HttpClientTest.php b/libs/jsonrpc/tests/HttpClientTest.php
new file mode 100644
index 00000000..71e6c8d0
--- /dev/null
+++ b/libs/jsonrpc/tests/HttpClientTest.php
@@ -0,0 +1,220 @@
+<?php
+
+namespace JsonRPC;
+
+require_once __DIR__.'/../../../vendor/autoload.php';
+
+defined('CURLOPT_URL') or define('CURLOPT_URL', 10002);
+defined('CURLOPT_RETURNTRANSFER') or define('CURLOPT_RETURNTRANSFER', 19913);
+defined('CURLOPT_CONNECTTIMEOUT') or define('CURLOPT_CONNECTTIMEOUT', 78);
+defined('CURLOPT_MAXREDIRS') or define('CURLOPT_MAXREDIRS', 68);
+defined('CURLOPT_SSL_VERIFYPEER') or define('CURLOPT_SSL_VERIFYPEER', 64);
+defined('CURLOPT_POST') or define('CURLOPT_POST', 47);
+defined('CURLOPT_POSTFIELDS') or define('CURLOPT_POSTFIELDS', 10015);
+defined('CURLOPT_HTTPHEADER') or define('CURLOPT_HTTPHEADER', 10023);
+defined('CURLOPT_HEADERFUNCTION') or define('CURLOPT_HEADERFUNCTION', 20079);
+defined('CURLOPT_CAINFO') or define('CURLOPT_CAINFO', 10065);
+
+function extension_loaded($extension) {
+ return HttpClientTest::$functions->extension_loaded($extension);
+}
+
+function fopen($url, $mode, $use_include_path, $context)
+{
+ return HttpClientTest::$functions->fopen($url, $mode, $use_include_path, $context);
+}
+
+function stream_context_create(array $params)
+{
+ return HttpClientTest::$functions->stream_context_create($params);
+}
+
+function curl_init() {
+ return HttpClientTest::$functions->curl_init();
+}
+
+function curl_setopt_array($ch, array $params) {
+ HttpClientTest::$functions->curl_setopt_array($ch, $params);
+}
+
+function curl_setopt($ch, $option, $value) {
+ HttpClientTest::$functions->curl_setopt($ch, $option, $value);
+}
+
+function curl_exec($ch) {
+ return HttpClientTest::$functions->curl_exec($ch);
+}
+
+function curl_close($ch) {
+ HttpClientTest::$functions->curl_close($ch);
+}
+
+class HttpClientTest extends \PHPUnit_Framework_TestCase
+{
+ public static $functions;
+
+ public function setUp()
+ {
+ self::$functions = $this
+ ->getMockBuilder('stdClass')
+ ->setMethods(array('extension_loaded', 'fopen', 'stream_context_create',
+ 'curl_init', 'curl_setopt_array', 'curl_setopt', 'curl_exec', 'curl_close'))
+ ->getMock();
+ }
+
+ public function testWithServerError()
+ {
+ $this->setExpectedException('\JsonRPC\Exception\ServerErrorException');
+
+ $httpClient = new HttpClient();
+ $httpClient->handleExceptions(array(
+ 'HTTP/1.0 301 Moved Permanently',
+ 'Connection: close',
+ 'HTTP/1.1 500 Internal Server Error',
+ ));
+ }
+
+ public function testWithConnectionFailure()
+ {
+ $this->setExpectedException('\JsonRPC\Exception\ConnectionFailureException');
+
+ $httpClient = new HttpClient();
+ $httpClient->handleExceptions(array(
+ 'HTTP/1.1 404 Not Found',
+ ));
+ }
+
+ public function testWithAccessForbidden()
+ {
+ $this->setExpectedException('\JsonRPC\Exception\AccessDeniedException');
+
+ $httpClient = new HttpClient();
+ $httpClient->handleExceptions(array(
+ 'HTTP/1.1 403 Forbidden',
+ ));
+ }
+
+ public function testWithAccessNotAllowed()
+ {
+ $this->setExpectedException('\JsonRPC\Exception\AccessDeniedException');
+
+ $httpClient = new HttpClient();
+ $httpClient->handleExceptions(array(
+ 'HTTP/1.0 401 Unauthorized',
+ ));
+ }
+
+ public function testWithCallback()
+ {
+ self::$functions
+ ->expects($this->at(0))
+ ->method('extension_loaded')
+ ->with('curl')
+ ->will($this->returnValue(false));
+
+ self::$functions
+ ->expects($this->at(1))
+ ->method('stream_context_create')
+ ->with(array(
+ 'http' => array(
+ 'method' => 'POST',
+ 'protocol_version' => 1.1,
+ 'timeout' => 5,
+ 'max_redirects' => 2,
+ 'header' => implode("\r\n", array(
+ 'User-Agent: JSON-RPC PHP Client <https://github.com/fguillot/JsonRPC>',
+ 'Content-Type: application/json',
+ 'Accept: application/json',
+ 'Connection: close',
+ 'Content-Length: 4',
+ )),
+ 'content' => 'test',
+ 'ignore_errors' => true,
+ ),
+ 'ssl' => array(
+ 'verify_peer' => true,
+ 'verify_peer_name' => true,
+ )
+ ))
+ ->will($this->returnValue('context'));
+
+ self::$functions
+ ->expects($this->at(2))
+ ->method('fopen')
+ ->with('url', 'r', false, 'context')
+ ->will($this->returnValue(false));
+
+ $httpClient = new HttpClient('url');
+ $httpClient->withBeforeRequestCallback(function(HttpClient $client, $payload) {
+ $client->withHeaders(array('Content-Length: '.strlen($payload)));
+ });
+
+ $this->setExpectedException('\JsonRPC\Exception\ConnectionFailureException');
+ $httpClient->execute('test');
+ }
+
+ public function testWithCurl()
+ {
+ self::$functions
+ ->expects($this->at(0))
+ ->method('extension_loaded')
+ ->with('curl')
+ ->will($this->returnValue(true));
+
+ self::$functions
+ ->expects($this->at(1))
+ ->method('curl_init')
+ ->will($this->returnValue('curl'));
+
+ self::$functions
+ ->expects($this->at(2))
+ ->method('curl_setopt_array')
+ ->with('curl', array(
+ CURLOPT_URL => 'url',
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_CONNECTTIMEOUT => 5,
+ CURLOPT_MAXREDIRS => 2,
+ CURLOPT_SSL_VERIFYPEER => true,
+ CURLOPT_POST => true,
+ CURLOPT_POSTFIELDS => 'test',
+ CURLOPT_HTTPHEADER => array(
+ 'User-Agent: JSON-RPC PHP Client <https://github.com/fguillot/JsonRPC>',
+ 'Content-Type: application/json',
+ 'Accept: application/json',
+ 'Connection: close',
+ 'Content-Length: 4',
+ ),
+ CURLOPT_HEADERFUNCTION => function ($curl, $header) use (&$headers) {
+ $headers[] = $header;
+ return strlen($header);
+ }
+ ));
+
+ self::$functions
+ ->expects($this->at(3))
+ ->method('curl_setopt')
+ ->with('curl', CURLOPT_CAINFO, 'test.crt');
+
+ self::$functions
+ ->expects($this->at(4))
+ ->method('curl_exec')
+ ->with('curl')
+ ->will($this->returnValue(false));
+
+ self::$functions
+ ->expects($this->at(5))
+ ->method('curl_close')
+ ->with('curl');
+
+ $httpClient = new HttpClient('url');
+ $httpClient
+ ->withSslLocalCert('test.crt')
+ ->withBeforeRequestCallback(function(HttpClient $client, $payload) {
+ $client->withHeaders(array('Content-Length: '.strlen($payload)));
+ });
+
+
+ $this->setExpectedException('\JsonRPC\Exception\ConnectionFailureException');
+ $httpClient->execute('test');
+ }
+}
diff --git a/libs/jsonrpc/tests/MiddlewareHandlerTest.php b/libs/jsonrpc/tests/MiddlewareHandlerTest.php
new file mode 100644
index 00000000..be70cbf7
--- /dev/null
+++ b/libs/jsonrpc/tests/MiddlewareHandlerTest.php
@@ -0,0 +1,40 @@
+<?php
+
+use JsonRPC\Exception\AuthenticationFailureException;
+use JsonRPC\MiddlewareHandler;
+use JsonRPC\MiddlewareInterface;
+
+require_once __DIR__.'/../../../vendor/autoload.php';
+
+class FirstMiddleware implements MiddlewareInterface
+{
+ public function execute($username, $password, $procedureName)
+ {
+ }
+}
+
+class SecondMiddleware implements MiddlewareInterface
+{
+ public function execute($username, $password, $procedureName)
+ {
+ if ($username === 'myUsername' && $password === 'myPassword' && $procedureName === 'myProcedure') {
+ throw new AuthenticationFailureException('Bad user');
+ }
+ }
+}
+
+class MiddlewareHandlerTest extends PHPUnit_Framework_TestCase
+{
+ public function testMiddlewareCanRaiseException()
+ {
+ $this->setExpectedException('JsonRpc\Exception\AuthenticationFailureException');
+
+ $middlewareHandler = new MiddlewareHandler();
+ $middlewareHandler->withUsername('myUsername');
+ $middlewareHandler->withPassword('myPassword');
+ $middlewareHandler->withProcedure('myProcedure');
+ $middlewareHandler->withMiddleware(new FirstMiddleware());
+ $middlewareHandler->withMiddleware(new SecondMiddleware());
+ $middlewareHandler->execute();
+ }
+}
diff --git a/libs/jsonrpc/tests/ProcedureHandlerTest.php b/libs/jsonrpc/tests/ProcedureHandlerTest.php
new file mode 100644
index 00000000..983016c5
--- /dev/null
+++ b/libs/jsonrpc/tests/ProcedureHandlerTest.php
@@ -0,0 +1,153 @@
+<?php
+
+use JsonRPC\ProcedureHandler;
+
+require_once __DIR__.'/../../../vendor/autoload.php';
+
+class A
+{
+ public function getAll($p1, $p2, $p3 = 4)
+ {
+ return $p1 + $p2 + $p3;
+ }
+}
+
+class B
+{
+ public function getAll($p1)
+ {
+ return $p1 + 2;
+ }
+}
+
+class ClassWithBeforeMethod
+{
+ private $foobar = '';
+
+ public function before($procedure)
+ {
+ $this->foobar = $procedure;
+ }
+
+ public function myProcedure()
+ {
+ return $this->foobar;
+ }
+}
+
+class ProcedureHandlerTest extends PHPUnit_Framework_TestCase
+{
+ public function testProcedureNotFound()
+ {
+ $this->setExpectedException('BadFunctionCallException');
+ $handler = new ProcedureHandler;
+ $handler->executeProcedure('a');
+ }
+
+ public function testCallbackNotFound()
+ {
+ $this->setExpectedException('BadFunctionCallException');
+ $handler = new ProcedureHandler;
+ $handler->withCallback('b', function() {});
+ $handler->executeProcedure('a');
+ }
+
+ public function testClassNotFound()
+ {
+ $this->setExpectedException('BadFunctionCallException');
+ $handler = new ProcedureHandler;
+ $handler->withClassAndMethod('getAllTasks', 'c', 'getAll');
+ $handler->executeProcedure('getAllTasks');
+ }
+
+ public function testMethodNotFound()
+ {
+ $this->setExpectedException('BadFunctionCallException');
+ $handler = new ProcedureHandler;
+ $handler->withClassAndMethod('getAllTasks', 'A', 'getNothing');
+ $handler->executeProcedure('getAllTasks');
+ }
+
+ public function testIsPositionalArguments()
+ {
+ $handler = new ProcedureHandler;
+ $this->assertFalse($handler->isPositionalArguments(
+ array('a' => 'b', 'c' => 'd')
+ ));
+
+ $handler = new ProcedureHandler;
+ $this->assertTrue($handler->isPositionalArguments(
+ array('a', 'b', 'c')
+ ));
+ }
+
+ public function testBindNamedArguments()
+ {
+ $handler = new ProcedureHandler;
+ $handler->withClassAndMethod('getAllA', 'A', 'getAll');
+ $handler->withClassAndMethod('getAllB', 'B', 'getAll');
+ $handler->withClassAndMethod('getAllC', new B, 'getAll');
+ $this->assertEquals(6, $handler->executeProcedure('getAllA', array('p2' => 4, 'p1' => -2)));
+ $this->assertEquals(10, $handler->executeProcedure('getAllA', array('p2' => 4, 'p3' => 8, 'p1' => -2)));
+ $this->assertEquals(6, $handler->executeProcedure('getAllB', array('p1' => 4)));
+ $this->assertEquals(5, $handler->executeProcedure('getAllC', array('p1' => 3)));
+ }
+
+ public function testBindPositionalArguments()
+ {
+ $handler = new ProcedureHandler;
+ $handler->withClassAndMethod('getAllA', 'A', 'getAll');
+ $handler->withClassAndMethod('getAllB', 'B', 'getAll');
+ $this->assertEquals(6, $handler->executeProcedure('getAllA', array(4, -2)));
+ $this->assertEquals(2, $handler->executeProcedure('getAllA', array(4, 0, -2)));
+ $this->assertEquals(4, $handler->executeProcedure('getAllB', array(2)));
+ }
+
+ public function testRegisterNamedArguments()
+ {
+ $handler = new ProcedureHandler;
+ $handler->withCallback('getAllA', function($p1, $p2, $p3 = 4) {
+ return $p1 + $p2 + $p3;
+ });
+
+ $this->assertEquals(6, $handler->executeProcedure('getAllA', array('p2' => 4, 'p1' => -2)));
+ $this->assertEquals(10, $handler->executeProcedure('getAllA', array('p2' => 4, 'p3' => 8, 'p1' => -2)));
+ }
+
+ public function testRegisterPositionalArguments()
+ {
+ $handler = new ProcedureHandler;
+ $handler->withCallback('getAllA', function($p1, $p2, $p3 = 4) {
+ return $p1 + $p2 + $p3;
+ });
+
+ $this->assertEquals(6, $handler->executeProcedure('getAllA', array(4, -2)));
+ $this->assertEquals(2, $handler->executeProcedure('getAllA', array(4, 0, -2)));
+ }
+
+ public function testTooManyArguments()
+ {
+ $this->setExpectedException('InvalidArgumentException');
+
+ $handler = new ProcedureHandler;
+ $handler->withClassAndMethod('getAllC', new B, 'getAll');
+ $handler->executeProcedure('getAllC', array('p1' => 3, 'p2' => 5));
+ }
+
+ public function testNotEnoughArguments()
+ {
+ $this->setExpectedException('InvalidArgumentException');
+
+ $handler = new ProcedureHandler;
+ $handler->withClassAndMethod('getAllC', new B, 'getAll');
+ $handler->executeProcedure('getAllC');
+ }
+
+ public function testBeforeMethod()
+ {
+ $handler = new ProcedureHandler;
+ $handler->withObject(new ClassWithBeforeMethod);
+ $handler->withBeforeMethod('before');
+ $this->assertEquals('myProcedure', $handler->executeProcedure('myProcedure'));
+ }
+}
diff --git a/libs/jsonrpc/tests/Request/RequestBuilderTest.php b/libs/jsonrpc/tests/Request/RequestBuilderTest.php
new file mode 100644
index 00000000..ce9cf674
--- /dev/null
+++ b/libs/jsonrpc/tests/Request/RequestBuilderTest.php
@@ -0,0 +1,53 @@
+<?php
+
+use JsonRPC\Request\RequestBuilder;
+
+require_once __DIR__.'/../../../../vendor/autoload.php';
+
+class RequestBuilderTest extends PHPUnit_Framework_TestCase
+{
+ public function testBuilder()
+ {
+ $payload = RequestBuilder::create()
+ ->withId(123)
+ ->withProcedure('foobar')
+ ->withParams(array(1, 2, 3))
+ ->build();
+
+ $this->assertEquals('{"jsonrpc":"2.0","method":"foobar","id":123,"params":[1,2,3]}', $payload);
+ }
+
+ public function testBuilderWithoutParams()
+ {
+ $payload = RequestBuilder::create()
+ ->withId(123)
+ ->withProcedure('foobar')
+ ->build();
+
+ $this->assertEquals('{"jsonrpc":"2.0","method":"foobar","id":123}', $payload);
+ }
+
+ public function testBuilderWithoutId()
+ {
+ $payload = RequestBuilder::create()
+ ->withProcedure('foobar')
+ ->withParams(array(1, 2, 3))
+ ->build();
+
+ $result = json_decode($payload, true);
+ $this->assertNotNull($result['id']);
+ }
+
+ public function testBuilderWithAdditionalRequestAttributes()
+ {
+ $payload = RequestBuilder::create()
+ ->withProcedure('foobar')
+ ->withParams(array(1, 2, 3))
+ ->withRequestAttributes(array("some-attr" => 42))
+ ->build();
+
+ $result = json_decode($payload, true);
+ $this->assertNotNull($result['some-attr']);
+ }
+
+}
diff --git a/libs/jsonrpc/tests/Response/HeaderMockTest.php b/libs/jsonrpc/tests/Response/HeaderMockTest.php
new file mode 100644
index 00000000..cbeb7388
--- /dev/null
+++ b/libs/jsonrpc/tests/Response/HeaderMockTest.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace JsonRPC\Response;
+
+use PHPUnit_Framework_TestCase;
+
+require_once __DIR__.'/../../../../vendor/autoload.php';
+
+function header($value)
+{
+ HeaderMockTest::$functions->header($value);
+}
+
+abstract class HeaderMockTest extends PHPUnit_Framework_TestCase
+{
+ public static $functions;
+
+ public function setUp()
+ {
+ self::$functions = $this
+ ->getMockBuilder('stdClass')
+ ->setMethods(array('header'))
+ ->getMock();
+ }
+}
diff --git a/libs/jsonrpc/tests/Response/ResponseBuilderTest.php b/libs/jsonrpc/tests/Response/ResponseBuilderTest.php
new file mode 100644
index 00000000..e2dcb2a0
--- /dev/null
+++ b/libs/jsonrpc/tests/Response/ResponseBuilderTest.php
@@ -0,0 +1,151 @@
+<?php
+
+use JsonRPC\Exception\AccessDeniedException;
+use JsonRPC\Exception\AuthenticationFailureException;
+use JsonRPC\Exception\InvalidJsonFormatException;
+use JsonRPC\Exception\InvalidJsonRpcFormatException;
+use JsonRPC\Exception\ResponseEncodingFailureException;
+use JsonRPC\Exception\ResponseException;
+use JsonRPC\Response\ResponseBuilder;
+
+require_once __DIR__.'/../../../../vendor/autoload.php';
+
+class ResponseBuilderTest extends PHPUnit_Framework_TestCase
+{
+ public function testBuildResponse()
+ {
+ $response = ResponseBuilder::create()
+ ->withId(123)
+ ->withResult('test')
+ ->build();
+
+ $this->assertEquals('{"jsonrpc":"2.0","result":"test","id":123}', $response);
+ }
+
+ public function testBuildResponseWithError()
+ {
+ $response = ResponseBuilder::create()
+ ->withId(123)
+ ->withResult('test')
+ ->withError(42, 'Test', 'More info')
+ ->build();
+
+ $this->assertEquals('{"jsonrpc":"2.0","error":{"code":42,"message":"Test","data":"More info"},"id":123}', $response);
+ }
+
+ public function testBuildResponseWithException()
+ {
+ $response = ResponseBuilder::create()
+ ->withId(123)
+ ->withResult('test')
+ ->withException(new Exception('Test'))
+ ->build();
+
+ $this->assertEquals('{"jsonrpc":"2.0","error":{"code":0,"message":"Test"},"id":123}', $response);
+ }
+
+ public function testBuildResponseWithResponseException()
+ {
+ $exception = new ResponseException('Error', 42);
+ $exception->setData('Data');
+
+ $response = ResponseBuilder::create()
+ ->withId(123)
+ ->withResult('test')
+ ->withException($exception)
+ ->build();
+
+ $this->assertEquals('{"jsonrpc":"2.0","error":{"code":42,"message":"Error","data":"Data"},"id":123}', $response);
+ }
+
+ public function testBuildResponseWithAccessDeniedException()
+ {
+ $responseBuilder = ResponseBuilder::create();
+ $response = $responseBuilder
+ ->withId(123)
+ ->withResult('test')
+ ->withException(new AccessDeniedException('Test'))
+ ->build();
+
+ $this->assertEquals('{"jsonrpc":"2.0","error":{"code":403,"message":"Forbidden"},"id":123}', $response);
+ $this->assertEquals('HTTP/1.0 403 Forbidden', $responseBuilder->getStatus());
+
+ $this->assertEquals(
+ array('Content-Type' => 'application/json'),
+ $responseBuilder->getHeaders()
+ );
+ }
+
+ public function testBuildResponseWithAuthenticationFailureException()
+ {
+ $responseBuilder = ResponseBuilder::create();
+ $response = $responseBuilder
+ ->withId(123)
+ ->withResult('test')
+ ->withException(new AuthenticationFailureException('Test'))
+ ->build();
+
+ $this->assertEquals('{"jsonrpc":"2.0","error":{"code":401,"message":"Unauthorized"},"id":123}', $response);
+ $this->assertEquals('HTTP/1.0 401 Unauthorized', $responseBuilder->getStatus());
+
+ $this->assertEquals(
+ array('Content-Type' => 'application/json', 'WWW-Authenticate' => 'Basic realm="JsonRPC"'),
+ $responseBuilder->getHeaders()
+ );
+ }
+
+ public function testBuildResponseWithResponseEncodingFailureException()
+ {
+ $response = ResponseBuilder::create()
+ ->withId(123)
+ ->withResult('test')
+ ->withException(new ResponseEncodingFailureException('Test'))
+ ->build();
+
+ $this->assertEquals('{"jsonrpc":"2.0","error":{"code":-32603,"message":"Internal error","data":"Test"},"id":123}', $response);
+ }
+
+ public function testBuildResponseWithInvalidArgumentException()
+ {
+ $response = ResponseBuilder::create()
+ ->withId(123)
+ ->withResult('test')
+ ->withException(new InvalidArgumentException('Test'))
+ ->build();
+
+ $this->assertEquals('{"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid params","data":"Test"},"id":123}', $response);
+ }
+
+ public function testBuildResponseWithBadFunctionCallException()
+ {
+ $response = ResponseBuilder::create()
+ ->withId(123)
+ ->withResult('test')
+ ->withException(new BadFunctionCallException('Test'))
+ ->build();
+
+ $this->assertEquals('{"jsonrpc":"2.0","error":{"code":-32601,"message":"Method not found"},"id":123}', $response);
+ }
+
+ public function testBuildResponseWithInvalidJsonRpcFormatException()
+ {
+ $response = ResponseBuilder::create()
+ ->withId(123)
+ ->withResult('test')
+ ->withException(new InvalidJsonRpcFormatException('Test'))
+ ->build();
+
+ $this->assertEquals('{"jsonrpc":"2.0","error":{"code":-32600,"message":"Invalid Request"},"id":null}', $response);
+ }
+
+ public function testBuildResponseWithInvalidJsonFormatException()
+ {
+ $response = ResponseBuilder::create()
+ ->withId(123)
+ ->withResult('test')
+ ->withException(new InvalidJsonFormatException('Test'))
+ ->build();
+
+ $this->assertEquals('{"jsonrpc":"2.0","error":{"code":-32700,"message":"Parse error"},"id":null}', $response);
+ }
+}
diff --git a/libs/jsonrpc/tests/Response/ResponseParserTest.php b/libs/jsonrpc/tests/Response/ResponseParserTest.php
new file mode 100644
index 00000000..f195014f
--- /dev/null
+++ b/libs/jsonrpc/tests/Response/ResponseParserTest.php
@@ -0,0 +1,100 @@
+<?php
+
+use JsonRPC\Response\ResponseParser;
+
+require_once __DIR__.'/../../../../vendor/autoload.php';
+
+class ResponseParserTest extends PHPUnit_Framework_TestCase
+{
+ public function testSingleRequest()
+ {
+ $result = ResponseParser::create()
+ ->withPayload(json_decode('{"jsonrpc": "2.0", "result": "foobar", "id": "1"}', true))
+ ->parse();
+
+ $this->assertEquals('foobar', $result);
+ }
+
+ public function testWithBadJsonFormat()
+ {
+ $this->setExpectedException('\JsonRPC\Exception\InvalidJsonFormatException');
+
+ ResponseParser::create()
+ ->withPayload('foobar')
+ ->parse();
+ }
+
+ public function testWithBadProcedure()
+ {
+ $this->setExpectedException('BadFunctionCallException');
+
+ ResponseParser::create()
+ ->withPayload(json_decode('{"jsonrpc": "2.0", "error": {"code": -32601, "message": "Method not found"}, "id": "1"}', true))
+ ->parse();
+ }
+
+ public function testWithInvalidArgs()
+ {
+ $this->setExpectedException('InvalidArgumentException');
+
+ ResponseParser::create()
+ ->withPayload(json_decode('{"jsonrpc": "2.0", "error": {"code": -32602, "message": "Invalid params"}, "id": "1"}', true))
+ ->parse();
+ }
+
+ public function testWithInvalidRequest()
+ {
+ $this->setExpectedException('\JsonRPC\Exception\InvalidJsonRpcFormatException');
+
+ ResponseParser::create()
+ ->withPayload(json_decode('{"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null}', true))
+ ->parse();
+ }
+
+ public function testWithParseError()
+ {
+ $this->setExpectedException('\JsonRPC\Exception\InvalidJsonFormatException');
+
+ ResponseParser::create()
+ ->withPayload(json_decode('{"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error"}, "id": null}', true))
+ ->parse();
+ }
+
+ public function testWithOtherError()
+ {
+ $this->setExpectedException('\JsonRPC\Exception\ResponseException');
+
+ ResponseParser::create()
+ ->withPayload(json_decode('{"jsonrpc": "2.0", "error": {"code": 42, "message": "Something", "data": "foobar"}, "id": null}', true))
+ ->parse();
+ }
+
+ public function testBatch()
+ {
+ $payload = '[
+ {"jsonrpc": "2.0", "result": 7, "id": "1"},
+ {"jsonrpc": "2.0", "result": 19, "id": "2"}
+ ]';
+
+ $result = ResponseParser::create()
+ ->withPayload(json_decode($payload, true))
+ ->parse();
+
+ $this->assertEquals(array(7, 19), $result);
+ }
+
+ public function testBatchWithError()
+ {
+ $payload = '[
+ {"jsonrpc": "2.0", "result": 7, "id": "1"},
+ {"jsonrpc": "2.0", "result": 19, "id": "2"},
+ {"jsonrpc": "2.0", "error": {"code": -32602, "message": "Invalid params"}, "id": "1"}
+ ]';
+
+ $this->setExpectedException('InvalidArgumentException');
+
+ ResponseParser::create()
+ ->withPayload(json_decode($payload, true))
+ ->parse();
+ }
+}
diff --git a/libs/jsonrpc/tests/ServerProtocolTest.php b/libs/jsonrpc/tests/ServerProtocolTest.php
new file mode 100644
index 00000000..a488015b
--- /dev/null
+++ b/libs/jsonrpc/tests/ServerProtocolTest.php
@@ -0,0 +1,237 @@
+<?php
+
+use JsonRPC\Server;
+
+require_once __DIR__.'/../../../vendor/autoload.php';
+require_once __DIR__.'/Response/HeaderMockTest.php';
+
+class C
+{
+ public function doSomething()
+ {
+ return 'something';
+ }
+}
+
+class ServerProtocolTest extends \JsonRPC\Response\HeaderMockTest
+{
+ public function testPositionalParameters()
+ {
+ $subtract = function ($minuend, $subtrahend) {
+ return $minuend - $subtrahend;
+ };
+
+ $server = new Server('{"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1}');
+ $server->register('subtract', $subtract);
+
+ $this->assertEquals(
+ json_decode('{"jsonrpc": "2.0", "result": 19, "id": 1}', true),
+ json_decode($server->execute(), true)
+ );
+
+ $server = new Server('{"jsonrpc": "2.0", "method": "subtract", "params": [23, 42], "id": 1}');
+ $server->register('subtract', $subtract);
+
+ $this->assertEquals(
+ json_decode('{"jsonrpc": "2.0", "result": -19, "id": 1}', true),
+ json_decode($server->execute(), true)
+ );
+ }
+
+ public function testNamedParameters()
+ {
+ $subtract = function ($minuend, $subtrahend) {
+ return $minuend - $subtrahend;
+ };
+
+ $server = new Server('{"jsonrpc": "2.0", "method": "subtract", "params": {"subtrahend": 23, "minuend": 42}, "id": 3}');
+ $server->register('subtract', $subtract);
+
+ $this->assertEquals(
+ json_decode('{"jsonrpc": "2.0", "result": 19, "id": 3}', true),
+ json_decode($server->execute(), true)
+ );
+
+ $server = new Server('{"jsonrpc": "2.0", "method": "subtract", "params": {"minuend": 42, "subtrahend": 23}, "id": 4}');
+ $server->register('subtract', $subtract);
+
+ $this->assertEquals(
+ json_decode('{"jsonrpc": "2.0", "result": 19, "id": 4}', true),
+ json_decode($server->execute(), true)
+ );
+ }
+
+ public function testNotification()
+ {
+ $update = function($p1, $p2, $p3, $p4, $p5) {};
+ $foobar = function() {};
+
+ $server = new Server('{"jsonrpc": "2.0", "method": "update", "params": [1,2,3,4,5]}');
+ $server->register('update', $update);
+ $server->register('foobar', $foobar);
+
+ $this->assertEquals('', $server->execute());
+
+ $server = new Server('{"jsonrpc": "2.0", "method": "foobar"}');
+ $server->register('update', $update);
+ $server->register('foobar', $foobar);
+
+ $this->assertEquals('', $server->execute());
+ }
+
+ public function testNoMethod()
+ {
+ $server = new Server('{"jsonrpc": "2.0", "method": "foobar", "id": "1"}');
+
+ $this->assertEquals(
+ json_decode('{"jsonrpc": "2.0", "error": {"code": -32601, "message": "Method not found"}, "id": "1"}', true),
+ json_decode($server->execute(), true)
+ );
+ }
+
+ public function testInvalidJson()
+ {
+ $server = new Server('{"jsonrpc": "2.0", "method": "foobar, "params": "bar", "baz]');
+
+ $this->assertEquals(
+ json_decode('{"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error"}, "id": null}', true),
+ json_decode($server->execute(), true)
+ );
+ }
+
+ public function testInvalidRequest()
+ {
+ $server = new Server('{"jsonrpc": "2.0", "method": 1, "params": "bar", "id": 1}');
+
+ $this->assertEquals(
+ json_decode('{"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null}', true),
+ json_decode($server->execute(), true)
+ );
+ }
+
+ public function testInvalidResponse_MalformedCharacters()
+ {
+ $server = new Server('{"jsonrpc": "2.0", "method": "invalidresponse","id": 1}');
+
+ $invalidresponse = function() {
+ return pack("H*" ,'c32e');
+ };
+
+ $server->register('invalidresponse', $invalidresponse);
+
+ $this->assertEquals(
+ json_decode('{"jsonrpc": "2.0","id": 1, "error": {"code": -32603, "message": "Internal error","data": "Malformed UTF-8 characters, possibly incorrectly encoded"}}', true),
+ json_decode($server->execute(), true)
+ );
+ }
+
+ public function testBatchInvalidJson()
+ {
+ $server = new Server('[
+ {"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"},
+ {"jsonrpc": "2.0", "method"
+ ]');
+
+ $this->assertEquals(
+ json_decode('{"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error"}, "id": null}', true),
+ json_decode($server->execute(), true)
+ );
+ }
+
+ public function testBatchEmptyArray()
+ {
+ $server = new Server('[]');
+
+ $this->assertEquals(
+ json_decode('{"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null}', true),
+ json_decode($server->execute(), true)
+ );
+ }
+
+ public function testBatchNotEmptyButInvalid()
+ {
+ $server = new Server('[1]');
+
+ $this->assertEquals(
+ json_decode('[{"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error"}, "id": null}]', true),
+ json_decode($server->execute(), true)
+ );
+ }
+
+ public function testBatchInvalid()
+ {
+ $server = new Server('[1,2,3]');
+
+ $this->assertEquals(
+ json_decode('[
+ {"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error"}, "id": null},
+ {"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error"}, "id": null},
+ {"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error"}, "id": null}
+ ]', true),
+ json_decode($server->execute(), true)
+ );
+ }
+
+ public function testBatchOk()
+ {
+ $server = new Server('[
+ {"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"},
+ {"jsonrpc": "2.0", "method": "notify_hello", "params": [7]},
+ {"jsonrpc": "2.0", "method": "subtract", "params": [42,23], "id": "2"},
+ {"foo": "boo"},
+ {"jsonrpc": "2.0", "method": "foo.get", "params": {"name": "myself"}, "id": "5"},
+ {"jsonrpc": "2.0", "method": "get_data", "id": "9"},
+ {"jsonrpc": "2.0", "method": "doSomething", "id": 10},
+ {"jsonrpc": "2.0", "method": "doStuff", "id": 15}
+ ]');
+
+ $server->register('sum', function($a, $b, $c) {
+ return $a + $b + $c;
+ });
+
+ $server->register('subtract', function($minuend, $subtrahend) {
+ return $minuend - $subtrahend;
+ });
+
+ $server->register('get_data', function() {
+ return array('hello', 5);
+ });
+
+ $server->attach(new C);
+
+ $server->bind('doStuff', 'C', 'doSomething');
+
+ $response = $server->execute();
+
+ $this->assertEquals(
+ json_decode('[
+ {"jsonrpc": "2.0", "result": 7, "id": "1"},
+ {"jsonrpc": "2.0", "result": 19, "id": "2"},
+ {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null},
+ {"jsonrpc": "2.0", "error": {"code": -32601, "message": "Method not found"}, "id": "5"},
+ {"jsonrpc": "2.0", "result": ["hello", 5], "id": "9"},
+ {"jsonrpc": "2.0", "result": "something", "id": "10"},
+ {"jsonrpc": "2.0", "result": "something", "id": "15"}
+ ]', true),
+ json_decode($response, true)
+ );
+ }
+
+ public function testBatchNotifications()
+ {
+ $server = new Server('[
+ {"jsonrpc": "2.0", "method": "notify_sum", "params": [1,2,4]},
+ {"jsonrpc": "2.0", "method": "notify_hello", "params": [7]}
+ ]');
+
+ $server->register('notify_sum', function($a, $b, $c) {
+
+ });
+
+ $server->register('notify_hello', function($id) {
+
+ });
+
+ $this->assertEquals('', $server->execute());
+ }
+}
diff --git a/libs/jsonrpc/tests/ServerTest.php b/libs/jsonrpc/tests/ServerTest.php
new file mode 100644
index 00000000..87f37c2d
--- /dev/null
+++ b/libs/jsonrpc/tests/ServerTest.php
@@ -0,0 +1,258 @@
+<?php
+
+use JsonRPC\Exception\AccessDeniedException;
+use JsonRPC\Exception\AuthenticationFailureException;
+use JsonRPC\Exception\ResponseException;
+use JsonRPC\MiddlewareInterface;
+use JsonRPC\Response\HeaderMockTest;
+use JsonRPC\Server;
+
+require_once __DIR__.'/../../../vendor/autoload.php';
+require_once __DIR__.'/Response/HeaderMockTest.php';
+
+class MyException extends Exception
+{
+
+}
+
+class DummyMiddleware implements MiddlewareInterface
+{
+ public function execute($username, $password, $procedureName)
+ {
+ throw new AuthenticationFailureException('Bad user');
+ }
+}
+
+class ServerTest extends HeaderMockTest
+{
+ private $payload = '{"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"}';
+
+ public function testCustomAuthenticationHeader()
+ {
+ $env = array(
+ 'HTTP_X_AUTH' => base64_encode('myuser:mypassword'),
+ );
+
+ $server = new Server($this->payload, $env);
+ $server->setAuthenticationHeader('X-Auth');
+ $this->assertEquals('myuser', $server->getUsername());
+ $this->assertEquals('mypassword', $server->getPassword());
+ }
+
+ public function testCustomAuthenticationHeaderWithEmptyValue()
+ {
+ $server = new Server($this->payload);
+ $server->setAuthenticationHeader('X-Auth');
+ $this->assertNull($server->getUsername());
+ $this->assertNull($server->getPassword());
+ }
+
+ public function testGetUsername()
+ {
+ $server = new Server($this->payload);
+ $this->assertNull($server->getUsername());
+
+ $server = new Server($this->payload, array('PHP_AUTH_USER' => 'username'));
+ $this->assertEquals('username', $server->getUsername());
+ }
+
+ public function testGetPassword()
+ {
+ $server = new Server($this->payload);
+ $this->assertNull($server->getPassword());
+
+ $server = new Server($this->payload, array('PHP_AUTH_PW' => 'password'));
+ $this->assertEquals('password', $server->getPassword());
+ }
+
+ public function testExecute()
+ {
+ $server = new Server($this->payload);
+ $server->getProcedureHandler()->withCallback('sum', function($a, $b, $c) {
+ return $a + $b + $c;
+ });
+
+ self::$functions
+ ->expects($this->once())
+ ->method('header')
+ ->with('Content-Type: application/json');
+
+ $this->assertEquals('{"jsonrpc":"2.0","result":7,"id":"1"}', $server->execute());
+ }
+
+ public function testExecuteRequestParserOverride()
+ {
+ $requestParser = $this->getMockBuilder('JsonRPC\Request\RequestParser')
+ ->getMock();
+
+ $requestParser->method('withPayload')->willReturn($requestParser);
+ $requestParser->method('withProcedureHandler')->willReturn($requestParser);
+ $requestParser->method('withMiddlewareHandler')->willReturn($requestParser);
+ $requestParser->method('withLocalException')->willReturn($requestParser);
+
+ $server = new Server($this->payload, array(), null, $requestParser);
+
+ $requestParser->expects($this->once())
+ ->method('parse');
+
+ $server->execute();
+ }
+
+ public function testExecuteBatchRequestParserOverride()
+ {
+ $batchRequestParser = $this->getMockBuilder('JsonRPC\Request\BatchRequestParser')
+ ->getMock();
+
+ $batchRequestParser->method('withPayload')->willReturn($batchRequestParser);
+ $batchRequestParser->method('withProcedureHandler')->willReturn($batchRequestParser);
+ $batchRequestParser->method('withMiddlewareHandler')->willReturn($batchRequestParser);
+ $batchRequestParser->method('withLocalException')->willReturn($batchRequestParser);
+
+ $server = new Server('["...", "..."]', array(), null, null, $batchRequestParser);
+
+ $batchRequestParser->expects($this->once())
+ ->method('parse');
+
+ $server->execute();
+ }
+
+ public function testExecuteResponseBuilderOverride()
+ {
+ $responseBuilder = $this->getMockBuilder('JsonRPC\Response\ResponseBuilder')
+ ->getMock();
+
+ $responseBuilder->expects($this->once())
+ ->method('sendHeaders');
+
+ $server = new Server($this->payload, array(), $responseBuilder);
+ $server->execute();
+ }
+
+ public function testExecuteProcedureHandlerOverride()
+ {
+ $batchRequestParser = $this->getMockBuilder('JsonRPC\Request\BatchRequestParser')
+ ->getMock();
+
+ $procedureHandler = $this->getMockBuilder('JsonRPC\ProcedureHandler')
+ ->getMock();
+
+ $batchRequestParser->method('withPayload')->willReturn($batchRequestParser);
+ $batchRequestParser->method('withProcedureHandler')->willReturn($batchRequestParser);
+ $batchRequestParser->method('withMiddlewareHandler')->willReturn($batchRequestParser);
+ $batchRequestParser->method('withLocalException')->willReturn($batchRequestParser);
+
+ $server = new Server('["...", "..."]', array(), null, null, $batchRequestParser, $procedureHandler);
+
+ $batchRequestParser->expects($this->once())
+ ->method('parse');
+
+ $batchRequestParser->expects($this->once())
+ ->method('withProcedureHandler')
+ ->with($this->identicalTo($procedureHandler));
+
+ $server->execute();
+ }
+
+ public function testWhenCallbackRaiseForbiddenException()
+ {
+ $server = new Server($this->payload);
+ $server->getProcedureHandler()->withCallback('sum', function($a, $b, $c) {
+ throw new AccessDeniedException();
+ });
+
+ self::$functions
+ ->expects($this->at(0))
+ ->method('header')
+ ->with('HTTP/1.0 403 Forbidden');
+
+ self::$functions
+ ->expects($this->at(1))
+ ->method('header')
+ ->with('Content-Type: application/json');
+
+ $this->assertEquals('{"jsonrpc":"2.0","error":{"code":403,"message":"Forbidden"},"id":null}', $server->execute());
+ }
+
+ public function testWhenCallbackRaiseUnauthorizedException()
+ {
+ $server = new Server($this->payload);
+ $server->getProcedureHandler()->withCallback('sum', function($a, $b, $c) {
+ throw new AuthenticationFailureException();
+ });
+
+ self::$functions
+ ->expects($this->at(0))
+ ->method('header')
+ ->with('HTTP/1.0 401 Unauthorized');
+
+ self::$functions
+ ->expects($this->at(1))
+ ->method('header')
+ ->with('Content-Type: application/json');
+
+ $this->assertEquals('{"jsonrpc":"2.0","error":{"code":401,"message":"Unauthorized"},"id":null}', $server->execute());
+ }
+
+ public function testWhenMiddlewareRaiseUnauthorizedException()
+ {
+ $server = new Server($this->payload);
+ $server->getMiddlewareHandler()->withMiddleware(new DummyMiddleware());
+ $server->getProcedureHandler()->withCallback('sum', function($a, $b) {
+ return $a + $b;
+ });
+
+ self::$functions
+ ->expects($this->at(0))
+ ->method('header')
+ ->with('HTTP/1.0 401 Unauthorized');
+
+ self::$functions
+ ->expects($this->at(1))
+ ->method('header')
+ ->with('Content-Type: application/json');
+
+ $this->assertEquals('{"jsonrpc":"2.0","error":{"code":401,"message":"Unauthorized"},"id":null}', $server->execute());
+ }
+
+ public function testFilterRelayExceptions()
+ {
+ $server = new Server($this->payload);
+ $server->withLocalException('MyException');
+ $server->getProcedureHandler()->withCallback('sum', function($a, $b, $c) {
+ throw new MyException('test');
+ });
+
+ $this->setExpectedException('MyException');
+ $server->execute();
+ }
+
+ public function testCustomExceptionAreRelayedToClient()
+ {
+ $server = new Server($this->payload);
+ $server->getProcedureHandler()->withCallback('sum', function($a, $b, $c) {
+ throw new MyException('test');
+ });
+
+ self::$functions
+ ->expects($this->once())
+ ->method('header')
+ ->with('Content-Type: application/json');
+
+ $this->assertEquals('{"jsonrpc":"2.0","error":{"code":0,"message":"test"},"id":"1"}', $server->execute());
+ }
+
+ public function testCustomResponseException()
+ {
+ $server = new Server($this->payload);
+ $server->getProcedureHandler()->withCallback('sum', function($a, $b, $c) {
+ throw new ResponseException('test', 123, null, 'more info');
+ });
+
+ self::$functions
+ ->expects($this->once())
+ ->method('header')
+ ->with('Content-Type: application/json');
+
+ $this->assertEquals('{"jsonrpc":"2.0","error":{"code":123,"message":"test","data":"more info"},"id":"1"}', $server->execute());
+ }
+}
diff --git a/libs/jsonrpc/tests/Validator/HostValidatorTest.php b/libs/jsonrpc/tests/Validator/HostValidatorTest.php
new file mode 100644
index 00000000..a5fed7e0
--- /dev/null
+++ b/libs/jsonrpc/tests/Validator/HostValidatorTest.php
@@ -0,0 +1,32 @@
+<?php
+
+use JsonRPC\Validator\HostValidator;
+
+require_once __DIR__.'/../../../../vendor/autoload.php';
+
+class HostValidatorTest extends PHPUnit_Framework_TestCase
+{
+ public function testWithEmptyHosts()
+ {
+ $this->assertNull(HostValidator::validate(array(), '127.0.0.1', '127.0.0.1'));
+ }
+
+ public function testWithValidHosts()
+ {
+ $this->assertNull(HostValidator::validate(array('127.0.0.1'), '127.0.0.1', '127.0.0.1'));
+ }
+
+ public function testWithValidNetwork()
+ {
+ $this->assertNull(HostValidator::validate(array('192.168.10.1/24'), '192.168.10.1'),'test ip match');
+ $this->assertNull(HostValidator::validate(array('192.168.10.1/24'), '192.168.10.250'),'test ip match');
+ $this->setExpectedException('\JsonRPC\Exception\AccessDeniedException');
+ HostValidator::validate(array('192.168.10.1/24'), '192.168.11.1');
+ }
+
+ public function testWithNotAuthorizedHosts()
+ {
+ $this->setExpectedException('\JsonRPC\Exception\AccessDeniedException');
+ HostValidator::validate(array('192.168.1.1'), '127.0.0.1', '127.0.0.1');
+ }
+}
diff --git a/libs/jsonrpc/tests/Validator/JsonEncodingValidatorTest.php b/libs/jsonrpc/tests/Validator/JsonEncodingValidatorTest.php
new file mode 100644
index 00000000..a1b2b80e
--- /dev/null
+++ b/libs/jsonrpc/tests/Validator/JsonEncodingValidatorTest.php
@@ -0,0 +1,22 @@
+<?php
+
+use JsonRPC\Validator\JsonEncodingValidator;
+
+require_once __DIR__.'/../../../../vendor/autoload.php';
+
+class JsonEncodingValidatorTest extends PHPUnit_Framework_TestCase
+{
+ public function testWithValidJson()
+ {
+ json_encode('{"foo": "bar"}');
+ $this->assertNull(JsonEncodingValidator::validate());
+ }
+
+ public function testWithJsonError()
+ {
+ json_encode("\xB1\x31");
+
+ $this->setExpectedException('\JsonRPC\Exception\ResponseEncodingFailureException');
+ JsonEncodingValidator::validate();
+ }
+}
diff --git a/libs/jsonrpc/tests/Validator/JsonFormatValidatorTest.php b/libs/jsonrpc/tests/Validator/JsonFormatValidatorTest.php
new file mode 100644
index 00000000..a838ada9
--- /dev/null
+++ b/libs/jsonrpc/tests/Validator/JsonFormatValidatorTest.php
@@ -0,0 +1,19 @@
+<?php
+
+use JsonRPC\Validator\JsonFormatValidator;
+
+require_once __DIR__.'/../../../../vendor/autoload.php';
+
+class JsonFormatValidatorTest extends PHPUnit_Framework_TestCase
+{
+ public function testJsonParsedCorrectly()
+ {
+ $this->assertNull(JsonFormatValidator::validate(array('foobar')));
+ }
+
+ public function testJsonNotParsedCorrectly()
+ {
+ $this->setExpectedException('\JsonRPC\Exception\InvalidJsonFormatException');
+ JsonFormatValidator::validate('');
+ }
+}
diff --git a/libs/jsonrpc/tests/Validator/RpcFormatValidatorTest.php b/libs/jsonrpc/tests/Validator/RpcFormatValidatorTest.php
new file mode 100644
index 00000000..3e6ba8bc
--- /dev/null
+++ b/libs/jsonrpc/tests/Validator/RpcFormatValidatorTest.php
@@ -0,0 +1,48 @@
+<?php
+
+use JsonRPC\Validator\RpcFormatValidator;
+
+require_once __DIR__.'/../../../../vendor/autoload.php';
+
+class RpcFormatValidatorTest extends PHPUnit_Framework_TestCase
+{
+ public function testWithMinimumRequirement()
+ {
+ $this->assertNull(RpcFormatValidator::validate(array('jsonrpc' => '2.0', 'method' => 'foobar')));
+ }
+
+ public function testWithNoVersion()
+ {
+ $this->setExpectedException('\JsonRPC\Exception\InvalidJsonRpcFormatException');
+ RpcFormatValidator::validate(array('method' => 'foobar'));
+ }
+
+ public function testWithNoMethod()
+ {
+ $this->setExpectedException('\JsonRPC\Exception\InvalidJsonRpcFormatException');
+ RpcFormatValidator::validate(array('jsonrpc' => '2.0'));
+ }
+
+ public function testWithMethodNotString()
+ {
+ $this->setExpectedException('\JsonRPC\Exception\InvalidJsonRpcFormatException');
+ RpcFormatValidator::validate(array('jsonrpc' => '2.0', 'method' => array()));
+ }
+
+ public function testWithBadVersion()
+ {
+ $this->setExpectedException('\JsonRPC\Exception\InvalidJsonRpcFormatException');
+ RpcFormatValidator::validate(array('jsonrpc' => '1.0', 'method' => 'abc'));
+ }
+
+ public function testWithBadParams()
+ {
+ $this->setExpectedException('\JsonRPC\Exception\InvalidJsonRpcFormatException');
+ RpcFormatValidator::validate(array('jsonrpc' => '2.0', 'method' => 'abc', 'params' => 'foobar'));
+ }
+
+ public function testWithParams()
+ {
+ $this->assertNull(RpcFormatValidator::validate(array('jsonrpc' => '2.0', 'method' => 'abc', 'params' => array(1, 2))));
+ }
+}
diff --git a/libs/jsonrpc/tests/Validator/UserValidatorTest.php b/libs/jsonrpc/tests/Validator/UserValidatorTest.php
new file mode 100644
index 00000000..e514c105
--- /dev/null
+++ b/libs/jsonrpc/tests/Validator/UserValidatorTest.php
@@ -0,0 +1,24 @@
+<?php
+
+use JsonRPC\Validator\UserValidator;
+
+require_once __DIR__.'/../../../../vendor/autoload.php';
+
+class UserValidatorTest extends PHPUnit_Framework_TestCase
+{
+ public function testWithEmptyHosts()
+ {
+ $this->assertNull(UserValidator::validate(array(), 'user', 'pass'));
+ }
+
+ public function testWithValidHosts()
+ {
+ $this->assertNull(UserValidator::validate(array('user' => 'pass'), 'user', 'pass'));
+ }
+
+ public function testWithNotAuthorizedHosts()
+ {
+ $this->setExpectedException('\JsonRPC\Exception\AuthenticationFailureException');
+ UserValidator::validate(array('user' => 'pass'), 'user', 'wrong password');
+ }
+}