Files
myep/tests/Service/BookingEditDataLoaderDraftRestoreTest.php
T

126 lines
4.3 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Tests\Service;
use App\BusProNet\ApiClient;
use App\BusProNet\DataProcessor\BookingDataProcessor;
use App\BusProNet\Model\BaseData;
use App\BusProNet\Model\Booking;
use App\BusProNet\Model\ServiceAvailabilityResponse;
use App\BusProNet\Model\Travel;
use App\BusProNet\XmlLoader\AgencyLoader;
use App\Entity\BookingEditDraft;
use App\Entity\User;
use App\Form\Model\BookingDto;
use App\Form\Model\ParticipantDto;
use App\Security\Crypt;
use App\Service\BookingChangeTracker;
use App\Service\BookingEditDataLoader;
use App\Service\BookingEditDraftManager;
use App\Service\BookingSessionManager;
use App\Service\TravelDataProvider;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Contracts\Cache\TagAwareCacheInterface;
/**
* Covers the "draft restored" signal that drives the overview flash message.
*
* A draft is written on every participant save, including saves that changed nothing.
* Such a draft reproduces the API state exactly, so applying it is a no-op and must not
* be reported as a restore — otherwise the user is told their draft was restored for
* edits they never made.
*/
class BookingEditDataLoaderDraftRestoreTest extends TestCase
{
public function testNoOpDraftIsNotReportedAsRestored(): void
{
$loader = $this->createLoader(static function (BookingDto $dto): void {
// Draft reproduces the API state: nothing changes.
});
$loader->initializeFromApi(new Request(), 42, $this->createUser());
$this->assertFalse($loader->isDraftRestored());
}
public function testDraftThatChangesDataIsReportedAsRestored(): void
{
$loader = $this->createLoader(static function (BookingDto $dto): void {
$dto->participants[0]->firstName = 'Berta';
});
$loader->initializeFromApi(new Request(), 42, $this->createUser());
$this->assertTrue($loader->isDraftRestored());
}
private function createUser(): User
{
$user = new User('[email protected]');
$user->setPassword('encrypted');
return $user;
}
/**
* @param callable(BookingDto): void $applyDraft what the stored draft does to the DTO
*/
private function createLoader(callable $applyDraft): BookingEditDataLoader
{
$booking = new Booking();
$booking->id = 42;
$booking->dateId = 1234;
$booking->hotelId = 7;
$travel = new Travel();
$travel->id = 1234;
$bookingDto = new BookingDto($travel, 77);
$bookingDto->booking = $booking;
$participant = new ParticipantDto();
$participant->index = 0;
$participant->firstName = 'Anna';
$bookingDto->participants = [$participant];
$cache = $this->createStub(TagAwareCacheInterface::class);
$cache->method('get')->willReturn($booking);
$travelDataService = $this->createStub(TravelDataProvider::class);
$travelDataService->method('getTravelData')->willReturn($travel);
$travelDataService->method('getMutabilityData')->willReturn($this->createStub(BaseData::class));
$travelDataService->method('getAvailabilityData')
->willReturn($this->createStub(ServiceAvailabilityResponse::class));
$bookingDataProcessor = $this->createStub(BookingDataProcessor::class);
$bookingDataProcessor->method('createBookingDtoFromBooking')->willReturn($bookingDto);
$draftService = $this->createStub(BookingEditDraftManager::class);
$draftService->method('findDraft')->willReturn($this->createStub(BookingEditDraft::class));
$draftService->method('applyDraftToDto')->willReturnCallback(
static function (BookingEditDraft $draft, BookingDto $dto, Travel $travel) use ($applyDraft): bool {
$applyDraft($dto);
return true;
}
);
$crypt = $this->createStub(Crypt::class);
$crypt->method('decrypt')->willReturn('secret');
return new BookingEditDataLoader(
$this->createStub(ApiClient::class),
$bookingDataProcessor,
$this->createStub(BookingSessionManager::class),
new BookingChangeTracker(),
$travelDataService,
$draftService,
$this->createStub(AgencyLoader::class),
$crypt,
$cache,
);
}
}