109 lines
3.7 KiB
PHP
109 lines
3.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Tests\BusProNet\XmlParser;
|
|
|
|
use App\BusProNet\XmlCrawlerFactory;
|
|
use App\BusProNet\XmlParser\BookingParser;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
/**
|
|
* Tests that participantsStatus stays aligned with the participants array.
|
|
*
|
|
* Participants are keyed by "BusPro participant id - 1" while status_teilnehmer is an
|
|
* id-less, slash-separated list in document order. BookingPayloadBuilder reads
|
|
* participantsStatus[$index] while iterating participants, and
|
|
* ParticipantController::isParticipantCanceled() gates editing on it, so the two arrays
|
|
* must share their keys even when BusPro's ids are not contiguous from 1.
|
|
*/
|
|
class BookingParserParticipantsStatusTest extends TestCase
|
|
{
|
|
private BookingParser $parser;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
$this->parser = new BookingParser();
|
|
}
|
|
|
|
public function testStatusesAreKeyedLikeParticipantsForContiguousIds(): void
|
|
{
|
|
$booking = $this->parse('F/S/F', [1, 2, 3]);
|
|
|
|
$this->assertSame([0, 1, 2], array_keys($booking->participants));
|
|
$this->assertSame([0 => 'F', 1 => 'S', 2 => 'F'], $booking->participantsStatus);
|
|
}
|
|
|
|
public function testStatusesFollowParticipantIdsWhenIdsAreNotContiguous(): void
|
|
{
|
|
$booking = $this->parse('F/S/F', [1, 4, 7]);
|
|
|
|
$this->assertSame([0, 3, 6], array_keys($booking->participants));
|
|
$this->assertSame([0 => 'F', 3 => 'S', 6 => 'F'], $booking->participantsStatus);
|
|
|
|
// Every participant the payload builder iterates must find its own status.
|
|
foreach ($booking->participants as $index => $participant) {
|
|
$this->assertArrayHasKey($index, $booking->participantsStatus);
|
|
}
|
|
}
|
|
|
|
public function testSurplusStatusEntriesAreDroppedInsteadOfShifting(): void
|
|
{
|
|
$booking = $this->parse('F/S/F/F', [1, 2, 3]);
|
|
|
|
$this->assertSame([0 => 'F', 1 => 'S', 2 => 'F'], $booking->participantsStatus);
|
|
}
|
|
|
|
public function testMissingStatusEntriesLeaveTheRemainingParticipantsAligned(): void
|
|
{
|
|
$booking = $this->parse('F/S', [1, 2, 3]);
|
|
|
|
$this->assertSame([0 => 'F', 1 => 'S'], $booking->participantsStatus);
|
|
$this->assertArrayNotHasKey(2, $booking->participantsStatus);
|
|
}
|
|
|
|
public function testStatusListSurroundedByWhitespaceIsParsed(): void
|
|
{
|
|
// BusPro pretty-prints the element, so the text node carries newlines and indentation.
|
|
$booking = $this->parse("\n F/S/F\n ", [1, 2, 3]);
|
|
|
|
$this->assertSame([0 => 'F', 1 => 'S', 2 => 'F'], $booking->participantsStatus);
|
|
}
|
|
|
|
public function testEmptyStatusListDoesNotFail(): void
|
|
{
|
|
$booking = $this->parse('', [1, 2]);
|
|
|
|
$this->assertSame([], $booking->participantsStatus);
|
|
$this->assertCount(2, $booking->participants);
|
|
}
|
|
|
|
/** @param list<int> $participantIds */
|
|
private function parse(string $statusList, array $participantIds): \App\BusProNet\Model\Booking
|
|
{
|
|
$participants = '';
|
|
foreach ($participantIds as $id) {
|
|
$participants .= sprintf(
|
|
'<teilnehmer id="%d"><name>Teilnehmer %1$d</name><vorname>Test</vorname></teilnehmer>',
|
|
$id,
|
|
);
|
|
}
|
|
|
|
$xml = sprintf(
|
|
'<?xml version="1.0" encoding="utf-8"?>
|
|
<ergebnis>
|
|
<satz typ="KUNDENKONTO" />
|
|
<art>Vorgang_Details</art>
|
|
<idbuchung>98787</idbuchung>
|
|
<status_teilnehmer>%s</status_teilnehmer>
|
|
<zahlung idzahlungsart="1" bezeichnung="Überweisung" art="U" />
|
|
<teilnehmerliste>%s</teilnehmerliste>
|
|
</ergebnis>',
|
|
$statusList,
|
|
$participants,
|
|
);
|
|
|
|
return $this->parser->parse(XmlCrawlerFactory::create($xml)->filterXPath('//ergebnis'));
|
|
}
|
|
}
|