127 lines
4.3 KiB
PHP
127 lines
4.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Tests\Service;
|
|
|
|
use App\BusProNet\Constants;
|
|
use App\BusProNet\Model\Service;
|
|
use App\BusProNet\Model\Travel;
|
|
use App\Form\Model\BookingDto;
|
|
use App\Form\Model\ParticipantDto;
|
|
use App\Service\ServiceAvailabilityCalculator;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
class ServiceAvailabilityCalculatorTest extends TestCase
|
|
{
|
|
private ServiceAvailabilityCalculator $calculator;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
$this->calculator = new ServiceAvailabilityCalculator();
|
|
}
|
|
|
|
public function testParkingServiceIsUnavailableWhenSoldOut(): void
|
|
{
|
|
$parkingService = $this->createParkingService(id: 1, available: 0);
|
|
$bookingDto = $this->createBookingDtoWithServices([$parkingService]);
|
|
|
|
$this->assertTrue($this->calculator->isServiceUnavailable(1, $bookingDto, 0));
|
|
}
|
|
|
|
public function testParkingServiceIsAvailableWhenQuotaRemains(): void
|
|
{
|
|
$parkingService = $this->createParkingService(id: 1, available: 5);
|
|
$bookingDto = $this->createBookingDtoWithServices([$parkingService]);
|
|
|
|
$this->assertFalse($this->calculator->isServiceUnavailable(1, $bookingDto, 0));
|
|
}
|
|
|
|
public function testParkingSelectedByOtherParticipantCountsTowardUsage(): void
|
|
{
|
|
$parkingService = $this->createParkingService(id: 1, available: 1);
|
|
$bookingDto = $this->createBookingDtoWithServices([$parkingService]);
|
|
|
|
$otherParticipant = new ParticipantDto();
|
|
$otherParticipant->parkingService = $parkingService;
|
|
$bookingDto->participants[1] = $otherParticipant;
|
|
|
|
// Only one parking slot remains, and another participant already claimed it,
|
|
// so it must show unavailable for the current participant (index 0)
|
|
$this->assertTrue($this->calculator->isServiceUnavailable(1, $bookingDto, 0));
|
|
}
|
|
|
|
public function testServiceOnBookingStopIsUnavailableDespiteUnlimitedQuota(): void
|
|
{
|
|
$skiPass = $this->createSkiPass(id: 1, available: null, status: Constants::STATUS_BLOCKED);
|
|
$bookingDto = $this->createBookingDtoWithServices([$skiPass]);
|
|
|
|
$this->assertTrue($this->calculator->isServiceUnavailable(1, $bookingDto, 0));
|
|
}
|
|
|
|
public function testServiceOnBookingStopIsUnavailableDespiteRemainingQuota(): void
|
|
{
|
|
$skiPass = $this->createSkiPass(id: 1, available: 10, status: Constants::STATUS_BLOCKED);
|
|
$bookingDto = $this->createBookingDtoWithServices([$skiPass]);
|
|
|
|
$this->assertTrue($this->calculator->isServiceUnavailable(1, $bookingDto, 0));
|
|
}
|
|
|
|
public function testFilterAvailableServicesRemovesSoldOutAndBlockedServices(): void
|
|
{
|
|
$bookable = $this->createSkiPass(id: 1, available: 5);
|
|
$soldOut = $this->createSkiPass(id: 2, available: 0);
|
|
$blocked = $this->createSkiPass(id: 3, available: null, status: Constants::STATUS_BLOCKED);
|
|
$unlimited = $this->createSkiPass(id: 4, available: null);
|
|
|
|
$bookingDto = $this->createBookingDtoWithServices([$bookable, $soldOut, $blocked, $unlimited]);
|
|
|
|
$filtered = $this->calculator->filterAvailableServices(
|
|
$bookingDto->travel->additionalServices,
|
|
$bookingDto,
|
|
0
|
|
);
|
|
|
|
$this->assertSame([1, 4], array_keys($filtered));
|
|
}
|
|
|
|
private function createParkingService(int $id, int $available): Service
|
|
{
|
|
$service = new Service();
|
|
$service->id = $id;
|
|
$service->label = 'Parkplatz';
|
|
$service->subType = Constants::TOKEN_PARKING;
|
|
$service->available = $available;
|
|
|
|
return $service;
|
|
}
|
|
|
|
private function createSkiPass(int $id, ?int $available, string $status = Constants::STATUS_AVAILABLE): Service
|
|
{
|
|
$service = new Service();
|
|
$service->id = $id;
|
|
$service->label = sprintf('Skipass %d', $id);
|
|
$service->subType = Constants::TOKEN_SKI_PASS;
|
|
$service->available = $available;
|
|
$service->status = $status;
|
|
|
|
return $service;
|
|
}
|
|
|
|
private function createBookingDtoWithServices(array $services): BookingDto
|
|
{
|
|
$travel = new Travel();
|
|
|
|
$indexed = [];
|
|
foreach ($services as $service) {
|
|
$indexed[$service->id] = $service;
|
|
}
|
|
$travel->additionalServices = $indexed;
|
|
|
|
$bookingDto = new BookingDto($travel, 1);
|
|
$bookingDto->participants[0] = new ParticipantDto();
|
|
|
|
return $bookingDto;
|
|
}
|
|
}
|