fix: make email readonly in personal data form to prevent user lockout

This commit is contained in:
Björn Fromme
2026-08-11 18:08:48 +02:00
parent a1506ef58d
commit 70a10c4dba
8 changed files with 296 additions and 18 deletions
@@ -5,6 +5,7 @@ declare(strict_types=1);
namespace App\Tests\Controller\Account;
use App\BusProNet\ApiClient;
use App\BusProNet\Model\Notification;
use App\BusProNet\Model\PersonalData;
use App\Controller\Account\PersonalDataController;
use App\Entity\User;
@@ -150,6 +151,49 @@ class PersonalDataControllerTest extends TestCase
], $controller->flashes);
}
/**
* The e-mail lives on the BPN address and doubles as the login identity of every person on it,
* so this form must never accept a submitted value for it.
*/
public function testIndexLocksTheEmailField(): void
{
$controller = $this->createController();
$controller->apiClient
->method('getPersonalData')
->willReturn($this->createPersonalData('Mia', 'Muster'));
$controller->index(Request::create('/personal-data', 'GET'));
self::assertFalse($controller->createFormOptions['email_editable']);
}
/**
* A failed load yields an empty PersonalData. Handing that to BPN would blank every field we
* never read - including the e-mail, which would lock the customer out of the portal.
*/
public function testIndexDoesNotSubmitTheFormWhenPersonalDataCouldNotBeLoaded(): void
{
$controller = $this->createController();
$controller->apiClient
->expects(self::once())
->method('getPersonalData')
->willReturn(new Notification(500, 'no such customer'));
$controller->apiClient
->expects(self::never())
->method('updatePersonalData');
$controller->form
->expects(self::never())
->method('handleRequest');
$response = $controller->index(Request::create('/personal-data', 'POST', [
'personal_data' => ['email' => '[email protected]'],
]));
self::assertSame(200, $response->getStatusCode());
self::assertSame('account/personal_data.html.twig', $controller->renderedView);
}
private function createController(): TestablePersonalDataController
{
$user = new User('[email protected]');
@@ -187,8 +231,11 @@ class PersonalDataControllerTest extends TestCase
private function createPersonalData(string $firstName, string $lastName): PersonalData
{
$personalData = new PersonalData();
$personalData->addressId = 4711;
$personalData->personId = 815;
$personalData->firstName = $firstName;
$personalData->name = $lastName;
$personalData->communication->email = '[email protected]';
return $personalData;
}
@@ -208,6 +255,11 @@ final class TestablePersonalDataController extends PersonalDataController
public string $renderedView = '';
/**
* @var array<string, mixed>
*/
public array $createFormOptions = [];
public function __construct(
public readonly ApiClient $apiClient,
Crypt $crypt,
@@ -217,7 +269,7 @@ final class TestablePersonalDataController extends PersonalDataController
public readonly NewsletterManager $newsletterManager,
LoggerInterface $logger,
private readonly User $user,
private readonly FormInterface $form,
public readonly FormInterface $form,
) {
parent::__construct(
$apiClient,
@@ -232,6 +284,8 @@ final class TestablePersonalDataController extends PersonalDataController
public function createForm(string $type, mixed $data = null, array $options = []): FormInterface
{
$this->createFormOptions = $options;
return $this->form;
}