Files
myep/tests/BusProNet/XmlParser/VoucherResponseParserTest.php
T
2026-10-01 15:03:27 +02:00

129 lines
6.2 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Tests\BusProNet\XmlParser;
use App\BusProNet\ApiClient;
use App\BusProNet\Exception\ResponseParserException;
use App\BusProNet\Model\Notification;
use App\BusProNet\Model\VoucherPaymentMethod;
use App\BusProNet\Model\VoucherPreview;
use App\BusProNet\Model\VoucherSaleResponse;
use App\BusProNet\Model\VoucherTemplates;
use App\BusProNet\XmlParser\ApiResponseParser;
use App\BusProNet\XmlParser\TravelParser;
use PHPUnit\Framework\TestCase;
/**
* The voucher purchase responses. Fixtures are the probes against the test system of 2026-10-01,
* except the completed purchase, which follows the vendor documentation.
*/
class VoucherResponseParserTest extends TestCase
{
public function testTemplatesWithTheUndocumentedAmountBounds(): void
{
$xml = '<?xml version="1.0" encoding="utf-8"?><ergebnis><satz typ="GUTSCHEINVORLAGEN"></satz><gutscheinminbetrag>10</gutscheinminbetrag><gutscheinmaxbetrag>5000</gutscheinmaxbetrag><gutscheine><gutschein idgutscheinvorlage="3"><gutscheinart>K</gutscheinart><bezeichnung>Allgemein</bezeichnung><hinweis></hinweis></gutschein><gutschein idgutscheinvorlage="4"><gutscheinart>K</gutscheinart><bezeichnung>Ski</bezeichnung><hinweis></hinweis></gutschein><gutschein idgutscheinvorlage="5"><gutscheinart>K</gutscheinart><bezeichnung>Weihnachten</bezeichnung><hinweis></hinweis></gutschein></gutscheine></ergebnis>';
$result = $this->parse(ApiClient::TYPE_VOUCHER_TEMPLATES, $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 = '<?xml version="1.0" encoding="utf-8"?><ergebnis><satz typ="GUTSCHEINVORLAGEN"></satz><gutscheine><gutschein idgutscheinvorlage="3"><gutscheinart>K</gutscheinart><bezeichnung>Allgemein</bezeichnung></gutschein></gutscheine></ergebnis>';
$this->expectException(ResponseParserException::class);
$this->expectExceptionMessage('amount bounds');
$this->parse(ApiClient::TYPE_VOUCHER_TEMPLATES, $xml);
}
public function testPaymentMethods(): void
{
$xml = '<?xml version="1.0" encoding="utf-8"?><ergebnis><satz typ="GUTSCHEINZAHLUNGSARTEN"></satz><zahlungsarten><zahlungsart id="2" bezeichnung="Überweisung" art="UEBERW"></zahlungsart></zahlungsarten></ergebnis>';
$result = $this->parse(ApiClient::TYPE_VOUCHER_PAYMENT_METHODS, $xml);
self::assertEquals([new VoucherPaymentMethod(2, 'Überweisung', 'UEBERW')], $result);
self::assertTrue($result[0]->isTransfer());
}
public function testPreviewIsDecodedFromItsDataUri(): void
{
$pdf = "%PDF-1.4\nprobe";
$xml = '<?xml version="1.0" encoding="utf-8"?><ergebnis><satz typ="GUTSCHEINVORSCHAU"/><gutscheinpdf>data:application/pdf;base64,'.base64_encode($pdf).'</gutscheinpdf></ergebnis>';
$result = $this->parse(ApiClient::TYPE_VOUCHER_PREVIEW, $xml);
self::assertInstanceOf(VoucherPreview::class, $result);
self::assertSame($pdf, $result->pdf);
}
public function testPreviewWithoutAPdfDataUriIsRejected(): void
{
$xml = '<?xml version="1.0" encoding="utf-8"?><ergebnis><satz typ="GUTSCHEINVORSCHAU"/><gutscheinpdf></gutscheinpdf></ergebnis>';
$this->expectException(ResponseParserException::class);
$this->parse(ApiClient::TYPE_VOUCHER_PREVIEW, $xml);
}
public function testTheDryRunAnswersPossibleAndIssuesNothing(): void
{
$xml = '<?xml version="1.0" encoding="utf-8"?><ergebnis><satz typ="GUTSCHEINBUCHUNG"></satz><buchung>möglich</buchung></ergebnis>';
$result = $this->parse(ApiClient::TYPE_VOUCHER_SALE, $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 = '<?xml version="1.0" encoding="utf-8"?><ergebnis><satz typ="GUTSCHEINBUCHUNG"/><buchung>erfolgt</buchung><idgutschein>4711</idgutschein><gutscheinnummer>K-001234</gutscheinnummer><einloesecode>ABCD1234</einloesecode><preis>111,00</preis><rechnungsnummer>R-998877</rechnungsnummer><email>[email protected]</email></ergebnis>';
$result = $this->parse(ApiClient::TYPE_VOUCHER_SALE, $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('[email protected]', $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 = '<?xml version="1.0" encoding="utf-8"?><ergebnis><satz typ="HINWEIS"><nr>650</nr><text>Fehlende Adress Daten. Bitte folgende Eingabefelder prüfen: Strasse</text></satz></ergebnis>';
$result = $this->parse(ApiClient::TYPE_VOUCHER_SALE, $xml);
self::assertInstanceOf(Notification::class, $result);
self::assertSame(650, $result->code);
}
private function parse(string $type, string $xml): mixed
{
return (new ApiResponseParser($this->createStub(TravelParser::class)))->parseXmlString($type, $xml);
}
}