285 lines
10 KiB
PHP
285 lines
10 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Tests\Service;
|
|
|
|
use App\BusProNet\Model\Insurance;
|
|
use App\Form\Model\BookingDto;
|
|
use App\Form\Model\ParticipantDto;
|
|
use App\Service\BookingPriceCalculatorService;
|
|
use App\Service\InsuranceMatchingService;
|
|
use Carbon\Carbon;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
class InsuranceMatchingServiceTest extends TestCase
|
|
{
|
|
private InsuranceMatchingService $service;
|
|
private BookingPriceCalculatorService $priceCalculator;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
// Mock the price calculator service
|
|
$this->priceCalculator = $this->createMock(BookingPriceCalculatorService::class);
|
|
$this->priceCalculator
|
|
->method('calculateIndividualParticipantPriceExcludingInsurance')
|
|
->willReturn(500.0); // Default test price
|
|
|
|
$this->service = new InsuranceMatchingService($this->priceCalculator);
|
|
|
|
// Set a fixed test date for consistent test results
|
|
Carbon::setTestNow('2024-06-01 12:00:00');
|
|
}
|
|
|
|
protected function tearDown(): void
|
|
{
|
|
// Reset Carbon's test now after each test
|
|
Carbon::setTestNow();
|
|
}
|
|
|
|
public function testGetEligibleInsurancesWithMatchingCriteria(): void
|
|
{
|
|
$participant = $this->createParticipant('1990-06-15');
|
|
$booking = $this->createBooking('2024-08-01', '2024-08-08');
|
|
|
|
$insurance = $this->createInsurance([
|
|
'ageFrom' => 20,
|
|
'ageTo' => 50,
|
|
'travelDateFrom' => new \DateTimeImmutable('2024-01-01'),
|
|
'travelDateTo' => new \DateTimeImmutable('2024-12-31'),
|
|
'bookingDateFrom' => new \DateTimeImmutable('2024-01-01'),
|
|
'bookingDateTo' => new \DateTimeImmutable('2024-12-31'),
|
|
'travelPriceFrom' => 0.0,
|
|
'travelPriceTo' => 1000.0,
|
|
'travelDurationFrom' => 1,
|
|
'travelDurationTo' => 14,
|
|
]);
|
|
|
|
$result = $this->service->getEligibleInsurances([$insurance], $participant, $booking);
|
|
|
|
$this->assertCount(1, $result);
|
|
$this->assertContains($insurance, $result);
|
|
}
|
|
|
|
public function testGetEligibleInsurancesExcludesInsuranceWithAgeTooYoung(): void
|
|
{
|
|
$participant = $this->createParticipant('2010-06-15'); // 14 years old in 2024
|
|
$booking = $this->createBooking('2024-08-01', '2024-08-08');
|
|
|
|
$insurance = $this->createInsurance(['ageFrom' => 18, 'ageTo' => 65]);
|
|
|
|
$result = $this->service->getEligibleInsurances([$insurance], $participant, $booking);
|
|
|
|
$this->assertEmpty($result);
|
|
}
|
|
|
|
public function testGetEligibleInsurancesExcludesInsuranceWithAgeTooOld(): void
|
|
{
|
|
$participant = $this->createParticipant('1950-06-15'); // 74 years old in 2024
|
|
$booking = $this->createBooking('2024-08-01', '2024-08-08');
|
|
|
|
$insurance = $this->createInsurance(['ageFrom' => 18, 'ageTo' => 65]);
|
|
|
|
$result = $this->service->getEligibleInsurances([$insurance], $participant, $booking);
|
|
|
|
$this->assertEmpty($result);
|
|
}
|
|
|
|
public function testGetEligibleInsurancesExcludesInsuranceWithTravelDateTooEarly(): void
|
|
{
|
|
$participant = $this->createParticipant('1990-06-15');
|
|
$booking = $this->createBooking('2024-08-01', '2024-08-08');
|
|
|
|
$insurance = $this->createInsurance([
|
|
'travelDateFrom' => new \DateTimeImmutable('2024-09-01'),
|
|
'travelDateTo' => new \DateTimeImmutable('2024-12-31'),
|
|
]);
|
|
|
|
$result = $this->service->getEligibleInsurances([$insurance], $participant, $booking);
|
|
|
|
$this->assertEmpty($result);
|
|
}
|
|
|
|
public function testGetEligibleInsurancesExcludesInsuranceWithTravelDateTooLate(): void
|
|
{
|
|
$participant = $this->createParticipant('1990-06-15');
|
|
$booking = $this->createBooking('2024-08-01', '2024-08-08');
|
|
|
|
$insurance = $this->createInsurance([
|
|
'travelDateFrom' => new \DateTimeImmutable('2024-01-01'),
|
|
'travelDateTo' => new \DateTimeImmutable('2024-07-31'),
|
|
]);
|
|
|
|
$result = $this->service->getEligibleInsurances([$insurance], $participant, $booking);
|
|
|
|
$this->assertEmpty($result);
|
|
}
|
|
|
|
public function testGetEligibleInsurancesExcludesInsuranceWithBookingDateTooEarly(): void
|
|
{
|
|
$participant = $this->createParticipant('1990-06-15');
|
|
$booking = $this->createBooking('2024-08-01', '2024-08-08');
|
|
|
|
$insurance = $this->createInsurance([
|
|
'bookingDateFrom' => new \DateTimeImmutable('2025-01-01'),
|
|
'bookingDateTo' => new \DateTimeImmutable('2025-12-31'),
|
|
]);
|
|
|
|
$result = $this->service->getEligibleInsurances([$insurance], $participant, $booking);
|
|
|
|
$this->assertEmpty($result);
|
|
}
|
|
|
|
public function testGetEligibleInsurancesExcludesInsuranceWithBookingDateTooLate(): void
|
|
{
|
|
$participant = $this->createParticipant('1990-06-15');
|
|
$booking = $this->createBooking('2024-08-01', '2024-08-08');
|
|
|
|
$insurance = $this->createInsurance([
|
|
'bookingDateFrom' => new \DateTimeImmutable('2023-01-01'),
|
|
'bookingDateTo' => new \DateTimeImmutable('2023-12-31'),
|
|
]);
|
|
|
|
$result = $this->service->getEligibleInsurances([$insurance], $participant, $booking);
|
|
|
|
$this->assertEmpty($result);
|
|
}
|
|
|
|
public function testGetEligibleInsurancesExcludesInsuranceWithTravelDurationTooShort(): void
|
|
{
|
|
$participant = $this->createParticipant('1990-06-15');
|
|
$booking = $this->createBooking('2024-08-01', '2024-08-03'); // 2 days
|
|
|
|
$insurance = $this->createInsurance(['travelDurationFrom' => 7, 'travelDurationTo' => 30]);
|
|
|
|
$result = $this->service->getEligibleInsurances([$insurance], $participant, $booking);
|
|
|
|
$this->assertEmpty($result);
|
|
}
|
|
|
|
public function testGetEligibleInsurancesExcludesInsuranceWithTravelDurationTooLong(): void
|
|
{
|
|
$participant = $this->createParticipant('1990-06-15');
|
|
$booking = $this->createBooking('2024-08-01', '2024-08-31'); // 30 days
|
|
|
|
$insurance = $this->createInsurance(['travelDurationFrom' => 1, 'travelDurationTo' => 14]);
|
|
|
|
$result = $this->service->getEligibleInsurances([$insurance], $participant, $booking);
|
|
|
|
$this->assertEmpty($result);
|
|
}
|
|
|
|
public function testGetEligibleInsurancesHandlesParticipantWithoutBirthDate(): void
|
|
{
|
|
$participant = new ParticipantDto();
|
|
$participant->index = 0; // Set participant index for price calculations
|
|
$participant->dateOfBirth = null;
|
|
$booking = $this->createBooking('2024-08-01', '2024-08-08');
|
|
|
|
$insurance = $this->createInsurance(['ageFrom' => 18, 'ageTo' => 65]);
|
|
|
|
$result = $this->service->getEligibleInsurances([$insurance], $participant, $booking);
|
|
|
|
// Participants without birth date should now have insurances available
|
|
// (field visibility is controlled by field state conditions, not service logic)
|
|
$this->assertNotEmpty($result);
|
|
$this->assertCount(1, $result);
|
|
$this->assertSame($insurance, $result[0]);
|
|
}
|
|
|
|
public function testGetEligibleInsurancesWithNullConstraints(): void
|
|
{
|
|
$participant = $this->createParticipant('1990-06-15');
|
|
$booking = $this->createBooking('2024-08-01', '2024-08-08');
|
|
|
|
// Insurance with no constraints should match any criteria
|
|
$insurance = $this->createInsurance([]);
|
|
|
|
$result = $this->service->getEligibleInsurances([$insurance], $participant, $booking);
|
|
|
|
$this->assertCount(1, $result);
|
|
$this->assertContains($insurance, $result);
|
|
}
|
|
|
|
public function testGetEligibleInsurancesWithMultipleInsurances(): void
|
|
{
|
|
$participant = $this->createParticipant('1990-06-15');
|
|
$booking = $this->createBooking('2024-08-01', '2024-08-08');
|
|
|
|
$eligibleInsurance1 = $this->createInsurance(['ageFrom' => 20, 'ageTo' => 50]);
|
|
$eligibleInsurance2 = $this->createInsurance(['ageFrom' => 30, 'ageTo' => 40]);
|
|
$ineligibleInsurance = $this->createInsurance(['ageFrom' => 60, 'ageTo' => 80]);
|
|
|
|
$insurances = [$eligibleInsurance1, $eligibleInsurance2, $ineligibleInsurance];
|
|
$result = $this->service->getEligibleInsurances($insurances, $participant, $booking);
|
|
|
|
$this->assertCount(2, $result);
|
|
$this->assertContains($eligibleInsurance1, $result);
|
|
$this->assertContains($eligibleInsurance2, $result);
|
|
$this->assertNotContains($ineligibleInsurance, $result);
|
|
}
|
|
|
|
public function testGetEligibleInsurancesWithAgeExactlyAtBoundary(): void
|
|
{
|
|
$participant = $this->createParticipant('1990-08-01'); // Exactly 34 on travel start
|
|
$booking = $this->createBooking('2024-08-01', '2024-08-08');
|
|
|
|
$insurance = $this->createInsurance(['ageFrom' => 34, 'ageTo' => 34]);
|
|
|
|
$result = $this->service->getEligibleInsurances([$insurance], $participant, $booking);
|
|
|
|
$this->assertCount(1, $result);
|
|
$this->assertContains($insurance, $result);
|
|
}
|
|
|
|
public function testGetEligibleInsurancesWithTravelDurationExactlyAtBoundary(): void
|
|
{
|
|
$participant = $this->createParticipant('1990-06-15');
|
|
$booking = $this->createBooking('2024-08-01', '2024-08-08'); // Exactly 7 days
|
|
|
|
$insurance = $this->createInsurance(['travelDurationFrom' => 7, 'travelDurationTo' => 7]);
|
|
|
|
$result = $this->service->getEligibleInsurances([$insurance], $participant, $booking);
|
|
|
|
$this->assertCount(1, $result);
|
|
$this->assertContains($insurance, $result);
|
|
}
|
|
|
|
private function createParticipant(string $dateOfBirth): ParticipantDto
|
|
{
|
|
$participant = new ParticipantDto();
|
|
$participant->index = 0; // Set participant index for price calculations
|
|
$participant->dateOfBirth = new \DateTimeImmutable($dateOfBirth);
|
|
|
|
return $participant;
|
|
}
|
|
|
|
private function createBooking(string $travelDateFrom, string $travelDateTo): BookingDto
|
|
{
|
|
$travel = $this->createTravel($travelDateFrom, $travelDateTo);
|
|
$booking = new BookingDto($travel, 1);
|
|
|
|
return $booking;
|
|
}
|
|
|
|
private function createTravel(string $dateFrom, string $dateTo): \App\BusProNet\Model\Travel
|
|
{
|
|
$travel = new \App\BusProNet\Model\Travel();
|
|
$travel->dateFrom = new \DateTimeImmutable($dateFrom);
|
|
$travel->dateTo = new \DateTimeImmutable($dateTo);
|
|
|
|
return $travel;
|
|
}
|
|
|
|
private function createInsurance(array $constraints = []): Insurance
|
|
{
|
|
$insurance = new Insurance();
|
|
|
|
foreach ($constraints as $property => $value) {
|
|
$insurance->$property = $value;
|
|
}
|
|
|
|
return $insurance;
|
|
}
|
|
}
|