Files
myep-team/tests/Form/PickupChoiceWidgetTest.php
T

127 lines
5.0 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Tests\Form;
use App\Entity\Destination;
use App\Service\Common\PickupOptions;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormFactoryInterface;
use Twig\Environment;
/**
* Renders the radio list the way the assignment form does, because the parts that break here
* only break at render time: templates/forms.html.twig reads the departure and the street off
* each choice, twig runs with strict_variables, and the "Keine Busbegleitung" placeholder is a
* choice that carries neither.
*/
class PickupChoiceWidgetTest extends KernelTestCase
{
public function testEveryBoardingPointIsRenderedWithItsTimeAndStreet(): void
{
$html = $this->render([
['busProId' => 74, 'city' => 'Stuttgart', 'street' => 'Flughafen (Busterminal)', 'time' => '03:15'],
['busProId' => 673, 'city' => 'Stuttgart', 'street' => 'Schelmenwasenstr. 15', 'time' => '03:15'],
]);
$this->assertSame(3, substr_count($html, 'type="radio"'), 'two boarding points plus the placeholder');
$this->assertSame(2, substr_count($html, '>Stuttgart<'));
$this->assertStringContainsString('Flughafen (Busterminal)', $html);
$this->assertStringContainsString('Schelmenwasenstr. 15', $html);
$this->assertSame(2, substr_count($html, '03:15 Uhr'));
}
public function testThePlaceholderRendersWithoutADepartureOrStreet(): void
{
$html = $this->render([
['busProId' => 4, 'city' => 'Karlsruhe', 'street' => 'A5 - Autohof', 'time' => '23:59'],
]);
$this->assertStringContainsString('Keine Busbegleitung', $html);
// one time only: the placeholder must not pick up the boarding point's
$this->assertSame(1, substr_count($html, 'Uhr'));
}
public function testAFullDateInTheSourceIsRenderedAsAClock(): void
{
$html = $this->render([
['busProId' => 1, 'city' => 'Hannover', 'street' => 'ZOB', 'time' => '08.03.2024 20:45:00'],
]);
$this->assertStringContainsString('20:45 Uhr', $html);
$this->assertStringNotContainsString('08.03.2024', $html);
}
public function testABoardingPointWithoutATimeOrStreetStillRenders(): void
{
$html = $this->render([
['busProId' => 4711, 'city' => null, 'street' => null, 'time' => null],
]);
$this->assertStringContainsString('Zustieg 4711', $html);
$this->assertStringNotContainsString('Uhr', $html);
}
public function testWithoutADestinationTheFieldExplainsItselfInsteadOfShowingAnEmptySelect(): void
{
$html = $this->render([], 'Bitte erst eine Destination wählen …');
$this->assertStringContainsString('Bitte erst eine Destination wählen', $html);
$this->assertStringNotContainsString('type="radio"', $html);
}
public function testADestinationWithoutBoardingPointsSaysSoInstead(): void
{
// 1271 of 2267 destinations carry no boarding points at all
$html = $this->render([], 'Für diese Destination sind keine Zustiege hinterlegt.');
$this->assertStringContainsString('keine Zustiege hinterlegt', $html);
$this->assertStringNotContainsString('type="radio"', $html);
}
/**
* @param list<array<string, mixed>> $pickups
*/
private function render(array $pickups, string $emptyText = 'Keine Zustiege verfügbar.'): string
{
self::bootKernel();
$options = PickupOptions::inDepartureOrder((new Destination())->setPickups($pickups));
$labels = array_column($options, 'label', 'busProId');
$attributes = [];
foreach ($options as $option) {
$attributes[$option['busProId']] = [
'data-departure' => $option['departure'] ?? '',
'data-street' => $option['street'] ?? '',
];
}
/** @var FormFactoryInterface $formFactory */
$formFactory = self::getContainer()->get('form.factory');
$form = $formFactory->createNamed('pickup', ChoiceType::class, null, [
'label' => 'Busbegleitung ab',
'required' => false,
'placeholder' => 'Keine Busbegleitung',
'choices' => array_column($options, 'busProId'),
'choice_label' => static fn (int $busProId): string => $labels[$busProId],
'choice_attr' => static fn (int $busProId): array => $attributes[$busProId],
'expanded' => true,
'block_prefix' => 'pickup_choice',
'attr' => ['data-empty-text' => $emptyText],
// a bare field rendered outside a request, so there is no session to hold a token
'csrf_protection' => false,
]);
/** @var Environment $twig */
$twig = self::getContainer()->get('twig');
return $twig
->createTemplate('{{ form_widget(form) }}')
->render(['form' => $form->createView()])
;
}
}