fix: emit export pickup times as clock readings without an offset
This commit is contained in:
1 parent
6c700ea18b
commit
ede8fd840a
6 files changed
+136
-27
No files matched your search
@@ -159,14 +159,56 @@ class ProductExportBuilderTest extends TestCase
|
||||
'city' => 'Stadt 4',
|
||||
'street' => 'Strasse 4',
|
||||
'price' => 5.9,
|
||||
'datetime' => '2026-12-03T23:30:00+01:00',
|
||||
'datetime' => '2026-12-03T23:30:00',
|
||||
], $pickups[0]);
|
||||
self::assertNull($pickups[1]['price'], 'an absent price is null');
|
||||
self::assertSame('2026-12-04T01:45:00+01:00', $pickups[1]['datetime']);
|
||||
self::assertSame('2026-12-04T01:45:00', $pickups[1]['datetime']);
|
||||
self::assertSame(0.0, $pickups[2]['price'], 'a stated 0,00 is kept as 0');
|
||||
self::assertNull($pickups[2]['code']);
|
||||
}
|
||||
|
||||
public function testPickupTimesInTheSpringForwardGapAreNotShifted(): void
|
||||
{
|
||||
// DPWUSMP280327 in the 30.09.2026 13:11 export. Berlin skips 02:00-02:59 that night.
|
||||
$pickups = $this->pickupsFor('28.03.2027', <<<'XML'
|
||||
<zustieg id="1" idbuspro="4" zeit="00:30" />
|
||||
<zustieg id="2" idbuspro="27" zeit="02:45" />
|
||||
<zustieg id="3" idbuspro="3" zeit="27.03.2027 22:00:00" />
|
||||
<zustieg id="4" idbuspro="89" zeit="01:30" />
|
||||
<zustieg id="5" idbuspro="86" zeit="27.03.2027 23:30:00" />
|
||||
<zustieg id="6" idbuspro="74" zeit="03:45" />
|
||||
<zustieg id="7" idbuspro="262" zeit="04:45" />
|
||||
XML);
|
||||
|
||||
self::assertSame([
|
||||
'2027-03-28T00:30:00',
|
||||
'2027-03-28T02:45:00',
|
||||
'2027-03-27T22:00:00',
|
||||
'2027-03-28T01:30:00',
|
||||
'2027-03-27T23:30:00',
|
||||
'2027-03-28T03:45:00',
|
||||
'2027-03-28T04:45:00',
|
||||
], array_column($pickups, 'datetime'));
|
||||
}
|
||||
|
||||
public function testPickupTimesInTheFallBackHourPassThroughWhenRolledOntoTheNextDay(): void
|
||||
{
|
||||
// Berlin runs 02:00-02:59 twice on 31.10.2027; the bare times roll onto it from the 30th.
|
||||
$pickups = $this->pickupsFor('30.10.2027', <<<'XML'
|
||||
<zustieg id="1" idbuspro="4" zeit="30.10.2027 23:30:00" />
|
||||
<zustieg id="2" idbuspro="27" zeit="02:15" />
|
||||
<zustieg id="3" idbuspro="55" zeit="02:59" />
|
||||
<zustieg id="4" idbuspro="0" zeit="31.10.2027 02:30:00" />
|
||||
XML);
|
||||
|
||||
self::assertSame([
|
||||
'2027-10-30T23:30:00',
|
||||
'2027-10-31T02:15:00',
|
||||
'2027-10-31T02:59:00',
|
||||
'2027-10-31T02:30:00',
|
||||
], array_column($pickups, 'datetime'));
|
||||
}
|
||||
|
||||
public function testDoesNotLevelBoardingPointPrices(): void
|
||||
{
|
||||
// Point 27 is priced on the return leg only. The booking path levels that onto the
|
||||
@@ -200,6 +242,20 @@ class ProductExportBuilderTest extends TestCase
|
||||
self::fail('No row for '.$key);
|
||||
}
|
||||
|
||||
/**
|
||||
* The fixture's first date moved to $dateFrom, with $zustiege as its boarding list.
|
||||
*
|
||||
* @return list<array<string, mixed>>
|
||||
*/
|
||||
private function pickupsFor(string $dateFrom, string $zustiege): array
|
||||
{
|
||||
$xml = (string) file_get_contents(__DIR__.'/../Resources/product_export_data.xml');
|
||||
$xml = str_replace('termin="04.12.2026"', 'termin="'.$dateFrom.'"', $xml);
|
||||
$xml = (string) preg_replace('#<zustiege>.*?</zustiege>#s', '<zustiege>'.$zustiege.'</zustiege>', $xml);
|
||||
|
||||
return $this->build($xml)->rows[0]['pickups'];
|
||||
}
|
||||
|
||||
private function build(?string $xml = null, ?string $marker = null): Export
|
||||
{
|
||||
$xml ??= (string) file_get_contents(__DIR__.'/../Resources/product_export_data.xml');
|
||||
|
||||
@@ -61,26 +61,57 @@ class TravelExportBuilderTest extends TestCase
|
||||
$pickups = array_column($this->rowFor('900-1')['pickups'], null, 'busProId');
|
||||
|
||||
self::assertSame('23:59', $pickups[10]['time']);
|
||||
self::assertSame('2026-12-26T23:59:00+01:00', $pickups[10]['datetime']);
|
||||
self::assertSame('2026-12-26T23:59:00', $pickups[10]['datetime']);
|
||||
|
||||
// Time only, so it defaults to the departure date -- which would put it before the
|
||||
// 23:59 above. The coach cannot board backwards, so it rolls onto the next day.
|
||||
self::assertSame('02:15', $pickups[11]['time']);
|
||||
self::assertSame('2026-12-27T02:15:00+01:00', $pickups[11]['datetime']);
|
||||
self::assertSame('2026-12-27T02:15:00', $pickups[11]['datetime']);
|
||||
}
|
||||
|
||||
public function testEmitsTheSummerOffset(): void
|
||||
public function testEmitsNoOffsetInSummerEither(): void
|
||||
{
|
||||
$pickups = $this->rowFor('901-1')['pickups'];
|
||||
|
||||
self::assertSame('2027-07-15T08:00:00+02:00', $pickups[0]['datetime']);
|
||||
self::assertSame('2027-07-15T08:00:00', $pickups[0]['datetime']);
|
||||
}
|
||||
|
||||
public function testPickupTimesInTheSpringForwardGapAreNotShifted(): void
|
||||
{
|
||||
// Berlin skips 02:00-02:59 on 28.03.2027; BusPro still plans a stop at 02:45.
|
||||
$pickups = $this->build(<<<'XML'
|
||||
<?xml version="1.0"?>
|
||||
<reisen><reise><termin idbuspro="1" termin="28.03.2027" bis="03.04.2027"><hotel idbuspro="1"/><zustiege>
|
||||
<zustieg idbuspro="10" zeit="27.03.2027 23:30:00"/>
|
||||
<zustieg idbuspro="11" zeit="02:45"/>
|
||||
<zustieg idbuspro="12" zeit="03:45"/>
|
||||
</zustiege></termin></reise></reisen>
|
||||
XML)->rows[0]['pickups'];
|
||||
|
||||
self::assertSame(['23:30', '02:45', '03:45'], array_column($pickups, 'time'));
|
||||
self::assertSame(['2027-03-27T23:30:00', '2027-03-28T02:45:00', '2027-03-28T03:45:00'], array_column($pickups, 'datetime'));
|
||||
}
|
||||
|
||||
public function testPickupTimesInTheFallBackHourPassThroughWhenRolledOntoTheNextDay(): void
|
||||
{
|
||||
// Berlin runs 02:00-02:59 twice on 31.10.2027; the bare times roll onto it from the 30th.
|
||||
$pickups = $this->build(<<<'XML'
|
||||
<?xml version="1.0"?>
|
||||
<reisen><reise><termin idbuspro="1" termin="30.10.2027" bis="06.11.2027"><hotel idbuspro="1"/><zustiege>
|
||||
<zustieg idbuspro="10" zeit="30.10.2027 23:30:00"/>
|
||||
<zustieg idbuspro="11" zeit="02:15"/>
|
||||
<zustieg idbuspro="12" zeit="02:59"/>
|
||||
</zustiege></termin></reise></reisen>
|
||||
XML)->rows[0]['pickups'];
|
||||
|
||||
self::assertSame(['2027-10-30T23:30:00', '2027-10-31T02:15:00', '2027-10-31T02:59:00'], array_column($pickups, 'datetime'));
|
||||
}
|
||||
|
||||
public function testATimeOnlyPickupThatAlreadyFollowsTheLastDatedOneKeepsTheDepartureDate(): void
|
||||
{
|
||||
$pickups = array_column($this->rowFor('901-1')['pickups'], null, 'busProId');
|
||||
|
||||
self::assertSame('2027-07-15T09:30:00+02:00', $pickups[11]['datetime'], 'no roll when the order already holds');
|
||||
self::assertSame('2027-07-15T09:30:00', $pickups[11]['datetime'], 'no roll when the order already holds');
|
||||
}
|
||||
|
||||
public function testKeepsAPickupWithoutAZeitAndNullsBothTimeFields(): void
|
||||
@@ -104,7 +135,7 @@ class TravelExportBuilderTest extends TestCase
|
||||
self::assertNull($pickups[99]['city']);
|
||||
self::assertNull($pickups[99]['street']);
|
||||
self::assertSame('21:00', $pickups[99]['time'], 'the time is from the travel XML, not master data');
|
||||
self::assertSame('2026-12-26T21:00:00+01:00', $pickups[99]['datetime']);
|
||||
self::assertSame('2026-12-26T21:00:00', $pickups[99]['datetime']);
|
||||
|
||||
// Counted once, not once per row that references it.
|
||||
self::assertSame(1, $export->pickupsWithoutMasterData);
|
||||
|
||||
Reference in new issue
Block a user