From 75ce0836417441b4002efb3968f3b2de87f46174 Mon Sep 17 00:00:00 2001 From: geangontijo <64979293+geangontijo@users.noreply.github.com> Date: Wed, 25 Sep 2024 16:39:30 -0300 Subject: [PATCH 1/3] Allow parse expressions with Request::validate facade usage --- .../RequestValidateFacade.php | 39 +++++++++++++++++++ .../Strategies/GetFromInlineValidatorBase.php | 1 + 2 files changed, 40 insertions(+) create mode 100644 src/Extracting/Shared/ValidationRulesFinders/RequestValidateFacade.php diff --git a/src/Extracting/Shared/ValidationRulesFinders/RequestValidateFacade.php b/src/Extracting/Shared/ValidationRulesFinders/RequestValidateFacade.php new file mode 100644 index 00000000..07aaeb7e --- /dev/null +++ b/src/Extracting/Shared/ValidationRulesFinders/RequestValidateFacade.php @@ -0,0 +1,39 @@ +validateWithBag('', ...)` + */ +class RequestValidateFacade +{ + public static function find(Node $node) + { + if (!($node instanceof Node\Stmt\Expression)) return; + + $expr = $node->expr; + if ($expr instanceof Node\Expr\Assign) { + $expr = $expr->expr; // If it's an assignment, get the expression on the RHS + } + + if ( + $expr instanceof Node\Expr\StaticCall + && in_array((string) $expr->class, ['Request', \Illuminate\Support\Facades\Request::class]) + ) { + if ($expr->name->name == "validate") { + return $expr->args[0]->value; + } + + if ($expr->name->name == "validateWithBag") { + return $expr->args[1]->value; + } + } + } +} diff --git a/src/Extracting/Strategies/GetFromInlineValidatorBase.php b/src/Extracting/Strategies/GetFromInlineValidatorBase.php index e52640f5..255c6c87 100644 --- a/src/Extracting/Strategies/GetFromInlineValidatorBase.php +++ b/src/Extracting/Strategies/GetFromInlineValidatorBase.php @@ -175,6 +175,7 @@ protected function findValidationExpression($statements): ?array { $strategies = [ RequestValidate::class, // $request->validate(...); + RequestValidateFacade::class, // Request::validate(...); ValidatorMake::class, // Validator::make($request, ...) ThisValidate::class, // $this->validate(...); ]; From ebae6627fb3730227fb8edf633074affc0579198 Mon Sep 17 00:00:00 2001 From: geangontijo <64979293+geangontijo@users.noreply.github.com> Date: Thu, 26 Sep 2024 08:50:00 -0300 Subject: [PATCH 2/3] fix missing import --- src/Extracting/Strategies/GetFromInlineValidatorBase.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Extracting/Strategies/GetFromInlineValidatorBase.php b/src/Extracting/Strategies/GetFromInlineValidatorBase.php index 255c6c87..6995a15c 100644 --- a/src/Extracting/Strategies/GetFromInlineValidatorBase.php +++ b/src/Extracting/Strategies/GetFromInlineValidatorBase.php @@ -6,6 +6,7 @@ use Knuckles\Scribe\Extracting\MethodAstParser; use Knuckles\Scribe\Extracting\ParsesValidationRules; use Knuckles\Scribe\Extracting\Shared\ValidationRulesFinders\RequestValidate; +use Knuckles\Scribe\Extracting\Shared\ValidationRulesFinders\RequestValidateFacade; use Knuckles\Scribe\Extracting\Shared\ValidationRulesFinders\ThisValidate; use Knuckles\Scribe\Extracting\Shared\ValidationRulesFinders\ValidatorMake; use PhpParser\Node; From b058d7849b6352d7da05a42abac59550549ce2a5 Mon Sep 17 00:00:00 2001 From: geangontijo Date: Thu, 3 Oct 2024 09:56:24 -0300 Subject: [PATCH 3/3] creating tests --- tests/Fixtures/TestController.php | 105 +++++++++++++++++- .../Strategies/GetFromInlineValidatorTest.php | 52 +++++++++ 2 files changed, 156 insertions(+), 1 deletion(-) diff --git a/tests/Fixtures/TestController.php b/tests/Fixtures/TestController.php index 43b0992e..8ed6a69b 100644 --- a/tests/Fixtures/TestController.php +++ b/tests/Fixtures/TestController.php @@ -502,6 +502,109 @@ public function withInlineRequestValidateQueryParams(Request $request) // Do stuff } + public function withInlineRequestValidateFacade() + { + // Some stuff + $validated = Request::validate([ + // The id of the user. Example: 9 + 'user_id' => 'int|required', + // The id of the room. + 'room_id' => ['string', 'in:3,5,6'], + // Whether to ban the user forever. Example: false + 'forever' => 'boolean', + // Just need something here. No-example + 'another_one' => 'numeric', + 'even_more_param' => 'array', + 'book.name' => 'string', + 'book.author_id' => 'integer', + 'book.pages_count' => 'integer', + 'ids.*' => 'integer', + // The first name of the user. Example: John + 'users.*.first_name' => ['string'], + // The last name of the user. Example: Doe + 'users.*.last_name' => 'string', + ]); + + // Do stuff + } + + public function withInlineRequestValidateFacadeNoAssignment() + { + Request::validate([ + // The id of the user. Example: 9 + 'user_id' => 'int|required', + // The id of the room. + 'room_id' => ['string', 'in:3,5,6'], + // Whether to ban the user forever. Example: false + 'forever' => 'boolean', + // Just need something here. No-example + 'another_one' => 'numeric', + 'even_more_param' => 'array', + 'book.name' => 'string', + 'book.author_id' => 'integer', + 'book.pages_count' => 'integer', + 'ids.*' => 'integer', + // The first name of the user. Example: John + 'users.*.first_name' => ['string'], + // The last name of the user. Example: Doe + 'users.*.last_name' => 'string', + ]); + + // Do stuff + } + + public function withInlineRequestValidateFacadeWithFullImport() + { + // Some stuff + $validated = \Illuminate\Support\Facades\Request::validate([ + // The id of the user. Example: 9 + 'user_id' => 'int|required', + // The id of the room. + 'room_id' => ['string', 'in:3,5,6'], + // Whether to ban the user forever. Example: false + 'forever' => 'boolean', + // Just need something here. No-example + 'another_one' => 'numeric', + 'even_more_param' => 'array', + 'book.name' => 'string', + 'book.author_id' => 'integer', + 'book.pages_count' => 'integer', + 'ids.*' => 'integer', + // The first name of the user. Example: John + 'users.*.first_name' => ['string'], + // The last name of the user. Example: Doe + 'users.*.last_name' => 'string', + ]); + + // Do stuff + } + + public function withInlineRequestValidateWithBagFacade() + { + // Some stuff + $validated = Request::validateWithBag('stuff', [ + // The id of the user. Example: 9 + 'user_id' => 'int|required', + // The id of the room. + 'room_id' => ['string', 'in:3,5,6'], + // Whether to ban the user forever. Example: false + 'forever' => 'boolean', + // Just need something here. No-example + 'another_one' => 'numeric', + 'even_more_param' => 'array', + 'book.name' => 'string', + 'book.author_id' => 'integer', + 'book.pages_count' => 'integer', + 'ids.*' => 'integer', + // The first name of the user. Example: John + 'users.*.first_name' => ['string'], + // The last name of the user. Example: Doe + 'users.*.last_name' => 'string', + ]); + + // Do stuff + } + public function withInlineValidatorMake(Request $request) { // Some stuff @@ -585,7 +688,7 @@ public function withInjectedModel(TestUser $user) { return null; } - + public function withInjectedModelFullParamName(TestPost $testPost) { return null; diff --git a/tests/Strategies/GetFromInlineValidatorTest.php b/tests/Strategies/GetFromInlineValidatorTest.php index 4235b598..5bc8bd51 100644 --- a/tests/Strategies/GetFromInlineValidatorTest.php +++ b/tests/Strategies/GetFromInlineValidatorTest.php @@ -130,6 +130,58 @@ public function can_fetch_from_request_validatewithbag() $this->assertIsArray($results['ids']['example']); } + /** @test */ + public function can_fetch_from_request_validate_facade_assignment() + { + $endpoint = $this->endpoint(function (ExtractedEndpointData $e) { + $e->method = new \ReflectionMethod(TestController::class, 'withInlineRequestValidateFacade'); + }); + + $results = $this->fetchViaBodyParams($endpoint); + + $this->assertArraySubset(self::$expected, $results); + $this->assertIsArray($results['ids']['example']); + } + + /** @test */ + public function can_fetch_from_request_validate_facade_expression() + { + $endpoint = $this->endpoint(function (ExtractedEndpointData $e) { + $e->method = new \ReflectionMethod(TestController::class, 'withInlineRequestValidateFacadeNoAssignment'); + }); + + $results = $this->fetchViaBodyParams($endpoint); + + $this->assertArraySubset(self::$expected, $results); + $this->assertIsArray($results['ids']['example']); + } + + /** @test */ + public function can_fetch_from_request_validate_facade_with_full_import() + { + $endpoint = $this->endpoint(function (ExtractedEndpointData $e) { + $e->method = new \ReflectionMethod(TestController::class, 'withInlineRequestValidateFacadeWithFullImport'); + }); + + $results = $this->fetchViaBodyParams($endpoint); + + $this->assertArraySubset(self::$expected, $results); + $this->assertIsArray($results['ids']['example']); + } + + /** @test */ + public function can_fetch_from_request_validatewithbag_facade() + { + $endpoint = $this->endpoint(function (ExtractedEndpointData $e) { + $e->method = new \ReflectionMethod(TestController::class, 'withInlineRequestValidateWithBagFacade'); + }); + + $results = $this->fetchViaBodyParams($endpoint); + + $this->assertArraySubset(self::$expected, $results); + $this->assertIsArray($results['ids']['example']); + } + /** @test */ public function can_fetch_from_this_validate() {