From f9806aadb5b76bbe69c1b5b8a755ece7d8acbafa Mon Sep 17 00:00:00 2001 From: Xenofon Spafaridis Date: Tue, 7 Jun 2016 17:48:52 +0300 Subject: [PATCH] Use PSR-7 request interfaces --- composer.json | 6 +- src/Controller/Controller.php | 15 +- src/Controller/Delete.php | 62 +++++ src/Controller/Get.php | 3 +- src/Controller/GetById.php | 9 +- src/Controller/Patch.php | 5 +- src/Controller/Post.php | 5 +- src/Controller/Put.php | 62 +++++ src/Controller/Relationship.php | 27 +++ src/Directive/AdditionalParameter.php | 3 +- .../AdditionalRelationshipsParameter.php | 3 +- src/Directive/Directive.php | 9 +- src/Directive/Fields.php | 38 ++-- src/Directive/Filter.php | 55 ++--- src/Directive/IncludeResources.php | 9 +- src/Directive/Page.php | 30 +-- src/Directive/Sort.php | 35 +-- src/Model/Relationships.php | 10 +- src/Resource.php | 6 +- tests/APP/Bootstrap.php | 10 +- tests/APP/Models/Article.php | 6 +- tests/src/Controller/ControllerTest.php | 2 +- tests/src/Controller/GetByIdTest.php | 30 +++ tests/src/Directive/FieldsTest.php | 91 ++++---- tests/src/Directive/FilterTest.php | 215 +++++++++--------- tests/src/Directive/PageTest.php | 79 ++++--- tests/src/Directive/SortTest.php | 175 ++++++++++++++ tests/src/RelationshipTest.php | 6 +- 28 files changed, 676 insertions(+), 330 deletions(-) create mode 100644 src/Controller/Delete.php create mode 100644 src/Controller/Put.php create mode 100644 src/Controller/Relationship.php create mode 100644 tests/src/Controller/GetByIdTest.php create mode 100644 tests/src/Directive/SortTest.php diff --git a/composer.json b/composer.json index 00e90b6..05cbbb9 100644 --- a/composer.json +++ b/composer.json @@ -14,14 +14,16 @@ "require": { "php": ">=7", "phramework/phramework": "dev-dev-2.x", - "ext-json": "*" + "ext-json": "*", + "psr/http-message": "^1.0" }, "require-dev": { "squizlabs/php_codesniffer": "*", "phpunit/phpunit": "5.*", "phpdocumentor/phpdocumentor": "2.9", "satooshi/php-coveralls": "dev-master", - "codacy/coverage": "^1.0" + "codacy/coverage": "^1.0", + "zendframework/zend-diactoros": "^1.3" }, "minimum-stability": "dev", "prefer-stable": true, diff --git a/src/Controller/Controller.php b/src/Controller/Controller.php index 5625051..af9a40c 100644 --- a/src/Controller/Controller.php +++ b/src/Controller/Controller.php @@ -20,6 +20,7 @@ use Phramework\JSONAPI\InternalModel; use Phramework\JSONAPI\RelationshipResource; use Phramework\JSONAPI\Resource; +use Psr\Http\Message\ServerRequestInterface; /** * @license https://www.apache.org/licenses/LICENSE-2.0 Apache-2.0 @@ -46,7 +47,7 @@ protected static function getById( } protected static function includeRelationshipResources( - \stdClass $request, + ServerRequestInterface $request, InternalModel $model, array $resources, Directive ...$directives @@ -129,7 +130,7 @@ public static function viewData( return true; } - + /** * @param string[] $classes * @param Directive[] $directives @@ -155,7 +156,7 @@ public static function getByClasses( /** * @param string[] $classes * @param InternalModel $model - * @param \stdClass $request + * @param ServerRequestInterface $request * @param Directive[] $directives * @param bool $ignoreIfExists * @param bool $overwrite @@ -164,7 +165,7 @@ public static function getByClasses( public static function parseDirectives( array $classes, InternalModel $model, - \stdClass $request, + ServerRequestInterface $request, array $directives, bool $ignoreIfExists = true, bool $overwrite = false @@ -193,9 +194,9 @@ function ($d) { $overwrite && ( $key = array_search( - $directiveClass, - $existClasses, - true + $directiveClass, + $existClasses, + true ) !== false) ) { $directives[$key] = $parsed; diff --git a/src/Controller/Delete.php b/src/Controller/Delete.php new file mode 100644 index 0000000..1fb0b8d --- /dev/null +++ b/src/Controller/Delete.php @@ -0,0 +1,62 @@ + + * @since 3.0.0 + */ +trait Delete +{ + use Controller; + use RequestBodyQueue; + + //prototype + public static function handleDelete( + ServerRequestInterface $request, + InternalModel $model, + string $id, + array $validationCallbacks = [], + callable $viewCallback = null, + int $bulkLimit = null, + array $directives + ) { + //gather data as a queue + + //check bulk limit + + //on each validate + + //prefer PATCH validation model + $validationModel = $model->getValidationModel( + 'DELETE' + ); + + //check if exists + + //on each call validation callback + + //204 or view callback + } +} \ No newline at end of file diff --git a/src/Controller/Get.php b/src/Controller/Get.php index 213c5b7..6ae581a 100644 --- a/src/Controller/Get.php +++ b/src/Controller/Get.php @@ -23,6 +23,7 @@ use Phramework\JSONAPI\Directive\Page; use Phramework\JSONAPI\Directive\Sort; use Phramework\JSONAPI\InternalModel; +use Psr\Http\Message\ServerRequestInterface; /** * @license https://www.apache.org/licenses/LICENSE-2.0 Apache-2.0 @@ -34,7 +35,7 @@ trait Get use Controller; public static function handleGet( - \stdClass $request, + ServerRequestInterface $request, InternalModel $model, array $directives ) { diff --git a/src/Controller/GetById.php b/src/Controller/GetById.php index f4bece3..c244ba2 100644 --- a/src/Controller/GetById.php +++ b/src/Controller/GetById.php @@ -23,6 +23,7 @@ use Phramework\JSONAPI\Directive\Filter; use Phramework\JSONAPI\Directive\Directive; use Phramework\JSONAPI\InternalModel; +use Psr\Http\Message\ServerRequestInterface; /** * @license https://www.apache.org/licenses/LICENSE-2.0 Apache-2.0 @@ -34,14 +35,14 @@ trait GetById use Controller; /** - * @param \stdClass $request - * @param string $id - * @param InternalModel $model + * @param ServerRequestInterface $request + * @param string $id + * @param InternalModel $model * @param Directive[] $directives * @throws \Phramework\Exceptions\NotFoundException */ public static function handleGetById( - \stdClass $request, + ServerRequestInterface $request, string $id, InternalModel $model, array $directives diff --git a/src/Controller/Patch.php b/src/Controller/Patch.php index 42553a3..b28c05e 100644 --- a/src/Controller/Patch.php +++ b/src/Controller/Patch.php @@ -20,6 +20,7 @@ use Phramework\JSONAPI\Directive\Directive; use Phramework\JSONAPI\InternalModel; use Phramework\Phramework; +use Psr\Http\Message\ServerRequestInterface; /** * @license https://www.apache.org/licenses/LICENSE-2.0 Apache-2.0 @@ -33,7 +34,7 @@ trait Patch //prototype public static function handlePatch( - \stdClass $request, + ServerRequestInterface $request, InternalModel $model, string $id, array $validationCallbacks = [], @@ -49,7 +50,7 @@ public static function handlePatch( //prefer PATCH validation model $validationModel = $model->getValidationModel( - Phramework::METHOD_PATCH + 'PATCH' ); //check if exists diff --git a/src/Controller/Post.php b/src/Controller/Post.php index 59fa864..c6c6156 100644 --- a/src/Controller/Post.php +++ b/src/Controller/Post.php @@ -20,6 +20,7 @@ use Phramework\JSONAPI\Directive\Directive; use Phramework\JSONAPI\InternalModel; use Phramework\Phramework; +use Psr\Http\Message\ServerRequestInterface; /** * @license https://www.apache.org/licenses/LICENSE-2.0 Apache-2.0 @@ -33,7 +34,7 @@ trait Post //prototype public static function handlePost( - \stdClass $request, + ServerRequestInterface $request, InternalModel $model, array $validationCallbacks = [], callable $viewCallback = null, @@ -48,7 +49,7 @@ public static function handlePost( //prefer POST validation model $validationModel = $model->getValidationModel( - Phramework::METHOD_POST + 'POST' ); //on each call validation callback diff --git a/src/Controller/Put.php b/src/Controller/Put.php new file mode 100644 index 0000000..20ad9d4 --- /dev/null +++ b/src/Controller/Put.php @@ -0,0 +1,62 @@ + + * @since 3.0.0 + */ +trait Put +{ + use Controller; + use RequestBodyQueue; + + //prototype + public static function handlePut( + ServerRequestInterface $request, + InternalModel $model, + string $id, + array $validationCallbacks = [], + callable $viewCallback = null, + int $bulkLimit = null, + array $directives + ) { + //gather data as a queue + + //check bulk limit + + //on each validate + + //prefer PATCH validation model + $validationModel = $model->getValidationModel( + Phramework::METHOD_PUT + ); + + //check if exists + + //on each call validation callback + + //204 or view callback + } +} \ No newline at end of file diff --git a/src/Controller/Relationship.php b/src/Controller/Relationship.php new file mode 100644 index 0000000..c3d45c8 --- /dev/null +++ b/src/Controller/Relationship.php @@ -0,0 +1,27 @@ + + * @since 3.0.0 + */ +trait Relationship +{ + +} \ No newline at end of file diff --git a/src/Directive/AdditionalParameter.php b/src/Directive/AdditionalParameter.php index 68f80bd..4f6c864 100644 --- a/src/Directive/AdditionalParameter.php +++ b/src/Directive/AdditionalParameter.php @@ -17,6 +17,7 @@ namespace Phramework\JSONAPI\Directive; use Phramework\JSONAPI\InternalModel; +use Psr\Http\Message\ServerRequestInterface; /** * @license https://www.apache.org/licenses/LICENSE-2.0 Apache-2.0 @@ -64,7 +65,7 @@ public function validate(InternalModel $model) : bool } public static function parseFromRequest( - \stdClass $request, + ServerRequestInterface $request, InternalModel $model ) { return null; diff --git a/src/Directive/AdditionalRelationshipsParameter.php b/src/Directive/AdditionalRelationshipsParameter.php index 176a246..33c2162 100644 --- a/src/Directive/AdditionalRelationshipsParameter.php +++ b/src/Directive/AdditionalRelationshipsParameter.php @@ -17,6 +17,7 @@ namespace Phramework\JSONAPI\Directive; use Phramework\JSONAPI\InternalModel; +use Psr\Http\Message\ServerRequestInterface; /** * @license https://www.apache.org/licenses/LICENSE-2.0 Apache-2.0 @@ -81,7 +82,7 @@ public function validate(InternalModel $model) : bool * @inheritDoc */ public static function parseFromRequest( - \stdClass $request, + ServerRequestInterface $request, InternalModel $model ) { return null; diff --git a/src/Directive/Directive.php b/src/Directive/Directive.php index ab4ae2c..6533853 100644 --- a/src/Directive/Directive.php +++ b/src/Directive/Directive.php @@ -17,6 +17,7 @@ namespace Phramework\JSONAPI\Directive; use Phramework\JSONAPI\InternalModel; +use Psr\Http\Message\ServerRequestInterface; /** * @license https://www.apache.org/licenses/LICENSE-2.0 Apache-2.0 @@ -29,12 +30,12 @@ abstract public function validate(InternalModel $model) : bool; /** * @todo define request object in phramework - * @param \stdClass $request - * @param InternalModel $model - * @return Directive|null + * @param ServerRequestInterface $request + * @param InternalModel $model + * @return null|Directive */ abstract public static function parseFromRequest( - \stdClass $request, + ServerRequestInterface $request, InternalModel $model ); diff --git a/src/Directive/Fields.php b/src/Directive/Fields.php index a2aeaf3..08c46b2 100644 --- a/src/Directive/Fields.php +++ b/src/Directive/Fields.php @@ -23,6 +23,7 @@ use Phramework\Exceptions\Source\Parameter; use Phramework\JSONAPI\InternalModel; use Phramework\Util\Util; +use Psr\Http\Message\ServerRequestInterface; /** * Fields helper methods @@ -123,40 +124,29 @@ public function validate(InternalModel $model) : bool } /** - * @param \stdClass $parameters Request parameters - * @param InternalModel $model Primary model class - * @return Fields|null - * @throws RequestException - * @throws IncorrectParametersException - * @example - * ```php - * $fields = Fields::parseFromParameters( - * (object) [ - * 'fields' => [ - * 'article' => ['title', updated'], - * 'tag' => ['title'] - * ] - * ], //Request parameters object - * Article::getModel() - * ); - * ``` + * @param ServerRequestInterface $request Request parameters + * @param InternalModel $model Primary model class + * @return Sort|null + * @throws IncorrectParameterException * @uses Model::getFields for each resource type to parse allowed fields */ public static function parseFromRequest( - \stdClass $parameters, + ServerRequestInterface $request, InternalModel $model ) { - if (!isset($parameters->fields)) { + $param = $request->getQueryParams()['fields'] ?? null; + + if (empty($param)) { return null; } $fields = new Fields(); - if (!is_object($parameters->fields) + if (!is_object($param) && ( - !is_array($parameters->fields) - || (is_array($parameters->fields) - && !Util::isArrayAssoc($parameters->fields) + !is_array($param) + || (is_array($param) + && !Util::isArrayAssoc($param) ) ) ) { @@ -167,7 +157,7 @@ public static function parseFromRequest( ); } - foreach ($parameters->fields as $resourceType => $value) { + foreach ($param as $resourceType => $value) { if ($model->getResourceType() === $resourceType) { //check if $resourceType allowed (primary) $resourceModel = $model; diff --git a/src/Directive/Filter.php b/src/Directive/Filter.php index f9b5dfc..eebb530 100644 --- a/src/Directive/Filter.php +++ b/src/Directive/Filter.php @@ -25,6 +25,7 @@ use Phramework\Util\Util; use Phramework\Validate\StringValidator; use Phramework\Validate\UnsignedIntegerValidator; +use Psr\Http\Message\ServerRequestInterface; /** * Filter helper methods @@ -307,53 +308,24 @@ public function validate(InternalModel $model) : bool } /** - * @param \stdClass $parameters Request parameters - * @param InternalModel $model - * @return Filter|null + * @param ServerRequestInterface $request Request parameters + * @param InternalModel $model + * @return null|Filter + * @throws IncorrectParameterException + * @throws RequestException * @todo allow strings and integers as id * @todo Todo use filterValidation model for relationships * @todo allowed operator for JSON properties - * @example - * ```php - * $filter = Filter::parseFromParameters( - * (object) [ - * 'filter' => [ - * 'article' => '1, 2', //primary filter (parsed from URL's ?filter[article]=1, 2) - * 'tag' => '4, 5,7', //relationship filter (parsed from URL's ?filter[tag]=4, 5,7) - * 'creator' => '1', //relationship filter(parsed from URL's ?filter[creator]=1) - * 'status' => ['ENABLED', 'INACTIVE'], //multiple filters - * 'title' => [ - * Operator::OPERATOR_LIKE . 'blog', - * Operator::OPERATOR_NOT_LIKE . 'welcome' - * ], //multiple filters on title (parsed from URL's ?filter[title][]=~~blog&filter[title][]=!~~welcome) - * 'updated' => Operator::OPERATOR_NOT_ISNULL, - * 'meta.keywords' => 'blog' //JSON attribute filter - * ] - * ], //Request parameters object - * Article::class - * ); - * ``` - * @example - * ```php - * $filter = Filter::parseFromParameters( - * (object) [ - * 'filter' => [ - * 'tag' => Operator::OPERATOR_EMPTY - * ] - * ], - * Article::class - * ); - * @throws RequestException - * @throws \Exception - * @throws IncorrectParametersException * @todo add support for operators of class in, parsing input using explode `,` (as array) * @todo fix definition for version 3.x */ public static function parseFromRequest( - \stdClass $parameters, + ServerRequestInterface $request, InternalModel $model ) { - if (!isset($parameters->filter)) { + $param = $request->getQueryParams()['filter'] ?? null; + + if (empty($param)) { return null; } @@ -364,7 +336,7 @@ public static function parseFromRequest( $filterRelationships = new \stdClass(); $filterAttributes = []; - foreach ($parameters->filter as $filterKey => $filterValue) { + foreach ($param as $filterKey => $filterValue) { if ($filterKey === $model->getResourceType()) { //Filter primary data //Check filter value type if (!is_string($filterValue) && !is_int($filterValue)) { @@ -462,7 +434,10 @@ public static function parseFromRequest( * ); * ``` */ - public static function merge(Filter $first = null, Filter $second = null) { + public static function merge( + Filter $first = null, + Filter $second = null + ) { //Initialize if null if ($first === null) { $first = new Filter(); diff --git a/src/Directive/IncludeResources.php b/src/Directive/IncludeResources.php index 9f4b3fe..40844f8 100644 --- a/src/Directive/IncludeResources.php +++ b/src/Directive/IncludeResources.php @@ -17,6 +17,7 @@ namespace Phramework\JSONAPI\Directive; use Phramework\JSONAPI\InternalModel; +use Psr\Http\Message\ServerRequestInterface; /** * @license https://www.apache.org/licenses/LICENSE-2.0 Apache-2.0 @@ -69,18 +70,20 @@ public function validate(InternalModel $model) : bool * todo use include by default class defined in mode's relationships */ public static function parseFromRequest( - \stdClass $request, + ServerRequestInterface $request, InternalModel $model ) { - if (!isset($request->include) || empty($request->include)) { + $param = $request->getQueryParams()['include'] ?? null; + + if (empty($param)) { return null; } $include = []; //split parameter using , (for multiple values) - foreach (explode(',', $request->include) as $i) { + foreach (explode(',', $param) as $i) { $include[] = trim($i); } diff --git a/src/Directive/Page.php b/src/Directive/Page.php index 88eb49c..021ab66 100644 --- a/src/Directive/Page.php +++ b/src/Directive/Page.php @@ -21,6 +21,7 @@ use Phramework\Exceptions\Source\Parameter; use Phramework\JSONAPI\InternalModel; use Phramework\Validate\UnsignedIntegerValidator; +use Psr\Http\Message\ServerRequestInterface; /** * Page directive, allows pagination @@ -70,43 +71,44 @@ public function validate(InternalModel $model) : bool } /** - * @param \stdClass $parameters Request parameters - * @return Page|null - * @throws IncorrectParameterException When limit or offset are incorrect - * @throws IncorrectParameterException When limit exceeds model's maximum page limit + * @param ServerRequestInterface $request + * @param InternalModel $model + * @return null|Page + * @throws \Exception|null|\Phramework\Validate\Result\Exception * @todo use request instead of parameters * @uses InternalModel::getMaxPageLimit */ public static function parseFromRequest( - \stdClass $parameters, + ServerRequestInterface $request, InternalModel $model ) { - if (!isset($parameters->page)) { + $param = $request->getQueryParams()['page'] ?? null; + + if (empty($param)) { return null; } $limit = null; - $offset = 0; //Work with objects - if (is_array($parameters->page)) { - $parameters->page = (object) $parameters->page; - } + /*if (is_array($request->page)) { + $request->page = (object) $request->page; + }*/ - if (isset($parameters->page->limit)) { + if (isset($param['limit'])) { $limit = (new UnsignedIntegerValidator( 1, $model->getMaxPageLimit() )) ->setSource(new Parameter('page[limit]')) - ->parse($parameters->page->limit); + ->parse($param['limit']); } - if (isset($parameters->page->offset)) { + if (isset($param['offset'])) { $offset = (new UnsignedIntegerValidator()) ->setSource(new Parameter('page[offset]')) - ->parse($parameters->page->offset); + ->parse($param['offset']); } return new Page($limit, $offset); diff --git a/src/Directive/Sort.php b/src/Directive/Sort.php index a6b70fc..de71f61 100644 --- a/src/Directive/Sort.php +++ b/src/Directive/Sort.php @@ -18,6 +18,7 @@ use Phramework\Exceptions\RequestException; use Phramework\JSONAPI\InternalModel; +use Psr\Http\Message\ServerRequestInterface; /** * Sort helper methods @@ -61,32 +62,32 @@ public function validate(InternalModel $model) : bool } /** - * @param object $parameters Request parameters - * @param string $model - * @return Sort - * ```php - * $sort = Sort::parseFromParameters( - * (object) [ - * 'sort' => '-updated' - * ], //Request parameters object - * Article::class - * ); - * ``` + * @param ServerRequestInterface $request Request parameters + * @param InternalModel|string $model + * @return Sort|null * @throws RequestException */ - public static function parseFromRequest(\stdClass $parameters, InternalModel $model) - { - $sortableAttributes = $model->getSortableAttributes(); + public static function parseFromRequest( + ServerRequestInterface $request, + InternalModel $model + ) { + $param = $request->getQueryParams()['sort'] ?? null; + + if (empty($param)) { + return null; + } //Don't accept arrays - if (isset($parameters->sort)) { - if (!is_string($parameters->sort)) { + if (isset($param)) { + if (!is_string($param)) { throw new RequestException( 'String expected for sort' ); } + $sortableAttributes = $model->getSortableAttributes(); + if (empty($sortableAttributes)) { throw new RequestException('Not sortable attributes for this resource model'); } @@ -101,7 +102,7 @@ public static function parseFromRequest(\stdClass $parameters, InternalModel $mo )) ); - if (!!preg_match($validateExpression, $parameters->sort, $matches)) { + if (!!preg_match($validateExpression, $param, $matches)) { return new Sort( $matches['attribute'], ( diff --git a/src/Model/Relationships.php b/src/Model/Relationships.php index 3d339b3..5132e99 100644 --- a/src/Model/Relationships.php +++ b/src/Model/Relationships.php @@ -126,15 +126,19 @@ public static function getRelationshipData( ); case \Phramework\JSONAPI\Relationship::TYPE_TO_MANY: default: - if (!isset($relationship->getCallbacks()->{Phramework::METHOD_GET})) { + if (!isset($relationship->getCallbacks()->{'GET'})) { return []; } - $callMethod = $relationship->getCallbacks()->{Phramework::METHOD_GET}; + $callMethod = $relationship->getCallbacks()->{'GET'}; if (!is_callable($callMethod)) { throw new \Phramework\Exceptions\ServerException( - $callMethod[0] . '::' . $callMethod[1] + (//todo + is_array($callMethod[0] . '::' . $callMethod[1]) + ? $callMethod[0] . '::' . $callMethod[1] + : 'Callable' + ) . ' is not implemented' ); } diff --git a/src/Resource.php b/src/Resource.php index dd54f46..1c6bebc 100644 --- a/src/Resource.php +++ b/src/Resource.php @@ -321,7 +321,7 @@ public static function parseFromRecord( $directives, $flags ) { - return $relationshipObject->callbacks->{Phramework::METHOD_GET}( + return $relationshipObject->callbacks->{'GET'}( $resource->id, $directives, $flags // use $flagRelationshipsAttributes to enable/disable parsing of relationship attributes @@ -335,7 +335,7 @@ public static function parseFromRecord( if (isset($record->{$recordDataAttribute}) && $record->{$recordDataAttribute}) { //preloaded $relationshipEntryResource = $record->{$recordDataAttribute}; - } elseif (isset($relationshipObject->callbacks->{Phramework::METHOD_GET})) { //available from callback + } elseif (isset($relationshipObject->callbacks->{'GET'})) { //available from callback $relationshipEntryResource = $dataCallback(); } @@ -367,7 +367,7 @@ public static function parseFromRecord( if (isset($record->{$recordDataAttribute}) && $record->{$recordDataAttribute}) { //preloaded $relationshipEntryResources = $record->{$recordDataAttribute}; - } elseif (isset($relationshipObject->callbacks->{Phramework::METHOD_GET})) { //available from callback + } elseif (isset($relationshipObject->callbacks->{'GET'})) { //available from callback $relationshipEntryResources = $dataCallback(); } diff --git a/tests/APP/Bootstrap.php b/tests/APP/Bootstrap.php index ee6f7af..6517342 100644 --- a/tests/APP/Bootstrap.php +++ b/tests/APP/Bootstrap.php @@ -36,11 +36,11 @@ public static function prepare() $settings = include __DIR__ . '/../../settings.php'; $URIStrategy = new \Phramework\URIStrategy\URITemplate([ - ['article/', NS . 'ArticleController', 'GET', Phramework::METHOD_GET], - ['article/', NS . 'ArticleController', 'POST', Phramework::METHOD_POST], - ['article/{id}', NS . 'ArticleController', 'GETById', Phramework::METHOD_GET], - ['article/{id}', NS . 'ArticleController', 'PATCH', Phramework::METHOD_PATCH], - ['article/{id}', NS . 'ArticleController', 'DELETE', Phramework::METHOD_DELETE], + ['article/', NS . 'ArticleController', 'GET', 'GET'], + ['article/', NS . 'ArticleController', 'POST', 'POST'], + ['article/{id}', NS . 'ArticleController', 'GETById', 'GET'], + ['article/{id}', NS . 'ArticleController', 'PATCH', 'PATCH'], + ['article/{id}', NS . 'ArticleController', 'DELETE', 'DELETE'], [ 'article/{id}/relationships/{relationship}', NS . 'ArticleController', diff --git a/tests/APP/Models/Article.php b/tests/APP/Models/Article.php index 97dcdb8..2351a44 100644 --- a/tests/APP/Models/Article.php +++ b/tests/APP/Models/Article.php @@ -179,9 +179,9 @@ public static function getRelationships() Relationship::TYPE_TO_MANY, null, (object) [ - Phramework::METHOD_GET => [Tag::class, 'getRelationshipArticle'], - Phramework::METHOD_POST => [Tag::class, 'postRelationshipArticle'], - Phramework::METHOD_PATCH => [Tag::class, 'patchRelationshipArticle'] + 'GET' => [Tag::class, 'getRelationshipArticle'], + 'POST' => [Tag::class, 'postRelationshipArticle'], + 'PATCH' => [Tag::class, 'patchRelationshipArticle'] ], Relationship::FLAG_DEFAULT | Relationship::FLAG_DATA ) diff --git a/tests/src/Controller/ControllerTest.php b/tests/src/Controller/ControllerTest.php index e2a7635..c7cfc9e 100644 --- a/tests/src/Controller/ControllerTest.php +++ b/tests/src/Controller/ControllerTest.php @@ -54,7 +54,7 @@ public function testExists() /** * @covers ::assertExists * @dataProvider testExistsProviderFailure - * @expectedException Phramework\Exceptions\NotFoundException + * @expectedException \Phramework\Exceptions\NotFoundException */ public function testExistsFailure($assert) { static::assertExists($assert); diff --git a/tests/src/Controller/GetByIdTest.php b/tests/src/Controller/GetByIdTest.php new file mode 100644 index 0000000..f2210bb --- /dev/null +++ b/tests/src/Controller/GetByIdTest.php @@ -0,0 +1,30 @@ + + */ +class GetByIdTest extends \PHPUnit_Framework_TestCase +{ + +} \ No newline at end of file diff --git a/tests/src/Directive/FieldsTest.php b/tests/src/Directive/FieldsTest.php index 1ad6140..60765d5 100644 --- a/tests/src/Directive/FieldsTest.php +++ b/tests/src/Directive/FieldsTest.php @@ -21,6 +21,7 @@ use Phramework\JSONAPI\APP\Models\Article; use Phramework\JSONAPI\APP\Models\Tag; use Phramework\JSONAPI\InternalModel; +use Zend\Diactoros\ServerRequest; /** * @coversDefaultClass Phramework\JSONAPI\Directive\Fields @@ -39,6 +40,11 @@ class FieldsTest extends \PHPUnit_Framework_TestCase */ protected $model; + /** + * @var ServerRequest + */ + protected $request; + public function setUp() { $this->fields = new Fields(); @@ -48,6 +54,17 @@ public function setUp() 'title', 'updated' ); + + $this->request = new ServerRequest( + [], + [], + null, + null, + 'php://input', + [], + [], + [] + ); } /** @@ -174,7 +191,7 @@ public function testGetFields() public function testParseFromRequestEmpty() { $fields = Fields::parseFromRequest( - (object) [], + $this->request->withQueryParams([]), $this->model ); @@ -186,14 +203,12 @@ public function testParseFromRequestEmpty() */ public function testParseFromRequest() { - $parameters = (object) [ - 'fields' => [ - $this->model->getResourceType() => 'title, updated', - ] - ]; - $fields = Fields::parseFromRequest( - $parameters, + $this->request->withQueryParams([ + 'fields' => [ + $this->model->getResourceType() => 'title, updated', + ] + ]), $this->model ); @@ -214,15 +229,11 @@ public function testParseFromRequest() */ public function testParseFromRequestFailureTypeNotArrayOrObject() { - - $parameters = (object) [ - 'fields' => - 'creator-user_id' - - ]; - $fields = Fields::parseFromRequest( - $parameters, + $this->request->withQueryParams([ + 'fields' => + 'creator-user_id' + ]), $this->model ); } @@ -233,14 +244,12 @@ public function testParseFromRequestFailureTypeNotArrayOrObject() */ public function testParseFromRequestFailureTypeNotAssociativeArray() { - $parameters = (object) [ - 'fields' => [ - 'creator-user_id' - ] - ]; - $fields = Fields::parseFromRequest( - $parameters, + $this->request->withQueryParams([ + 'fields' => [ + 'creator-user_id' + ] + ]), $this->model ); } @@ -251,14 +260,12 @@ public function testParseFromRequestFailureTypeNotAssociativeArray() */ public function testParseFromRequestFailureNotAllowed() { - $parameters = (object) [ - 'fields' => [ - $this->model->getResourceType() => 'creator-user_id' - ] - ]; - $fields = Fields::parseFromRequest( - $parameters, + $this->request->withQueryParams([ + 'fields' => [ + $this->model->getResourceType() => 'creator-user_id' + ] + ]), $this->model ); } @@ -269,14 +276,12 @@ public function testParseFromRequestFailureNotAllowed() */ public function testParseFromRequestFailureResourceValueNotStringValue() { - $parameters = (object) [ - 'fields' => [ - $this->model->getResourceType() => ['title, updated'] - ] - ]; - Fields::parseFromRequest( - $parameters, + $this->request->withQueryParams([ + 'fields' => [ + $this->model->getResourceType() => ['title, updated'] + ] + ]), $this->model ); } @@ -287,14 +292,12 @@ public function testParseFromRequestFailureResourceValueNotStringValue() */ public function testParseFromRequestFailureNotAllowedResourceType() { - $parameters = (object) [ - 'fields' => [ - 'offset' => 'title' - ] - ]; - Fields::parseFromRequest( - $parameters, + $this->request->withQueryParams([ + 'fields' => [ + 'offset' => 'title' + ] + ]), $this->model ); } diff --git a/tests/src/Directive/FilterTest.php b/tests/src/Directive/FilterTest.php index 9fbdec1..90d13ea 100644 --- a/tests/src/Directive/FilterTest.php +++ b/tests/src/Directive/FilterTest.php @@ -19,6 +19,7 @@ use Directive\APP\Bootstrap; use Directive\APP\Models\Article; use Directive\APP\Models\Tag; +use Phramework\Exceptions\Exception; use Phramework\JSONAPI\InternalModel; use Phramework\JSONAPI\Relationship; use Phramework\JSONAPI\ValidationModel; @@ -28,6 +29,7 @@ use Phramework\Validate\ObjectValidator; use Phramework\Validate\StringValidator; use Phramework\Validate\UnsignedIntegerValidator; +use Zend\Diactoros\ServerRequest; /** * @coversDefaultClass Phramework\JSONAPI\Directive\Filter @@ -40,7 +42,12 @@ class FilterTest extends \PHPUnit_Framework_TestCase * @var InternalModel */ protected $articleModel; - + + /** + * @var ServerRequest + */ + protected $request; + public function setUp() { $this->articleModel = (new InternalModel('article')) @@ -89,12 +96,23 @@ public function setUp() Relationship::TYPE_TO_MANY, null, (object) [ - Phramework::METHOD_GET => function () {}, - Phramework::METHOD_POST => function () {}, - Phramework::METHOD_PATCH => function () {} + 'GET' => function () {}, + 'POST' => function () {}, + 'PATCH' => function () {} ] ) ]); + + $this->request = new ServerRequest( + [], + [], + null, + null, + 'php://input', + [], + [], + [] + ); } /** @@ -155,14 +173,13 @@ public function testConstructFailure3() */ public function testParseFromRequestPrimaryUsingIntval() { - $parameters = (object) [ - 'filter' => (object) [ - $this->articleModel->getResourceType() => 4 - ] - ]; $filter = Filter::parseFromRequest( - $parameters, + $this->request->withQueryParams([ + 'filter' => [ + $this->articleModel->getResourceType() => 4 + ] + ]), $this->articleModel ); @@ -176,14 +193,12 @@ public function testParseFromRequestPrimaryUsingIntval() */ public function testParseFromRequestRelationshipEmpty() { - $parameters = (object) [ - 'filter' => (object) [ - 'tag' => Operator::OPERATOR_EMPTY - ] - ]; - $filter = Filter::parseFromRequest( - $parameters, + $this->request->withQueryParams([ + 'filter' => [ + 'tag' => Operator::OPERATOR_EMPTY + ] + ]), $this->articleModel ); @@ -201,7 +216,7 @@ public function testParseFromRequestRelationshipEmpty() public function testParseFromRequestEmpty() { $filter = Filter::parseFromRequest( - (object) [], + $this->request->withQueryParams([]), $this->articleModel ); @@ -213,23 +228,21 @@ public function testParseFromRequestEmpty() */ public function testParseFromRequest() { - $parameters = (object) [ - 'filter' => [ - 'article' => '1, 2', - 'tag' => '4, 5, 7', - 'creator' => '1', - 'status' => [true, false], - 'title' => [ - Operator::OPERATOR_LIKE . 'blog', - Operator::OPERATOR_NOT_LIKE . 'welcome' - ], - 'updated' => Operator::OPERATOR_NOT_ISNULL, - 'meta.keywords' => 'blog' - ] - ]; - $filter = Filter::parseFromRequest( - $parameters, + $this->request->withQueryParams([ + 'filter' => [ + 'article' => '1, 2', + 'tag' => '4, 5, 7', + 'creator' => '1', + 'status' => [true, false], + 'title' => [ + Operator::OPERATOR_LIKE . 'blog', + Operator::OPERATOR_NOT_LIKE . 'welcome' + ], + 'updated' => Operator::OPERATOR_NOT_ISNULL, + 'meta.keywords' => 'blog' + ] + ]), $this->articleModel ); @@ -312,14 +325,12 @@ public function testParseFromRequest() */ public function testParseFromRequestFailurePrimaryNotString() { - $parameters = (object) [ - 'filter' => [ - 'article' => [1, 2] - ] - ]; - Filter::parseFromRequest( - $parameters, + $this->request->withQueryParams([ + 'filter' => [ + 'article' => [1, 2] + ] + ]), $this->articleModel ); } @@ -331,14 +342,12 @@ public function testParseFromRequestFailurePrimaryNotString() */ public function testParseFromRequestFailurePrimaryToParse() { - $parameters = (object) [ - 'filter' => [ - $this->articleModel->getResourceType() => 10000 - ] - ]; - Filter::parseFromRequest( - $parameters, + $this->request->withQueryParams([ + 'filter' => [ + $this->articleModel->getResourceType() => 10000 + ] + ]), $this->articleModel )->validate($this->articleModel); } @@ -349,14 +358,12 @@ public function testParseFromRequestFailurePrimaryToParse() */ public function testParseFromRequestFailureRelationshipNotString() { - $parameters = (object) [ - 'filter' => [ - 'tag' => [1, 2] - ] - ]; - Filter::parseFromRequest( - $parameters, + $this->request->withQueryParams([ + 'filter' => [ + 'tag' => [1, 2] + ] + ]), $this->articleModel )->validate($this->articleModel); } @@ -367,32 +374,28 @@ public function testParseFromRequestFailureRelationshipNotString() */ public function testParseFromRequestFailureNotAllowedAttribute() { - $parameters = (object) [ - 'filter' => [ - 'not-found' => 1 - ] - ]; - Filter::parseFromRequest( - $parameters, + $this->request->withQueryParams([ + 'filter' => [ + 'not-found' => 1 + ] + ]), $this->articleModel )->validate($this->articleModel); } /** * @covers ::validate - * @expectedException Exception + * @expectedException \Exception */ public function testParseFromRequestFailureAttributeWithoutValidator() { - $parameters = (object) [ - 'filter' => [ - 'no-validator' => 1 - ] - ]; - Filter::parseFromRequest( - $parameters, + $this->request->withQueryParams([ + 'filter' => [ + 'no-validator' => 1 + ] + ]), $this->articleModel )->validate($this->articleModel); } @@ -403,14 +406,12 @@ public function testParseFromRequestFailureAttributeWithoutValidator() */ public function testParseFromRequestFailureAttributeIsArray() { - $parameters = (object) [ - 'filter' => [ - 'updated' => [[Operator::OPERATOR_ISNULL]] - ] - ]; - Filter::parseFromRequest( - $parameters, + $this->request->withQueryParams([ + 'filter' => [ + 'updated' => [[Operator::OPERATOR_ISNULL]] + ] + ]), $this->articleModel ); } @@ -421,14 +422,12 @@ public function testParseFromRequestFailureAttributeIsArray() */ public function testParseFromRequestFailureAttributeToParse() { - $parameters = (object) [ - 'filter' => [ - 'updated' => 'qwerty' - ] - ]; - Filter::parseFromRequest( - $parameters, + $this->request->withQueryParams([ + 'filter' => [ + 'updated' => 'qwerty' + ] + ]), $this->articleModel )->validate($this->articleModel); } @@ -439,14 +438,12 @@ public function testParseFromRequestFailureAttributeToParse() */ public function testParseFromRequestFailureAttributeNotAllowedOperator() { - $parameters = (object) [ - 'filter' => [ - 'status' => Operator::OPERATOR_GREATER_EQUAL . '1' - ] - ]; - Filter::parseFromRequest( - $parameters, + $this->request->withQueryParams([ + 'filter' => [ + 'status' => Operator::OPERATOR_GREATER_EQUAL . '1' + ] + ]), $this->articleModel )->validate($this->articleModel); } @@ -457,14 +454,12 @@ public function testParseFromRequestFailureAttributeNotAllowedOperator() */ public function testParseFromRequestFailureAttributeNotAcceptingJSONOperator() { - $parameters = (object) [ - 'filter' => [ - 'status.ok' => true - ] - ]; - Filter::parseFromRequest( - $parameters, + $this->request->withQueryParams([ + 'filter' => [ + 'status.ok' => true + ] + ]), $this->articleModel )->validate($this->articleModel); } @@ -475,14 +470,12 @@ public function testParseFromRequestFailureAttributeNotAcceptingJSONOperator() */ public function testParseFromRequestFailureAttributeUsingJSONPropertyValidator() { - $parameters = (object) [ - 'filter' => [ - 'meta.timestamp' => 'xsadas' - ] - ]; - $filter = Filter::parseFromRequest( - $parameters, + $this->request->withQueryParams([ + 'filter' => [ + 'meta.timestamp' => 'xsadas' + ] + ]), $this->articleModel ); @@ -495,14 +488,12 @@ public function testParseFromRequestFailureAttributeUsingJSONPropertyValidator() */ public function testParseFromRequestFailureAttributeJSONSecondLevel() { - $parameters = (object) [ - 'filter' => [ - 'meta.timestamp.time' => 123456789 - ] - ]; - $filter = Filter::parseFromRequest( - $parameters, + $this->request->withQueryParams([ + 'filter' => [ + 'meta.timestamp.time' => 123456789 + ] + ]), $this->articleModel ); diff --git a/tests/src/Directive/PageTest.php b/tests/src/Directive/PageTest.php index dcea416..a03f6c3 100644 --- a/tests/src/Directive/PageTest.php +++ b/tests/src/Directive/PageTest.php @@ -20,6 +20,8 @@ use Phramework\JSONAPI\InternalModel; use Phramework\Validate\EnumValidator; use Phramework\Validate\ObjectValidator; +use Zend\Diactoros\ServerRequest; +use Zend\Diactoros\Uri; /** * @coversDefaultClass Phramework\JSONAPI\Directive\Page @@ -28,17 +30,34 @@ */ class PageTest extends \PHPUnit_Framework_TestCase { - /** + /** + * @var ServerRequest + */ + protected $request; + + public function setUp() + { + $this->request = new ServerRequest( + [], + [], + null, + null, + 'php://input', + [], + [], + [] + ); + } + + /** * @covers ::__construct */ public function testConstruct() { $page = new Page(); - - + $page = new Page(1, 10); - $page = new Page(null, 10); } @@ -48,7 +67,7 @@ public function testConstruct() public function testParseFromRequestEmpty() { $page = Page::parseFromRequest( - (object) [], + $this->request->withQueryParams([]), new InternalModel('user') ); @@ -60,15 +79,13 @@ public function testParseFromRequestEmpty() */ public function testParseFromRequest() { - $parameters = (object) [ - 'page' => [ - 'limit' => '1', - 'offset' => '10' - ] - ]; - $page = Page::parseFromRequest( - $parameters, + $this->request->withQueryParams([ + 'page' => [ + 'limit' => '1', + 'offset' => '10' + ] + ]), new InternalModel('user') ); @@ -87,14 +104,12 @@ public function testParseFromRequest() */ public function testParseFromRequestFailureToParseLimit() { - $parameters = (object) [ - 'page' => (object) [ - 'limit' => 'x10' - ] - ]; - Page::parseFromRequest( - $parameters, + $this->request->withQueryParams([ + 'page' => [ + 'limit' => 'x10' + ] + ]), new InternalModel('user') ); } @@ -105,14 +120,12 @@ public function testParseFromRequestFailureToParseLimit() */ public function testParseFromRequestFailureToParseOffset() { - $parameters = (object) [ - 'page' => (object) [ - 'offset' => 'xx10' - ] - ]; - Page::parseFromRequest( - $parameters, + $this->request->withQueryParams([ + 'page' => [ + 'offset' => 'x10' + ] + ]), new InternalModel('user') ); } @@ -123,14 +136,12 @@ public function testParseFromRequestFailureToParseOffset() */ public function testParseFromRequestExceedMaximum() { - $parameters = (object) [ - 'page' => (object) [ - 'limit' => '100' - ] - ]; - Page::parseFromRequest( - $parameters, + $this->request->withQueryParams([ + 'page' => [ + 'limit' => '100' + ] + ]), (new InternalModel('user')) ->setMaxPageLimit(10) ); diff --git a/tests/src/Directive/SortTest.php b/tests/src/Directive/SortTest.php new file mode 100644 index 0000000..2dbd50b --- /dev/null +++ b/tests/src/Directive/SortTest.php @@ -0,0 +1,175 @@ + + */ +class SortTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var ServerRequest + */ + protected $request; + + /** + * @var InternalModel + */ + protected $model; + + public function setUp() + { + $this->model = (new InternalModel('user')) + ->setSortableAttributes( + 'id', + 'title', + 'updated' + ); + + $this->request = new ServerRequest( + [], + [], + null, + null, + 'php://input', + [], + [], + [] + ); + } + + /** + * @covers ::__construct + */ + public function testConstruct() + { + $sort = new Sort( + $this->model->getIdAttribute() + ); + } + + /** + * @covers ::parseFromRequest + */ + public function testParseFromRequestEmpty() + { + $sort = Sort::parseFromRequest( + $this->request->withQueryParams([]), + $this->model + ); + + $this->assertNull($sort); + } + + /** + * @covers ::parseFromRequest + */ + public function testParseFromRequest() + { + $request = $this->request->withQueryParams([ + 'sort' => '-id' + ]); + + $sort = Sort::parseFromRequest( + $request, + $this->model + ); + + $this->assertInstanceOf( + Sort::class, + $sort + ); + + $this->assertSame('id', $sort->getAttribute()); + $this->assertFalse($sort->getAscending()); + + //Test ascending + + $sort = Sort::parseFromRequest( + $this->request->withQueryParams([ + 'sort' => 'id' + ]), + $this->model + ); + + $this->assertSame('id', $sort->getAttribute()); + $this->assertTrue($sort->getAscending()); + } + + /** + * @covers ::parseFromRequest + * @expectedException \Phramework\Exceptions\RequestException + */ + public function testParseFromRequestFailureNotString() + { + $sort = Sort::parseFromRequest( + $this->request->withQueryParams([ + 'sort' => ['id'] + ]), + $this->model + ); + } + + /** + * @covers ::parseFromRequest + * @expectedException \Phramework\Exceptions\RequestException + */ + public function testParseFromRequestFailureParseExpression() + { + $sort = Sort::parseFromRequest( + $this->request->withQueryParams([ + 'sort' => '--id' + ]), + $this->model + ); + } + + /** + * @covers ::parseFromRequest + * @expectedException \Phramework\Exceptions\RequestException + */ + public function testParseFromRequestFailureNotSortable() + { + $sort = Sort::parseFromRequest( + $this->request->withQueryParams([ + 'sort' => 'meta' + ]), + $this->model + ); + } + + /** + * @covers ::parseFromRequest + * @expectedException \Phramework\Exceptions\RequestException + */ + public function testParseFromRequestFailureNoSortableAttributes() + { + $sort = Sort::parseFromRequest( + $this->request->withQueryParams([ + 'sort' => 'value' + ]), + $this->model + ); + } +} diff --git a/tests/src/RelationshipTest.php b/tests/src/RelationshipTest.php index 831eda7..f071bfb 100644 --- a/tests/src/RelationshipTest.php +++ b/tests/src/RelationshipTest.php @@ -66,13 +66,13 @@ public function testConstruct3() Relationship::TYPE_TO_ONE, 'tag-id', (object) [ - Phramework::METHOD_GET => function () {} + 'GET' => function () {} ] ); $this->assertEquals( (object) [ - Phramework::METHOD_GET => function () {} + 'GET' => function () {} ], $relationship->getCallbacks() ); @@ -136,7 +136,7 @@ public function testConstructFailureInvalidMethodNotCallable() Relationship::TYPE_TO_ONE, null, (object) [ - Phramework::METHOD_GET => [ + 'GET' => [ $this->model, 'getRelationshipByArticleNotCallable' ]