Changeset 793

Show
Ignore:
Timestamp:
08/09/07 18:39:56 (1 year ago)
Author:
mikey
Message:

refactored net.stubbles.service.jsonrpc.stubJsonRpcProcessor
added unit tests

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/config/xml/config.xml

    r763 r793  
    1010  <config name="net.stubbles.ipo.session.class" value="net.stubbles.ipo.session.stubPHPSession" /> 
    1111  <config name="net.stubbles.ipo.session.name" value="SID" /> 
    12   <config name="net.stubbles.services.jsonrpc.configfile" value="json-rpc-service.xml" /> 
     12  <config name="net.stubbles.service.jsonrpc.configfile" value="json-rpc-service.xml" /> 
    1313</xj:configuration> 
  • trunk/examples/config/xml/config.xml

    r762 r793  
    1010  <config name="net.stubbles.ipo.session.class" value="net.stubbles.ipo.session.stubPHPSession" /> 
    1111  <config name="net.stubbles.ipo.session.name" value="SID" /> 
    12   <config name="net.stubbles.services.jsonrpc.configfile" value="json-rpc-service.xml" /> 
     12  <config name="net.stubbles.service.jsonrpc.configfile" value="json-rpc-service.xml" /> 
    1313</xj:configuration> 
  • trunk/src/main/php/net/stubbles/service/jsonrpc/stubJsonRpcProcessor.php

    r789 r793  
    1414                      'net.stubbles.reflection.reflection', 
    1515                      'net.stubbles.service.annotations.stubWebMethodAnnotation', 
    16                       'net.stubbles.util.encoding.stubEncodingHelper', 
     16                      'net.stubbles.service.jsonrpc.stubJsonRpcResponse', 
    1717                      'net.stubbles.ioc.injection.injection' 
    1818); 
     
    2222 * @package     stubbles 
    2323 * @subpackage  service_jsonrpc 
     24 * @link        http://json-rpc.org/wiki/specification 
    2425 */ 
    25 class stubJsonRpcProcessor extends stubAbstractProcessor { 
    26  
     26class stubJsonRpcProcessor extends stubAbstractProcessor 
     27
    2728    /** 
    2829     * Regexp to validate method param 
    2930     */ 
    3031    const CLASS_AND_METHOD_PATTERN = '^([a-zA-Z0-9_]+\.[a-zA-Z0-9_]+)$'; 
    31  
    3232    /** 
    3333     * Regexp to validate param param 
    3434     */ 
    35     const PARAM_PATTERN = '^[a-zA-Z0-9_]+$'; 
    36  
     35    const PARAM_PATTERN            = '^[a-zA-Z0-9_]+$'; 
    3736    /** 
    3837     * Regexp to validate id param 
    3938     */ 
    40     const ID_PATTERN = '^\d{6,7}$'; 
    41  
     39    const ID_PATTERN               = '^\d{6,7}$'; 
     40    /** 
     41     * Registry key for the service config file 
     42     */ 
     43    const KEY_SERVICE_FILE         = 'net.stubbles.service.jsonrpc.configfile'; 
    4244    /** 
    4345     * Map client classes to fully qualified class names 
    4446     * 
    45      * @var array 
    46      */ 
    47     protected $classMap = array(); 
    48  
     47     * @var  array<string,array<string,string>> 
     48     */ 
     49    protected $classMap            = array(); 
    4950    /** 
    5051     * Configuration of the service 
    5152     * 
    52      * @var array 
    53      */ 
    54     protected $serviceConfig = array(); 
    55  
    56     /** 
    57      * The class used in the service 
    58      * 
    59      * @var stubReflectionClass 
    60      */ 
    61     protected $classObj = null; 
    62  
    63     /** 
    64      * The method used in the service 
    65      * 
    66      * @var stubReflectionMethod 
    67      */ 
    68     protected $methodObj = null; 
    69  
    70     /** 
    71      * Registry key for the service config file 
    72      */ 
    73     const KEY_SERVICE_FILE = 'net.stubbles.services.jsonrpc.configfile'; 
     53     * @var  array<string,mixed> 
     54     */ 
     55    protected $serviceConfig       = array(); 
     56 
     57    /** 
     58     * constructor 
     59     * 
     60     * @param  stubRequest      $request      the current request 
     61     * @param  stubSession      $session      the current session 
     62     * @param  stubResponse     $response     the current response 
     63     * @param  stubPageFactory  $pageFactory  page factory to use to read the page configuration 
     64     */ 
     65    public function __construct(stubRequest $request, stubSession $session, stubResponse $response, stubPageFactory $pageFactory) 
     66    { 
     67        $response = new stubJsonRpcResponse($response); 
     68        parent::__construct($request, $session, $response, $pageFactory); 
     69    } 
    7470 
    7571    /** 
     
    7874     * This method only dispatches the request to different methods. 
    7975     */ 
    80     public function doProcess() { 
     76    public function doProcess() 
     77    { 
    8178        $this->loadServiceConfig($this->getServiceFilePath()); 
    8279 
    83         if ($this->request->hasValue('__generateProxy', stubRequest::SOURCE_PARAM)) { 
     80        if ($this->request->hasValue('__generateProxy')) { 
    8481            $proxyClassvalidator = new stubRegexValidator('^[A-Za-z,0-9_\.]+$'); 
    8582            $classes = $this->request->getValidatedValue($proxyClassvalidator, '__generateProxy', stubRequest::SOURCE_PARAM); 
     
    8986                $this->generateProxies(explode(',', $classes)); 
    9087            } 
    91         } elseif ($this->request->getMethod() === 'get') { 
     88        } elseif ($this->request->getMethod() === 'post') { 
     89            $this->processPostRequest(); 
     90        } else { 
    9291            $this->processGetRequest(); 
    93         } else { 
    94             $this->processPostRequest(); 
    95         } 
     92        } 
     93    } 
     94 
     95    /** 
     96     * Get the full path to the config file describing the services 
     97     * 
     98     * @return  string 
     99     * @throws  stubFileNotFoundException 
     100     */ 
     101    protected function getServiceFilePath() 
     102    { 
     103        $configFile = stubConfig::getConfigPath() . '/xml/' . stubRegistry::getConfig(self::KEY_SERVICE_FILE,'json-rpc-service.xml'); 
     104        if (!file_exists($configFile) || !is_readable($configFile)) { 
     105            stubClassLoader::load('net.stubbles.lang.exceptions.stubFileNotFoundException'); 
     106            throw new stubFileNotFoundException($configFile); 
     107        } 
     108         
     109        return $configFile; 
    96110    } 
    97111 
     
    99113     * Load the service configuration file 
    100114     * 
    101      * @param string $serviceConfigFile 
    102      */ 
    103     protected function loadServiceConfig($serviceConfigFile) { 
    104  
    105         $cacheFile = stubConfig::getCachePath() . '/' . md5($serviceConfigFile) . '.cache'; 
     115     * @param string $serviceConfigFile 
     116     */ 
     117    protected function loadServiceConfig($serviceConfigFile) 
     118    { 
     119        $cacheFile = stubConfig::getCachePath() . '/jsonrpc_' . md5($serviceConfigFile) . '.cache'; 
    106120        if (file_exists($cacheFile)) { 
    107121            $cacheData = unserialize(file_get_contents($cacheFile)); 
     
    130144     * Generate and send the generated javascript clients 
    131145     * 
    132      * @param array        restrict to classes 
    133      */ 
    134     public function generateProxies($classes = null) { 
     146     * @param  array  $classes  optional  restrict to this list of classes 
     147     */ 
     148    public function generateProxies($classes = null) 
     149    { 
    135150        stubClassLoader::load('net.stubbles.service.jsonrpc.util.stubJsonRpcProxyGenerator'); 
    136  
    137151        $tmp        = parse_url($this->request->getURI()); 
    138152        $serviceUrl = '//' . $tmp['path']; 
     
    160174 
    161175    /** 
     176     * Converts any string to Javascript code that writes 
     177     * messages to the firebug console 
     178     * 
     179     * @param   string  $string  the message to output to the console 
     180     * @param   string  $level   level of the message 
     181     * @return  string 
     182     */ 
     183    protected function convertStringToFirebug($string, $level = 'error') 
     184    { 
     185        $result = ''; 
     186        $lines  = explode("\n", $string); 
     187        foreach ($lines as $line) { 
     188            $result .= "console.{$level}('" . addslashes($line) . "');\n"; 
     189        } 
     190         
     191        return $result; 
     192    } 
     193 
     194    /** 
    162195     * Handle a JSON-RPC POST request 
    163      */ 
    164     public function processPostRequest() { 
    165         $requestJsonObj  = $this->request->getValidatedRawData(new stubPassThruValidator()); 
    166         $phpJsonObj      = json_decode($requestJsonObj); 
     196     * 
     197     * @throws  stubException 
     198     */ 
     199    public function processPostRequest() 
     200    { 
     201        $requestJsonObj = $this->request->getValidatedRawData(new stubPassThruValidator()); 
     202        $phpJsonObj     = json_decode($requestJsonObj); 
    167203        if (!is_object($phpJsonObj)) { 
    168             throw new stubException('Invalid request.'); 
    169         } 
     204            $this->response->writeFault(null, 'Invalid request.'); 
     205            return; 
     206        } 
     207         
    170208        if (!isset($phpJsonObj->id)) { 
    171             throw new stubException('Invalid request: No id given.'); 
    172         } 
     209            $this->response->writeFault(null, 'Invalid request: No id given.'); 
     210            return; 
     211        } 
     212         
    173213        if (!isset($phpJsonObj->method)) { 
    174             throw new stubException('Invalid request: No method given.'); 
    175         } 
     214            $this->response->writeFault($phpJsonObj->id, 'Invalid request: No method given.'); 
     215            return; 
     216        } 
     217         
    176218        if (!isset($phpJsonObj->params)) { 
    177             throw new stubException('Invalid request: No params given.'); 
     219            $this->response->writeFault($phpJsonObj->id, 'Invalid request: No params given.'); 
     220            return; 
    178221        } 
    179222 
    180223        try { 
    181             $result = $this->invokeServiceMethod($phpJsonObj->method, $phpJsonObj->params); 
    182             $this->sendResponse($phpJsonObj->id, $result); 
     224            $reflect = $this->getClassAndMethod($phpJsonObj->method); 
     225            $result  = $this->invokeServiceMethod($reflect['class'], $reflect['method'], $phpJsonObj->params); 
     226            $this->response->writeResponse($phpJsonObj->id, $result); 
    183227        } catch (Exception $e) { 
    184             $this->sendFault($phpJsonObj->id, $e->getMessage()); 
    185         } 
    186     } 
    187  
    188     /** 
    189      * Invoke the requested methods 
    190      * 
    191      * @param string $methodName 
    192      * @param array $params 
    193      * @return mixed 
    194      */ 
    195     protected function invokeServiceMethod($methodName, $params) { 
    196         if (!preg_match('/'.self::CLASS_AND_METHOD_PATTERN.'/', $methodName)) { 
    197             throw new stubException('method-Pattern has to be <className>.<methodName>'); 
    198         } 
    199         list($className, $methodName) = explode('.', $methodName); 
    200         $clazz = $this->getReflectionClass($className); 
    201         if ($clazz == null) { 
    202             throw new stubException('Unknown class ' . $className . '.'); 
    203         } 
    204  
    205         $method = $clazz->getMethod($methodName); 
    206         if ($method == null) { 
    207             throw new stubException('Unknown method ' . $className . '.' . $methodName . '.'); 
    208         } 
    209         if (!$method->hasAnnotation('WebMethod')) { 
    210             throw new stubException('Method ' . $className . '.' . $methodName . ' is no WebMethod.'); 
    211         } 
    212         if ($method->getNumberOfRequiredParameters() > count($params)) { 
    213             throw new stubException('Invalid amount of parameters passed.'); 
    214         } 
    215  
    216         $instance = $clazz->newInstance(); 
    217         $injectionMap = new stubInjectionMap(); 
    218         $injectionMap->addInjection('Session', $this->session); 
    219  
    220         stubInjectAnnotation::factory($injectionMap, $instance); 
    221         return $method->invokeArgs($instance, $params); 
     228            $this->response->writeFault($phpJsonObj->id, $e->getMessage()); 
     229        } 
    222230    } 
    223231 
     
    233241     * &id=186252 
    234242     */ 
    235     public function processGetRequest() { 
     243    public function processGetRequest() 
     244    { 
    236245        try { 
    237246            $idPattern = new stubRegexValidator(self::ID_PATTERN); 
    238247            $requestId = $this->request->getValidatedValue($idPattern, 'id'); 
    239  
    240             $classAndMethodPattern = new stubRegexValidator(self::CLASS_AND_METHOD_PATTERN); 
    241             $classAndMethod = $this->request->getValidatedValue($classAndMethodPattern, 'method'); 
    242  
    243             $params = $this->retrieveGETParams($classAndMethod); 
    244             $result = $this->invokeServiceMethod($classAndMethod, $params); 
    245             $this->sendResponse($requestId, $result); 
     248            $reflect   = $this->getClassAndMethod($this->request->getValidatedValue(new stubPassThruValidator(), 'method')); 
     249            $params    = $this->retrieveGETParams($reflect['method']); 
     250            $result    = $this->invokeServiceMethod($reflect['class'], $reflect['method'], $params); 
     251            $this->response->writeResponse($requestId, $result); 
    246252        } catch (Exception $e) { 
    247             $this->sendFault($requestId, $e->getMessage()); 
    248         } 
    249     } 
    250  
    251     /** 
    252      * Create the class object from the client class name 
    253      * 
    254      * @param string $class 
    255      * @return stubReflectionClass 
    256      */ 
    257     protected function getReflectionClass($class) { 
    258         if (!isset($this->classMap[$class])) { 
    259             throw new Exception('Unknown class ' . $class . '.'); 
    260         } 
    261         $fqClass = $this->classMap[$class]['className']; 
    262         $classObj = new stubReflectionClass($fqClass); 
    263         return $classObj; 
     253            $this->response->writeFault($requestId, $e->getMessage()); 
     254        } 
     255    } 
     256 
     257    /** 
     258     * creates the method to call 
     259     * 
     260     * @param   string  $methodName 
     261     * @return  array 
     262     * @throws  stubClassNotFoundException 
     263     * @throws  stubException 
     264     */ 
     265    protected function getClassAndMethod($methodName) 
     266    { 
     267        if (!preg_match('/'.self::CLASS_AND_METHOD_PATTERN.'/', $methodName)) { 
     268            throw new stubException('Invalid request: method-Pattern has to be <className>.<methodName>.'); 
     269        } 
     270         
     271        list($className, $methodName) = explode('.', $methodName); 
     272        if (!isset($this->classMap[$className])) { 
     273            throw new stubException('Unknown class ' . $className . '.'); 
     274        } 
     275         
     276        $clazz = new stubReflectionClass($this->classMap[$className]['className']); 
     277        if ($clazz->hasMethod($methodName) == false) { 
     278            throw new stubException('Unknown method ' . $className . '.' . $methodName . '.'); 
     279        } 
     280         
     281        $method = $clazz->getMethod($methodName); 
     282        if (!$method->hasAnnotation('WebMethod')) { 
     283            throw new stubException('Method ' . $className . '.' . $methodName . ' is no WebMethod.'); 
     284        } 
     285         
     286        return array('class' => $clazz, 'method' => $method); 
     287    } 
     288 
     289    /** 
     290     * Invoke the requested methods 
     291     * 
     292     * @param   stubReflectionMethod  $method 
     293     * @param   array                 $params 
     294     * @return  mixed 
     295     * @throws  stubClassNotFoundException 
     296     * @throws  stubException 
     297     */ 
     298    protected function invokeServiceMethod(stubReflectionClass $class, stubReflectionMethod $method, $params) 
     299    { 
     300        if ($method->getNumberOfRequiredParameters() > count($params)) { 
     301            throw new stubException('Invalid amount of parameters passed.'); 
     302        } 
     303 
     304        $instance     = $class->newInstance(); 
     305        $injectionMap = new stubInjectionMap(); 
     306        $injectionMap->addInjection('Session', $this->session); 
     307 
     308        stubInjectAnnotation::factory($injectionMap, $instance); 
     309        return $method->invokeArgs($instance, $params); 
    264310    } 
    265311 
     
    267313     * Get the parameters from the GET request 
    268314     * 
    269      * @param string $methodName 
    270      * @return array 
    271      */ 
    272     protected function retrieveGETParams($methodName) { 
    273         $paramValues = array(); 
    274  
    275         list($className, $methodName) = explode('.', $methodName); 
    276         $clazz = $this->getReflectionClass($className); 
    277         if ($clazz == null) { 
    278             throw new stubException('Unknown class ' . $className . '.'); 
    279         } 
    280  
    281         $method = $clazz->getMethod($methodName); 
    282  
     315     * @param   stubReflectionMethod  $method 
     316     * @return  array 
     317     * @throws  stubException 
     318     */ 
     319    protected function retrieveGETParams(stubReflectionMethod $method) 
     320    { 
    283321        $paramPattern = new stubRegexValidator(self::PARAM_PATTERN); 
     322        $paramValues  = array(); 
    284323        foreach ($method->getParameters() as $param) { 
    285             $paramName = $param->getName(); 
    286             $currentRequest = $this->request->getValidatedValue($paramPattern, $paramName); 
    287             if (!isset($currentRequest)) { 
     324            $paramName = $param->getName(); 
     325            $paramValue = $this->request->getValidatedValue($paramPattern, $paramName); 
     326            if (null === $paramValue) { 
    288327                throw new stubException('Param '. $paramName . ' is missing.'); 
    289328            } 
    290             array_push($paramValues, $currentRequest); 
    291         } 
     329             
     330            array_push($paramValues, $paramValue); 
     331        } 
     332         
    292333        return $paramValues; 
    293     } 
    294  
    295     /** 
    296      * Send a json fault 
    297      * 
    298      * @param string    request id 
    299      * @param string    fault message 
    300      */ 
    301     protected function sendFault($reqId, $message) { 
    302         $fault = array( 
    303                     'id'    => $reqId, 
    304                     'error' => stubEncodingHelper::recursiveUtf8Encode($message) 
    305                 ); 
    306         $faultEncoded = json_encode($fault); 
    307         $this->response->write($faultEncoded); 
    308     } 
    309  
    310     /** 
    311      * Send a json response 
    312      * 
    313      * @param string    request id 
    314      * @param string    result 
    315      */ 
    316     protected function sendResponse($reqId, $result) { 
    317         $response = array( 
    318                     'id'     => $reqId, 
    319                     'result' => stubEncodingHelper::recursiveUtf8Encode($result) 
    320                 ); 
    321         $responseEncoded = json_encode($response); 
    322         $this->response->write($responseEncoded); 
    323     } 
    324  
    325     /** 
    326      * Get the full path to the config file describing the services 
    327      * 
    328      * @return string 
    329      */ 
    330     protected function getServiceFilePath() { 
    331         $configFile = stubConfig::getConfigPath() . '/xml/' . stubRegistry::getConfig(self::KEY_SERVICE_FILE,'json-rpc-service.xml'); 
    332         if (!file_exists($configFile) || !is_readable($configFile)) { 
    333             stubClassLoader::load('net.stubbles.lang.exceptions.stubFileNotFoundException'); 
    334             throw new stubFileNotFoundException($configFile); 
    335         } 
    336         return $configFile; 
    337     } 
    338  
    339     /** 
    340      * Converts any string to Javascript code that writes 
    341      * messages to the firebug console 
    342      * 
    343      * @param string $string 
    344      * @param string $level 
    345      * @return string 
    346      */ 
    347     protected function convertStringToFirebug($string, $level = 'error') { 
    348         $result = ''; 
    349         $lines = explode("\n", $string); 
    350         foreach ($lines as $line) { 
    351             $result .= "console.{$level}('" . addslashes($line) . "');\n"; 
    352         } 
    353         return $result; 
    354334    } 
    355335} 
  • trunk/src/test/php/net/stubbles/service/ServiceTestSuite.php

    r789 r793  
    2323        $dir = dirname(__FILE__); 
    2424        $this->addTestFile($dir . '/jsonrpc/stubJsonRpcProcessorTestCase.php'); 
     25        $this->addTestFile($dir . '/jsonrpc/stubJsonRpcResponseTestCase.php'); 
    2526        $this->addTestFile($dir . '/jsonrpc/util/stubJsonRpcProxyGeneratorTestCase.php'); 
    2627    } 
  • trunk/src/test/php/net/stubbles/service/jsonrpc/stubJsonRpcProcessorTestCase.php

    r789 r793  
    1313Mock::generate('stubResponse'); 
    1414Mock::generate('stubSession'); 
    15  
    16 /** 
    17  * Extend the JSON-RPC processor to make methods accessible 
     15/** 
     16 * Test service 
    1817 * 
    1918 * @package     stubbles 
    2019 * @subpackage  service_jsonrpc_test 
    2120 */ 
    22 class stubMyJsonRpcProcessor extends stubJsonRpcProcessor 
     21class TeststubJsonRpcProcessor extends stubJsonRpcProcessor 
    2322{ 
    2423    /** 
    25      * Send a fault 
    26      * 
    27      * @param string $reqId 
    28      * @param string $message 
    29      */ 
    30     public function testSendFault($reqId, $message) { 
    31         $this->sendFault($reqId, $message); 
    32     } 
    33  
    34     /** 
    35      * Send a json response 
    36      * 
    37      * @param string    request id 
    38      * @param string    result 
    39      */ 
    40     public function testSendResponse($reqId, $result) { 
    41         $this->sendResponse($reqId, $result); 
     24     * sets the class map 
     25     * 
     26     * @param  array<string,array<string,string>>  $classMap 
     27     */ 
     28    public function setClassMap(array $classMap) 
     29    { 
     30        $this->classMap = $classMap; 
    4231    } 
    4332} 
    44  
    45 /** 
    46  * Tests for net.stubbles.service.jsonrpc.stubJsonRpcProcessor 
     33/** 
     34 * Test service 
    4735 * 
    4836 * @package     stubbles 
    4937 * @subpackage  service_jsonrpc_test 
    5038 */ 
     39class TestService extends stubBaseObject 
     40{ 
     41    /** 
     42     * test method for web service 
     43     * 
     44     * @param   int  $a 
     45     * @param   int  $b 
     46     * @return  int 
     47     * @WebMethod 
     48     */ 
     49    public function add($a, $b) 
     50    { 
     51        return ($a + $b); 
     52    } 
     53 
     54    /** 
     55     * another method that is not marked as WebMethod 
     56     * 
     57     * @param   int  $a 
     58     * @param   int  $b 
     59     * @return  int 
     60     */ 
     61    public function mod($a, $b) 
     62    { 
     63        return ($a % $b); 
     64    } 
     65} 
     66/** 
     67 * Tests for net.stubbles.service.jsonrpc.stubJsonRpcProcessor 
     68 * 
     69 * @package     stubbles 
     70 * @subpackage  service_jsonrpc_test 
     71 */ 
    5172class stubJsonRpcProcessorTestCase extends UnitTestCase 
    5273{ 
     
    7899     * mocked processor 
    79100     * 
    80      * @var  stubMyJsonRpcProcessor 
     101     * @var  TeststubJsonRpcProcessor 
    81102     */ 
    82103    protected $proc; 
     
    85106     * set up test environment 
    86107     */ 
    87     public function setUp() { 
    88         $this->mockRequest           = new MockstubRequest(); 
    89         $this->mockSession           = new MockstubSession(); 
    90         $this->mockResponse          = new MockstubResponse(); 
    91         $this->mockPageFactory       = new MockstubPageFactory(); 
    92         $this->proc                  = new stubMyJsonRpcProcessor($this->mockRequest, 
    93                                                                   $this->mockSession, 
    94                                                                   $this->mockResponse, 
    95                                                                   $this->mockPageFactory); 
    96     } 
    97  
    98     /** 
    99      * test sending a fault 
    100      */ 
    101     public function testSendFault() { 
    102         $this->mockResponse->expect('write', array('{"id":"12345","error":"Test error message."}')); 
    103         $this->proc->testSendFault('12345', 'Test error message.'); 
    104     } 
    105  
    106     /** 
    107      * test sending a response 
    108      */ 
    109     public function testSendResponse() { 
    110         $this->mockResponse->expect('write', array('{"id":"12345","result":"string"}')); 
    111         $this->proc->testSendResponse('12345', 'string'); 
    112  
    113         $this->mockResponse->expect('write', array('{"id":"12345","result":true}')); 
    114         $this->proc->testSendResponse('12345', true); 
    115  
    116         $this->mockResponse->expect('write', array('{"id":"12345","result":[1,2,3]}')); 
    117         $this->proc->testSendResponse('12345', array(1,2,3)); 
     108    public function setUp() 
     109    { 
     110        $this->mockRequest     = new MockstubRequest(); 
     111        $this->mockSession     = new MockstubSession(); 
     112        $this->mockResponse    = new MockstubResponse(); 
     113        $this->mockPageFactory = new MockstubPageFactory(); 
     114        $this->proc            = new TeststubJsonRpcProcessor($this->mockRequest, 
     115                                                              $this->mockSession, 
     116                                                              $this->mockResponse, 
     117                                                              $this->mockPageFactory 
     118                                     ); 
     119        $this->proc->setClassMap(array('Test' => array('className' => 'TestService'), 
     120                                       'Nope' => array('className' => 'DoesNotExist') 
     121                                 ) 
     122        ); 
     123    } 
     124 
     125    /** 
     126     * test processing invalid post request 
     127     */ 
     128    public function testProcessPostRequestInvalidRequest() 
     129    { 
     130        $this->mockRequest->setReturnValue('getValidatedRawData', 'invalid'); 
     131        $this->mockResponse->expect('write', array('{"id":null,"result":null,"error":"Invalid request."}')); 
     132        $this->proc->processPostRequest(); 
     133    } 
     134 
     135    /** 
     136     * test processing invalid post request 
     137     */ 
     138    public function testProcessPostRequestRequestWithoutId() 
     139    { 
     140        $this->mockRequest->setReturnValue('getValidatedRawData', '{"method":"Dummy.add","params":["2","2"]}'); 
     141        $this->mockResponse->expect('write', array('{"id":null,"result":null,"error":"Invalid request: No id given."}')); 
     142        $this->proc->processPostRequest(); 
     143    } 
     144 
     145    /** 
     146     * test processing invalid post request 
     147     */ 
     148    public function testProcessPostRequestRequestWithoutMethod() 
     149    { 
     150        $this->mockRequest->setReturnValue('getValidatedRawData', '{"params":["2","2"],"id":"1"}'); 
     151        $this->mockResponse->expect('write', array('{"id":"1","result":null,"error":"Invalid request: No method given."}')); 
     152        $this->proc->processPostRequest(); 
     153    } 
     154 
     155    /** 
     156     * test processing invalid post request 
     157     */ 
     158    public function testProcessPostRequestRequestWithoutParams() 
     159    { 
     160        $this->mockRequest->setReturnValue('getValidatedRawData', '{"method":"Dummy.add","id":"1"}'); 
     161        $this->mockResponse->expect('write', array('{"id":"1","result":null,"error":"Invalid request: No params given."}')); 
     162        $this->proc->processPostRequest(); 
     163    } 
     164 
     165    /** 
     166     * test processing invalid post request 
     167     */ 
     168    public function testProcessPostRequestRequestWithInvalidMethod() 
     169    { 
     170        $this->mockRequest->setReturnValue('getValidatedRawData', '{"method":"invalid","params":["2","2"],"id":"1"}'); 
     171        $this->mockResponse->expect('write', array('{"id":"1","result":null,"error":"Invalid request: method-Pattern has to be <className>.<methodName>."}')); 
     172        $this->proc->processPostRequest(); 
     173    } 
     174 
     175    /** 
     176     * test processing invalid post request 
     177     */ 
     178    public function testProcessPostRequestRequestWithNonExistingClass() 
     179    { 
     180        $this->mockRequest->setReturnValue('getValidatedRawData', '{"method":"DoesNotExist.add","params":["2","2"],"id":"1"}'); 
     181        $this->mockResponse->expect('write', array('{"id":"1","result":null,"error":"Unknown class DoesNotExist."}')); 
     182        $this->proc->processPostRequest(); 
     183    } 
     184 
     185    /** 
     186     * test processing invalid post request 
     187     */ 
     188    public function testProcessPostRequestRequestWithMissingClass() 
     189    { 
     190        $this->mockRequest->setReturnValue('getValidatedRawData', '{"method":"Nope.add","params":["2","2"],"id":"1"}'); 
     191        $this->mockResponse->expect('write', array('{"id":"1","result":null,"error":"Class DoesNotExist does not exist"}')); 
     192        $this->proc->processPostRequest(); 
     193    } 
     194 
     195    /** 
     196     * test processing invalid post request 
     197     */ 
     198    public function testProcessPostRequestRequestWithUnknownMethod() 
     199    { 
     200        $this->mockRequest->setReturnValue('getValidatedRawData', '{"method":"Test.sub","params":["2","2"],"id":"1"}'); 
     201        $this->mockResponse->expect('write', array('{"id":"1","result":null,"error":"Unknown method Test.sub."}')); 
     202        $this->proc->processPostRequest(); 
     203    } 
     204 
     205    /** 
     206     * test processing invalid post request 
     207     */ 
     208    public function testProcessPostRequestRequestWithNoWebMethod() 
     209    { 
     210        $this->mockRequest->setReturnValue('getValidatedRawData', '{"method":"Test.mod","params":["2","2"],"id":"1"}'); 
     211        $this->mockResponse->expect('write', array('{"id":"1","result":null,"error":"Method Test.mod is no WebMethod."}')); 
     212        $this->proc->processPostRequest(); 
     213    } 
     214 
     215    /** 
     216     * test processing invalid post request: to less params triggers error, too much params are ignored 
     217     */ 
     218    public function testProcessPostRequestRequestWithInvalidAmountOfParams() 
     219    { 
     220        $this->mockRequest->setReturnValueAt(0, 'getValidatedRawData', '{"method":"Test.add","params":["2"],"id":"1"}'); 
     221        $this->mockRequest->setReturnValueAt(1, 'getValidatedRawData', '{"method":"Test.add","params":["2","2","2"],"id":"1"}'); 
     222        $this->mockResponse->expectAt(0, 'write', array('{"id":"1","result":null,"error":"Invalid amount of parameters passed."}')); 
     223        $this->mockResponse->expectAt(1, 'write', array('{"id":"1","result":4,"error":null}')); 
     224        $this->proc->processPostRequest(); 
     225        $this->proc->processPostRequest(); 
     226    } 
     227 
     228    /** 
     229     * test processing correct post request 
     230     */ 
     231    public function testProcessPostRequestRequest() 
     232    { 
     233        $this->mockRequest->setReturnValue('getValidatedRawData', '{"method":"Test.add","params":["2","2"],"id":"1"}'); 
     234        $this->mockResponse->expect('write', array('{"id":"1","result":4,"error":null}')); 
     235        $this->proc->processPostRequest(); 
    118236    } 
    119237}