'on']); $client->disableReboot(); $rateLimiter = $this->createMock(PublicFormRateLimiter::class); $rateLimiter ->expects(self::once()) ->method('isPortalAccessAllowed') ->with('customer@example.com', self::isInstanceOf(Request::class)) ->willReturn(true); $guestAccountManager = $this->createMock(BookingGuestAccountManager::class); $guestAccountManager ->expects(self::once()) ->method('requestPortalAccess') ->with('customer@example.com', 123) ->willReturn(BookingGuestAccountManager::PORTAL_ACCESS_SENT); self::getContainer()->set(PublicFormRateLimiter::class, $rateLimiter); self::getContainer()->set(BookingGuestAccountManager::class, $guestAccountManager); $crawler = $client->request('GET', '/'); $token = $crawler->filter('input[name="_token"]')->attr('value'); $client->request('POST', '/portal-access/request', [ 'email' => 'customer@example.com', 'bookingNumber' => '123', '_token' => $token, ]); self::assertResponseRedirects('/'); $client->followRedirect(); self::assertStringContainsString('Wenn zu deiner Buchung ein Portalzugang möglich ist, haben wir dir eine E-Mail gesendet.', $client->getResponse()->getContent()); } public function testPortalAccessRequestRejectsMismatchedBookingGenerically(): void { $client = self::createClient([], ['HTTPS' => 'on']); $client->disableReboot(); $rateLimiter = $this->createMock(PublicFormRateLimiter::class); $rateLimiter ->expects(self::once()) ->method('isPortalAccessAllowed') ->with('customer@example.com', self::isInstanceOf(Request::class)) ->willReturn(true); $guestAccountManager = $this->createMock(BookingGuestAccountManager::class); $guestAccountManager ->expects(self::once()) ->method('requestPortalAccess') ->with('customer@example.com', 123) ->willReturn(BookingGuestAccountManager::PORTAL_ACCESS_NOT_SENT); self::getContainer()->set(PublicFormRateLimiter::class, $rateLimiter); self::getContainer()->set(BookingGuestAccountManager::class, $guestAccountManager); $crawler = $client->request('GET', '/'); $token = $crawler->filter('input[name="_token"]')->attr('value'); $client->request('POST', '/portal-access/request', [ 'email' => 'customer@example.com', 'bookingNumber' => '123', '_token' => $token, ]); self::assertResponseRedirects('/'); $client->followRedirect(); self::assertStringContainsString('Wenn zu deiner Buchung ein Portalzugang möglich ist, haben wir dir eine E-Mail gesendet.', $client->getResponse()->getContent()); } public function testPortalAccessRequestShowsLoginHintForAlreadyActiveAccount(): void { $client = self::createClient([], ['HTTPS' => 'on']); $client->disableReboot(); $rateLimiter = $this->createMock(PublicFormRateLimiter::class); $rateLimiter ->expects(self::once()) ->method('isPortalAccessAllowed') ->with('customer@example.com', self::isInstanceOf(Request::class)) ->willReturn(true); $guestAccountManager = $this->createMock(BookingGuestAccountManager::class); $guestAccountManager ->expects(self::once()) ->method('requestPortalAccess') ->with('customer@example.com', 123) ->willReturn(BookingGuestAccountManager::PORTAL_ACCESS_ALREADY_ACTIVE); self::getContainer()->set(PublicFormRateLimiter::class, $rateLimiter); self::getContainer()->set(BookingGuestAccountManager::class, $guestAccountManager); $crawler = $client->request('GET', '/'); $token = $crawler->filter('input[name="_token"]')->attr('value'); $client->request('POST', '/portal-access/request', [ 'email' => 'customer@example.com', 'bookingNumber' => '123', '_token' => $token, ]); self::assertResponseRedirects('/'); $client->followRedirect(); self::assertStringContainsString('Für diese E-Mail-Adresse besteht bereits ein aktiver Portalzugang.', $client->getResponse()->getContent()); } public function testPortalAccessRequestReturns429WhenThrottled(): void { $client = self::createClient([], ['HTTPS' => 'on']); $client->disableReboot(); $rateLimiter = $this->createMock(PublicFormRateLimiter::class); $rateLimiter ->expects(self::once()) ->method('isPortalAccessAllowed') ->with('customer@example.com', self::isInstanceOf(Request::class)) ->willReturn(false); $guestAccountManager = $this->createMock(BookingGuestAccountManager::class); $guestAccountManager->expects(self::never())->method('requestPortalAccess'); self::getContainer()->set(PublicFormRateLimiter::class, $rateLimiter); self::getContainer()->set(BookingGuestAccountManager::class, $guestAccountManager); $crawler = $client->request('GET', '/'); $token = $crawler->filter('input[name="_token"]')->attr('value'); $client->request('POST', '/portal-access/request', [ 'email' => 'customer@example.com', 'bookingNumber' => '123', '_token' => $token, ]); self::assertResponseStatusCodeSame(429); self::assertStringContainsString(PublicFormRateLimiter::THROTTLED_MESSAGE, $client->getResponse()->getContent()); } }