feat: sync contingents for TYPO3 calendar hotels
This commit is contained in:
1 parent
ec36b61275
commit
97c6330a9a
24 files changed
+1067
-180
No files matched your search
@@ -6,10 +6,12 @@ namespace App\Tests\Command;
|
||||
|
||||
use App\Command\BpnSyncContingentsCommand;
|
||||
use App\Entity\Groups\Accommodation;
|
||||
use App\Entity\Groups\CalendarHotel;
|
||||
use App\Model\ContingentHotel;
|
||||
use App\Model\ContingentSyncResult;
|
||||
use App\Repository\Groups\AccommodationRepository;
|
||||
use App\Repository\Groups\ContingentDayRepository;
|
||||
use App\Repository\Groups\ContingentSyncStateRepository;
|
||||
use App\Service\ContingentHotelDirectory;
|
||||
use App\Service\ContingentSnapshotManager;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Log\NullLogger;
|
||||
@@ -53,36 +55,113 @@ class BpnSyncContingentsCommandTest extends TestCase
|
||||
self::assertSame(Command::SUCCESS, $tester->getStatusCode());
|
||||
}
|
||||
|
||||
public function testARunWithNoAccommodationsSucceeds(): void
|
||||
public function testARunWithNoHotelsSucceeds(): void
|
||||
{
|
||||
$tester = $this->runSync([], []);
|
||||
|
||||
self::assertSame(Command::SUCCESS, $tester->getStatusCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $hotelCodes
|
||||
* @param ContingentSyncResult[] $results
|
||||
*/
|
||||
private function runSync(array $hotelCodes, array $results): CommandTester
|
||||
public function testSyncsAccommodationAndTypo3CodesAndDropsTheRest(): void
|
||||
{
|
||||
$accommodations = array_map(
|
||||
static fn (string $code) => (new Accommodation())->setCalendarCode($code),
|
||||
$hotelCodes,
|
||||
$manager = $this->createMock(ContingentSnapshotManager::class);
|
||||
$synced = [];
|
||||
$manager->expects(self::exactly(2))->method('sync')
|
||||
->willReturnCallback(static function (string $code) use (&$synced): ContingentSyncResult {
|
||||
$synced[] = $code;
|
||||
|
||||
return ContingentSyncResult::synced(false, 0, 0, 0, 0);
|
||||
});
|
||||
|
||||
$dayRepository = $this->createMock(ContingentDayRepository::class);
|
||||
$dayRepository->expects(self::once())->method('deleteExceptHotelCodes')->with(['DGS', 'DKI']);
|
||||
$syncStateRepository = $this->createMock(ContingentSyncStateRepository::class);
|
||||
$syncStateRepository->expects(self::once())->method('deleteExceptHotelCodes')->with(['DGS', 'DKI']);
|
||||
|
||||
$this->runSync(
|
||||
['DGS' => 'accommodation', 'DKI' => 'typo3'],
|
||||
manager: $manager,
|
||||
dayRepository: $dayRepository,
|
||||
syncStateRepository: $syncStateRepository,
|
||||
);
|
||||
|
||||
$accommodationRepository = $this->createStub(AccommodationRepository::class);
|
||||
$accommodationRepository->method('findAllWithCalendarCode')->willReturn($accommodations);
|
||||
self::assertSame(['DGS', 'DKI'], $synced);
|
||||
}
|
||||
|
||||
$manager = $this->createStub(ContingentSnapshotManager::class);
|
||||
if ([] !== $results) {
|
||||
$manager->method('sync')->willReturnOnConsecutiveCalls(...$results);
|
||||
public function testASingleHotelRunAcceptsATypo3OnlyCodeAndDropsNothing(): void
|
||||
{
|
||||
$manager = $this->createMock(ContingentSnapshotManager::class);
|
||||
$manager->expects(self::once())->method('sync')
|
||||
->with('DKI', self::anything(), self::anything())
|
||||
->willReturn(ContingentSyncResult::synced(false, 0, 0, 0, 0));
|
||||
|
||||
$dayRepository = $this->createMock(ContingentDayRepository::class);
|
||||
$dayRepository->expects(self::never())->method('deleteExceptHotelCodes');
|
||||
$syncStateRepository = $this->createMock(ContingentSyncStateRepository::class);
|
||||
$syncStateRepository->expects(self::never())->method('deleteExceptHotelCodes');
|
||||
|
||||
$tester = $this->runSync(
|
||||
['DGS' => 'accommodation', 'DKI' => 'typo3'],
|
||||
manager: $manager,
|
||||
dayRepository: $dayRepository,
|
||||
syncStateRepository: $syncStateRepository,
|
||||
options: ['--hotel' => 'DKI'],
|
||||
);
|
||||
|
||||
self::assertSame(Command::SUCCESS, $tester->getStatusCode());
|
||||
}
|
||||
|
||||
public function testASingleHotelRunIgnoresAnUnknownCode(): void
|
||||
{
|
||||
$manager = $this->createMock(ContingentSnapshotManager::class);
|
||||
$manager->expects(self::never())->method('sync');
|
||||
|
||||
$tester = $this->runSync(['DGS' => 'accommodation'], manager: $manager, options: ['--hotel' => 'NOPE']);
|
||||
|
||||
self::assertSame(Command::SUCCESS, $tester->getStatusCode());
|
||||
self::assertStringContainsString('No accommodation calendarCode or TYPO3 calendar hotel matched', $tester->getDisplay());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int|string, string> $hotels codes, or code => 'accommodation'|'typo3'
|
||||
* @param ContingentSyncResult[] $results
|
||||
* @param array<string, string> $options
|
||||
*/
|
||||
private function runSync(
|
||||
array $hotels,
|
||||
array $results = [],
|
||||
?ContingentSnapshotManager $manager = null,
|
||||
?ContingentDayRepository $dayRepository = null,
|
||||
?ContingentSyncStateRepository $syncStateRepository = null,
|
||||
array $options = [],
|
||||
): CommandTester {
|
||||
if (array_is_list($hotels)) {
|
||||
$hotels = array_fill_keys($hotels, 'accommodation');
|
||||
}
|
||||
|
||||
$directoryEntries = [];
|
||||
|
||||
foreach ($hotels as $code => $source) {
|
||||
$code = (string) $code;
|
||||
$directoryEntries[$code] = 'typo3' === $source
|
||||
? new ContingentHotel($code, null, (new CalendarHotel())->setCode($code)->setName($code))
|
||||
: new ContingentHotel($code, (new Accommodation())->setCalendarCode($code), null);
|
||||
}
|
||||
|
||||
$hotelDirectory = $this->createStub(ContingentHotelDirectory::class);
|
||||
$hotelDirectory->method('all')->willReturn($directoryEntries);
|
||||
|
||||
if (null === $manager) {
|
||||
$manager = $this->createStub(ContingentSnapshotManager::class);
|
||||
if ([] !== $results) {
|
||||
$manager->method('sync')->willReturnOnConsecutiveCalls(...$results);
|
||||
}
|
||||
}
|
||||
|
||||
$command = new BpnSyncContingentsCommand(
|
||||
$accommodationRepository,
|
||||
$this->createStub(ContingentSyncStateRepository::class),
|
||||
$this->createStub(ContingentDayRepository::class),
|
||||
$hotelDirectory,
|
||||
$syncStateRepository ?? $this->createStub(ContingentSyncStateRepository::class),
|
||||
$dayRepository ?? $this->createStub(ContingentDayRepository::class),
|
||||
$manager,
|
||||
new NullLogger(),
|
||||
);
|
||||
@@ -91,7 +170,7 @@ class BpnSyncContingentsCommandTest extends TestCase
|
||||
$application->addCommand($command);
|
||||
|
||||
$tester = new CommandTester($application->find('app:bpn:sync-contingents'));
|
||||
$tester->execute(['--horizon-months' => '1']);
|
||||
$tester->execute(['--horizon-months' => '1'] + $options);
|
||||
|
||||
// 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.
|
||||
|
||||
Reference in new issue
Block a user