feat: automatically assign rooms only for unique room type selection
This commit is contained in:
@@ -0,0 +1,214 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Tests\Service;
|
||||
|
||||
use App\BusProNet\Constants;
|
||||
use App\BusProNet\Model\Room;
|
||||
use App\BusProNet\Model\Travel;
|
||||
use App\Form\Model\BookingDto;
|
||||
use App\Form\Model\ParticipantDto;
|
||||
use App\Form\Model\RoomSelectionDto;
|
||||
use App\Service\RoomAssignmentService;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* Tests for RoomAssignmentService.
|
||||
*/
|
||||
class RoomAssignmentServiceTest extends TestCase
|
||||
{
|
||||
private RoomAssignmentService $service;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->service = new RoomAssignmentService();
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldAutoAssignRoomsReturnsTrueForSingleRoomType(): void
|
||||
{
|
||||
$bookingDto = $this->createBookingDtoWithRoomSelections([
|
||||
['roomId' => 1, 'quantity' => 3],
|
||||
]);
|
||||
|
||||
$result = $this->service->shouldAutoAssignRooms($bookingDto);
|
||||
|
||||
self::assertTrue($result, 'Should auto-assign when exactly one room type is selected');
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldAutoAssignRoomsReturnsFalseForMultipleRoomTypes(): void
|
||||
{
|
||||
$bookingDto = $this->createBookingDtoWithRoomSelections([
|
||||
['roomId' => 1, 'quantity' => 2],
|
||||
['roomId' => 2, 'quantity' => 1],
|
||||
]);
|
||||
|
||||
$result = $this->service->shouldAutoAssignRooms($bookingDto);
|
||||
|
||||
self::assertFalse($result, 'Should not auto-assign when multiple room types are selected');
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldAutoAssignRoomsReturnsFalseForNoRoomSelections(): void
|
||||
{
|
||||
$bookingDto = $this->createBookingDtoWithRoomSelections([]);
|
||||
|
||||
$result = $this->service->shouldAutoAssignRooms($bookingDto);
|
||||
|
||||
self::assertFalse($result, 'Should not auto-assign when no rooms are selected');
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldAutoAssignRoomsIgnoresZeroQuantityRooms(): void
|
||||
{
|
||||
$bookingDto = $this->createBookingDtoWithRoomSelections([
|
||||
['roomId' => 1, 'quantity' => 2],
|
||||
['roomId' => 2, 'quantity' => 0],
|
||||
['roomId' => 3, 'quantity' => null],
|
||||
]);
|
||||
|
||||
$result = $this->service->shouldAutoAssignRooms($bookingDto);
|
||||
|
||||
self::assertTrue($result, 'Should treat zero/null quantity as not selected');
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function assignParticipantsToRoomsWorksWithSingleRoomType(): void
|
||||
{
|
||||
$bookingDto = $this->createBookingDtoWithRoomSelections([
|
||||
['roomId' => 100, 'quantity' => 2, 'capacity' => 2],
|
||||
]);
|
||||
|
||||
// Create 4 participants (2 rooms × 2 capacity)
|
||||
$bookingDto->participants = [
|
||||
new ParticipantDto(),
|
||||
new ParticipantDto(),
|
||||
new ParticipantDto(),
|
||||
new ParticipantDto(),
|
||||
];
|
||||
|
||||
// Mock available room
|
||||
$room = new Room();
|
||||
$room->id = 100;
|
||||
$room->minPax = 2;
|
||||
$room->available = 10;
|
||||
$room->status = Constants::STATUS_AVAILABLE;
|
||||
|
||||
$bookingDto->travel->rooms = [$room];
|
||||
|
||||
$this->service->assignParticipantsToRooms($bookingDto);
|
||||
|
||||
// Verify all participants got assigned
|
||||
self::assertSame(100, $bookingDto->participants[0]->assignedRoomId);
|
||||
self::assertSame(100, $bookingDto->participants[1]->assignedRoomId);
|
||||
self::assertSame(100, $bookingDto->participants[2]->assignedRoomId);
|
||||
self::assertSame(100, $bookingDto->participants[3]->assignedRoomId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function assignParticipantsToRoomsSkipsAssignmentWithMultipleRoomTypes(): void
|
||||
{
|
||||
$bookingDto = $this->createBookingDtoWithRoomSelections([
|
||||
['roomId' => 100, 'quantity' => 1, 'capacity' => 2],
|
||||
['roomId' => 200, 'quantity' => 1, 'capacity' => 2],
|
||||
]);
|
||||
|
||||
// Create 4 participants (2 rooms × 2 capacity)
|
||||
$bookingDto->participants = [
|
||||
new ParticipantDto(),
|
||||
new ParticipantDto(),
|
||||
new ParticipantDto(),
|
||||
new ParticipantDto(),
|
||||
];
|
||||
|
||||
// Mock available rooms
|
||||
$room1 = new Room();
|
||||
$room1->id = 100;
|
||||
$room1->minPax = 2;
|
||||
$room1->available = 10;
|
||||
$room1->status = Constants::STATUS_AVAILABLE;
|
||||
|
||||
$room2 = new Room();
|
||||
$room2->id = 200;
|
||||
$room2->minPax = 2;
|
||||
$room2->available = 10;
|
||||
$room2->status = Constants::STATUS_AVAILABLE;
|
||||
|
||||
$bookingDto->travel->rooms = [$room1, $room2];
|
||||
|
||||
$this->service->assignParticipantsToRooms($bookingDto);
|
||||
|
||||
// Verify NO participants got assigned (conditional logic skipped assignment)
|
||||
self::assertNull($bookingDto->participants[0]->assignedRoomId);
|
||||
self::assertNull($bookingDto->participants[1]->assignedRoomId);
|
||||
self::assertNull($bookingDto->participants[2]->assignedRoomId);
|
||||
self::assertNull($bookingDto->participants[3]->assignedRoomId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function assignParticipantsToRoomsHandlesMixedRoomCapacities(): void
|
||||
{
|
||||
$bookingDto = $this->createBookingDtoWithRoomSelections([
|
||||
['roomId' => 100, 'quantity' => 1, 'capacity' => 2],
|
||||
]);
|
||||
|
||||
// Create participants
|
||||
$bookingDto->participants = [
|
||||
new ParticipantDto(),
|
||||
new ParticipantDto(),
|
||||
];
|
||||
|
||||
// Mock available room with capacity 2
|
||||
$room = new Room();
|
||||
$room->id = 100;
|
||||
$room->minPax = 2;
|
||||
$room->available = 10;
|
||||
$room->status = Constants::STATUS_AVAILABLE;
|
||||
|
||||
$bookingDto->travel->rooms = [$room];
|
||||
|
||||
$this->service->assignParticipantsToRooms($bookingDto);
|
||||
|
||||
// Both participants assigned to same room
|
||||
self::assertSame(100, $bookingDto->participants[0]->assignedRoomId);
|
||||
self::assertSame(100, $bookingDto->participants[1]->assignedRoomId);
|
||||
}
|
||||
|
||||
private function createBookingDtoWithRoomSelections(array $selections): BookingDto
|
||||
{
|
||||
$travel = new Travel();
|
||||
$travel->rooms = [];
|
||||
|
||||
$bookingDto = new BookingDto($travel, 1);
|
||||
$bookingDto->roomSelections = [];
|
||||
|
||||
foreach ($selections as $selection) {
|
||||
$roomSelectionDto = new RoomSelectionDto();
|
||||
$roomSelectionDto->roomId = $selection['roomId'];
|
||||
$roomSelectionDto->quantity = $selection['quantity'];
|
||||
if (isset($selection['capacity'])) {
|
||||
$roomSelectionDto->capacity = $selection['capacity'];
|
||||
}
|
||||
|
||||
$bookingDto->roomSelections[] = $roomSelectionDto;
|
||||
}
|
||||
|
||||
return $bookingDto;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user