Files

109 lines
4.3 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Tests\Validator\Constraints;
use App\BusProNet\Model\Communication;
use App\BusProNet\Model\PersonalData;
use App\Form\Model\ParticipantDto;
use App\Form\Model\VoucherPurchaseDto;
use App\Validator\Constraints\PhoneNumber;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Validator\Validation;
use Symfony\Component\Validator\Validator\ValidatorInterface;
class PhoneNumberTest extends TestCase
{
private ValidatorInterface $validator;
protected function setUp(): void
{
$this->validator = Validation::createValidatorBuilder()->enableAttributeMapping()->getValidator();
}
/** @return iterable<string, array{string, bool}> */
public static function numbers(): iterable
{
yield 'digits' => ['01711234567', true];
yield 'international' => ['+49 171 1234567', true];
yield 'hyphen' => ['0171-1234567', true];
yield 'slash' => ['0171/1234567', true];
yield 'brackets' => ['+49 (0) 171 1234567', false];
yield 'sanitized plus' => ['&#43;49 171 1234567', false];
yield 'plus inside' => ['0171+1234567', false];
yield 'letters' => ['0171 privat', false];
}
#[DataProvider('numbers')]
public function testOnlyDigitsSpacesHyphensAndALeadingPlusPass(string $number, bool $valid): void
{
self::assertSame($valid, 0 === $this->validator->validate($number, new PhoneNumber())->count());
}
public function testAnEnteredParticipantNumberIsValidated(): void
{
$participant = new ParticipantDto();
$participant->mobile = '0171 (1234567)';
self::assertCount(1, $this->validator->validateProperty($participant, 'mobile', ['booking_create']));
self::assertCount(1, $this->validator->validateProperty($participant, 'mobile', ['booking_edit']));
}
/**
* A number loaded from BusPro goes back unchanged, so it must not block the form, even when it
* is one the rule would reject.
*/
public function testAParticipantNumberLoadedFromBusProIsExemptUntilChanged(): void
{
$personalData = new PersonalData();
$personalData->communication->mobile = '&#43;49 171 1234567';
$participant = ParticipantDto::fromPersonalData($personalData);
self::assertCount(0, $this->validator->validateProperty($participant, 'mobile', ['booking_edit']));
$participant->mobile = '0171 (1234567)';
self::assertCount(1, $this->validator->validateProperty($participant, 'mobile', ['booking_edit']));
}
public function testTheExemptionSurvivesTheSessionRoundTrip(): void
{
$personalData = new PersonalData();
$personalData->communication->mobile = '+49 (171) 1234567';
$participant = unserialize(serialize(ParticipantDto::fromPersonalData($personalData)));
self::assertCount(0, $this->validator->validateProperty($participant, 'mobile', ['booking_edit']));
}
public function testCommunicationExemptsOnlyTheNumbersItWasLoadedWith(): void
{
$communication = new Communication();
$communication->phone = '030 (123456)';
$communication->mobile = '+49 (171) 1234567';
$communication->rememberLoadedNumbers();
self::assertCount(0, $this->validator->validate($communication, null, ['personal_data']));
$communication->phone = '030 (654321)';
$violations = $this->validator->validate($communication, null, ['personal_data']);
self::assertCount(1, $violations);
self::assertSame('phone', $violations->get(0)->getPropertyPath());
}
public function testVoucherBuyerNumbersAreExemptOnlyAsPrefilled(): void
{
$personalData = new PersonalData();
$personalData->communication->phone = '030 (123456)';
$personalData->communication->mobile = '+49 (171) 1234567';
$dto = new VoucherPurchaseDto();
$dto->prefillBuyer($personalData, null);
self::assertCount(0, $this->validator->validateProperty($dto, 'phone', ['voucher_step_2']));
self::assertCount(0, $this->validator->validateProperty($dto, 'mobile', ['voucher_step_2']));
$dto->mobile = '0171 (1234567)';
self::assertCount(1, $this->validator->validateProperty($dto, 'mobile', ['voucher_step_2']));
}
}