diff --git a/composer.json b/composer.json index 23a0967..3e71aca 100644 --- a/composer.json +++ b/composer.json @@ -26,10 +26,12 @@ "spatie/laravel-query-builder": "^5.2|^6.0" }, "require-dev": { + "knuckleswtf/scribe": "^4.37", "laravel/pint": "^1.0", "orchestra/testbench": "^8.0|^9.0", "pestphp/pest": "^2.0", - "pestphp/pest-plugin-laravel": "^2.0" + "pestphp/pest-plugin-laravel": "^2.0", + "spatie/invade": "^2.1" }, "autoload": { "psr-4": { diff --git a/config/datatables.php b/config/datatables.php index c87ea5d..46143f5 100644 --- a/config/datatables.php +++ b/config/datatables.php @@ -1,5 +1,9 @@ [ 'per_page' => 'per_page', @@ -9,4 +13,16 @@ // Represents the value to be sent by the user, to obtain all records, if using the result method. 'all' => 'all', ], + + 'documentation' => [ + QueryBuilder\Filters\FiltersExact::class => Documentations\Filters\ExactFilter::class, + QueryBuilder\Filters\FiltersPartial::class => Documentations\Filters\PartialFilter::class, + QueryBuilder\Filters\FiltersBeginsWithStrict::class => Documentations\Filters\BeginsWithStrictFilter::class, + QueryBuilder\Filters\FiltersEndsWithStrict::class => Documentations\Filters\EndsWithStrictFilter::class, + QueryBuilder\Filters\FiltersTrashed::class => Documentations\Filters\TrashedFilter::class, + Datatables\Filters\GlobalFilter::class => Documentations\Filters\GlobalFilter::class, + Datatables\Filters\DateFilter::class => Documentations\Filters\DateFilter::class, + Datatables\Filters\NumberFilter::class => Documentations\Filters\NumberFilter::class, + Datatables\Filters\TextFilter::class => Documentations\Filters\TextFilter::class, + ], ]; diff --git a/src/Scribe/Strategies/Documentations/Documentation.php b/src/Scribe/Strategies/Documentations/Documentation.php new file mode 100644 index 0000000..c28bdfa --- /dev/null +++ b/src/Scribe/Strategies/Documentations/Documentation.php @@ -0,0 +1,40 @@ +getAttributes(QueryParam::class); + + if (! empty($documentation)) { + $documentation = $documentation[0]->newInstance(); + + return $documentation->toArray(); + } + + if (method_exists($param, 'docs')) { + return $param::docs()->toArray(); + } + + return []; + } +} diff --git a/src/Scribe/Strategies/Documentations/Filters/BeginsWithStrictFilter.php b/src/Scribe/Strategies/Documentations/Filters/BeginsWithStrictFilter.php new file mode 100644 index 0000000..96f4927 --- /dev/null +++ b/src/Scribe/Strategies/Documentations/Filters/BeginsWithStrictFilter.php @@ -0,0 +1,25 @@ + $name, + 'type' => 'string', + 'required' => false, + 'description' => 'Begin Partial Filter. It is evaluated as: The field starts with this value.', + // 'example' => str($value)->substr(0, 3) ?: 'https://', + ]; + } +} diff --git a/src/Scribe/Strategies/Documentations/Filters/DateFilter.php b/src/Scribe/Strategies/Documentations/Filters/DateFilter.php new file mode 100644 index 0000000..d67f49d --- /dev/null +++ b/src/Scribe/Strategies/Documentations/Filters/DateFilter.php @@ -0,0 +1,40 @@ +map(fn (Number $operator) => "
  • {$operator->value} - {$operator->name}
  • ") + ->join(''); + + return [ + 'name' => $name, + 'type' => 'string', + 'required' => false, + 'description' => "
    Date Filter. It belongs to a type of advanced filter, it allows filtering according to operators. Can receive different payload: + + Valid comparison operators are: + +
    ", + ]; + } +} diff --git a/src/Scribe/Strategies/Documentations/Filters/EndsWithStrictFilter.php b/src/Scribe/Strategies/Documentations/Filters/EndsWithStrictFilter.php new file mode 100644 index 0000000..e77be7b --- /dev/null +++ b/src/Scribe/Strategies/Documentations/Filters/EndsWithStrictFilter.php @@ -0,0 +1,25 @@ + $name, + 'type' => 'string', + 'required' => false, + 'description' => 'End Partial Filter. It is evaluated as: The field ends with this value.', + // 'example' => str($value)->substr(0, 3) ?: '@gmail.com', + ]; + } +} diff --git a/src/Scribe/Strategies/Documentations/Filters/ExactFilter.php b/src/Scribe/Strategies/Documentations/Filters/ExactFilter.php new file mode 100644 index 0000000..ccb61cb --- /dev/null +++ b/src/Scribe/Strategies/Documentations/Filters/ExactFilter.php @@ -0,0 +1,25 @@ + $name, + 'type' => 'string', + 'required' => false, + 'description' => 'Exact Filter. It is evaluated as: The field is exactly equal to this value.', + // 'example' => $value ?: 'laa@teamq.biz', + ]; + } +} diff --git a/src/Scribe/Strategies/Documentations/Filters/GlobalFilter.php b/src/Scribe/Strategies/Documentations/Filters/GlobalFilter.php new file mode 100644 index 0000000..a5e65e3 --- /dev/null +++ b/src/Scribe/Strategies/Documentations/Filters/GlobalFilter.php @@ -0,0 +1,24 @@ + $name, + 'type' => 'string', + 'required' => false, + 'description' => 'This will search for the given value among the following fields: ', + ]; + } +} diff --git a/src/Scribe/Strategies/Documentations/Filters/NumberFilter.php b/src/Scribe/Strategies/Documentations/Filters/NumberFilter.php new file mode 100644 index 0000000..158bcee --- /dev/null +++ b/src/Scribe/Strategies/Documentations/Filters/NumberFilter.php @@ -0,0 +1,40 @@ +map(fn (Number $operator) => "
  • {$operator->value} - {$operator->name}
  • ") + ->join(''); + + return [ + 'name' => $name, + 'type' => 'string', + 'required' => false, + 'description' => "
    Number Filter. It belongs to a type of advanced filter, it allows filtering according to operators. Can receive different payload: + + Valid comparison operators are: + +
    ", + ]; + } +} diff --git a/src/Scribe/Strategies/Documentations/Filters/PartialFilter.php b/src/Scribe/Strategies/Documentations/Filters/PartialFilter.php new file mode 100644 index 0000000..74b53c2 --- /dev/null +++ b/src/Scribe/Strategies/Documentations/Filters/PartialFilter.php @@ -0,0 +1,25 @@ + $name, + 'type' => 'string', + 'required' => false, + 'description' => 'Partial Filter. It is evaluated as: The field contains this value.', + // 'example' => str($value)->substr(2, 5) ?: str()->words(2)->lower(), + ]; + } +} diff --git a/src/Scribe/Strategies/Documentations/Filters/TextFilter.php b/src/Scribe/Strategies/Documentations/Filters/TextFilter.php new file mode 100644 index 0000000..da33c99 --- /dev/null +++ b/src/Scribe/Strategies/Documentations/Filters/TextFilter.php @@ -0,0 +1,39 @@ +map(fn (Text $operator) => "
  • {$operator->value} - {$operator->name}
  • ") + ->join(''); + + return [ + 'name' => $name, + 'type' => 'string', + 'required' => false, + 'description' => "
    Text Filter. It belongs to a type of advanced filter, it allows filtering according to operators. Can receive different payload: + + Valid comparison operators are: + +
    ", + ]; + } +} diff --git a/src/Scribe/Strategies/Documentations/Filters/TrashedFilter.php b/src/Scribe/Strategies/Documentations/Filters/TrashedFilter.php new file mode 100644 index 0000000..bd08c0e --- /dev/null +++ b/src/Scribe/Strategies/Documentations/Filters/TrashedFilter.php @@ -0,0 +1,30 @@ + $name, + 'type' => 'string', + 'required' => false, + 'description' => 'Trashed Filter. For soft deleted records. The accepted values are: + ', + 'example' => 'only', + ]; + } +} diff --git a/src/Scribe/Strategies/GetFromAuthorizeMiddleware.php b/src/Scribe/Strategies/GetFromAuthorizeMiddleware.php new file mode 100644 index 0000000..5efcc7e --- /dev/null +++ b/src/Scribe/Strategies/GetFromAuthorizeMiddleware.php @@ -0,0 +1,70 @@ +route->getAction(); + + if (! is_array($action) || ! isset($action['middleware'])) { + return []; + } + + $permissions = $this->getPermissionsFromAuthorizeMiddleware($action['middleware']); + + if ($permissions->isEmpty()) { + return []; + } + + $endpointData->metadata->description .= ""; + + return $endpointData->metadata->toArray(); + } + + /** + * Filters and extracts permissions from Authorize middleware. + */ + protected function getPermissionsFromAuthorizeMiddleware(array $middlewares): Collection + { + return collect($middlewares) + ->filter(fn ($middleware) => str($middleware)->startsWith('can')) + ->map(function ($permission) { + $permission = str($permission) + ->replace('can:', '') + ->replace(',', ':') + ->toString(); + + return "$permission"; + }); + } +} diff --git a/src/Scribe/Strategies/GetFromSpatieQueryBuilder.php b/src/Scribe/Strategies/GetFromSpatieQueryBuilder.php new file mode 100644 index 0000000..23ceba3 --- /dev/null +++ b/src/Scribe/Strategies/GetFromSpatieQueryBuilder.php @@ -0,0 +1,126 @@ + GetFromFilters::class, + 'allowedSorts' => GetFromSorts::class, + 'allowedFields' => GetFromFields::class, + 'allowedIncludes' => GetFromIncludes::class, + ]; + + /** + * @link https://scribe.knuckles.wtf/laravel/advanced/plugins + * + * @param ExtractedEndpointData $endpointData The endpoint we are currently processing. + * Contains details about httpMethods, controller, method, route, url, etc, as well as already extracted data. + * @param array $routeRules Array of rules for the ruleset which this route belongs to. + * + * See the documentation linked above for more details about writing custom strategies. + * + * @throws ReflectionException + */ + public function __invoke(ExtractedEndpointData $endpointData, array $settings = []): ?array + { + if (! $queryBuilderReflectionClass = $this->getQueryBuilderReflectionClass($endpointData->method)) { + return []; + } + + // Get the name of the QueryBuilder class associated to the Controller. + $className = $queryBuilderReflectionClass->getName(); + + // Create an instance of that query builder class. + $queryBuilder = app($className); + + $documentation = new Collection; + + if ($queryBuilder instanceof QueryBuilder) { + $documentation = $documentation->merge(app(GetFromQueryBuilder::class)->__invoke($queryBuilder)); + } + + foreach ($this->properties as $property => $resolver) { + // Get properties used in the QueryBuilder. + $properties = $queryBuilderReflectionClass + ->getProperty($property) + ->getValue($queryBuilder); + + if (! $properties instanceof Collection) { + continue; + } + + $documentation = $documentation->merge(app($resolver)->__invoke($properties, $queryBuilder)); + } + + return $documentation->toArray(); + } + + /** + * Gets the reflection class from Spatie's Query Builder class. + */ + protected function getQueryBuilderReflectionClass(ReflectionFunctionAbstract $method): ?ReflectionClass + { + foreach ($method->getParameters() as $argument) { + $argType = $argument->getType(); + + if ($argType === null || $argType instanceof ReflectionUnionType) { + continue; + } + + $argumentClassName = $argType->getName(); + + try { + $argumentClass = new ReflectionClass($argumentClassName); + } catch (ReflectionException $e) { + continue; + } + + if ( + class_exists(SpatieQueryBuilder::class) && + $argumentClass->isSubclassOf(SpatieQueryBuilder::class) + ) { + return $argumentClass; + } + } + + return null; + } +} diff --git a/src/Scribe/Strategies/GetFromSpatieQueryBuilderParamAttribute.php b/src/Scribe/Strategies/GetFromSpatieQueryBuilderParamAttribute.php new file mode 100644 index 0000000..23066a7 --- /dev/null +++ b/src/Scribe/Strategies/GetFromSpatieQueryBuilderParamAttribute.php @@ -0,0 +1,57 @@ +getQueryBuilderReflectionClass($endpointData->method)) { + return []; + } + + return collect($queryBuilderReflectionClass->getAttributes()) + ->mapWithKeys(function (ReflectionAttribute $attribute) { + $arguments = $attribute->getArguments(); + + return [ + $arguments['name'] => [ + 'type' => $arguments['type'] ?? 'string', + 'description' => $arguments['description'] ?? null, + 'required' => $arguments['required'] ?? false, + 'example' => $arguments['example'] ?? null, + ], + ]; + }) + ->toArray(); + } +} diff --git a/src/Scribe/Strategies/Resolvers/GetFromBase.php b/src/Scribe/Strategies/Resolvers/GetFromBase.php new file mode 100644 index 0000000..69fc6f0 --- /dev/null +++ b/src/Scribe/Strategies/Resolvers/GetFromBase.php @@ -0,0 +1,70 @@ +getAttributes(QueryParam::class); + + if (! empty($documentation)) { + $documentation = $documentation[0]->newInstance(); + + return $documentation->toArray(); + } + + if (method_exists($param, 'docs')) { + return $param::docs()->toArray(); + } + + return []; + } +} diff --git a/src/Scribe/Strategies/Resolvers/GetFromFields.php b/src/Scribe/Strategies/Resolvers/GetFromFields.php new file mode 100644 index 0000000..9e50f0d --- /dev/null +++ b/src/Scribe/Strategies/Resolvers/GetFromFields.php @@ -0,0 +1,69 @@ +getParameterName(); + + return $properties->groupBy(fn ($field) => Str::of($field)->beforeLast('.')->toString()) + ->reduce(function (Collection $queryParams, Collection $fields, string $key) use ($parameterName) { + $name = sprintf('%s[%s]', $parameterName, $key); + + $param = $fields + ->map(fn ($field) => Str::of($field)->afterLast('.')->toString()); + + return $queryParams->put( + $name, + array_merge([ + 'type' => 'string', + 'required' => false, + ], $this->getDocumentation($param), [ + 'name' => $name, + ]) + ); + }, new Collection); + } + + /** + * {@inheritDoc} + */ + protected function getDocumentation(Filter|Sort|Collection|string $param, mixed $value = null, ?string $name = null): array + { + $values = $param + ->map(fn ($value) => "$value") + ->join(', '); + + return [ + 'description' => "Each value separated by a comma.
    Allowed values: {$values}
    ", + 'example' => $param->shuffle()->take(2)->join(','), + ]; + } + + /** + * {@inheritDoc} + */ + protected function getParameterName(): string + { + return config('query-builder.parameters.fields'); + } +} diff --git a/src/Scribe/Strategies/Resolvers/GetFromFilters.php b/src/Scribe/Strategies/Resolvers/GetFromFilters.php new file mode 100644 index 0000000..8a99142 --- /dev/null +++ b/src/Scribe/Strategies/Resolvers/GetFromFilters.php @@ -0,0 +1,120 @@ +getParameterName(); + + $model = $this->getFactoryModelFromQueryBuilder($queryBuilder); + + return $properties + ->reduce(function (Collection $queryParams, AllowedFilter $allowedFilter) use ($parameterName, $model) { + $name = sprintf('%s[%s]', $parameterName, $allowedFilter->getName()); + + $allowedFilterReflectionClass = new ReflectionClass($allowedFilter); + + $filterClass = $allowedFilterReflectionClass + ->getProperty('filterClass') + ->getValue($allowedFilter); + + $value = $this->getExampleValue($model, $allowedFilter->getInternalName()); + + return $queryParams->put( + $name, + array_merge([ + 'type' => 'string', + 'required' => false, + ], $this->getDocumentation($filterClass, $value, $name), [ + 'name' => $name, + ]) + ); + }, new Collection); + } + + /** + * {@inheritDoc} + * + * @throws ReflectionException + */ + protected function getDocumentation(Filter|Sort|Collection|string $param, mixed $value = null, ?string $name = null): array + { + $documentations = config('datatables.documentation'); + + $documentation = $documentations[is_string($param) ? $param : $param::class] ?? Documentation::class; + + $documentation = app($documentation); + + return $documentation($param, $value, $name); + } + + /** + * {@inheritDoc} + */ + protected function getParameterName(): string + { + return config('query-builder.parameters.filter'); + } + + /** + * Gets the data factory related to the model that is associated to the query builder class. + */ + protected function getFactoryModelFromQueryBuilder(QueryBuilder $queryBuilder): Model + { + return $queryBuilder->getSubject()->getModel(); + } + + /** + * It allows to generate a value according to the model being queried. + */ + protected function getExampleValue(Model $model, string $property): mixed + { + try { + $value = $model->getAttribute($property); + + if ($value instanceof BackedEnum) { + $value = $value->value; + } + + if (is_null($value) && isset($model->getCasts()[$property])) { + $type = $model->getCasts()[$property]; + + $value = match ($type) { + 'int' => fake()->randomDigit(), + 'string' => fake()->words(2), + 'datetime' => fake()->dateTimeBetween('-5 years'), + }; + } + } catch (Exception|Error) { + $value = null; + } + + return $value; + } +} diff --git a/src/Scribe/Strategies/Resolvers/GetFromIncludes.php b/src/Scribe/Strategies/Resolvers/GetFromIncludes.php new file mode 100644 index 0000000..f68dd08 --- /dev/null +++ b/src/Scribe/Strategies/Resolvers/GetFromIncludes.php @@ -0,0 +1,62 @@ +map(fn (AllowedInclude $allowedInclude) => $allowedInclude->getName()); + + $parameterName = $this->getParameterName(); + + return collect()->put( + $parameterName, + array_merge([ + 'type' => 'string', + 'required' => false, + ], $this->getDocumentation($allowedIncludes), [ + 'name' => $parameterName, + ]) + ); + } + + /** + * {@inheritDoc} + */ + protected function getDocumentation(Filter|Sort|Collection|string $param, mixed $value = null, ?string $name = null): array + { + $values = $param + ->map(fn ($value) => "$value") + ->join(', '); + + return [ + 'description' => "Each value separated by a comma.
    Allowed values: {$values}
    ", + ]; + } + + /** + * {@inheritDoc} + */ + protected function getParameterName(): string + { + return config('query-builder.parameters.include'); + } +} diff --git a/src/Scribe/Strategies/Resolvers/GetFromQueryBuilder.php b/src/Scribe/Strategies/Resolvers/GetFromQueryBuilder.php new file mode 100644 index 0000000..978ba2f --- /dev/null +++ b/src/Scribe/Strategies/Resolvers/GetFromQueryBuilder.php @@ -0,0 +1,29 @@ + [ + 'name' => config('query-builder.parameters.per_page'), + 'type' => 'string', + 'required' => false, + 'description' => 'Allows you to limit the amount of results per page. The accepted values are: + ', + 'example' => 15, + ], + ]); + } +} diff --git a/src/Scribe/Strategies/Resolvers/GetFromSorts.php b/src/Scribe/Strategies/Resolvers/GetFromSorts.php new file mode 100644 index 0000000..ba62e9a --- /dev/null +++ b/src/Scribe/Strategies/Resolvers/GetFromSorts.php @@ -0,0 +1,62 @@ +map(fn (AllowedSort $allowedSort) => $allowedSort->getName()); + + $parameterName = $this->getParameterName(); + + return collect()->put( + $parameterName, + array_merge([ + 'type' => 'string', + 'required' => false, + ], $this->getDocumentation($allowedSorts), [ + 'name' => $parameterName, + ]) + ); + } + + /** + * {@inheritDoc} + */ + protected function getDocumentation(Filter|Sort|Collection|string $param, mixed $value = null, ?string $name = null): array + { + $values = $param + ->map(fn ($value) => "$value") + ->join(', '); + + return [ + 'description' => "Each value separated by a comma. To indicate descending order, add \"-\" before the field to sort.
    Allowed values: {$values}
    ", + ]; + } + + /** + * {@inheritDoc} + */ + protected function getParameterName(): string + { + return config('query-builder.parameters.sort'); + } +} diff --git a/src/Sorts/CaseSort.php b/src/Sorts/CaseSort.php index 4706dd7..fbd86ed 100644 --- a/src/Sorts/CaseSort.php +++ b/src/Sorts/CaseSort.php @@ -25,8 +25,7 @@ public function __construct( protected array $cases, private readonly JoinType $joinType = JoinType::Inner, private readonly ?AggregationType $aggregationType = null, - ) { - } + ) {} /** * {@inheritDoc} diff --git a/src/Sorts/RelationSort.php b/src/Sorts/RelationSort.php index ac6b5dd..996cb93 100644 --- a/src/Sorts/RelationSort.php +++ b/src/Sorts/RelationSort.php @@ -23,8 +23,7 @@ public function __construct( private readonly JoinType $joinType = JoinType::Inner, private readonly ?AggregationType $aggregationType = null, private readonly array|string|null $joinAliases = null, - ) { - } + ) {} /** * {@inheritDoc} diff --git a/tests/Filters/DateFilterTest.php b/tests/Filters/DateFilterTest.php index 4f59ae6..1e23ffa 100644 --- a/tests/Filters/DateFilterTest.php +++ b/tests/Filters/DateFilterTest.php @@ -13,7 +13,7 @@ use Tests\Mocks\Models\Country; beforeEach(function () { - $this->request = new Illuminate\Http\Request(); + $this->request = new Illuminate\Http\Request; $this->request->setMethod(Request::METHOD_GET); $this->firstBook = Book::factory() @@ -85,7 +85,7 @@ $queryBuilder = QueryBuilder::for(Book::class, $this->request) ->allowedFilters([ - AllowedFilter::custom('created_at', new DateFilter()), + AllowedFilter::custom('created_at', new DateFilter), ]); expect($queryBuilder->toRawSql()) @@ -106,7 +106,7 @@ $queryBuilder = QueryBuilder::for(Book::class, $this->request) ->allowedFilters([ - AllowedFilter::custom('created_at', new DateFilter()), + AllowedFilter::custom('created_at', new DateFilter), ]); expect($queryBuilder->toRawSql()) @@ -124,7 +124,7 @@ $queryBuilder = QueryBuilder::for(Book::class, $this->request) ->allowedFilters([ - AllowedFilter::custom('created_at', new DateFilter()), + AllowedFilter::custom('created_at', new DateFilter), ]); expect($queryBuilder->toSql()) @@ -144,7 +144,7 @@ $queryBuilder = QueryBuilder::for(Book::class, $this->request) ->allowedFilters([ - AllowedFilter::custom('created_at', new DateFilter()), + AllowedFilter::custom('created_at', new DateFilter), ]); expect($queryBuilder->toSql()) @@ -164,7 +164,7 @@ $queryBuilder = QueryBuilder::for(Book::class, $this->request) ->allowedFilters([ - AllowedFilter::custom('created_at', new DateFilter()), + AllowedFilter::custom('created_at', new DateFilter), ]); expect($queryBuilder->toSql()) @@ -188,7 +188,7 @@ $queryBuilder = QueryBuilder::for(Book::class, $this->request) ->allowedFilters([ - AllowedFilter::custom('created_at', new DateFilter()), + AllowedFilter::custom('created_at', new DateFilter), ]); expect($queryBuilder->toSql()) @@ -209,7 +209,7 @@ $queryBuilder = QueryBuilder::for(Book::class, $this->request) ->allowedFilters([ - AllowedFilter::custom('created_at', new DateFilter()), + AllowedFilter::custom('created_at', new DateFilter), ]); $result = $queryBuilder->get(); @@ -242,7 +242,7 @@ $queryBuilder = QueryBuilder::for(Book::class, $this->request) ->allowedFilters([ - AllowedFilter::custom('author.created_at', new DateFilter()), + AllowedFilter::custom('author.created_at', new DateFilter), ]); expect($queryBuilder->toSql()) @@ -263,7 +263,7 @@ $queryBuilder = QueryBuilder::for(Book::class, $this->request) ->allowedFilters([ - AllowedFilter::custom('chapters.created_at', new DateFilter()), + AllowedFilter::custom('chapters.created_at', new DateFilter), ]); expect($queryBuilder->toSql()) diff --git a/tests/Filters/GlobalFilterTest.php b/tests/Filters/GlobalFilterTest.php index 887b8d0..d914a93 100644 --- a/tests/Filters/GlobalFilterTest.php +++ b/tests/Filters/GlobalFilterTest.php @@ -11,7 +11,7 @@ use Tests\Mocks\Models\Country; beforeEach(function () { - $this->request = new Illuminate\Http\Request(); + $this->request = new Illuminate\Http\Request; $this->request->setMethod(Request::METHOD_GET); $this->firstBook = Book::factory() diff --git a/tests/Filters/HasRelationshipFilterTest.php b/tests/Filters/HasRelationshipFilterTest.php index 7faceac..29c668d 100644 --- a/tests/Filters/HasRelationshipFilterTest.php +++ b/tests/Filters/HasRelationshipFilterTest.php @@ -11,7 +11,7 @@ use Tests\Mocks\Models\Country; beforeEach(function () { - $this->request = new Illuminate\Http\Request(); + $this->request = new Illuminate\Http\Request; $this->request->setMethod(Request::METHOD_GET); $this->firstBook = Book::factory() @@ -72,7 +72,7 @@ $queryBuilder = QueryBuilder::for(Book::class, $this->request) ->allowedFilters([ - AllowedFilter::custom('has_chapters', new HasRelationshipFilter(), 'chapters'), + AllowedFilter::custom('has_chapters', new HasRelationshipFilter, 'chapters'), ]); expect($queryBuilder->toRawSql()) @@ -90,7 +90,7 @@ $queryBuilder = QueryBuilder::for(Book::class, $this->request) ->allowedFilters([ - AllowedFilter::custom('has_chapters', new HasRelationshipFilter(), 'chapters'), + AllowedFilter::custom('has_chapters', new HasRelationshipFilter, 'chapters'), ]); expect($queryBuilder->toSql()) @@ -108,7 +108,7 @@ $queryBuilder = QueryBuilder::for(Book::class, $this->request) ->allowedFilters([ - AllowedFilter::custom('has_chapters', new HasRelationshipFilter(), 'chapters'), + AllowedFilter::custom('has_chapters', new HasRelationshipFilter, 'chapters'), ]); expect($queryBuilder->toSql()) diff --git a/tests/Filters/NumberFilterTest.php b/tests/Filters/NumberFilterTest.php index 410e78c..22ca714 100644 --- a/tests/Filters/NumberFilterTest.php +++ b/tests/Filters/NumberFilterTest.php @@ -13,7 +13,7 @@ use Tests\Mocks\Models\Country; beforeEach(function () { - $this->request = new Illuminate\Http\Request(); + $this->request = new Illuminate\Http\Request; $this->request->setMethod(Request::METHOD_GET); $this->firstBook = Book::factory() @@ -85,7 +85,7 @@ $queryBuilder = QueryBuilder::for(Book::class, $this->request) ->allowedFilters([ - AllowedFilter::custom('order', new NumberFilter()), + AllowedFilter::custom('order', new NumberFilter), ]); expect($queryBuilder->toRawSql()) @@ -106,7 +106,7 @@ $queryBuilder = QueryBuilder::for(Book::class, $this->request) ->allowedFilters([ - AllowedFilter::custom('order', new NumberFilter()), + AllowedFilter::custom('order', new NumberFilter), ]); expect($queryBuilder->toRawSql()) @@ -124,7 +124,7 @@ $queryBuilder = QueryBuilder::for(Book::class, $this->request) ->allowedFilters([ - AllowedFilter::custom('order', new NumberFilter()), + AllowedFilter::custom('order', new NumberFilter), ]); expect($queryBuilder->toSql()) @@ -144,7 +144,7 @@ $queryBuilder = QueryBuilder::for(Book::class, $this->request) ->allowedFilters([ - AllowedFilter::custom('order', new NumberFilter()), + AllowedFilter::custom('order', new NumberFilter), ]); expect($queryBuilder->toSql()) @@ -164,7 +164,7 @@ $queryBuilder = QueryBuilder::for(Book::class, $this->request) ->allowedFilters([ - AllowedFilter::custom('order', new NumberFilter()), + AllowedFilter::custom('order', new NumberFilter), ]); expect($queryBuilder->toSql()) @@ -188,7 +188,7 @@ $queryBuilder = QueryBuilder::for(Book::class, $this->request) ->allowedFilters([ - AllowedFilter::custom('order', new NumberFilter()), + AllowedFilter::custom('order', new NumberFilter), ]); expect($queryBuilder->toSql()) @@ -209,7 +209,7 @@ $queryBuilder = QueryBuilder::for(Book::class, $this->request) ->allowedFilters([ - AllowedFilter::custom('order', new NumberFilter()), + AllowedFilter::custom('order', new NumberFilter), ]); $result = $queryBuilder->get(); @@ -242,7 +242,7 @@ $queryBuilder = QueryBuilder::for(Book::class, $this->request) ->allowedFilters([ - AllowedFilter::custom('author.order', new NumberFilter()), + AllowedFilter::custom('author.order', new NumberFilter), ]); expect($queryBuilder->toSql()) @@ -263,7 +263,7 @@ $queryBuilder = QueryBuilder::for(Book::class, $this->request) ->allowedFilters([ - AllowedFilter::custom('chapters.order', new NumberFilter()), + AllowedFilter::custom('chapters.order', new NumberFilter), ]); expect($queryBuilder->toSql()) diff --git a/tests/Filters/PowerJoins/TextFilterTest.php b/tests/Filters/PowerJoins/TextFilterTest.php index 91b5044..329ee28 100644 --- a/tests/Filters/PowerJoins/TextFilterTest.php +++ b/tests/Filters/PowerJoins/TextFilterTest.php @@ -10,7 +10,7 @@ use Tests\Mocks\Models\Flight; beforeEach(function () { - $this->request = new Illuminate\Http\Request(); + $this->request = new Illuminate\Http\Request; $this->request->setMethod(Request::METHOD_GET); $belgium = Country::factory()->create(['name' => 'Belgium', 'code' => 'BE']); diff --git a/tests/Filters/TextFilterTest.php b/tests/Filters/TextFilterTest.php index a7e612a..42c86a3 100644 --- a/tests/Filters/TextFilterTest.php +++ b/tests/Filters/TextFilterTest.php @@ -13,7 +13,7 @@ use Tests\Mocks\Models\Country; beforeEach(function () { - $this->request = new Illuminate\Http\Request(); + $this->request = new Illuminate\Http\Request; $this->request->setMethod(Request::METHOD_GET); $this->firstBook = Book::factory() @@ -85,7 +85,7 @@ $queryBuilder = QueryBuilder::for(Book::class, $this->request) ->allowedFilters([ - AllowedFilter::custom('isbn', new TextFilter()), + AllowedFilter::custom('isbn', new TextFilter), ]); expect($queryBuilder->toRawSql()) @@ -106,7 +106,7 @@ $queryBuilder = QueryBuilder::for(Book::class, $this->request) ->allowedFilters([ - AllowedFilter::custom('isbn', new TextFilter()), + AllowedFilter::custom('isbn', new TextFilter), ]); expect($queryBuilder->toRawSql()) @@ -124,7 +124,7 @@ $queryBuilder = QueryBuilder::for(Book::class, $this->request) ->allowedFilters([ - AllowedFilter::custom('isbn', new TextFilter()), + AllowedFilter::custom('isbn', new TextFilter), ]); expect($queryBuilder->toSql()) @@ -144,7 +144,7 @@ $queryBuilder = QueryBuilder::for(Book::class, $this->request) ->allowedFilters([ - AllowedFilter::custom('isbn', new TextFilter()), + AllowedFilter::custom('isbn', new TextFilter), ]); expect($queryBuilder->toSql()) @@ -164,7 +164,7 @@ $queryBuilder = QueryBuilder::for(Book::class, $this->request) ->allowedFilters([ - AllowedFilter::custom('isbn', new TextFilter()), + AllowedFilter::custom('isbn', new TextFilter), ]); expect($queryBuilder->toSql()) @@ -187,7 +187,7 @@ $queryBuilder = QueryBuilder::for(Book::class, $this->request) ->allowedFilters([ - AllowedFilter::custom('isbn', new TextFilter()), + AllowedFilter::custom('isbn', new TextFilter), ]); expect($queryBuilder->toSql()) @@ -208,7 +208,7 @@ $queryBuilder = QueryBuilder::for(Book::class, $this->request) ->allowedFilters([ - AllowedFilter::custom('isbn', new TextFilter()), + AllowedFilter::custom('isbn', new TextFilter), ]); $result = $queryBuilder->get(); @@ -243,7 +243,7 @@ $queryBuilder = QueryBuilder::for(Book::class, $this->request) ->allowedFilters([ - AllowedFilter::custom('author.email', new TextFilter()), + AllowedFilter::custom('author.email', new TextFilter), ]); expect($queryBuilder->toSql()) @@ -264,7 +264,7 @@ $queryBuilder = QueryBuilder::for(Book::class, $this->request) ->allowedFilters([ - AllowedFilter::custom('chapters.title', new TextFilter()), + AllowedFilter::custom('chapters.title', new TextFilter), ]); expect($queryBuilder->toSql()) diff --git a/tests/Queries/PerPageQueryBuilderTest.php b/tests/Queries/PerPageQueryBuilderTest.php index 23535d3..c2ea077 100644 --- a/tests/Queries/PerPageQueryBuilderTest.php +++ b/tests/Queries/PerPageQueryBuilderTest.php @@ -7,7 +7,7 @@ use Tests\Mocks\Models\Author; beforeEach(function () { - $this->request = new Illuminate\Http\Request(); + $this->request = new Illuminate\Http\Request; $this->request->setMethod(Request::METHOD_GET); }); diff --git a/tests/Sorts/CaseSortTest.php b/tests/Sorts/CaseSortTest.php index 5df52cb..b4e8681 100644 --- a/tests/Sorts/CaseSortTest.php +++ b/tests/Sorts/CaseSortTest.php @@ -10,7 +10,7 @@ use Tests\Mocks\Models\Book; beforeEach(function () { - $this->request = new Illuminate\Http\Request(); + $this->request = new Illuminate\Http\Request; $this->request->setMethod(Request::METHOD_GET); $this->firstBook = Book::factory() diff --git a/tests/Sorts/PowerJoins/RelationSortTest.php b/tests/Sorts/PowerJoins/RelationSortTest.php index ad78149..eeed366 100644 --- a/tests/Sorts/PowerJoins/RelationSortTest.php +++ b/tests/Sorts/PowerJoins/RelationSortTest.php @@ -9,7 +9,7 @@ use Tests\Mocks\Models\Flight; beforeEach(function () { - $this->request = new Illuminate\Http\Request(); + $this->request = new Illuminate\Http\Request; $this->request->setMethod(Request::METHOD_GET); $belgium = Country::factory()->create(['name' => 'Belgium', 'code' => 'BE']); diff --git a/tests/Sorts/RelationSortTest.php b/tests/Sorts/RelationSortTest.php index 77a323a..d509d88 100644 --- a/tests/Sorts/RelationSortTest.php +++ b/tests/Sorts/RelationSortTest.php @@ -13,7 +13,7 @@ use Tests\Mocks\Models\Country; beforeEach(function () { - $this->request = new Illuminate\Http\Request(); + $this->request = new Illuminate\Http\Request; $this->request->setMethod(Request::METHOD_GET); $this->firstBook = Book::factory()