149 lines
6.2 KiB
PHP
149 lines
6.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Tests\Service;
|
|
|
|
use App\Entity\Groups\Accommodation;
|
|
use App\Entity\Groups\CalendarHotel;
|
|
use App\Enum\ContingentHotelSource;
|
|
use App\Model\CmsCalendarHotel;
|
|
use App\Repository\Groups\AccommodationRepository;
|
|
use App\Repository\Groups\CalendarHotelRepository;
|
|
use App\Service\CmsDataProvider;
|
|
use App\Service\ContingentHotelDirectory;
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use PHPUnit\Framework\MockObject\Stub;
|
|
use PHPUnit\Framework\TestCase;
|
|
use Psr\Log\LoggerInterface;
|
|
|
|
class ContingentHotelDirectoryTest extends TestCase
|
|
{
|
|
private CmsDataProvider&Stub $cmsDataProvider;
|
|
private AccommodationRepository&Stub $accommodationRepository;
|
|
private CalendarHotelRepository&Stub $calendarHotelRepository;
|
|
private EntityManagerInterface&Stub $entityManager;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
$this->cmsDataProvider = $this->createStub(CmsDataProvider::class);
|
|
$this->accommodationRepository = $this->createStub(AccommodationRepository::class);
|
|
$this->calendarHotelRepository = $this->createStub(CalendarHotelRepository::class);
|
|
$this->entityManager = $this->createStub(EntityManagerInterface::class);
|
|
}
|
|
|
|
public function testRefreshAddsRenamesAndRemovesStoredHotels(): void
|
|
{
|
|
$this->entityManager = $this->createMock(EntityManagerInterface::class);
|
|
|
|
$renamed = (new CalendarHotel())->setCode('DKI')->setName('Schwendi');
|
|
$dropped = (new CalendarHotel())->setCode('ASB')->setName('Sportclub Bader');
|
|
$this->calendarHotelRepository->method('findAllIndexedByCode')->willReturn(['DKI' => $renamed, 'ASB' => $dropped]);
|
|
$this->cmsDataProvider->method('fetchCalendarHotels')->willReturn([
|
|
new CmsCalendarHotel('DKI', 'Sportclub Schwendi'),
|
|
new CmsCalendarHotel('DWW', 'Sportclub Weissfluh'),
|
|
]);
|
|
|
|
$this->entityManager->expects(self::once())->method('persist')
|
|
->with(self::callback(static fn (CalendarHotel $hotel) => 'DWW' === $hotel->getCode() && 'Sportclub Weissfluh' === $hotel->getName()));
|
|
$this->entityManager->expects(self::once())->method('remove')->with($dropped);
|
|
$this->entityManager->expects(self::once())->method('flush');
|
|
|
|
self::assertTrue($this->directory()->refresh());
|
|
self::assertSame('Sportclub Schwendi', $renamed->getName());
|
|
}
|
|
|
|
public function testRefreshKeepsTheStoredListWhenTypo3IsUnavailable(): void
|
|
{
|
|
$this->assertKeepsStoredList(null);
|
|
}
|
|
|
|
public function testRefreshKeepsTheStoredListWhenTypo3ReturnsNoHotels(): void
|
|
{
|
|
$this->assertKeepsStoredList([]);
|
|
}
|
|
|
|
public function testRefreshIgnoresCodesTheApiCouldNotBeAskedFor(): void
|
|
{
|
|
$this->entityManager = $this->createMock(EntityManagerInterface::class);
|
|
|
|
$this->calendarHotelRepository->method('findAllIndexedByCode')->willReturn([]);
|
|
$this->cmsDataProvider->method('fetchCalendarHotels')->willReturn([
|
|
new CmsCalendarHotel('DKI', 'Sportclub Schwendi'),
|
|
new CmsCalendarHotel('ABCDEFGHIJKLMNOPQ', 'Too long'),
|
|
new CmsCalendarHotel('A B', 'Space'),
|
|
]);
|
|
|
|
$this->entityManager->expects(self::once())->method('persist')
|
|
->with(self::callback(static fn (CalendarHotel $hotel) => 'DKI' === $hotel->getCode()));
|
|
|
|
$this->directory()->refresh();
|
|
}
|
|
|
|
public function testAllIsTheUnionOfAccommodationsAndTypo3Hotels(): void
|
|
{
|
|
$this->accommodationRepository->method('findAllWithCalendarCode')->willReturn([
|
|
(new Accommodation())->setCalendarCode('DGS'),
|
|
(new Accommodation())->setCalendarCode('SERASCSO'),
|
|
]);
|
|
$this->calendarHotelRepository->method('findAllIndexedByCode')->willReturn([
|
|
'ASCGR' => (new CalendarHotel())->setCode('ASCGR')->setName('Christiler'),
|
|
'DGS' => (new CalendarHotel())->setCode('DGS')->setName('Spinabad'),
|
|
]);
|
|
|
|
$hotels = $this->directory()->all();
|
|
|
|
self::assertSame(['ASCGR', 'DGS', 'SERASCSO'], array_keys($hotels));
|
|
self::assertSame([ContingentHotelSource::Typo3], $hotels['ASCGR']->sources());
|
|
self::assertSame([ContingentHotelSource::Accommodation, ContingentHotelSource::Typo3], $hotels['DGS']->sources());
|
|
self::assertSame([ContingentHotelSource::Accommodation], $hotels['SERASCSO']->sources());
|
|
}
|
|
|
|
public function testFindKnowsATypo3OnlyHotel(): void
|
|
{
|
|
$this->accommodationRepository->method('findOneByCalendarCode')->willReturn(null);
|
|
$this->calendarHotelRepository->method('findOneBy')->willReturn((new CalendarHotel())->setCode('DKI')->setName('Schwendi'));
|
|
|
|
self::assertSame('DKI', $this->directory()->find('DKI')?->code);
|
|
}
|
|
|
|
public function testFindReturnsNullForAnUnknownCode(): void
|
|
{
|
|
$this->accommodationRepository->method('findOneByCalendarCode')->willReturn(null);
|
|
$this->calendarHotelRepository->method('findOneBy')->willReturn(null);
|
|
|
|
self::assertNull($this->directory()->find('NOPE'));
|
|
}
|
|
|
|
/**
|
|
* @param list<CmsCalendarHotel>|null $fetched
|
|
*/
|
|
private function assertKeepsStoredList(?array $fetched): void
|
|
{
|
|
$this->entityManager = $this->createMock(EntityManagerInterface::class);
|
|
$logger = $this->createMock(LoggerInterface::class);
|
|
|
|
$this->calendarHotelRepository->method('findAllIndexedByCode')->willReturn([
|
|
'DKI' => (new CalendarHotel())->setCode('DKI')->setName('Sportclub Schwendi'),
|
|
]);
|
|
$this->cmsDataProvider->method('fetchCalendarHotels')->willReturn($fetched);
|
|
|
|
$this->entityManager->expects(self::never())->method('remove');
|
|
$this->entityManager->expects(self::never())->method('flush');
|
|
$logger->expects(self::once())->method('warning');
|
|
|
|
self::assertFalse($this->directory($logger)->refresh());
|
|
}
|
|
|
|
private function directory(?LoggerInterface $logger = null): ContingentHotelDirectory
|
|
{
|
|
return new ContingentHotelDirectory(
|
|
$this->cmsDataProvider,
|
|
$this->accommodationRepository,
|
|
$this->calendarHotelRepository,
|
|
$this->entityManager,
|
|
$logger ?? $this->createStub(LoggerInterface::class),
|
|
);
|
|
}
|
|
}
|