runSync(['A', 'B'], [ ContingentSyncResult::failed('upstream down'), ContingentSyncResult::failed('upstream down'), ]); self::assertSame(Command::FAILURE, $tester->getStatusCode()); } public function testASingleFailingHotelDoesNotFailTheTask(): void { $tester = $this->runSync(['A', 'B', 'C'], [ ContingentSyncResult::synced(true, 3, 0, 0), ContingentSyncResult::failed('unknown hotel code'), ContingentSyncResult::synced(false, 0, 0, 0), ]); self::assertSame(Command::SUCCESS, $tester->getStatusCode()); self::assertStringContainsString('B', $tester->getDisplay()); self::assertStringContainsString('unknown hotel code', $tester->getDisplay()); } public function testASuccessfulRunSucceeds(): void { $tester = $this->runSync(['A'], [ContingentSyncResult::synced(true, 3, 1, 0)]); self::assertSame(Command::SUCCESS, $tester->getStatusCode()); } public function testARunWithNoAccommodationsSucceeds(): void { $tester = $this->runSync([], []); self::assertSame(Command::SUCCESS, $tester->getStatusCode()); } /** * @param string[] $hotelCodes * @param ContingentSyncResult[] $results */ private function runSync(array $hotelCodes, array $results): CommandTester { $accommodations = array_map( static fn (string $code) => (new Accommodation())->setCalendarCode($code), $hotelCodes, ); $accommodationRepository = $this->createStub(AccommodationRepository::class); $accommodationRepository->method('findAllWithCalendarCode')->willReturn($accommodations); $manager = $this->createStub(ContingentSnapshotManager::class); if ([] !== $results) { $manager->method('sync')->willReturnOnConsecutiveCalls(...$results); } $command = new BpnSyncContingentsCommand( $accommodationRepository, $this->createStub(ContingentSyncStateRepository::class), $this->createStub(ContingentDayRepository::class), $manager, new NullLogger(), ); $application = new Application(); $application->addCommand($command); $tester = new CommandTester($application->find('app:bpn:sync-contingents')); $tester->execute(['--horizon-months' => '1']); // LockableTrait's lock lives for the life of the process, so without releasing it every // run after the first would exit early and these assertions would pass for the wrong reason. $release = new \ReflectionMethod($command, 'release'); $release->invoke($command); return $tester; } }