feat: replace *Service suffix with role-based class names

This commit is contained in:
Björn Fromme
2026-04-16 13:34:54 +02:00
parent 0d2cc5b998
commit d1c92f2957
88 changed files with 435 additions and 435 deletions
+443
View File
@@ -0,0 +1,443 @@
<?php
declare(strict_types=1);
namespace App\Tests\Service;
use App\BusProNet\ApiClient;
use App\BusProNet\Model\Travel;
use App\BusProNet\XmlLoader\TravelLoader;
use App\Exception\TravelNotFoundException;
use App\Service\TravelDataProvider;
use App\Service\TravelEnricher;
use App\Service\TravelIndex;
use App\Service\TravelSnapshotManager;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
use Symfony\Contracts\Cache\CacheInterface;
class TravelDataProviderTest extends TestCase
{
private TravelDataProvider $service;
private TravelLoader $travelLoader;
private ApiClient $apiClient;
private CacheInterface $cache;
private LoggerInterface $logger;
private TravelSnapshotManager $travelSnapshotService;
private TravelIndex $travelLookupService;
private TravelEnricher $travelEnrichmentService;
protected function setUp(): void
{
$this->travelLoader = $this->createMock(TravelLoader::class);
$this->apiClient = $this->createMock(ApiClient::class);
$this->cache = $this->createMock(CacheInterface::class);
$this->logger = $this->createMock(LoggerInterface::class);
$this->travelSnapshotService = $this->createMock(TravelSnapshotManager::class);
$this->travelLookupService = $this->createMock(TravelIndex::class);
$this->travelEnrichmentService = $this->createMock(TravelEnricher::class);
$this->service = new TravelDataProvider(
$this->travelLoader,
$this->apiClient,
$this->cache,
$this->logger,
$this->travelSnapshotService,
$this->travelLookupService,
$this->travelEnrichmentService,
false, // preferRemote
true, // enableFallback
);
}
public function testGetTravelDataFromXmlSuccess(): void
{
$dateId = 12345;
$hotelId = 67890;
$travel = new Travel();
$travel->id = $dateId;
$travel->hotelId = $hotelId;
$this->travelLoader
->expects($this->once())
->method('loadById')
->with($dateId, $hotelId)
->willReturn($travel);
$this->travelEnrichmentService
->expects($this->once())
->method('enrichFromXml')
->with($travel)
->willReturn(true);
$this->travelSnapshotService
->expects($this->once())
->method('upsertFromTravel')
->with($travel);
$result = $this->service->getTravelDataFromXml($dateId, $hotelId);
$this->assertSame($travel, $result);
}
public function testGetTravelDataFromXmlSkipsSnapshotWhenEnrichmentFails(): void
{
$dateId = 12345;
$hotelId = 67890;
$travel = new Travel();
$travel->id = $dateId;
$travel->hotelId = $hotelId;
$this->travelLoader
->expects($this->once())
->method('loadById')
->with($dateId, $hotelId)
->willReturn($travel);
$this->travelEnrichmentService
->expects($this->once())
->method('enrichFromXml')
->with($travel)
->willReturn(false);
$this->travelSnapshotService
->expects($this->never())
->method('upsertFromTravel');
$result = $this->service->getTravelDataFromXml($dateId, $hotelId);
$this->assertSame($travel, $result);
}
public function testGetTravelDataFromXmlNotFound(): void
{
$dateId = 12345;
$hotelId = 67890;
$this->travelLoader
->expects($this->once())
->method('loadById')
->with($dateId, $hotelId)
->willThrowException(new TravelNotFoundException($dateId));
$this->travelEnrichmentService
->expects($this->never())
->method('enrichFromXml');
$this->expectException(TravelNotFoundException::class);
$this->service->getTravelDataFromXml($dateId, $hotelId);
}
public function testGetTravelDataFromApiSuccess(): void
{
$dateId = 12345;
$hotelId = 67890;
$productId = 555;
$travel = new Travel();
$travel->id = $dateId;
$travel->hotelId = $hotelId;
$this->travelLookupService
->expects($this->once())
->method('mapDateIdToProductId')
->with($dateId)
->willReturn($productId);
$this->apiClient
->expects($this->once())
->method('getTravelData')
->with($productId, $hotelId)
->willReturn($travel);
$this->travelEnrichmentService
->expects($this->once())
->method('patchInsurances')
->with($travel);
$this->travelSnapshotService
->expects($this->once())
->method('upsertFromTravel')
->with($travel);
$result = $this->service->getTravelDataFromApi($dateId, $hotelId);
$this->assertSame($travel, $result);
}
public function testGetTravelDataFromApiSnapshotFailureDoesNotDiscardApiTravel(): void
{
$dateId = 12345;
$hotelId = 67890;
$productId = 555;
$travel = new Travel();
$travel->id = $dateId;
$travel->hotelId = $hotelId;
$this->travelLookupService
->method('mapDateIdToProductId')
->willReturn($productId);
$this->apiClient
->method('getTravelData')
->willReturn($travel);
$this->travelSnapshotService
->expects($this->once())
->method('upsertFromTravel')
->willThrowException(new \RuntimeException('DB write failed'));
$this->logger
->expects($this->once())
->method('warning')
->with('Failed to persist travel snapshot after API load', $this->arrayHasKey('dateId'));
$result = $this->service->getTravelDataFromApi($dateId, $hotelId);
$this->assertNotNull($result);
$this->assertSame($travel, $result);
}
public function testGetTravelDataFromApiCannotMapDateId(): void
{
$dateId = 12345;
$hotelId = 67890;
$this->travelLookupService
->expects($this->once())
->method('mapDateIdToProductId')
->with($dateId)
->willReturn(null);
$this->apiClient
->expects($this->never())
->method('getTravelData');
$result = $this->service->getTravelDataFromApi($dateId, $hotelId);
$this->assertNull($result);
}
public function testExistsLocallyDelegatesToLookupService(): void
{
$dateId = 12345;
$hotelId = 67890;
$this->travelLookupService
->expects($this->once())
->method('existsLocally')
->with($dateId, $hotelId)
->willReturn(true);
$this->assertTrue($this->service->existsLocally($dateId, $hotelId));
}
public function testGetAvailableSourcesDelegatesToLookupService(): void
{
$dateId = 12345;
$hotelId = 67890;
$expected = ['local' => true, 'remote' => true];
$this->travelLookupService
->expects($this->once())
->method('getAvailableSources')
->with($dateId, $hotelId)
->willReturn($expected);
$this->assertSame($expected, $this->service->getAvailableSources($dateId, $hotelId));
}
public function testGenerateFilesMapDelegatesToLookupService(): void
{
$mapping = [12345 => ['id' => 12345, 'hotels' => []]];
$this->travelLookupService
->expects($this->once())
->method('generateFilesMap')
->willReturn($mapping);
$this->assertSame($mapping, $this->service->generateFilesMap());
}
public function testGetTravelDataFromLocalPrefersSnapshot(): void
{
$dateId = 12345;
$hotelId = 67890;
$travel = new Travel();
$travel->id = $dateId;
$travel->hotelId = $hotelId;
$this->travelSnapshotService
->expects($this->once())
->method('loadTravel')
->with($dateId, $hotelId)
->willReturn($travel);
$this->travelLoader
->expects($this->never())
->method('loadById');
$this->travelEnrichmentService
->expects($this->once())
->method('patchInsurances')
->with($travel);
$result = $this->service->getTravelDataFromLocal($dateId, $hotelId);
$this->assertSame($travel, $result);
}
public function testGetTravelDataFromLocalFallsBackToXmlWhenSnapshotMissing(): void
{
$dateId = 12345;
$hotelId = 67890;
$travel = new Travel();
$travel->id = $dateId;
$travel->hotelId = $hotelId;
$this->travelSnapshotService
->expects($this->once())
->method('loadTravel')
->with($dateId, $hotelId)
->willReturn(null);
$this->travelLoader
->expects($this->once())
->method('loadById')
->with($dateId, $hotelId)
->willReturn($travel);
$this->travelEnrichmentService
->expects($this->once())
->method('enrichFromXml')
->with($travel)
->willReturn(true);
$this->travelSnapshotService
->expects($this->once())
->method('upsertFromTravel')
->with($travel);
$this->travelEnrichmentService
->expects($this->once())
->method('patchInsurances')
->with($travel);
$result = $this->service->getTravelDataFromLocal($dateId, $hotelId);
$this->assertSame($travel, $result);
}
public function testGetTravelDataFromLocalPropagatesTravelNotFoundFromXmlFallback(): void
{
$dateId = 12345;
$hotelId = 67890;
$this->travelSnapshotService
->expects($this->once())
->method('loadTravel')
->with($dateId, $hotelId)
->willReturn(null);
$this->travelLoader
->expects($this->once())
->method('loadById')
->with($dateId, $hotelId)
->willThrowException(new TravelNotFoundException($dateId));
$this->expectException(TravelNotFoundException::class);
$this->service->getTravelDataFromLocal($dateId, $hotelId);
}
public function testSnapshotLoadFailureFallsBackToXml(): void
{
$dateId = 12345;
$hotelId = 67890;
$travel = new Travel();
$travel->id = $dateId;
$travel->hotelId = $hotelId;
$this->travelSnapshotService
->expects($this->once())
->method('loadTravel')
->with($dateId, $hotelId)
->willThrowException(new \RuntimeException('DB connection failed'));
$this->logger
->expects($this->once())
->method('warning')
->with('Snapshot lookup failed, falling back to XML', $this->arrayHasKey('dateId'));
$this->travelLoader
->expects($this->once())
->method('loadById')
->with($dateId, $hotelId)
->willReturn($travel);
$result = $this->service->getTravelDataFromLocal($dateId, $hotelId);
$this->assertSame($travel, $result);
}
public function testSnapshotPersistenceFailureDoesNotDiscardXmlTravel(): void
{
$dateId = 12345;
$hotelId = 67890;
$travel = new Travel();
$travel->id = $dateId;
$travel->hotelId = $hotelId;
$this->travelLoader
->expects($this->once())
->method('loadById')
->with($dateId, $hotelId)
->willReturn($travel);
$this->travelEnrichmentService
->method('enrichFromXml')
->willReturn(true);
$this->travelSnapshotService
->expects($this->once())
->method('upsertFromTravel')
->willThrowException(new \RuntimeException('DB write failed'));
$this->logger
->expects($this->once())
->method('warning')
->with('Failed to persist travel snapshot after XML load', $this->arrayHasKey('dateId'));
$result = $this->service->getTravelDataFromXml($dateId, $hotelId);
$this->assertNotNull($result);
$this->assertSame($travel, $result);
}
public function testGetTravelDataDelegatesToLoadUncached(): void
{
$dateId = 12345;
$hotelId = 67890;
$travel = new Travel();
$travel->id = $dateId;
$travel->hotelId = $hotelId;
$this->cache
->expects($this->never())
->method('get');
$this->travelSnapshotService
->expects($this->once())
->method('loadTravel')
->with($dateId, $hotelId)
->willReturn(null);
$this->travelLoader
->expects($this->once())
->method('loadById')
->with($dateId, $hotelId)
->willReturn($travel);
$result = $this->service->getTravelData($dateId, $hotelId, false);
$this->assertSame($travel, $result);
}
}