Files
myep/tests/Form/Model/VoucherPurchaseDtoTest.php
2026-10-01 15:03:27 +02:00

168 lines
5.4 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Tests\Form\Model;
use App\BusProNet\Model\PersonalData;
use App\BusProNet\Model\VoucherTemplate;
use App\Form\Model\VoucherPurchaseDto;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Validator\ConstraintViolationListInterface;
use Symfony\Component\Validator\Validation;
class VoucherPurchaseDtoTest extends TestCase
{
private const array STEP_1 = ['voucher_step_1'];
private const array STEP_2 = ['voucher_step_2', 'personal_data'];
private const array STEP_3 = ['voucher_step_3'];
public function testACompleteVoucherPassesStep1(): void
{
self::assertCount(0, $this->validate($this->createDto(), self::STEP_1));
}
public function testTheBoundsAreInclusiveAndComeFromBusPro(): void
{
$dto = $this->createDto();
foreach ([10 => 0, 5000 => 0, 9 => 1, 5001 => 1] as $amount => $violations) {
$dto->amount = $amount;
$result = $this->validate($dto, self::STEP_1);
self::assertCount($violations, $result, sprintf('amount %d', $amount));
if (1 === $violations) {
self::assertSame('amount', $result->get(0)->getPropertyPath());
}
}
}
public function testStep1RequiresDesignNamesAndValue(): void
{
$dto = $this->createDto();
$dto->template = null;
$dto->from = '';
$dto->to = null;
$dto->amount = null;
self::assertSame(
['template', 'from', 'to', 'amount'],
$this->propertyPaths($this->validate($dto, self::STEP_1)),
);
}
/**
* The mandatory fields of the live voucher shop: no phone, no gender, no salutation.
*/
public function testStep2RequiresWhatTheLiveShopRequires(): void
{
$dto = new VoucherPurchaseDto();
$dto->address->country = null;
self::assertEqualsCanonicalizing(
['lastName', 'firstName', 'address.street', 'address.postCode', 'address.city', 'address.country', 'email'],
$this->propertyPaths($this->validate($dto, self::STEP_2)),
);
}
public function testACompleteBuyerPassesStep2(): void
{
self::assertCount(0, $this->validate($this->createDto(), self::STEP_2));
}
public function testTheCountryDefaultsToGermany(): void
{
self::assertSame('D', (new VoucherPurchaseDto())->address->country);
}
public function testStep2RejectsAnInvalidEmailAndSalutation(): void
{
$dto = $this->createDto();
$dto->email = 'kein-mail';
$dto->salutation = 'Divers';
self::assertEqualsCanonicalizing(['email', 'salutation'], $this->propertyPaths($this->validate($dto, self::STEP_2)));
}
public function testStep3RequiresBothConfirmations(): void
{
$dto = $this->createDto();
self::assertSame(['termsAccepted', 'purchaseConfirmed'], $this->propertyPaths($this->validate($dto, self::STEP_3)));
$dto->termsAccepted = true;
$dto->purchaseConfirmed = true;
self::assertCount(0, $this->validate($dto, self::STEP_3));
}
public function testPrefillTakesTheLoginEmailAndKeepsAnUnknownSalutationOut(): void
{
$personalData = new PersonalData();
$personalData->name = 'Muster';
$personalData->firstName = 'Erika';
$personalData->salutation = 'Familie';
$personalData->address->street = ' Hauptstr. 1 ';
$personalData->address->postCode = '12345';
$personalData->address->city = 'Musterstadt';
$personalData->address->country = 'A';
$personalData->communication->email = '[email protected]';
$personalData->communication->mobile = '0170';
$dto = new VoucherPurchaseDto();
$dto->prefillBuyer($personalData, '[email protected]');
self::assertSame('Muster', $dto->lastName);
self::assertSame('Erika', $dto->firstName);
self::assertNull($dto->salutation);
self::assertSame('Hauptstr. 1', $dto->address->street);
self::assertSame('A', $dto->address->country);
self::assertSame('[email protected]', $dto->email);
self::assertSame('0170', $dto->mobile);
self::assertTrue($dto->hasBuyerData());
self::assertNotSame($personalData->address, $dto->address);
}
private function createDto(): VoucherPurchaseDto
{
$dto = new VoucherPurchaseDto();
$dto->minAmount = 10;
$dto->maxAmount = 5000;
$dto->template = new VoucherTemplate(3, 'K', 'Allgemein');
$dto->from = 'Oma';
$dto->to = 'Max';
$dto->amount = 111;
$dto->lastName = 'Muster';
$dto->firstName = 'Erika';
$dto->address->street = 'Hauptstr. 1';
$dto->address->postCode = '12345';
$dto->address->city = 'Musterstadt';
$dto->email = '[email protected]';
return $dto;
}
/**
* @param list<string> $groups
*/
private function validate(VoucherPurchaseDto $dto, array $groups): ConstraintViolationListInterface
{
return Validation::createValidatorBuilder()
->enableAttributeMapping()
->getValidator()
->validate($dto, null, $groups);
}
/**
* @return list<string>
*/
private function propertyPaths(ConstraintViolationListInterface $violations): array
{
$paths = [];
foreach ($violations as $violation) {
$paths[] = $violation->getPropertyPath();
}
return $paths;
}
}