Skip to content

Commit 936b4b6

Browse files
authored
minor: fix tests for url-safe signed urls (#203)
1 parent 2cb1cd9 commit 936b4b6

File tree

3 files changed

+50
-57
lines changed

3 files changed

+50
-57
lines changed

phpstan-baseline.neon

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -97,32 +97,37 @@ parameters:
9797

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

103103
-
104-
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\\.$#"
104+
message: "#^Call to method sign\\(\\) on an unknown class Symfony\\\\Component\\\\HttpKernel\\\\UriSigner\\.$#"
105105
count: 1
106106
path: tests/AcceptanceTests/VerifyEmailAcceptanceTest.php
107107

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

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

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

123+
-
124+
message: "#^Call to method sign\\(\\) on an unknown class Symfony\\\\Component\\\\HttpKernel\\\\UriSigner\\.$#"
125+
count: 1
126+
path: tests/FunctionalTests/VerifyEmailHelperFunctionalTest.php
127+
123128
-
124129
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\\.$#"
125-
count: 2
130+
count: 1
126131
path: tests/FunctionalTests/VerifyEmailHelperFunctionalTest.php
127132

128133
-
@@ -131,13 +136,13 @@ parameters:
131136
path: tests/FunctionalTests/VerifyEmailHelperFunctionalTest.php
132137

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

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

143148
-
@@ -150,6 +155,11 @@ parameters:
150155
count: 1
151156
path: tests/FunctionalTests/VerifyEmailHelperFunctionalTest.php
152157

158+
-
159+
message: "#^Property SymfonyCasts\\\\Bundle\\\\VerifyEmail\\\\Tests\\\\FunctionalTests\\\\VerifyEmailHelperFunctionalTest\\:\\:\\$uriSigner has unknown class Symfony\\\\Component\\\\HttpKernel\\\\UriSigner as its type\\.$#"
160+
count: 1
161+
path: tests/FunctionalTests/VerifyEmailHelperFunctionalTest.php
162+
153163
-
154164
message: "#^Constructor of class SymfonyCasts\\\\Bundle\\\\VerifyEmail\\\\Tests\\\\IntegrationTests\\\\VerifyEmailHelperAutowireTest has an unused parameter \\$helper\\.$#"
155165
count: 1
@@ -170,6 +180,11 @@ parameters:
170180
count: 1
171181
path: tests/UnitTests/Exception/VerifyEmailExceptionTest.php
172182

183+
-
184+
message: "#^Parameter \\#2 \\$array of static method PHPUnit\\\\Framework\\\\Assert\\:\\:assertArrayHasKey\\(\\) expects array\\|ArrayAccess, array\\<string, class\\-string\\>\\|false given\\.$#"
185+
count: 1
186+
path: tests/UnitTests/Exception/VerifyEmailExceptionTest.php
187+
173188
-
174189
message: "#^Parameter \\#2 \\$data of function hash_hmac expects string, string\\|false given\\.$#"
175190
count: 1
@@ -224,8 +239,3 @@ parameters:
224239
message: "#^Property SymfonyCasts\\\\Bundle\\\\VerifyEmail\\\\Tests\\\\VerifyEmailTestKernel\\:\\:\\$routes has no type specified\\.$#"
225240
count: 1
226241
path: tests/VerifyEmailTestKernel.php
227-
228-
-
229-
identifier: argument.type
230-
count: 1
231-
path: tests/UnitTests/Exception/VerifyEmailExceptionTest.php

tests/AcceptanceTests/VerifyEmailAcceptanceTest.php

Lines changed: 19 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@
1111

1212
use PHPUnit\Framework\TestCase;
1313
use Symfony\Component\DependencyInjection\ContainerBuilder;
14+
use Symfony\Component\DependencyInjection\Reference;
1415
use Symfony\Component\HttpFoundation\Request;
1516
use Symfony\Component\HttpFoundation\UriSigner;
1617
use Symfony\Component\HttpKernel\KernelInterface;
18+
use Symfony\Component\HttpKernel\UriSigner as LegacyUriSigner;
19+
use SymfonyCasts\Bundle\VerifyEmail\Generator\VerifyEmailTokenGenerator;
1720
use SymfonyCasts\Bundle\VerifyEmail\Tests\VerifyEmailTestKernel;
1821
use SymfonyCasts\Bundle\VerifyEmail\VerifyEmailHelper;
1922
use SymfonyCasts\Bundle\VerifyEmail\VerifyEmailHelperInterface;
@@ -32,36 +35,22 @@ final class VerifyEmailAcceptanceTest extends TestCase
3235
public function testGenerateSignature(): void
3336
{
3437
$kernel = $this->getBootedKernel();
35-
3638
$container = $kernel->getContainer();
3739

38-
/** @var VerifyEmailHelper $helper */
39-
$helper = $container->get(VerifyEmailAcceptanceFixture::class)->helper;
40+
/** @var VerifyEmailAcceptanceFixture $testHelper */
41+
$testHelper = $container->get(VerifyEmailAcceptanceFixture::class);
42+
$helper = $testHelper->helper;
4043

4144
$components = $helper->generateSignature('verify-test', '1234', 'jr@rushlow.dev');
42-
43-
$signature = $components->getSignedUrl();
4445
$expiresAt = $components->getExpiresAt()->getTimestamp();
45-
46-
$expectedUserData = json_encode(['1234', 'jr@rushlow.dev']);
47-
48-
$expectedToken = base64_encode(hash_hmac('sha256', $expectedUserData, 'foo', true));
49-
50-
$expectedSignature = base64_encode(hash_hmac(
51-
'sha256',
52-
\sprintf('http://localhost/verify/user?expires=%s&token=%s', $expiresAt, urlencode($expectedToken)),
53-
'foo',
54-
true
46+
$actual = $components->getSignedUrl();
47+
$expected = $testHelper->uriSigner->sign(\sprintf(
48+
'http://localhost/verify/user?expires=%s&token=%s',
49+
$expiresAt,
50+
$testHelper->generator->createToken('1234', 'jr@rushlow.dev')
5551
));
5652

57-
$parsed = parse_url($signature);
58-
parse_str($parsed['query'], $result);
59-
60-
self::assertTrue(hash_equals($expectedSignature, $result['signature']));
61-
self::assertSame(
62-
\sprintf('http://localhost/verify/user?expires=%s&signature=%s&token=%s', $expiresAt, urlencode($expectedSignature), urlencode($expectedToken)),
63-
$signature
64-
);
53+
self::assertSame($expected, $actual);
6554
}
6655

6756
/** @group legacy */
@@ -133,6 +122,8 @@ private function getBootedKernel(): KernelInterface
133122
$builder = new ContainerBuilder();
134123
$builder->autowire(VerifyEmailAcceptanceFixture::class)
135124
->setPublic(true)
125+
->setArgument(1, new Reference('symfonycasts.verify_email.uri_signer'))
126+
->setArgument(2, new Reference('symfonycasts.verify_email.token_generator'))
136127
;
137128

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

149140
final class VerifyEmailAcceptanceFixture
150141
{
151-
public $helper;
152-
153-
public function __construct(VerifyEmailHelperInterface $helper)
154-
{
155-
$this->helper = $helper;
142+
public function __construct(
143+
public VerifyEmailHelperInterface $helper,
144+
public LegacyUriSigner|UriSigner $uriSigner,
145+
public VerifyEmailTokenGenerator $generator,
146+
) {
156147
}
157148
}

tests/FunctionalTests/VerifyEmailHelperFunctionalTest.php

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
final class VerifyEmailHelperFunctionalTest extends TestCase
2929
{
3030
private $mockRouter;
31+
private UriSigner|LegacyUriSigner $uriSigner;
3132
private $expiryTimestamp;
3233

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

58-
$result = $this->getHelper()->generateSignature('app_verify_route', '1234', 'jr@rushlow.dev');
59+
$actual = $this->getHelper()->generateSignature('app_verify_route', '1234', 'jr@rushlow.dev')->getSignedUrl();
60+
$expected = $this->uriSigner->sign(\sprintf('/verify?expires=%s&token=%s', $this->expiryTimestamp, urlencode($token)));
5961

60-
$parsedUri = parse_url($result->getSignedUrl());
61-
parse_str($parsedUri['query'], $queryParams);
62-
63-
$knownToken = $token;
64-
$testToken = $queryParams['token'];
65-
66-
$knownSignature = $this->getTestSignature();
67-
$testSignature = $queryParams['signature'];
68-
69-
self::assertTrue(hash_equals($knownToken, $testToken));
70-
self::assertTrue(hash_equals($knownSignature, $testSignature));
62+
self::assertSame($expected, $actual);
7163
}
7264

7365
/**
@@ -117,14 +109,14 @@ private function getTestSignedUri(): string
117109
private function getHelper(): VerifyEmailHelperInterface
118110
{
119111
if (class_exists(UriSigner::class)) {
120-
$uriSigner = new UriSigner('foo', 'signature');
112+
$this->uriSigner = new UriSigner('foo', 'signature');
121113
} else {
122-
$uriSigner = new LegacyUriSigner('foo', 'signature');
114+
$this->uriSigner = new LegacyUriSigner('foo', 'signature');
123115
}
124116

125117
return new VerifyEmailHelper(
126118
$this->mockRouter,
127-
$uriSigner,
119+
$this->uriSigner,
128120
new VerifyEmailQueryUtility(),
129121
new VerifyEmailTokenGenerator('foo'),
130122
3600

0 commit comments

Comments
 (0)