Files
myep/tests/BusProNet/XmlParser/TravelParserTest.php
T

361 lines
16 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
namespace App\Tests\BusProNet\XmlParser;
use App\BusProNet\XmlParser\TravelParser;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DomCrawler\Crawler;
class TravelParserTest extends TestCase
{
private TravelParser $parser;
protected function setUp(): void
{
$this->parser = new TravelParser();
}
public function testParseServiceDescriptions(): void
{
$xmlContent = '<?xml version="1.0" encoding="utf-8"?>
<reisen>
<reise id="1" idbuspro="2187" code="SSTMR" erstellt_am="27.08.2025 09:09:40">
<termin id="1" idbuspro="11946" idprodukt="2187" termin="01.01.2030" bis="06.01.2030" code="SSTMR010130" reiseart="F">
<text>Test Travel</text>
<abpreis>659,00</abpreis>
<lei_sonstiges>
<leistung id="1" idbuspro="183658" unterart="SON" termin="01.01.2030" bis="06.01.2030" automatisch_buchen="False" pflicht="False">
<text>Begleitperson (gemäß Gruppenregelung)</text>
<hinweis>Gilt für Betreuende, Lehrkräfte, Gruppenleitungen oder andere berechtigte Begleitpersonen laut Buchungsregelung. Bei Unklarheiten bitte zunächst ohne Angabe buchen eine spätere Ergänzung ist möglich.</hinweis>
<preis>0,00</preis>
<status>Frei</status>
</leistung>
<leistung id="2" idbuspro="183659" unterart="SON" termin="01.01.2030" bis="06.01.2030" automatisch_buchen="True" pflicht="False">
<text>Bettwäsche-Set inkl. Handtuch</text>
<hinweis>Das Bettwäsche-Set umfasst Spannbettlaken, Kissen- und Deckenbezug. Beim Handtuch handelt es sich um ein Duschtuch (ca. 70x140cm).</hinweis>
<preis>13,90</preis>
<status>Frei</status>
</leistung>
<leistung id="3" idbuspro="183656" unterart="SPA" termin="01.01.2030" bis="06.01.2030" automatisch_buchen="False" pflicht="False">
<text>Skipass 6 Tage (Erwachsene) (Jahrgang 1926-2006) inkl. Anreisetag</text>
<hinweis_stamm>JG:1926-2006</hinweis_stamm>
<preis>59,00</preis>
<status>Frei</status>
</leistung>
<leistung id="4" idbuspro="183660" unterart="VPF" termin="01.01.2030" bis="01.01.2030" automatisch_buchen="False" pflicht="False">
<text>Frühstück am Anreisetag</text>
<preis>8,90</preis>
<status>Frei</status>
</leistung>
</lei_sonstiges>
<lei_befoerderung>
<leistung id="5" idbuspro="183649" unterart="BUS" termin="30.12.2029" bis="01.01.2030" automatisch_buchen="False" pflicht="True">
<text>Bus-Hinfahrt</text>
<hinweis>Bus fährt nur bei ausreichender Teilnehmerzahl</hinweis>
<preis>0,00</preis>
<status>Frei</status>
<richtung>HIN</richtung>
</leistung>
</lei_befoerderung>
<hotel id="1" code="SSTGR" idbuspro="157047" ankunft="01.01.2030" abreise="06.01.2030">
<zimmer>
<preis zimmercode="4erDW" idbuspro_zimmer="95" zimmertext="4er Zimmer Dusche/WC" MinPax="4" MaxPax="4" naechte="5" kat="GR" vpcode="Lt. Auss." idbuspro_vp="2" vptext="Laut Ausschreibung" preis="689,00" status="Frei" verfuegbar="8" />
</zimmer>
</hotel>
</termin>
</reise>
</reisen>';
$crawler = new Crawler($xmlContent);
$travelNode = $crawler->filterXPath('//reise/termin')->first();
$travel = $this->parser->parse($travelNode);
// Test additional services descriptions
$additionalServices = $travel->additionalServices;
// Service with description (ID 183658 - Begleitperson)
$this->assertArrayHasKey(183658, $additionalServices);
$begleitpersonService = $additionalServices[183658];
$this->assertSame('Begleitperson (gemäß Gruppenregelung)', $begleitpersonService->label);
$this->assertSame(
'Gilt für Betreuende, Lehrkräfte, Gruppenleitungen oder andere berechtigte Begleitpersonen laut Buchungsregelung. Bei Unklarheiten bitte zunächst ohne Angabe buchen eine spätere Ergänzung ist möglich.',
$begleitpersonService->description
);
// Service with description (ID 183659 - Bettwäsche)
$this->assertArrayHasKey(183659, $additionalServices);
$bettwascheService = $additionalServices[183659];
$this->assertSame('Bettwäsche-Set inkl. Handtuch', $bettwascheService->label);
$this->assertSame(
'Das Bettwäsche-Set umfasst Spannbettlaken, Kissen- und Deckenbezug. Beim Handtuch handelt es sich um ein Duschtuch (ca. 70x140cm).',
$bettwascheService->description
);
$this->assertTrue($bettwascheService->autoBook);
// Service without description (ID 183656 - Skipass, has hinweis_stamm but no hinweis)
$this->assertArrayHasKey(183656, $additionalServices);
$skipassService = $additionalServices[183656];
$this->assertSame('Skipass 6 Tage (Erwachsene) (Jahrgang 1926-2006) inkl. Anreisetag', $skipassService->label);
$this->assertNull($skipassService->description); // No hinweis node for this service
$this->assertSame('JG:1926-2006', $skipassService->rawAgeConstraintData); // But has age constraints
// Service without description (ID 183660 - Frühstück)
$this->assertArrayHasKey(183660, $additionalServices);
$fruehstueckService = $additionalServices[183660];
$this->assertSame('Frühstück am Anreisetag', $fruehstueckService->label);
$this->assertNull($fruehstueckService->description); // No hinweis node
// Test transportation services descriptions
$transportationServices = $travel->transportationServices;
$this->assertArrayHasKey(183649, $transportationServices);
$busService = $transportationServices[183649];
$this->assertSame('Bus-Hinfahrt', $busService->label);
$this->assertSame('Bus fährt nur bei ausreichender Teilnehmerzahl', $busService->description);
$this->assertFalse($busService->autoBook);
}
public function testParseServiceWithoutDescriptions(): void
{
$xmlContent = '<?xml version="1.0" encoding="utf-8"?>
<reisen>
<reise id="1" idbuspro="2187" code="SSTMR">
<termin id="1" idbuspro="11946" termin="01.01.2030" bis="06.01.2030" reiseart="F">
<text>Test Travel</text>
<abpreis>659,00</abpreis>
<lei_sonstiges>
<leistung id="1" idbuspro="183660" unterart="VPF">
<text>Service without description</text>
<preis>8,90</preis>
<status>Frei</status>
</leistung>
</lei_sonstiges>
<hotel id="1" idbuspro="157047">
<zimmer>
<preis zimmercode="4erDW" idbuspro_zimmer="95" zimmertext="4er Zimmer" MinPax="4" MaxPax="4" naechte="5" preis="689,00" status="Frei" verfuegbar="8" />
</zimmer>
</hotel>
</termin>
</reise>
</reisen>';
$crawler = new Crawler($xmlContent);
$travelNode = $crawler->filterXPath('//reise/termin')->first();
$travel = $this->parser->parse($travelNode);
$additionalServices = $travel->additionalServices;
$this->assertArrayHasKey(183660, $additionalServices);
$service = $additionalServices[183660];
$this->assertSame('Service without description', $service->label);
$this->assertNull($service->description); // No hinweis node should result in null description
}
public function testParseServiceWithLowerCaseAutoBookFlag(): void
{
$xmlContent = '<?xml version="1.0" encoding="utf-8"?>
<reisen>
<reise id="1" idbuspro="2187" code="SSTMR">
<termin id="1" idbuspro="11946" termin="01.01.2030" bis="06.01.2030" reiseart="F">
<text>Test Travel</text>
<abpreis>659,00</abpreis>
<lei_sonstiges>
<leistung id="1" idbuspro="183660" unterart="VPF" automatisch_buchen="true" pflicht="False">
<text>Service with auto-book</text>
<preis>8,90</preis>
<status>Frei</status>
</leistung>
</lei_sonstiges>
<hotel id="1" idbuspro="157047">
<zimmer>
<preis zimmercode="4erDW" idbuspro_zimmer="95" zimmertext="4er Zimmer" MinPax="4" MaxPax="4" naechte="5" preis="689,00" status="Frei" verfuegbar="8" />
</zimmer>
</hotel>
</termin>
</reise>
</reisen>';
$crawler = new Crawler($xmlContent);
$travelNode = $crawler->filterXPath('//reise/termin')->first();
$travel = $this->parser->parse($travelNode);
$additionalServices = $travel->additionalServices;
$this->assertArrayHasKey(183660, $additionalServices);
$this->assertTrue($additionalServices[183660]->autoBook);
}
public function testParseAdditionalServicesUsesTerminLevelOnly(): void
{
$xmlContent = '<?xml version="1.0" encoding="utf-8"?>
<reisen>
<reise id="1" idbuspro="2187" code="SSTMR">
<termin id="1" idbuspro="11946" termin="01.01.2030" bis="06.01.2030" reiseart="F">
<text>Test Travel</text>
<abpreis>659,00</abpreis>
<lei_sonstiges>
<leistung id="1" idbuspro="183656" unterart="SPA" automatisch_buchen="True" pflicht="False">
<text>Skipass 6 Tage</text>
<preis>59,00</preis>
<status>Frei</status>
</leistung>
</lei_sonstiges>
<hotel id="1" idbuspro="157047">
<lei_sonstiges>
<leistung id="1" idbuspro="183656" unterart="SPA" automatisch_buchen="False" pflicht="False">
<text>Skipass 6 Tage Hotel</text>
<preis>59,00</preis>
<status>Frei</status>
</leistung>
</lei_sonstiges>
<zimmer>
<preis zimmercode="4erDW" idbuspro_zimmer="95" zimmertext="4er Zimmer" MinPax="4" MaxPax="4" naechte="5" preis="689,00" status="Frei" verfuegbar="8" />
</zimmer>
</hotel>
</termin>
</reise>
</reisen>';
$crawler = new Crawler($xmlContent);
$travelNode = $crawler->filterXPath('//reise/termin')->first();
$travel = $this->parser->parse($travelNode);
$additionalServices = $travel->additionalServices;
$this->assertArrayHasKey(183656, $additionalServices);
$this->assertTrue($additionalServices[183656]->autoBook);
$this->assertSame('Skipass 6 Tage', $additionalServices[183656]->label);
}
public function testParseServiceWithEmptyDescription(): void
{
$xmlContent = '<?xml version="1.0" encoding="utf-8"?>
<reisen>
<reise id="1" idbuspro="2187" code="SSTMR">
<termin id="1" idbuspro="11946" termin="01.01.2030" bis="06.01.2030" reiseart="F">
<text>Test Travel</text>
<abpreis>659,00</abpreis>
<lei_sonstiges>
<leistung id="1" idbuspro="183660" unterart="VPF">
<text>Service with empty description</text>
<hinweis></hinweis>
<preis>8,90</preis>
<status>Frei</status>
</leistung>
</lei_sonstiges>
<hotel id="1" idbuspro="157047">
<zimmer>
<preis zimmercode="4erDW" idbuspro_zimmer="95" zimmertext="4er Zimmer" MinPax="4" MaxPax="4" naechte="5" preis="689,00" status="Frei" verfuegbar="8" />
</zimmer>
</hotel>
</termin>
</reise>
</reisen>';
$crawler = new Crawler($xmlContent);
$travelNode = $crawler->filterXPath('//reise/termin')->first();
$travel = $this->parser->parse($travelNode);
$additionalServices = $travel->additionalServices;
$this->assertArrayHasKey(183660, $additionalServices);
$service = $additionalServices[183660];
$this->assertSame('Service with empty description', $service->label);
$this->assertNull($service->description); // Empty hinweis should result in null description
}
public function testParseTravelWithoutStatus(): void
{
$xmlContent = '<?xml version="1.0" encoding="utf-8"?>
<reisen>
<reise id="1" idbuspro="2187" code="SSTMR">
<termin id="1" idbuspro="11946" termin="01.01.2030" bis="06.01.2030" reiseart="F">
<text>Test Travel</text>
<abpreis>659,00</abpreis>
<hotel id="1" idbuspro="157047">
<zimmer>
<preis zimmercode="4erDW" idbuspro_zimmer="95" zimmertext="4er Zimmer" MinPax="4" MaxPax="4" naechte="5" preis="689,00" status="Frei" verfuegbar="8" />
</zimmer>
</hotel>
</termin>
</reise>
</reisen>';
$crawler = new Crawler($xmlContent);
$travelNode = $crawler->filterXPath('//reise/termin')->first();
$travel = $this->parser->parse($travelNode);
$this->assertNull($travel->status); // No status_hin node should result in null
}
public function testGetPickupsAdjustsOvernightTimes(): void
{
$xml = '<?xml version="1.0" encoding="utf-8"?>
<zustiege>
<zustieg idbuspro="1" zeit="30.12.2029 18:00" preis="0,00" />
<zustieg idbuspro="2" zeit="30.12.2029 20:30" preis="0,00" />
<zustieg idbuspro="3" zeit="23:00" preis="0,00" />
<zustieg idbuspro="4" zeit="01:00" preis="0,00" />
</zustiege>';
$crawler = new Crawler($xml);
$defaultDate = new \DateTimeImmutable('2029-12-30');
$pickups = $this->parser->getPickups(
$crawler->filterXPath('//zustiege/zustieg'),
$defaultDate,
true
);
// Full-datetime entries keep their original date
$this->assertSame('2029-12-30 18:00', $pickups[1]->time->format('Y-m-d H:i'));
$this->assertSame('2029-12-30 20:30', $pickups[2]->time->format('Y-m-d H:i'));
// Time-only "23:00" is after latest full-datetime (20:30), so stays on same day
$this->assertSame('2029-12-30 23:00', $pickups[3]->time->format('Y-m-d H:i'));
// Time-only "01:00" is before latest full-datetime (20:30), so gets +1 day
$this->assertSame('2029-12-31 01:00', $pickups[4]->time->format('Y-m-d H:i'));
}
public function testGetPickupsDoesNotAdjustWhenAllEntriesAreFullDatetime(): void
{
$xml = '<?xml version="1.0" encoding="utf-8"?>
<zustiege>
<zustieg idbuspro="1" zeit="30.12.2029 18:00" preis="0,00" />
<zustieg idbuspro="2" zeit="30.12.2029 20:30" preis="0,00" />
</zustiege>';
$crawler = new Crawler($xml);
$defaultDate = new \DateTimeImmutable('2029-12-30');
$pickups = $this->parser->getPickups(
$crawler->filterXPath('//zustiege/zustieg'),
$defaultDate,
true
);
$this->assertSame('2029-12-30 18:00', $pickups[1]->time->format('Y-m-d H:i'));
$this->assertSame('2029-12-30 20:30', $pickups[2]->time->format('Y-m-d H:i'));
}
public function testGetPickupsDoesNotAdjustWhenAllEntriesAreTimeOnly(): void
{
$xml = '<?xml version="1.0" encoding="utf-8"?>
<zustiege>
<zustieg idbuspro="1" zeit="18:00" preis="0,00" />
<zustieg idbuspro="2" zeit="01:00" preis="0,00" />
</zustiege>';
$crawler = new Crawler($xml);
$defaultDate = new \DateTimeImmutable('2029-12-30');
$pickups = $this->parser->getPickups(
$crawler->filterXPath('//zustiege/zustieg'),
$defaultDate,
true
);
// No full-datetime reference entries, so no adjustment happens
$this->assertSame('2029-12-30 18:00', $pickups[1]->time->format('Y-m-d H:i'));
$this->assertSame('2029-12-30 01:00', $pickups[2]->time->format('Y-m-d H:i'));
}
}