feat: replace *Service suffix with role-based class names

This commit is contained in:
Björn Fromme
2026-04-16 13:34:54 +02:00
parent 0d2cc5b998
commit d1c92f2957
88 changed files with 435 additions and 435 deletions
+317
View File
@@ -0,0 +1,317 @@
<?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\RoomAssigner;
use PHPUnit\Framework\TestCase;
/**
* Tests for RoomAssigner.
*/
class RoomAssignerTest extends TestCase
{
private RoomAssigner $service;
protected function setUp(): void
{
$this->service = new RoomAssigner();
}
/**
* @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);
}
/**
* @test
*/
public function validateAndResetInvalidAssignmentsResetsOrphanedAssignments(): void
{
// Create DTO with only room 100 selected
$bookingDto = $this->createBookingDtoWithRoomSelections([
['roomId' => 100, 'quantity' => 2, 'capacity' => 2],
]);
// Create participants with assignments to room 100 and room 200 (no longer selected)
$bookingDto->participants = [
new ParticipantDto(),
new ParticipantDto(),
new ParticipantDto(),
new ParticipantDto(),
];
$bookingDto->participants[0]->assignedRoomId = 100;
$bookingDto->participants[1]->assignedRoomId = 100;
$bookingDto->participants[2]->assignedRoomId = 200; // Invalid - room not selected
$bookingDto->participants[3]->assignedRoomId = 200; // Invalid - room not selected
$result = $this->service->validateAndResetInvalidAssignments($bookingDto);
self::assertTrue($result, 'Should return true when assignments were reset');
self::assertSame(100, $bookingDto->participants[0]->assignedRoomId);
self::assertSame(100, $bookingDto->participants[1]->assignedRoomId);
self::assertNull($bookingDto->participants[2]->assignedRoomId, 'Invalid assignment should be reset to null');
self::assertNull($bookingDto->participants[3]->assignedRoomId, 'Invalid assignment should be reset to null');
}
/**
* @test
*/
public function validateAndResetInvalidAssignmentsReturnsFalseWhenAllValid(): void
{
$bookingDto = $this->createBookingDtoWithRoomSelections([
['roomId' => 100, 'quantity' => 2, 'capacity' => 2],
]);
// All participants assigned to the valid room
$bookingDto->participants = [
new ParticipantDto(),
new ParticipantDto(),
];
$bookingDto->participants[0]->assignedRoomId = 100;
$bookingDto->participants[1]->assignedRoomId = 100;
$result = $this->service->validateAndResetInvalidAssignments($bookingDto);
self::assertFalse($result, 'Should return false when no assignments needed reset');
self::assertSame(100, $bookingDto->participants[0]->assignedRoomId);
self::assertSame(100, $bookingDto->participants[1]->assignedRoomId);
}
/**
* @test
*/
public function validateAndResetInvalidAssignmentsHandlesNullAssignments(): void
{
$bookingDto = $this->createBookingDtoWithRoomSelections([
['roomId' => 100, 'quantity' => 1, 'capacity' => 2],
]);
// Participants with null assignments should not trigger a reset
$bookingDto->participants = [
new ParticipantDto(),
new ParticipantDto(),
];
$bookingDto->participants[0]->assignedRoomId = null;
$bookingDto->participants[1]->assignedRoomId = null;
$result = $this->service->validateAndResetInvalidAssignments($bookingDto);
self::assertFalse($result, 'Should return false when only null assignments exist');
}
/**
* @test
*/
public function validateAndResetInvalidAssignmentsHandlesEmptySelectedRooms(): void
{
// All rooms have quantity 0 (none selected)
$bookingDto = $this->createBookingDtoWithRoomSelections([
['roomId' => 100, 'quantity' => 0, 'capacity' => 2],
['roomId' => 200, 'quantity' => 0, 'capacity' => 2],
]);
// Participants still have old assignments
$bookingDto->participants = [
new ParticipantDto(),
new ParticipantDto(),
];
$bookingDto->participants[0]->assignedRoomId = 100;
$bookingDto->participants[1]->assignedRoomId = 200;
$result = $this->service->validateAndResetInvalidAssignments($bookingDto);
self::assertTrue($result, 'Should return true when all assignments become invalid');
self::assertNull($bookingDto->participants[0]->assignedRoomId);
self::assertNull($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->id = $selection['roomId'];
$roomSelectionDto->quantity = $selection['quantity'];
if (isset($selection['capacity'])) {
$roomSelectionDto->capacity = $selection['capacity'];
}
$bookingDto->roomSelections[] = $roomSelectionDto;
}
return $bookingDto;
}
}