createMock(TagAwareCacheInterface::class);
$filesystem = $this->createMock(FilesystemOperator::class);
$parser = $this->createMock(ContingentParser::class);
$filesystem->method('listContents')->willReturn(new DirectoryListing([
new FileAttributes('HotelZimmer_100.xml', 10),
new FileAttributes('HotelZimmer_200.xml', 10),
new FileAttributes('other.xml', 10),
]));
$item = $this->createMock(ItemInterface::class);
$item->expects($this->once())->method('expiresAfter')->with(3 * 60 * 60);
$item->expects($this->once())->method('tag')->with(['xml-sync']);
$cache->expects($this->once())
->method('get')
->with('bpn_contingent_files', $this->isType('callable'))
->willReturnCallback(fn (string $key, callable $callback) => $callback($item));
$loader = new ContingentLoader($parser, $cache, $filesystem);
$map = $loader->generateFilesMap();
$this->assertSame([
100 => 'HotelZimmer_100.xml',
200 => 'HotelZimmer_200.xml',
], $map);
}
public function testLoadByHotelIdUsesRootLinkOneHopAndTagsCache(): void
{
$cache = $this->createMock(TagAwareCacheInterface::class);
$filesystem = $this->createMock(FilesystemOperator::class);
$parser = $this->createMock(ContingentParser::class);
$originalXml = '';
$linkedXml = '';
$parsed = ['roomTypes' => [], 'rows' => [['roomCode' => 'DZ']]];
$filesystem->method('listContents')->willReturn(new DirectoryListing([
new FileAttributes('HotelZimmer_100.xml', 10),
new FileAttributes('HotelZimmer_200.xml', 10),
]));
$filesystem->method('read')->willReturnMap([
['HotelZimmer_100.xml', $originalXml],
['HotelZimmer_200.xml', $linkedXml],
]);
$mapItem = $this->createMock(ItemInterface::class);
$mapItem->method('expiresAfter')->with(3 * 60 * 60);
$mapItem->method('tag')->with(['xml-sync']);
$hotelItem = $this->createMock(ItemInterface::class);
$hotelItem->method('expiresAfter')->with(3600);
$hotelItem->method('tag')->with(['xml-sync']);
$cache->method('get')->willReturnCallback(
function (string $key, callable $callback) use ($mapItem, $hotelItem) {
if ('bpn_contingent_files' === $key) {
return $callback($mapItem);
}
if ('contingent_hotel_100' === $key) {
return $callback($hotelItem);
}
return null;
}
);
$parser->expects($this->once())->method('parse')->with($linkedXml)->willReturn($parsed);
$loader = new ContingentLoader($parser, $cache, $filesystem);
$result = $loader->loadByHotelId(100);
$this->assertSame($parsed, $result);
}
public function testLoadByHotelIdReturnsEmptyWhenLinkedTargetIsMissing(): void
{
$cache = $this->createMock(TagAwareCacheInterface::class);
$filesystem = $this->createMock(FilesystemOperator::class);
$parser = $this->createMock(ContingentParser::class);
$xml = '';
$filesystem->method('listContents')->willReturn(new DirectoryListing([
new FileAttributes('HotelZimmer_100.xml', 10),
]));
$filesystem->method('read')->willReturn($xml);
$mapItem = $this->createMock(ItemInterface::class);
$mapItem->method('expiresAfter')->with(3 * 60 * 60);
$mapItem->method('tag')->with(['xml-sync']);
$hotelItem = $this->createMock(ItemInterface::class);
$hotelItem->method('expiresAfter')->with(3600);
$hotelItem->method('tag')->with(['xml-sync']);
$cache->method('get')->willReturnCallback(
function (string $key, callable $callback) use ($mapItem, $hotelItem) {
if ('bpn_contingent_files' === $key) {
return $callback($mapItem);
}
if ('contingent_hotel_100' === $key) {
return $callback($hotelItem);
}
return null;
}
);
$parser->expects($this->never())->method('parse');
$loader = new ContingentLoader($parser, $cache, $filesystem);
$result = $loader->loadByHotelId(100);
$this->assertSame(['roomTypes' => [], 'rows' => []], $result);
}
}