From dfdb8f9117a1ea99cec925e6f93ea63fe69c6789 Mon Sep 17 00:00:00 2001 From: drtheuns Date: Mon, 9 Mar 2020 16:02:54 +0100 Subject: [PATCH] Learn2draw feature/notify undefined sort or filter (#31) * The consumer will not be notified if the field they sort on or filter by does not exist * new active column to users * changed unexisting filter to an existing one * Make dedicated exceptions for undefined sort/filter Co-authored-by: Lex --- .../Exceptions/InvalidInputException.php | 33 +++++++++++++++++-- src/Apitizer/Support/FetchSpecFactory.php | 10 ++++++ tests/Feature/QueryBuilder/PaginationTest.php | 4 +-- .../database/factories/UserFactory.php | 1 + .../2019_12_24_182300_create_users_table.php | 1 + tests/Support/Builders/UserBuilder.php | 1 + 6 files changed, 46 insertions(+), 4 deletions(-) diff --git a/src/Apitizer/Exceptions/InvalidInputException.php b/src/Apitizer/Exceptions/InvalidInputException.php index 527d74d..2127d83 100644 --- a/src/Apitizer/Exceptions/InvalidInputException.php +++ b/src/Apitizer/Exceptions/InvalidInputException.php @@ -33,7 +33,12 @@ class InvalidInputException extends ApitizerException /** * @var Filter|Sort */ - public $type; + public $instance; + + /** + * @var string 'filter' | 'sort' + */ + public $namespace; /** * @param Filter $filter @@ -49,9 +54,33 @@ public static function filterTypeError(Filter $filter, $given): self $message = "Expected $filterParam to receive [$expectedType] got [$type]"; $e = new static($message); - $e->type = $filter; + $e->instance = $filter; $e->queryBuilder = $filter->getQueryBuilder(); return $e; } + + public static function undefinedFilterCalled(string $name, QueryBuilder $queryBuilder): self + { + $class = get_class($queryBuilder); + $message = "Filter $name does not exist on [$class]"; + + $e = new static($message); + $e->namespace = 'filter'; + $e->queryBuilder = $queryBuilder; + + return $e; + } + + public static function undefinedSortCalled(string $name, QueryBuilder $queryBuilder): self + { + $class = get_class($queryBuilder); + $message = "Sort $name does not exist on [$class]"; + + $e = new static($message); + $e->namespace = 'sort'; + $e->queryBuilder = $queryBuilder; + + return $e; + } } diff --git a/src/Apitizer/Support/FetchSpecFactory.php b/src/Apitizer/Support/FetchSpecFactory.php index 58fa20f..0a74b69 100644 --- a/src/Apitizer/Support/FetchSpecFactory.php +++ b/src/Apitizer/Support/FetchSpecFactory.php @@ -149,6 +149,11 @@ protected function selectedSorting(): array $sort = $availableSorting[$parserSort->getField()]; $sort->setOrder($parserSort->getOrder()); $selectedSorting[] = $sort; + } else { + $this->queryBuilder->getExceptionStrategy()->handle( + $this->queryBuilder, + InvalidInputException::undefinedSortCalled($parserSort->getField(), $this->queryBuilder) + ); } } @@ -169,6 +174,11 @@ protected function selectedFilters(): array $filter = $availableFilters[$name]; $filter->setValue($filterInput); $selectedFilters[] = $filter; + } else { + $this->queryBuilder->getExceptionStrategy()->handle( + $this->queryBuilder, + InvalidInputException::undefinedFilterCalled($name, $this->queryBuilder) + ); } } catch (InvalidInputException $e) { $this->queryBuilder->getExceptionStrategy()->handle( diff --git a/tests/Feature/QueryBuilder/PaginationTest.php b/tests/Feature/QueryBuilder/PaginationTest.php index a20a69e..4f3df87 100644 --- a/tests/Feature/QueryBuilder/PaginationTest.php +++ b/tests/Feature/QueryBuilder/PaginationTest.php @@ -28,7 +28,7 @@ public function pagination_links_contain_all_supported_query_parameters() factory(User::class, 2)->create(); $request = $this->request() ->fields('id') - ->filter('empty', 1) + ->filter('active', 1) ->sort('id') ->limit(1) ->make(); @@ -38,7 +38,7 @@ public function pagination_links_contain_all_supported_query_parameters() $this->assertNotNull($paginator->nextPageUrl()); $this->paginatorLinkContainsString($paginator, Apitizer::getFieldKey() . '=id'); $this->paginatorLinkContainsString($paginator, Apitizer::getSortKey() . '=id'); - $this->paginatorLinkContainsString($paginator, Apitizer::getFilterKey() . '[empty]=1'); + $this->paginatorLinkContainsString($paginator, Apitizer::getFilterKey() . '[active]=1'); $this->paginatorLinkContainsString($paginator, 'limit=1'); } diff --git a/tests/Feature/database/factories/UserFactory.php b/tests/Feature/database/factories/UserFactory.php index b008ae6..8c00b83 100644 --- a/tests/Feature/database/factories/UserFactory.php +++ b/tests/Feature/database/factories/UserFactory.php @@ -8,6 +8,7 @@ return [ 'name' => $faker->name, 'email' => $faker->email, + 'active' => 1, ]; }); diff --git a/tests/Feature/database/migrations/2019_12_24_182300_create_users_table.php b/tests/Feature/database/migrations/2019_12_24_182300_create_users_table.php index 5f821f4..d2f8181 100644 --- a/tests/Feature/database/migrations/2019_12_24_182300_create_users_table.php +++ b/tests/Feature/database/migrations/2019_12_24_182300_create_users_table.php @@ -18,6 +18,7 @@ public function up() $table->uuid('uuid'); $table->string('name'); $table->string('email'); + $table->boolean('active'); $table->string('should_reset_password')->default(false); $table->timestamps(); }); diff --git a/tests/Support/Builders/UserBuilder.php b/tests/Support/Builders/UserBuilder.php index 25818b2..5a945a1 100644 --- a/tests/Support/Builders/UserBuilder.php +++ b/tests/Support/Builders/UserBuilder.php @@ -33,6 +33,7 @@ public function filters(): array 'created_at' => $this->filter()->expect()->datetime()->byField('created_at', '>'), 'posts' => $this->filter()->expect()->array()->whereEach()->string()->byAssociation('posts', 'id'), 'updated_at' => $this->filter()->expect()->datetime('d-m-Y')->byField('updated_at', '>'), + 'active' => $this->filter()->expect()->boolean()->byField('active'), ]; }