parser = new TravelParser(); } public function testParseServiceDescriptions(): void { $xmlContent = ' Test Travel 659,00 Begleitperson (gemäß Gruppenregelung) 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. 0,00 Frei Bettwäsche-Set inkl. Handtuch Das Bettwäsche-Set umfasst Spannbettlaken, Kissen- und Deckenbezug. Beim Handtuch handelt es sich um ein Duschtuch (ca. 70x140cm). 13,90 Frei Skipass 6 Tage (Erwachsene) (Jahrgang 1926-2006) inkl. Anreisetag JG:1926-2006 59,00 Frei Frühstück am Anreisetag 8,90 Frei Bus-Hinfahrt Bus fährt nur bei ausreichender Teilnehmerzahl 0,00 Frei HIN '; $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 ); // 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); } public function testParseServiceWithoutDescriptions(): void { $xmlContent = ' Test Travel 659,00 Service without description 8,90 Frei '; $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 testParseServiceWithEmptyDescription(): void { $xmlContent = ' Test Travel 659,00 Service with empty description 8,90 Frei '; $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 = ' Test Travel 659,00 '; $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 = ' '; $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 = ' '; $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 = ' '; $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')); } }