Skip to content

Commit

Permalink
minor: fix tests for url-safe signed urls (#203)
Browse files Browse the repository at this point in the history
  • Loading branch information
kbond authored Jan 16, 2025
1 parent 2cb1cd9 commit 936b4b6
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 57 deletions.
38 changes: 24 additions & 14 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -97,32 +97,37 @@ parameters:

-
message: "#^Access to an undefined property object\\:\\:\\$helper\\.$#"
count: 3
count: 2
path: tests/AcceptanceTests/VerifyEmailAcceptanceTest.php

-
message: "#^Cannot access offset 'query' on array\\{scheme\\?\\: string, host\\?\\: string, port\\?\\: int\\<0, 65535\\>, user\\?\\: string, pass\\?\\: string, path\\?\\: string, query\\?\\: string, fragment\\?\\: string\\}\\|false\\.$#"
message: "#^Call to method sign\\(\\) on an unknown class Symfony\\\\Component\\\\HttpKernel\\\\UriSigner\\.$#"
count: 1
path: tests/AcceptanceTests/VerifyEmailAcceptanceTest.php

-
message: "#^Parameter \\#2 \\$data of function hash_hmac expects string, string\\|false given\\.$#"
count: 3
count: 2
path: tests/AcceptanceTests/VerifyEmailAcceptanceTest.php

-
message: "#^Parameter \\#2 \\$user_string of function hash_equals expects string, array\\|string given\\.$#"
message: "#^Parameter \\$uriSigner of method SymfonyCasts\\\\Bundle\\\\VerifyEmail\\\\Tests\\\\AcceptanceTests\\\\VerifyEmailAcceptanceFixture\\:\\:__construct\\(\\) has invalid type Symfony\\\\Component\\\\HttpKernel\\\\UriSigner\\.$#"
count: 1
path: tests/AcceptanceTests/VerifyEmailAcceptanceTest.php

-
message: "#^Property SymfonyCasts\\\\Bundle\\\\VerifyEmail\\\\Tests\\\\AcceptanceTests\\\\VerifyEmailAcceptanceFixture\\:\\:\\$helper has no type specified\\.$#"
message: "#^Property SymfonyCasts\\\\Bundle\\\\VerifyEmail\\\\Tests\\\\AcceptanceTests\\\\VerifyEmailAcceptanceFixture\\:\\:\\$uriSigner has unknown class Symfony\\\\Component\\\\HttpKernel\\\\UriSigner as its type\\.$#"
count: 1
path: tests/AcceptanceTests/VerifyEmailAcceptanceTest.php

-
message: "#^Call to method sign\\(\\) on an unknown class Symfony\\\\Component\\\\HttpKernel\\\\UriSigner\\.$#"
count: 1
path: tests/FunctionalTests/VerifyEmailHelperFunctionalTest.php

-
message: "#^Cannot access offset 'query' on array\\{scheme\\?\\: string, host\\?\\: string, port\\?\\: int\\<0, 65535\\>, user\\?\\: string, pass\\?\\: string, path\\?\\: string, query\\?\\: string, fragment\\?\\: string\\}\\|false\\.$#"
count: 2
count: 1
path: tests/FunctionalTests/VerifyEmailHelperFunctionalTest.php

-
Expand All @@ -131,13 +136,13 @@ parameters:
path: tests/FunctionalTests/VerifyEmailHelperFunctionalTest.php

-
message: "#^Parameter \\#2 \\$data of function hash_hmac expects string, string\\|false given\\.$#"
message: "#^Method SymfonyCasts\\\\Bundle\\\\VerifyEmail\\\\Tests\\\\FunctionalTests\\\\VerifyEmailHelperFunctionalTest\\:\\:getTestSignature\\(\\) is unused\\.$#"
count: 1
path: tests/FunctionalTests/VerifyEmailHelperFunctionalTest.php

-
message: "#^Parameter \\#2 \\$user_string of function hash_equals expects string, array\\|string given\\.$#"
count: 2
message: "#^Parameter \\#2 \\$data of function hash_hmac expects string, string\\|false given\\.$#"
count: 1
path: tests/FunctionalTests/VerifyEmailHelperFunctionalTest.php

-
Expand All @@ -150,6 +155,11 @@ parameters:
count: 1
path: tests/FunctionalTests/VerifyEmailHelperFunctionalTest.php

-
message: "#^Property SymfonyCasts\\\\Bundle\\\\VerifyEmail\\\\Tests\\\\FunctionalTests\\\\VerifyEmailHelperFunctionalTest\\:\\:\\$uriSigner has unknown class Symfony\\\\Component\\\\HttpKernel\\\\UriSigner as its type\\.$#"
count: 1
path: tests/FunctionalTests/VerifyEmailHelperFunctionalTest.php

-
message: "#^Constructor of class SymfonyCasts\\\\Bundle\\\\VerifyEmail\\\\Tests\\\\IntegrationTests\\\\VerifyEmailHelperAutowireTest has an unused parameter \\$helper\\.$#"
count: 1
Expand All @@ -170,6 +180,11 @@ parameters:
count: 1
path: tests/UnitTests/Exception/VerifyEmailExceptionTest.php

-
message: "#^Parameter \\#2 \\$array of static method PHPUnit\\\\Framework\\\\Assert\\:\\:assertArrayHasKey\\(\\) expects array\\|ArrayAccess, array\\<string, class\\-string\\>\\|false given\\.$#"
count: 1
path: tests/UnitTests/Exception/VerifyEmailExceptionTest.php

-
message: "#^Parameter \\#2 \\$data of function hash_hmac expects string, string\\|false given\\.$#"
count: 1
Expand Down Expand Up @@ -224,8 +239,3 @@ parameters:
message: "#^Property SymfonyCasts\\\\Bundle\\\\VerifyEmail\\\\Tests\\\\VerifyEmailTestKernel\\:\\:\\$routes has no type specified\\.$#"
count: 1
path: tests/VerifyEmailTestKernel.php

-
identifier: argument.type
count: 1
path: tests/UnitTests/Exception/VerifyEmailExceptionTest.php
47 changes: 19 additions & 28 deletions tests/AcceptanceTests/VerifyEmailAcceptanceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\UriSigner;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\HttpKernel\UriSigner as LegacyUriSigner;
use SymfonyCasts\Bundle\VerifyEmail\Generator\VerifyEmailTokenGenerator;
use SymfonyCasts\Bundle\VerifyEmail\Tests\VerifyEmailTestKernel;
use SymfonyCasts\Bundle\VerifyEmail\VerifyEmailHelper;
use SymfonyCasts\Bundle\VerifyEmail\VerifyEmailHelperInterface;
Expand All @@ -32,36 +35,22 @@ final class VerifyEmailAcceptanceTest extends TestCase
public function testGenerateSignature(): void
{
$kernel = $this->getBootedKernel();

$container = $kernel->getContainer();

/** @var VerifyEmailHelper $helper */
$helper = $container->get(VerifyEmailAcceptanceFixture::class)->helper;
/** @var VerifyEmailAcceptanceFixture $testHelper */
$testHelper = $container->get(VerifyEmailAcceptanceFixture::class);
$helper = $testHelper->helper;

$components = $helper->generateSignature('verify-test', '1234', '[email protected]');

$signature = $components->getSignedUrl();
$expiresAt = $components->getExpiresAt()->getTimestamp();

$expectedUserData = json_encode(['1234', '[email protected]']);

$expectedToken = base64_encode(hash_hmac('sha256', $expectedUserData, 'foo', true));

$expectedSignature = base64_encode(hash_hmac(
'sha256',
\sprintf('http://localhost/verify/user?expires=%s&token=%s', $expiresAt, urlencode($expectedToken)),
'foo',
true
$actual = $components->getSignedUrl();
$expected = $testHelper->uriSigner->sign(\sprintf(
'http://localhost/verify/user?expires=%s&token=%s',
$expiresAt,
$testHelper->generator->createToken('1234', '[email protected]')
));

$parsed = parse_url($signature);
parse_str($parsed['query'], $result);

self::assertTrue(hash_equals($expectedSignature, $result['signature']));
self::assertSame(
\sprintf('http://localhost/verify/user?expires=%s&signature=%s&token=%s', $expiresAt, urlencode($expectedSignature), urlencode($expectedToken)),
$signature
);
self::assertSame($expected, $actual);
}

/** @group legacy */
Expand Down Expand Up @@ -133,6 +122,8 @@ private function getBootedKernel(): KernelInterface
$builder = new ContainerBuilder();
$builder->autowire(VerifyEmailAcceptanceFixture::class)
->setPublic(true)
->setArgument(1, new Reference('symfonycasts.verify_email.uri_signer'))
->setArgument(2, new Reference('symfonycasts.verify_email.token_generator'))
;

$kernel = new VerifyEmailTestKernel(
Expand All @@ -148,10 +139,10 @@ private function getBootedKernel(): KernelInterface

final class VerifyEmailAcceptanceFixture
{
public $helper;

public function __construct(VerifyEmailHelperInterface $helper)
{
$this->helper = $helper;
public function __construct(
public VerifyEmailHelperInterface $helper,
public LegacyUriSigner|UriSigner $uriSigner,
public VerifyEmailTokenGenerator $generator,
) {
}
}
22 changes: 7 additions & 15 deletions tests/FunctionalTests/VerifyEmailHelperFunctionalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
final class VerifyEmailHelperFunctionalTest extends TestCase
{
private $mockRouter;
private UriSigner|LegacyUriSigner $uriSigner;
private $expiryTimestamp;

protected function setUp(): void
Expand Down Expand Up @@ -55,19 +56,10 @@ public function testGenerateSignature(): void
->willReturn(\sprintf('/verify?expires=%s&token=%s', $this->expiryTimestamp, urlencode($token)))
;

$result = $this->getHelper()->generateSignature('app_verify_route', '1234', '[email protected]');
$actual = $this->getHelper()->generateSignature('app_verify_route', '1234', '[email protected]')->getSignedUrl();
$expected = $this->uriSigner->sign(\sprintf('/verify?expires=%s&token=%s', $this->expiryTimestamp, urlencode($token)));

$parsedUri = parse_url($result->getSignedUrl());
parse_str($parsedUri['query'], $queryParams);

$knownToken = $token;
$testToken = $queryParams['token'];

$knownSignature = $this->getTestSignature();
$testSignature = $queryParams['signature'];

self::assertTrue(hash_equals($knownToken, $testToken));
self::assertTrue(hash_equals($knownSignature, $testSignature));
self::assertSame($expected, $actual);
}

/**
Expand Down Expand Up @@ -117,14 +109,14 @@ private function getTestSignedUri(): string
private function getHelper(): VerifyEmailHelperInterface
{
if (class_exists(UriSigner::class)) {
$uriSigner = new UriSigner('foo', 'signature');
$this->uriSigner = new UriSigner('foo', 'signature');
} else {
$uriSigner = new LegacyUriSigner('foo', 'signature');
$this->uriSigner = new LegacyUriSigner('foo', 'signature');
}

return new VerifyEmailHelper(
$this->mockRouter,
$uriSigner,
$this->uriSigner,
new VerifyEmailQueryUtility(),
new VerifyEmailTokenGenerator('foo'),
3600
Expand Down

0 comments on commit 936b4b6

Please sign in to comment.