Skip to content

Commit

Permalink
refactor token generator unit test
Browse files Browse the repository at this point in the history
  • Loading branch information
jrushlow committed May 16, 2024
1 parent 07b2244 commit 7a82b0c
Showing 1 changed file with 51 additions and 73 deletions.
124 changes: 51 additions & 73 deletions tests/Unit/Generator/ResetPasswordTokenGeneratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,93 +20,71 @@
*/
class ResetPasswordTokenGeneratorTest extends TestCase
{
/**
* @var MockObject|ResetPasswordRandomGenerator
*/
private $mockRandomGenerator;

/**
* @var MockObject|\DateTimeImmutable
*/
private $mockExpiresAt;
private MockObject&\DateTimeImmutable $mockExpiresAt;
private ResetPasswordTokenGenerator $tokenGenerator;

protected function setUp(): void
{
$this->mockRandomGenerator = $this->createMock(ResetPasswordRandomGenerator::class);
$this->mockExpiresAt = $this->createMock(\DateTimeImmutable::class);
$this->tokenGenerator = new ResetPasswordTokenGenerator('secret-key', new ResetPasswordRandomGenerator());
}

public function testSelectorGeneratedByRandomGenerator(): void
public function testCreateTokenReturnsValidHashedTokenComponents(): void
{
$this->mockRandomGenerator
->expects($this->exactly(2))
->method('getRandomAlphaNumStr')
;
$result = $this->tokenGenerator->createToken($this->mockExpiresAt, 'userId');

$generator = $this->getTokenGenerator();
$generator->createToken($this->mockExpiresAt, 'userId');
}
// The public token = "selector token" + "verifier token"
self::assertSame(20, \strlen($result->getSelector()));
self::assertSame(40, \strlen($result->getPublicToken()));

public function testHashedTokenIsCreatedWithExpectedParams(): void
{
$this->mockRandomGenerator
->expects($this->exactly(2))
->method('getRandomAlphaNumStr')
->willReturnOnConsecutiveCalls('verifier', 'selector')
;

$this->mockExpiresAt
->expects($this->once())
->method('getTimestamp')
->willReturn(2020)
;

$expected = hash_hmac(
'sha256',
json_encode(['verifier', 'user1234', 2020]),
'key',
true
);

$generator = $this->getTokenGenerator();
$result = $generator->createToken($this->mockExpiresAt, 'user1234');

self::assertSame(base64_encode($expected), $result->getHashedToken());
$verifier = substr($result->getPublicToken(), 20, 20);

$expectedHash = base64_encode(hash_hmac(
algo: 'sha256',
data: json_encode([$verifier, 'userId', $this->mockExpiresAt->getTimestamp()]),
key: 'secret-key',
binary: true
));

self::assertSame($expectedHash, $result->getHashedToken());
}

public function testHashedTokenIsCreatedUsingOptionVerifierParam(): void
public function testCreateTokenUsesProvidedVerifierToken(): void
{
$date = 2020;
$userId = 'user1234';
$knownVerifier = 'verified';

$this->mockRandomGenerator
->expects($this->once())
->method('getRandomAlphaNumStr')
->willReturnOnConsecutiveCalls('un-used-verifier', 'selector')
;

$this->mockExpiresAt
->expects($this->once())
->method('getTimestamp')
->willReturn($date)
;

$knownToken = hash_hmac(
'sha256',
json_encode([$knownVerifier, $userId, $date]),
'key',
true
);

$generator = $this->getTokenGenerator();
$result = $generator->createToken($this->mockExpiresAt, $userId, $knownVerifier);

self::assertSame(base64_encode($knownToken), $result->getHashedToken());
$result = $this->tokenGenerator->createToken($this->mockExpiresAt, 'userId', '1234');

$expectedHash = base64_encode(hash_hmac(
algo: 'sha256',
data: json_encode(['1234', 'userId', $this->mockExpiresAt->getTimestamp()]),
key: 'secret-key',
binary: true
));

self::assertSame($expectedHash, $result->getHashedToken());
}

private function getTokenGenerator(): ResetPasswordTokenGenerator
public function testCreateTokenUsesProvidedParams(): void
{
return new ResetPasswordTokenGenerator('key', $this->mockRandomGenerator);
$result = $this->tokenGenerator->createToken($this->mockExpiresAt, 'userId', '1234');

$expectedHash = base64_encode(hash_hmac(
algo: 'sha256',
data: json_encode(['1234', 'userId', '0123456789']),
key: 'secret-key',
binary: true
));

// We used a "fake" timestamp in our expectedHash
self::assertNotSame($expectedHash, $result->getHashedToken());

$expectedHash = base64_encode(hash_hmac(
algo: 'sha256',
data: json_encode(['1234', 'bad-user-id', $this->mockExpiresAt->getTimestamp()]),
key: 'secret-key',
binary: true
));

// We used a "fake" user id in our expectedHash
self::assertNotSame($expectedHash, $result->getHashedToken());
}
}

0 comments on commit 7a82b0c

Please sign in to comment.