chore: drop the teamer provisioning feature flag

This commit is contained in:
fromme committed 2026-09-25 14:51:39 +02:00
1 parent b530679658
commit 5141673bcd
5 files changed
+135 -82

No files matched your search

@@ -12,13 +12,13 @@ use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\HttpFoundation\Response;
/**
* The feature gate, which is the only part of provisioning a test can exercise: everything behind
* it writes to the production CRM, where the teamer selection is changeable - the test database
* answers aenderbar="False" for it (.ddev/plans/buspro-crm-selection-write.md).
* Everything around the provisioning click that can be exercised without writing to BusPro.
*
* With the flag off the route must not exist at all, not merely hide its button: the modal is
* reachable by url, and a reviewer who bookmarked it would otherwise write to BusPro from a
* release where the feature is meant to be dormant.
* The write itself cannot: the teamer CRM selection is only changeable in the production database
* (.ddev/plans/buspro-crm-selection-write.md), and a POST that gets as far as the api client would
* open a socket to it from a test. TeamerProvisionerTest covers the flow against a mocked client;
* what is left here is the route, the confirmation and the one POST that is safe to make - a
* submission TeamerProvisioner refuses before it sends anything.
*/
class CreateTeamerControllerTest extends WebTestCase
{
@@ -37,51 +37,115 @@ class CreateTeamerControllerTest extends WebTestCase
$this->client->loginUser($this->reviewer());
}
public function testTheDisabledFeatureHidesTheRouteEntirely(): void
public function testTheDetailPageOffersTheProvisioningButton(): void
{
$this->client->request('GET', $this->url());
$submission = $this->submission();
$this->assertSame(Response::HTTP_NOT_FOUND, $this->client->getResponse()->getStatusCode());
}
/**
* The POST is the one that writes, so it is pinned separately rather than trusted to share the
* guard with the GET.
*/
public function testTheDisabledFeatureRefusesThePostAsWell(): void
{
$this->client->request('POST', $this->url());
$this->assertSame(Response::HTTP_NOT_FOUND, $this->client->getResponse()->getStatusCode());
$this->assertNull($this->submission()->getTeamerCreatedAt());
}
public function testTheDetailPageOffersNoProvisioningWhileTheFeatureIsOff(): void
{
$crawler = $this->client->request(
'GET',
sprintf('/admin/application-form-submission/detail/%s', $this->submission()->getUuid())
sprintf('/admin/application-form-submission/detail/%s', $submission->getUuid()),
['r' => rawurlencode('/admin/application-form-submission')]
);
$this->assertSame(Response::HTTP_OK, $this->client->getResponse()->getStatusCode());
$this->assertCount(0, $crawler->filter('button[hx-get*="create-teamer"]'));
$button = $crawler->filter('button[hx-get*="create-teamer"]');
$this->assertCount(1, $button);
// Like every other action on that page: it hands on the return url it was given, so "zurück"
// keeps pointing at the list.
$this->assertStringContainsString('r='.rawurlencode('/admin/application-form-submission'), (string) $button->attr('hx-get'));
}
private function url(): string
/**
* The three writes cannot be undone from here, so the confirmation names what goes to BusPro
* rather than asking "are you sure".
*/
public function testTheConfirmationNamesWhatGoesToBusPro(): void
{
return sprintf('/admin/application-form-submission/create-teamer/%s', $this->submission()->getUuid());
$crawler = $this->client->request('GET', $this->url($this->submission()));
$this->assertSame(Response::HTTP_OK, $this->client->getResponse()->getStatusCode());
$modal = $crawler->filter('#htmx-confirmation-modal')->text();
$this->assertStringContainsString('Anna Muster', $modal);
$this->assertStringContainsString('01.01.1990', $modal);
$this->assertStringContainsString('Musterstraße 1, 10115 Berlin', $modal);
}
/**
* A row from before the tightened endpoint contract. The confirmation says so before the
* reviewer clicks, because BusPro would answer the same thing only after the attempt.
*/
public function testTheConfirmationFlagsAnIncompleteSubmission(): void
{
$crawler = $this->client->request('GET', $this->url($this->incompleteSubmission()));
$modal = $crawler->filter('#htmx-confirmation-modal')->text();
$this->assertStringContainsString('ohne Geburtsdatum', $modal);
$this->assertStringContainsString('ohne Straße, PLZ und Ort', $modal);
}
/**
* The only POST a test may make: TeamerProvisioner refuses an unprovisionable submission before
* it touches the api client, so nothing here reaches BusPro. It covers what the reviewer
* actually sees when provisioning fails - the refusal's own wording, not "es ist ein Fehler
* aufgetreten".
*/
public function testAnUnprovisionableSubmissionFailsWithoutWritingAnything(): void
{
$submission = $this->incompleteSubmission();
$this->client->request('POST', $this->url($submission));
$response = $this->client->getResponse();
$this->assertSame(Response::HTTP_OK, $response->getStatusCode());
$this->assertStringContainsString('detail', (string) $response->headers->get('HX-Redirect'));
$flashes = $this->client->getRequest()->getSession()->getFlashBag()->peekAll();
$this->assertArrayHasKey('error', $flashes);
$this->assertStringContainsString('Geburtsdatum', $flashes['error'][0]);
$this->entityManager->clear();
$stored = $this->entityManager->getRepository(ApplicationFormSubmission::class)->find($submission->getId());
$this->assertNotNull($stored);
$this->assertFalse($stored->isProvisioned());
$this->assertNull($stored->getBusProAddressId());
$this->assertNull($stored->getUser());
}
private function url(ApplicationFormSubmission $submission): string
{
return sprintf('/admin/application-form-submission/create-teamer/%s', $submission->getUuid());
}
private function submission(): ApplicationFormSubmission
{
$repository = $this->entityManager->getRepository(ApplicationFormSubmission::class);
$submission = $repository->findOneBy([], ['id' => 'DESC']);
return $this->persist(
$this->newSubmission()
->setBirthDate('1990-01-01')
->setStreet('Musterstraße 1')
->setZipCode('10115')
->setCity('Berlin')
);
}
if (null !== $submission) {
return $submission;
}
/**
* Everything the contract now requires, missing - which only a row stored before it can be.
*/
private function incompleteSubmission(): ApplicationFormSubmission
{
return $this->persist($this->newSubmission()->setBirthDate('01.01.1990'));
}
$submission = (new ApplicationFormSubmission(
private function newSubmission(): ApplicationFormSubmission
{
return (new ApplicationFormSubmission(
'applicationform',
'Bewerbungsformular',
new \DateTimeImmutable('2026-09-22T12:30:00+02:00'),
@@ -90,9 +154,11 @@ class CreateTeamerControllerTest extends WebTestCase
->setFirstName('Anna')
->setLastName('Muster')
->setEmail('[email protected]')
->setBirthDate('1990-01-01')
;
}
private function persist(ApplicationFormSubmission $submission): ApplicationFormSubmission
{
$this->entityManager->persist($submission);
$this->entityManager->flush();