fix: derive contingent change signal from the sync diff

This commit is contained in:
2026-09-11 19:34:29 +02:00
parent e863025fb1
commit 5f8a586385
8 changed files with 87 additions and 73 deletions
@@ -36,9 +36,9 @@ class BpnSyncContingentsCommandTest extends TestCase
public function testASingleFailingHotelDoesNotFailTheTask(): void
{
$tester = $this->runSync(['A', 'B', 'C'], [
ContingentSyncResult::synced(true, 3, 0, 0),
ContingentSyncResult::synced(true, 3, 0, 0, 0),
ContingentSyncResult::failed('unknown hotel code'),
ContingentSyncResult::synced(false, 0, 0, 0),
ContingentSyncResult::synced(false, 0, 0, 0, 0),
]);
self::assertSame(Command::SUCCESS, $tester->getStatusCode());
@@ -48,7 +48,7 @@ class BpnSyncContingentsCommandTest extends TestCase
public function testASuccessfulRunSucceeds(): void
{
$tester = $this->runSync(['A'], [ContingentSyncResult::synced(true, 3, 1, 0)]);
$tester = $this->runSync(['A'], [ContingentSyncResult::synced(true, 3, 0, 1, 0)]);
self::assertSame(Command::SUCCESS, $tester->getStatusCode());
}
@@ -41,7 +41,6 @@ class ContingentSnapshotManagerTest extends TestCase
$this->entityManager = $this->createMock(EntityManagerInterface::class);
$this->dayRepository->method('findByAccommodationAndDateRange')->willReturn([]);
$this->dayRepository->method('findStatusFingerprintParts')->willReturn(['2026-07-01:OK', '2026-07-02:BLOCKED']);
$this->client->method('getContingentCalendar')->willReturn($this->response([
new ContingentCalendarEntry('2026-07-01', ContingentStatus::Ok),
new ContingentCalendarEntry('2026-07-02', ContingentStatus::Blocked),
@@ -69,7 +68,6 @@ class ContingentSnapshotManagerTest extends TestCase
];
$this->dayRepository->method('findByAccommodationAndDateRange')->willReturn($existing);
$this->dayRepository->method('findStatusFingerprintParts')->willReturn(['2026-07-01:OK']);
$this->client->method('getContingentCalendar')->willReturn($this->response([
new ContingentCalendarEntry('2026-07-01', ContingentStatus::Ok),
new ContingentCalendarEntry('2026-07-02', ContingentStatus::OnRequest),
@@ -85,16 +83,14 @@ class ContingentSnapshotManagerTest extends TestCase
self::assertSame(ContingentStatus::OnRequest, $existing['2026-07-02']->getStatus());
}
public function testUnchangedFingerprintDoesNotMoveChangedAt(): void
public function testAnIdenticalUpstreamResponseDoesNotMoveChangedAt(): void
{
$state = new ContingentSyncState($this->accommodation());
$state->setContentHash(hash('sha256', '2026-07-01:OK'));
$this->syncStateRepository->method('findOneByAccommodation')->willReturn($state);
$this->dayRepository->method('findByAccommodationAndDateRange')->willReturn([
'2026-07-01' => $this->day('2026-07-01', ContingentStatus::Ok),
]);
$this->dayRepository->method('findStatusFingerprintParts')->willReturn(['2026-07-01:OK']);
$this->client->method('getContingentCalendar')->willReturn($this->response([
new ContingentCalendarEntry('2026-07-01', ContingentStatus::Ok),
]));
@@ -148,7 +144,6 @@ class ContingentSnapshotManagerTest extends TestCase
public function testDaysOutsideTheRequestedWindowAreIgnored(): void
{
$this->dayRepository->method('findByAccommodationAndDateRange')->willReturn([]);
$this->dayRepository->method('findStatusFingerprintParts')->willReturn([]);
$this->client->method('getContingentCalendar')->willReturn($this->response([
new ContingentCalendarEntry('2026-06-30', ContingentStatus::Ok),
new ContingentCalendarEntry('2026-07-01', ContingentStatus::Ok),
@@ -167,7 +162,6 @@ class ContingentSnapshotManagerTest extends TestCase
$this->syncStateRepository->method('findOneByAccommodation')->willReturn($state);
$this->dayRepository->method('findByAccommodationAndDateRange')->willReturn([]);
$this->dayRepository->method('findStatusFingerprintParts')->willReturn([]);
$this->client->method('getContingentCalendar')->willReturn($this->response([
new ContingentCalendarEntry('2026-07-01', ContingentStatus::Ok),
]));
@@ -185,7 +179,6 @@ class ContingentSnapshotManagerTest extends TestCase
$this->syncStateRepository->method('findOneByAccommodation')->willReturn($state);
$this->dayRepository->method('findByAccommodationAndDateRange')->willReturn([]);
$this->dayRepository->method('findStatusFingerprintParts')->willReturn([]);
$this->client->method('getContingentCalendar')->willReturn($this->response([
new ContingentCalendarEntry('2026-07-01', ContingentStatus::Ok),
]));
@@ -195,6 +188,32 @@ class ContingentSnapshotManagerTest extends TestCase
self::assertSame('2026-07-03', $state->getHorizonTo()?->format('Y-m-d'));
}
public function testTheRollingWindowGrowingIsNotAChange(): void
{
$state = new ContingentSyncState($this->accommodation());
$state->recordSuccess(new \DateTimeImmutable('2026-06-30'), new \DateTimeImmutable('2026-07-02'));
$this->syncStateRepository->method('findOneByAccommodation')->willReturn($state);
$this->dayRepository->method('findByAccommodationAndDateRange')->willReturn([
'2026-07-01' => $this->day('2026-07-01', ContingentStatus::Ok),
'2026-07-02' => $this->day('2026-07-02', ContingentStatus::Ok),
]);
// Same two days as before plus the one the window just grew by, which is what every
// scheduled run sees after midnight.
$this->client->method('getContingentCalendar')->willReturn($this->response([
new ContingentCalendarEntry('2026-07-01', ContingentStatus::Ok),
new ContingentCalendarEntry('2026-07-02', ContingentStatus::Ok),
new ContingentCalendarEntry('2026-07-03', ContingentStatus::Ok),
]));
$result = $this->sync();
self::assertFalse($result->changed);
self::assertSame(0, $result->added);
self::assertSame(1, $result->extended);
self::assertNull($state->getChangedAt());
}
private function sync(): \App\Model\ContingentSyncResult
{
$manager = new ContingentSnapshotManager(