Files
myep/tests/Service/BookingPriceCalculatorServiceTest.php
T

319 lines
11 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
namespace App\Tests\Service;
use App\BusProNet\Model\Room;
use App\BusProNet\Model\Service;
use App\BusProNet\Model\Travel;
use App\Form\Model\BookingCreateDto;
use App\Form\Model\ParticipantDto;
use App\Form\Model\RoomSelectionDto;
use App\Service\BookingPriceCalculatorService;
use PHPUnit\Framework\TestCase;
class BookingPriceCalculatorServiceTest extends TestCase
{
private BookingPriceCalculatorService $service;
protected function setUp(): void
{
$this->service = new BookingPriceCalculatorService();
}
public function testCalculateRoomPricingWithParticipantBasedCalculation(): void
{
// Create test data: 2 double rooms at €100 each, minPax=2
$room = new Room();
$room->id = 1;
$room->price = 100.0;
$room->minPax = 2;
$room->label = 'Double Room';
$travel = new Travel();
$travel->rooms = [$room];
$roomSelection = new RoomSelectionDto();
$roomSelection->roomId = 1;
$roomSelection->quantity = 2; // 2 rooms selected
$bookingDto = new BookingCreateDto($travel, 1);
$bookingDto->roomSelections = [$roomSelection];
// Test the calculation
$result = $this->service->calculateRoomPricing($bookingDto);
// Expected: 2 rooms × 2 participants/room × €100 = €400 total
$this->assertCount(1, $result);
$this->assertEquals(1, $result[0]['roomId']);
$this->assertEquals('Double Room', $result[0]['label']);
$this->assertEquals(2, $result[0]['quantity']); // 2 rooms
$this->assertEquals(4, $result[0]['participantCount']); // 4 participants total
$this->assertEquals(100.0, $result[0]['unitPrice']); // €100 per participant
$this->assertEquals(400.0, $result[0]['totalPrice']); // €400 total
}
public function testCalculateRoomPricingWithSingleRoomSelection(): void
{
// Create test data: 1 triple room at €150, minPax=3
$room = new Room();
$room->id = 2;
$room->price = 150.0;
$room->minPax = 3;
$room->label = 'Triple Room';
$travel = new Travel();
$travel->rooms = [$room];
$roomSelection = new RoomSelectionDto();
$roomSelection->roomId = 2;
$roomSelection->quantity = 1; // 1 room selected
$bookingDto = new BookingCreateDto($travel, 1);
$bookingDto->roomSelections = [$roomSelection];
// Test the calculation
$result = $this->service->calculateRoomPricing($bookingDto);
// Expected: 1 room × 3 participants/room × €150 = €450 total
$this->assertCount(1, $result);
$this->assertEquals(2, $result[0]['roomId']);
$this->assertEquals('Triple Room', $result[0]['label']);
$this->assertEquals(1, $result[0]['quantity']); // 1 room
$this->assertEquals(3, $result[0]['participantCount']); // 3 participants total
$this->assertEquals(150.0, $result[0]['unitPrice']); // €150 per participant
$this->assertEquals(450.0, $result[0]['totalPrice']); // €450 total
}
public function testCalculateRoomPricingWithMultipleRoomTypes(): void
{
// Create test data: Multiple room types
$singleRoom = new Room();
$singleRoom->id = 1;
$singleRoom->price = 80.0;
$singleRoom->minPax = 1;
$singleRoom->label = 'Single Room';
$doubleRoom = new Room();
$doubleRoom->id = 2;
$doubleRoom->price = 120.0;
$doubleRoom->minPax = 2;
$doubleRoom->label = 'Double Room';
$travel = new Travel();
$travel->rooms = [$singleRoom, $doubleRoom];
$singleRoomSelection = new RoomSelectionDto();
$singleRoomSelection->roomId = 1;
$singleRoomSelection->quantity = 1; // 1 single room
$doubleRoomSelection = new RoomSelectionDto();
$doubleRoomSelection->roomId = 2;
$doubleRoomSelection->quantity = 2; // 2 double rooms
$bookingDto = new BookingCreateDto($travel, 1);
$bookingDto->roomSelections = [$singleRoomSelection, $doubleRoomSelection];
// Test the calculation
$result = $this->service->calculateRoomPricing($bookingDto);
// Expected:
// - Single: 1 room × 1 participant × €80 = €80
// - Double: 2 rooms × 2 participants × €120 = €480
$this->assertCount(2, $result);
// Single room result
$singleResult = $result[0];
$this->assertEquals(1, $singleResult['roomId']);
$this->assertEquals(1, $singleResult['quantity']);
$this->assertEquals(1, $singleResult['participantCount']);
$this->assertEquals(80.0, $singleResult['unitPrice']);
$this->assertEquals(80.0, $singleResult['totalPrice']);
// Double room result
$doubleResult = $result[1];
$this->assertEquals(2, $doubleResult['roomId']);
$this->assertEquals(2, $doubleResult['quantity']);
$this->assertEquals(4, $doubleResult['participantCount']);
$this->assertEquals(120.0, $doubleResult['unitPrice']);
$this->assertEquals(480.0, $doubleResult['totalPrice']);
}
public function testCalculateRoomPricingSkipsRoomsWithNullPrice(): void
{
$room = new Room();
$room->id = 1;
$room->price = null; // No price set
$room->minPax = 2;
$room->label = 'Free Room';
$travel = new Travel();
$travel->rooms = [$room];
$roomSelection = new RoomSelectionDto();
$roomSelection->roomId = 1;
$roomSelection->quantity = 1;
$bookingDto = new BookingCreateDto($travel, 1);
$bookingDto->roomSelections = [$roomSelection];
$result = $this->service->calculateRoomPricing($bookingDto);
// Should skip rooms with null price
$this->assertEmpty($result);
}
public function testCalculateRoomPricingWithZeroQuantityRooms(): void
{
$room = new Room();
$room->id = 1;
$room->price = 100.0;
$room->minPax = 2;
$room->label = 'Double Room';
$travel = new Travel();
$travel->rooms = [$room];
$roomSelection = new RoomSelectionDto();
$roomSelection->roomId = 1;
$roomSelection->quantity = 0; // Zero quantity - not selected
$bookingDto = new BookingCreateDto($travel, 1);
$bookingDto->roomSelections = [$roomSelection];
$result = $this->service->calculateRoomPricing($bookingDto);
// Should skip rooms with zero quantity
$this->assertEmpty($result);
}
public function testCalculateIndividualParticipantPriceWithRoomAndServices(): void
{
// Create test room
$room = new Room();
$room->id = 1;
$room->price = 100.0;
$room->minPax = 2;
$travel = new Travel();
$travel->rooms = [$room];
// Create test services
$skiPass = new Service();
$skiPass->price = 50.0;
$course = new Service();
$course->price = 30.0;
// Create participant with room assignment and services
$participant = new ParticipantDto();
$participant->assignedRoomId = 1;
$participant->skiPass = $skiPass;
$participant->courses = [$course];
$bookingDto = new BookingCreateDto($travel, 1);
$bookingDto->participants = [$participant];
$result = $this->service->calculateIndividualParticipantPrice($bookingDto, 0);
// Expected: €100 (room) + €50 (ski pass) + €30 (course) = €180
$this->assertEquals(180.0, $result);
}
public function testCalculateIndividualParticipantPriceWithoutRoomAssignment(): void
{
$travel = new Travel();
// Create test services
$skiPass = new Service();
$skiPass->price = 50.0;
// Create participant without room assignment
$participant = new ParticipantDto();
$participant->assignedRoomId = null; // No room assigned
$participant->skiPass = $skiPass;
$bookingDto = new BookingCreateDto($travel, 1);
$bookingDto->participants = [$participant];
$result = $this->service->calculateIndividualParticipantPrice($bookingDto, 0);
// Expected: €0 (no room) + €50 (ski pass) = €50
$this->assertEquals(50.0, $result);
}
public function testCalculateIndividualParticipantPriceForNonExistentParticipant(): void
{
$travel = new Travel();
$bookingDto = new BookingCreateDto($travel, 1);
$bookingDto->participants = [];
$result = $this->service->calculateIndividualParticipantPrice($bookingDto, 0);
// Expected: €0 for non-existent participant
$this->assertEquals(0.0, $result);
}
public function testCalculateAllParticipantIndividualPricesWithMultipleParticipants(): void
{
// Create test rooms
$singleRoom = new Room();
$singleRoom->id = 1;
$singleRoom->price = 80.0;
$singleRoom->minPax = 1;
$doubleRoom = new Room();
$doubleRoom->id = 2;
$doubleRoom->price = 120.0;
$doubleRoom->minPax = 2;
$travel = new Travel();
$travel->rooms = [$singleRoom, $doubleRoom];
// Create test services
$skiPass = new Service();
$skiPass->price = 50.0;
$course = new Service();
$course->price = 30.0;
// Create participants
$participant1 = new ParticipantDto();
$participant1->assignedRoomId = 1; // Single room
$participant1->skiPass = $skiPass;
$participant2 = new ParticipantDto();
$participant2->assignedRoomId = 2; // Double room
$participant2->courses = [$course];
$participant3 = new ParticipantDto();
$participant3->assignedRoomId = null; // No room assigned
$bookingDto = new BookingCreateDto($travel, 1);
$bookingDto->participants = [$participant1, $participant2, $participant3];
$result = $this->service->calculateAllParticipantIndividualPrices($bookingDto);
// Expected results:
// Participant 0: €80 (single room) + €50 (ski pass) = €130
// Participant 1: €120 (double room) + €30 (course) = €150
// Participant 2: €0 (no room) + €0 (no services) = €0
$this->assertCount(3, $result);
$this->assertEquals(130.0, $result[0]);
$this->assertEquals(150.0, $result[1]);
$this->assertEquals(0.0, $result[2]);
}
public function testCalculateAllParticipantIndividualPricesWithEmptyBooking(): void
{
$travel = new Travel();
$bookingDto = new BookingCreateDto($travel, 1);
$bookingDto->participants = [];
$result = $this->service->calculateAllParticipantIndividualPrices($bookingDto);
$this->assertEmpty($result);
}
}