validator = Validation::createValidatorBuilder()->enableAttributeMapping()->getValidator(); } /** @return iterable */ 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' => ['+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 = '+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'])); } }