175 lines
6.4 KiB
PHP
175 lines
6.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Tests\Controller;
|
|
|
|
use App\Entity\User;
|
|
use App\Service\PasswordResetManager;
|
|
use App\Service\PublicFormRateLimiter;
|
|
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
|
|
class ResetPasswordControllerTest extends WebTestCase
|
|
{
|
|
public function testPasswordResetRequestUsesGenericSuccessMessageForExistingAccount(): void
|
|
{
|
|
$client = self::createClient([], [
|
|
'HTTPS' => 'on',
|
|
'HTTP_HX_REQUEST' => 'true',
|
|
]);
|
|
$client->disableReboot();
|
|
|
|
$manager = $this->createMock(PasswordResetManager::class);
|
|
$manager
|
|
->expects(self::once())
|
|
->method('requestPasswordReset')
|
|
->with('[email protected]')
|
|
->willReturn(true);
|
|
self::getContainer()->set(PasswordResetManager::class, $manager);
|
|
|
|
$crawler = $client->request('GET', '/reset-password');
|
|
$form = $crawler->selectButton('Passwort-Reset-Link anfordern')->form([
|
|
'form[email]' => '[email protected]',
|
|
]);
|
|
$client->submit($form);
|
|
|
|
self::assertResponseRedirects('/');
|
|
$client->followRedirect();
|
|
|
|
self::assertStringContainsString('Du erhältst in Kürze eine E-Mail mit einem Link zum Zurücksetzen deines Passworts', $client->getResponse()->getContent());
|
|
}
|
|
|
|
public function testPasswordResetRequestUsesSameGenericSuccessMessageForMissingAccount(): void
|
|
{
|
|
$client = self::createClient([], [
|
|
'HTTPS' => 'on',
|
|
]);
|
|
$client->disableReboot();
|
|
|
|
$manager = $this->createMock(PasswordResetManager::class);
|
|
$manager
|
|
->expects(self::once())
|
|
->method('requestPasswordReset')
|
|
->with('[email protected]')
|
|
->willReturn(false);
|
|
self::getContainer()->set(PasswordResetManager::class, $manager);
|
|
|
|
$crawler = $client->request('GET', '/reset-password');
|
|
$form = $crawler->selectButton('Passwort-Reset-Link anfordern')->form([
|
|
'form[email]' => '[email protected]',
|
|
]);
|
|
$client->submit($form);
|
|
|
|
self::assertResponseRedirects('/');
|
|
$client->followRedirect();
|
|
|
|
self::assertStringContainsString('Du erhältst in Kürze eine E-Mail mit einem Link zum Zurücksetzen deines Passworts', $client->getResponse()->getContent());
|
|
}
|
|
|
|
public function testPasswordResetRequestReturns429WhenThrottled(): void
|
|
{
|
|
$client = self::createClient([], [
|
|
'HTTPS' => 'on',
|
|
]);
|
|
$client->disableReboot();
|
|
|
|
$email = sprintf('throttle-%[email protected]', bin2hex(random_bytes(4)));
|
|
|
|
$manager = $this->createMock(PasswordResetManager::class);
|
|
$manager
|
|
->expects(self::exactly(5))
|
|
->method('requestPasswordReset')
|
|
->with($email)
|
|
->willReturn(true);
|
|
self::getContainer()->set(PasswordResetManager::class, $manager);
|
|
|
|
for ($i = 0; $i < 5; ++$i) {
|
|
$crawler = $client->request('GET', '/reset-password');
|
|
$form = $crawler->selectButton('Passwort-Reset-Link anfordern')->form([
|
|
'form[email]' => $email,
|
|
]);
|
|
$client->submit($form);
|
|
|
|
self::assertResponseRedirects('/');
|
|
$client->followRedirect();
|
|
}
|
|
|
|
$crawler = $client->request('GET', '/reset-password');
|
|
$form = $crawler->selectButton('Passwort-Reset-Link anfordern')->form([
|
|
'form[email]' => $email,
|
|
]);
|
|
$client->submit($form);
|
|
|
|
self::assertResponseStatusCodeSame(429);
|
|
self::assertStringContainsString(PublicFormRateLimiter::THROTTLED_MESSAGE, $client->getResponse()->getContent());
|
|
}
|
|
|
|
public function testPasswordResetConfirmationDisplaysFormAndUpdatesPassword(): void
|
|
{
|
|
$client = self::createClient([], [
|
|
'HTTPS' => 'on',
|
|
]);
|
|
$client->disableReboot();
|
|
|
|
$user = new User('[email protected]');
|
|
$manager = $this->createMock(PasswordResetManager::class);
|
|
$manager
|
|
->expects(self::exactly(2))
|
|
->method('validateResetRequest')
|
|
->with(self::isInstanceOf(Request::class))
|
|
->willReturn($user);
|
|
$manager
|
|
->expects(self::once())
|
|
->method('resetPassword')
|
|
->with($user, 'Str0ng-Passw0rd!');
|
|
self::getContainer()->set(PasswordResetManager::class, $manager);
|
|
|
|
$crawler = $client->request('GET', '/reset-password/[email protected]&nonce=token&expires=9999999999&_hash=signature');
|
|
self::assertResponseIsSuccessful();
|
|
self::assertSelectorTextContains('h1', 'Neues Passwort');
|
|
|
|
$form = $crawler->selectButton('Passwort speichern')->form([
|
|
'form[password][first]' => 'Str0ng-Passw0rd!',
|
|
'form[password][second]' => 'Str0ng-Passw0rd!',
|
|
]);
|
|
$client->submit($form);
|
|
|
|
self::assertResponseRedirects('/');
|
|
$client->followRedirect();
|
|
|
|
self::assertStringContainsString('Dein Passwort wurde aktualisiert', $client->getResponse()->getContent());
|
|
}
|
|
|
|
public function testPasswordResetConfirmationRejectsTooShortPasswordBeforeSaving(): void
|
|
{
|
|
$client = self::createClient([], [
|
|
'HTTPS' => 'on',
|
|
]);
|
|
$client->disableReboot();
|
|
|
|
$user = new User('[email protected]');
|
|
$manager = $this->createMock(PasswordResetManager::class);
|
|
$manager
|
|
->expects(self::exactly(2))
|
|
->method('validateResetRequest')
|
|
->with(self::isInstanceOf(Request::class))
|
|
->willReturn($user);
|
|
$manager->expects(self::never())->method('resetPassword');
|
|
self::getContainer()->set(PasswordResetManager::class, $manager);
|
|
|
|
$crawler = $client->request('GET', '/reset-password/[email protected]&nonce=token&expires=9999999999&_hash=signature');
|
|
self::assertResponseIsSuccessful();
|
|
self::assertSelectorTextContains('h1', 'Neues Passwort');
|
|
|
|
$form = $crawler->selectButton('Passwort speichern')->form([
|
|
'form[password][first]' => 'short7',
|
|
'form[password][second]' => 'short7',
|
|
]);
|
|
$client->submit($form);
|
|
|
|
self::assertResponseStatusCodeSame(422);
|
|
self::assertStringContainsString('Das Passwort muss mindestens 8 Zeichen lang sein.', $client->getResponse()->getContent());
|
|
}
|
|
}
|