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); } }