From 23ac1004b852f96a3444607d0be38149b451d5fd Mon Sep 17 00:00:00 2001 From: Ibrahim BinAlshikh Date: Sun, 3 May 2026 14:26:39 +0300 Subject: [PATCH] fix: Annotations on `processRequest` --- WebFiori/Http/WebServicesManager.php | 6 +- .../AnnotatedParamsProcessRequestTest.php | 117 ++++++++++++++++++ .../AnnotatedParamsLegacyService.php | 41 ++++++ 3 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 tests/WebFiori/Tests/Http/AnnotatedParamsProcessRequestTest.php create mode 100644 tests/WebFiori/Tests/Http/TestServices/AnnotatedParamsLegacyService.php diff --git a/WebFiori/Http/WebServicesManager.php b/WebFiori/Http/WebServicesManager.php index eb137381..7a4f8db2 100644 --- a/WebFiori/Http/WebServicesManager.php +++ b/WebFiori/Http/WebServicesManager.php @@ -522,7 +522,11 @@ public final function process() { $this->configureServiceParameters($actionObj); } - $params = $actionObj->getParameters(); + // Resolve #[RequestParam] annotations for the current HTTP method. + // This ensures annotated parameters are registered before filtering, + // even for services using the traditional processRequest() pattern. + $actionObj->getParameterByName('', $this->getRequest()->getRequestMethod()); + $params = $actionObj->getParameters(); $this->filter->clearParametersDef(); $this->filter->clearInputs(); diff --git a/tests/WebFiori/Tests/Http/AnnotatedParamsProcessRequestTest.php b/tests/WebFiori/Tests/Http/AnnotatedParamsProcessRequestTest.php new file mode 100644 index 00000000..c8b1e5fd --- /dev/null +++ b/tests/WebFiori/Tests/Http/AnnotatedParamsProcessRequestTest.php @@ -0,0 +1,117 @@ +addService(new AnnotatedParamsLegacyService()); + + $output = $this->postRequest($manager, 'annotated-params-legacy', [ + 'username' => 'admin@test.com', + 'password' => 'secret123', + ]); + + $response = json_decode($output, true); + $this->assertIsArray($response); + $this->assertEquals('success', $response['type']); + $this->assertStringContainsString('admin@test.com', $response['message']); + } + + /** + * Test that missing required parameters are correctly reported + * when using #[RequestParam] annotations without #[ResponseBody]. + */ + public function testMissingParamsReportedInProcessRequest() { + $manager = new WebServicesManager(); + $manager->addService(new AnnotatedParamsLegacyService()); + + $output = $this->postRequest($manager, 'annotated-params-legacy', []); + + $response = json_decode($output, true); + $this->assertIsArray($response); + $this->assertEquals('error', $response['type']); + // Framework should report missing required params + $this->assertArrayHasKey('missing', $response['more-info']); + $this->assertContains('username', $response['more-info']['missing']); + $this->assertContains('password', $response['more-info']['missing']); + } + + /** + * Test that partially missing parameters are reported. + */ + public function testPartialParamsMissing() { + $manager = new WebServicesManager(); + $manager->addService(new AnnotatedParamsLegacyService()); + + $output = $this->postRequest($manager, 'annotated-params-legacy', [ + 'username' => 'admin@test.com', + ]); + + $response = json_decode($output, true); + $this->assertIsArray($response); + $this->assertEquals('error', $response['type']); + $this->assertContains('password', $response['more-info']['missing']); + } + + /** + * Test that #[ResponseBody] services still work correctly after the fix. + * This ensures the fix doesn't break the existing auto-processing path. + */ + public function testResponseBodyServiceStillWorks() { + $manager = new WebServicesManager(); + $manager->addService(new AnnotatedService()); + + $output = $this->getRequest($manager, 'annotated-service', [ + 'name' => 'Ibrahim', + ]); + + $this->assertStringContainsString('Hi Ibrahim!', $output); + } + + /** + * Test that #[ResponseBody] service with no params still works. + */ + public function testResponseBodyServiceNoParams() { + $manager = new WebServicesManager(); + $manager->addService(new AnnotatedService()); + + $output = $this->getRequest($manager, 'annotated-service'); + + $this->assertStringContainsString('Hi user!', $output); + } + + /** + * Test wrong HTTP method is rejected for annotated legacy service. + */ + public function testWrongMethodRejected() { + $manager = new WebServicesManager(); + $manager->addService(new AnnotatedParamsLegacyService()); + + // Service only accepts POST, sending GET should fail + $output = $this->getRequest($manager, 'annotated-params-legacy', [ + 'username' => 'admin@test.com', + 'password' => 'secret123', + ]); + + $response = json_decode($output, true); + $this->assertIsArray($response); + $this->assertEquals('error', $response['type']); + } +} diff --git a/tests/WebFiori/Tests/Http/TestServices/AnnotatedParamsLegacyService.php b/tests/WebFiori/Tests/Http/TestServices/AnnotatedParamsLegacyService.php new file mode 100644 index 00000000..5f52d75a --- /dev/null +++ b/tests/WebFiori/Tests/Http/TestServices/AnnotatedParamsLegacyService.php @@ -0,0 +1,41 @@ +getParamVal('username'); + $password = $this->getParamVal('password'); + + if ($username === null) { + $this->sendResponse('Username is missing', 400, 'error'); + return; + } + + if ($password === null) { + $this->sendResponse('Password is missing', 400, 'error'); + return; + } + + $this->sendResponse('Login successful for: ' . $username, 200, 'success'); + } +}