diff --git a/build/api/core/Request.php b/build/api/core/Request.php index 8a066a6..588409c 100644 --- a/build/api/core/Request.php +++ b/build/api/core/Request.php @@ -544,43 +544,39 @@ if( !is_array($paramsdata) ) return $this->error->set(Err::ConfigError); + /* (3) So @paramsdata['type] manquant ou incorrect */ + if( !isset($paramsdata['type']) || !is_string($paramsdata['type']) ) + return $this->error->set(Err::ConfigError); + /* (2) Gestion des spécifications ---------------------------------------------------------*/ /* (1) On récupère si le paramètre est optionnel ou pas */ $optional = isset($paramsdata['optional']) && $paramsdata['optional'] === true; - /* (2) Récupère si le paramètre est un fichier et définit comme de type 'FILE' */ - $isFile = isset($paramsdata['type']) && $paramsdata['type'] == 'FILE' && isset($_FILES[$name]); + /* (2) Si de type 'FILE' + fichier existe => on enregistre la ref. */ + if( $paramsdata['type'] == 'FILE' && isset($_FILES[$name]) ) + $params[$name] = &$_FILES[$name]; - /* (3) Si le paramètre est obligatoire et qu'il n'est pas donné -> erreur */ - if( !isset($params[$name]) && !$optional && !$isFile ) + /* (3) Si param obligatoire et manquant -> erreur */ + if( !isset($params[$name]) && !$optional ) return $this->error->set(Err::MissingParam, $name); - /* (4) Si le type n'est pas defini, on a pas besoin de le vérifier */ - if( !isset($paramsdata['type']) ) - continue; - /* (5) Si le paramètre est optionnel et n'est pas donné */ - if( $isFile || $optional && (!isset($params[$name]) || is_null($params[$name])) ){ + /* (3) Gestion des valeurs + ---------------------------------------------------------*/ + /* (1) Si le paramètre est optionnel et manquant */ + if( $optional && !isset($params[$name]) ){ + // On le crée le param optionnel avec la valeur NULL $params[$name] = null; - // On donne une référence vers le fichier, si c'en est un - if( $isFile ) - $params[$name] = &$_FILES[$name]; - - continue; // On passe au paramètre suivant - - - /* (6) Si le paramètre est renseigné */ - }else{ + /* (2) Si le paramètre est renseigné (sauf FILE) */ + }elseif( $paramsdata['type'] != 'FILE'){ // Si la verification est fausse, on retourne faux - if( !Checker::run($paramsdata['type'], $params[$name]) ){ - $this->error->set(Err::WrongParam, $name, $paramsdata['type']); - return false; - } + if( !Checker::run($paramsdata['type'], $params[$name]) ) + return $this->error->set(Err::WrongParam, $name, $paramsdata['type']); } diff --git a/spec/build/api/core/RequestSpec.php b/spec/build/api/core/RequestSpec.php index 0d5f700..431aedc 100644 --- a/spec/build/api/core/RequestSpec.php +++ b/spec/build/api/core/RequestSpec.php @@ -4,6 +4,7 @@ use Kahlan\Plugin\Monkey; use api\core\Request; + use api\core\Checker; use api\core\AuthSystem; use api\core\AuthSystemDefault; use error\core\Error; @@ -533,7 +534,309 @@ }); - //TODO: blabla + it('fail if one \'parameters\' have no \'type\' clause', function(){ + + // bypass checkers + allow(Request::class)->toReceive('checkPermission')->andReturn(true); + allow(Request::class)->toReceive('buildOptions')->andReturn(true); + + allow('json_decode')->toBeCalled()->andReturn([ + 'moduleA' => [ + 'POST::methodA' => [ + 'parameters' => [ + 'paramName' => [ + 'optional' => false + ] + ] + ] + ] + ]); + + $req = new Request('moduleA/methodA'); + expect($req->error->get())->toBe(Err::ConfigError); + + }); + + it('fail if one \'parameters\' have incorrect \'type\' clause', function(){ + + // bypass checkers + allow(Request::class)->toReceive('checkPermission')->andReturn(true); + allow(Request::class)->toReceive('buildOptions')->andReturn(true); + + allow('json_decode')->toBeCalled()->andReturn([ + 'moduleA' => [ + 'POST::methodA' => [ + 'parameters' => [ + 'paramName' => [ + 'optional' => false, + 'type' => 12 + ] + ] + ] + ] + ]); + + $req = new Request('moduleA/methodA'); + expect($req->error->get())->toBe(Err::ConfigError); + + }); + + it('pass if missing optional parameter -> set to null by default', function(){ + + // bypass checkers + allow(Request::class)->toReceive('checkPermission')->andReturn(true); + allow(Request::class)->toReceive('buildOptions')->andReturn(true); + + // check param is now null + allow(Request::class)->toReceive('dispatch')->andRun(function(){ + return $this->params; + }); + + allow('json_decode')->toBeCalled()->andReturn([ + 'moduleA' => [ + 'POST::methodA' => [ + 'parameters' => [ + 'paramName' => [ + 'optional' => true, + 'type' => 'text' + ] + ] + ] + ] + ]); + + $req = new Request('moduleA/methodA'); + expect($req->error->get())->toBe(Err::Success); + + // check param created with 'null' value + $params = $req->dispatch(); + expect($params)->toContainKey('paramName'); + expect($params['paramName'])->toBeNull(); + + }); + + it('fail if optional param wrong type ', function(){ + + // bypass checkers + allow(Request::class)->toReceive('checkPermission')->andReturn(true); + allow(Request::class)->toReceive('buildOptions')->andReturn(true); + + allow('json_decode')->toBeCalled()->andReturn([ + 'moduleA' => [ + 'POST::methodA' => [ + 'parameters' => [ + 'paramName' => [ + 'optional' => true, + 'type' => 'id' + ] + ] + ] + ] + ]); + + expect(Checker::class)->toReceive('::run')->with('id', 'bla'); + $req = new Request('moduleA/methodA', ['paramName' => 'bla']); + expect($req->error->get())->toBe(Err::WrongParam); + + }); + + it('pass if optional param matching type ', function(){ + + // bypass checkers + allow(Request::class)->toReceive('checkPermission')->andReturn(true); + allow(Request::class)->toReceive('buildOptions')->andReturn(true); + + allow('json_decode')->toBeCalled()->andReturn([ + 'moduleA' => [ + 'POST::methodA' => [ + 'parameters' => [ + 'paramName' => [ + 'optional' => true, + 'type' => 'id' + ] + ] + ] + ] + ]); + + expect(Checker::class)->toReceive('::run')->with('id', '12'); + $req = new Request('moduleA/methodA', ['paramName' => '12']); + expect($req->error->get())->toBe(Err::Success); + + }); + + it('fail if required param missing ', function(){ + + // bypass checkers + allow(Request::class)->toReceive('checkPermission')->andReturn(true); + allow(Request::class)->toReceive('buildOptions')->andReturn(true); + + allow('json_decode')->toBeCalled()->andReturn([ + 'moduleA' => [ + 'POST::methodA' => [ + 'parameters' => [ + 'paramName' => [ + 'optional' => false, + 'type' => 'id' + ] + ] + ] + ] + ]); + + $req = new Request('moduleA/methodA', []); + expect($req->error->get())->toBe(Err::MissingParam); + + }); + + it('fail if required param wrong type ', function(){ + + // bypass checkers + allow(Request::class)->toReceive('checkPermission')->andReturn(true); + allow(Request::class)->toReceive('buildOptions')->andReturn(true); + + allow('json_decode')->toBeCalled()->andReturn([ + 'moduleA' => [ + 'POST::methodA' => [ + 'parameters' => [ + 'paramName' => [ + 'optional' => false, + 'type' => 'id' + ] + ] + ] + ] + ]); + + expect(Checker::class)->toReceive('::run')->with('id', 'bla'); + $req = new Request('moduleA/methodA', ['paramName' => 'bla']); + expect($req->error->get())->toBe(Err::WrongParam); + + }); + + it('pass if required param matching type ', function(){ + + // bypass checkers + allow(Request::class)->toReceive('checkPermission')->andReturn(true); + allow(Request::class)->toReceive('buildOptions')->andReturn(true); + + allow('json_decode')->toBeCalled()->andReturn([ + 'moduleA' => [ + 'POST::methodA' => [ + 'parameters' => [ + 'paramName' => [ + 'optional' => false, + 'type' => 'id' + ] + ] + ] + ] + ]); + + expect(Checker::class)->toReceive('::run')->with('id', '12'); + $req = new Request('moduleA/methodA', ['paramName' => '12']); + expect($req->error->get())->toBe(Err::Success); + + }); + + it('fail if FILE param required + file does not exist', function(){ + + // bypass checkers + allow(Request::class)->toReceive('checkPermission')->andReturn(true); + allow(Request::class)->toReceive('buildOptions')->andReturn(true); + + // check param is now null + allow(Request::class)->toReceive('dispatch')->andRun(function(){ + return $this->params; + }); + + allow('json_decode')->toBeCalled()->andReturn([ + 'moduleA' => [ + 'POST::methodA' => [ + 'parameters' => [ + 'paramName' => [ + 'type' => 'FILE' + ] + ] + ] + ] + ]); + + $_FILES = []; + $req = new Request('moduleA/methodA'); + expect($req->error->get())->toBe(Err::MissingParam); + + }); + + it('pass if FILE param required + file exists -> create ref', function(){ + + // bypass checkers + allow(Request::class)->toReceive('checkPermission')->andReturn(true); + allow(Request::class)->toReceive('buildOptions')->andReturn(true); + + // check param is now null + allow(Request::class)->toReceive('dispatch')->andRun(function(){ + return $this->params; + }); + + allow('json_decode')->toBeCalled()->andReturn([ + 'moduleA' => [ + 'POST::methodA' => [ + 'parameters' => [ + 'paramName' => [ + 'type' => 'FILE' + ] + ] + ] + ] + ]); + + $_FILES = [ 'paramName' => 'some_file_value' ]; + $req = new Request('moduleA/methodA'); + expect($req->error->get())->toBe(Err::Success); + + // check param created with 'null' value + $params = $req->dispatch(); + expect($params)->toContainKey('paramName'); + expect($params['paramName'])->toBe('some_file_value'); + + }); + + it('pass if FILE optional param missing -> null', function(){ + + // bypass checkers + allow(Request::class)->toReceive('checkPermission')->andReturn(true); + allow(Request::class)->toReceive('buildOptions')->andReturn(true); + + // check param is now null + allow(Request::class)->toReceive('dispatch')->andRun(function(){ + return $this->params; + }); + + allow('json_decode')->toBeCalled()->andReturn([ + 'moduleA' => [ + 'POST::methodA' => [ + 'parameters' => [ + 'paramName' => [ + 'optional' => true, + 'type' => 'FILE' + ] + ] + ] + ] + ]); + + $_FILES = [ ]; + $req = new Request('moduleA/methodA'); + expect($req->error->get())->toBe(Err::Success); + + // check param created with 'null' value + $params = $req->dispatch(); + expect($params)->toContainKey('paramName'); + expect($params['paramName'])->toBeNull(); + + }); + });