feat: voucher purchase flow
This commit is contained in:
1 parent
a628e96d06
commit
f3dd122678
70 files changed
+3672
-122
No files matched your search
@@ -0,0 +1,167 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user