127 lines
5.0 KiB
PHP
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()])
|
|
;
|
|
}
|
|
}
|