Skip to content

Commit

Permalink
Throw a proper exception when transformation fails
Browse files Browse the repository at this point in the history
  • Loading branch information
lgeorget committed Oct 21, 2024
1 parent 454a50e commit 4d74589
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 12 deletions.
30 changes: 18 additions & 12 deletions Form/DataTransformer/HCaptchaValueFetcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace MeteoConcept\HCaptchaBundle\Form\DataTransformer;

use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;
use Symfony\Component\HttpFoundation\RequestStack;

use MeteoConcept\HCaptchaBundle\Form\HCaptchaResponse;
Expand Down Expand Up @@ -71,20 +72,25 @@ public function transform($value)
*/
public function reverseTransform($value)
{
/*
* We need to get the data directly from the request since hCaptcha uses
* the POST variable h-captcha-response instead of a nicely named
* variable that would let the Symfony Form component find it on its own.
*/
$masterRequest = $this->requestStack->getMainRequest();
$response = $masterRequest->get("h-captcha-response");
try {
/*
* We need to get the data directly from the request since hCaptcha uses
* the POST variable h-captcha-response instead of a nicely named
* variable that would let the Symfony Form component find it on its own.
*/
$masterRequest = $this->requestStack->getMainRequest();
$response = $masterRequest->get("h-captcha-response");

// Can happen if the Captcha JS has failed to load for instance
if (null === $response)
return null;
// Can happen if the Captcha JS has failed to load for instance
if (null === $response)
return null;

$remoteIp = $masterRequest->getClientIp();
$remoteIp = $masterRequest->getClientIp();

return new HCaptchaResponse($response, $remoteIp, $this->siteKey);
return new HCaptchaResponse($response, $remoteIp, $this->siteKey);
} catch (\TypeError $error) {
// can happen if $response is not a string but an array for instance
throw new TransformationFailedException("Unable to extract the HCaptcha value from the query");
}
}
}
1 change: 1 addition & 0 deletions Form/HCaptchaType.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ public function configureOptions(OptionsResolver $resolver): void
new NotBlank(["message" => "The CAPTCHA is required."]),
new IsValidCaptcha(),
],
'invalid_message' => "Invalid CAPTCHA",
]);

/*
Expand Down
28 changes: 28 additions & 0 deletions Tests/Units/Form/DataTransformer/HCaptchaValueFetcherTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace MeteoConcept\HCaptchaBundle\Tests\Units\Form\DataTransformer;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Form\Exception\TransformationFailedException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;

Expand All @@ -19,6 +20,10 @@ class HCaptchaValueFetcherTest extends TestCase

private $noCaptchaRequest;

private $multipleCaptchaRequestStack;

private $multipleCaptchaRequest;

public function setUp(): void
{
$this->requestStack = $this->createMock(RequestStack::class);
Expand Down Expand Up @@ -48,6 +53,20 @@ public function setUp(): void
$this->noCaptchaRequestStack->expects($this->any())
->method('getMainRequest')
->willReturn($this->noCaptchaRequest);

$this->multipleCaptchaRequestStack = $this->createMock(RequestStack::class);
$this->multipleCaptchaRequest = Request::create(
'/some_route',
'POST',
[ 'h-captcha-response' => ['some_response1', 'some_response2'] ], // request parameters
[], // cookies
[], // files
[ 'REMOTE_ADDR' => '10.0.1.1' ], // server
''
);
$this->multipleCaptchaRequestStack->expects($this->any())
->method('getMainRequest')
->willReturn($this->multipleCaptchaRequest);
}

public function test_The_value_fetcher_builds_the_correct_form_value_from_the_request()
Expand Down Expand Up @@ -75,4 +94,13 @@ public function test_The_value_fetcher_does_not_do_transformation_from_model_to_
$value = $valueFetcher->transform(null);
$this->assertEquals(null, $value);
}

public function test_The_value_fetcher_throws_a_TransformationFailedException_if_the_request_contains_an_array_of_captchas()
{
$valueFetcher = new HCaptchaValueFetcher($this->multipleCaptchaRequestStack);
$valueFetcher->setSiteKey('some_site_key');

$this->expectException(TransformationFailedException::class);
$value = $valueFetcher->reverseTransform(null);
}
}

0 comments on commit 4d74589

Please sign in to comment.