105000KAllgemeinKSkiKWeihnachten';
$result = $this->parse(MessageType::VoucherTemplates, $xml);
self::assertInstanceOf(VoucherTemplates::class, $result);
self::assertSame(10, $result->minAmount);
self::assertSame(5000, $result->maxAmount);
self::assertSame([3, 4, 5], array_map(static fn ($template) => $template->id, $result->templates));
self::assertSame(['Allgemein', 'Ski', 'Weihnachten'], array_map(static fn ($template) => $template->label, $result->templates));
self::assertSame('K', $result->templates[1]->type);
self::assertNull($result->templates[1]->note);
self::assertSame('Ski', $result->find(4)?->label);
self::assertNull($result->find(999));
}
public function testTemplatesWithoutAmountBoundsAreRejected(): void
{
$xml = 'KAllgemein';
$this->expectException(ResponseParserException::class);
$this->expectExceptionMessage('amount bounds');
$this->parse(MessageType::VoucherTemplates, $xml);
}
public function testPaymentMethods(): void
{
$xml = '';
$result = $this->parse(MessageType::VoucherPaymentMethods, $xml);
self::assertEquals([new VoucherPaymentMethod(2, 'Überweisung', 'UEBERW')], $result);
self::assertTrue($result[0]->isTransfer());
}
public function testPreviewIsDecodedFromItsDataUri(): void
{
$pdf = "%PDF-1.4\nprobe";
$xml = 'data:application/pdf;base64,'.base64_encode($pdf).'';
$result = $this->parse(MessageType::VoucherPreview, $xml);
self::assertInstanceOf(VoucherPreview::class, $result);
self::assertSame($pdf, $result->pdf);
}
public function testPreviewWithoutAPdfDataUriIsRejected(): void
{
$xml = '';
$this->expectException(ResponseParserException::class);
$this->parse(MessageType::VoucherPreview, $xml);
}
public function testTheDryRunAnswersPossibleAndIssuesNothing(): void
{
$xml = 'möglich';
$result = $this->parse(MessageType::VoucherSale, $xml);
self::assertInstanceOf(VoucherSaleResponse::class, $result);
self::assertTrue($result->isInquiryValid());
self::assertFalse($result->isSaleSuccessful());
self::assertNull($result->voucherNumber);
self::assertNull($result->redemptionCode);
}
public function testACompletedPurchase(): void
{
$xml = 'erfolgt4711K-001234ABCD1234111,00R-998877kaeufer@example.invalid';
$result = $this->parse(MessageType::VoucherSale, $xml);
self::assertInstanceOf(VoucherSaleResponse::class, $result);
self::assertTrue($result->isSaleSuccessful());
self::assertSame(4711, $result->voucherId);
self::assertSame('K-001234', $result->voucherNumber);
self::assertSame('ABCD1234', $result->redemptionCode);
self::assertSame(111.0, $result->price);
self::assertSame('R-998877', $result->invoiceNumber);
self::assertSame('kaeufer@example.invalid', $result->email);
}
/**
* Missing address data comes as 650, the code Notification::isError() treats as success.
* The caller must take any HINWEIS as a rejection on this path.
*/
public function testAMissingAddressFieldIsAHinweis650(): void
{
$xml = '650Fehlende Adress Daten. Bitte folgende Eingabefelder prüfen: Strasse';
$result = $this->parse(MessageType::VoucherSale, $xml);
self::assertInstanceOf(Notification::class, $result);
self::assertSame(650, $result->code);
}
private function parse(MessageType $type, string $xml): mixed
{
return (new ApiResponseParser($this->createStub(TravelParser::class)))->parseXmlString($type, $xml);
}
}