dateFrom = new \DateTimeImmutable('2025-06-01'); $travel->dateTo = new \DateTimeImmutable('2025-06-08'); $bookingDto = new BookingDto($travel, 1); $this->assertInstanceOf(BookingDto::class, $bookingDto); $this->assertSame($travel, $bookingDto->travel); $this->assertSame(BookingDto::MODE_CREATE, $bookingDto->getMode()); } public function testUnserializeHandlesIntTravelId(): void { $travel = new Travel(); $travel->id = 42; $travel->dateFrom = new \DateTimeImmutable('2025-06-01'); $travel->dateTo = new \DateTimeImmutable('2025-06-08'); $dto = new BookingDto($travel, 1); $serialized = serialize($dto); $restored = unserialize($serialized); $this->assertInstanceOf(BookingDto::class, $restored); $this->assertSame(42, $restored->travel->id); } public function testUnserializeHandlesLegacyTravelObject(): void { $travel = new Travel(); $travel->id = 42; $travel->dateFrom = new \DateTimeImmutable('2025-06-01'); $travel->dateTo = new \DateTimeImmutable('2025-06-08'); // Simulate old session format where 'travel' is a full Travel object $data = [ 'travel' => $travel, 'hotelId' => 1, ]; $dto = new BookingDto(new Travel(), 1); $dto->__unserialize($data); $this->assertSame($travel, $dto->travel); $this->assertSame(42, $dto->travel->id); } public function testUnserializeNormalizesLegacyBodyDimensionsOnParticipants(): void { $travel = new Travel(); $travel->id = 42; $travel->dateFrom = new \DateTimeImmutable('2025-06-01'); $travel->dateTo = new \DateTimeImmutable('2025-06-08'); $participant = new ParticipantDto(); $participant->height = '149-157'; $participant->weight = '75'; $participant->shoeSize = '043'; $dto = new BookingDto($travel, 1); $dto->participants = [$participant]; $restored = unserialize(serialize($dto)); $this->assertInstanceOf(BookingDto::class, $restored); $this->assertNull($restored->participants[0]->height); $this->assertSame('75', $restored->participants[0]->weight); $this->assertSame('43', $restored->participants[0]->shoeSize); } public function testSyncRoomSelectionsWithAvailableRoomsClearsMissingOrOverbookedRooms(): void { $travel = new Travel(); $travel->dateFrom = new \DateTimeImmutable('2025-06-01'); $travel->dateTo = new \DateTimeImmutable('2025-06-08'); $availableRoom = new Room(); $availableRoom->id = 1; $availableRoom->label = 'Doppelzimmer'; $availableRoom->price = 100.0; $availableRoom->available = 2; $availableRoom->minPax = 2; $availableRoom->status = 'Frei'; $limitedRoom = new Room(); $limitedRoom->id = 2; $limitedRoom->label = 'Einzelzimmer'; $limitedRoom->price = 150.0; $limitedRoom->available = 1; $limitedRoom->minPax = 1; $limitedRoom->status = 'Frei'; $travel->rooms = [$availableRoom, $limitedRoom]; $dto = new BookingDto($travel, 1); $selection1 = new RoomSelectionDto(); $selection1->id = 1; $selection1->quantity = 2; $selection2 = new RoomSelectionDto(); $selection2->id = 2; $selection2->quantity = 2; $selection3 = new RoomSelectionDto(); $selection3->id = 3; $selection3->quantity = 1; $dto->roomSelections = [ 1 => $selection1, 2 => $selection2, 3 => $selection3, ]; $changed = $dto->syncRoomSelectionsWithAvailableRooms(); $this->assertTrue($changed); $this->assertCount(2, $dto->roomSelections); $this->assertArrayHasKey(1, $dto->roomSelections); $this->assertArrayHasKey(2, $dto->roomSelections); $this->assertArrayNotHasKey(3, $dto->roomSelections); $this->assertSame(1, $dto->roomSelections[1]->id); $this->assertSame(2, $dto->roomSelections[1]->quantity); $this->assertSame('Doppelzimmer', $dto->roomSelections[1]->label); $this->assertSame(100.0, $dto->roomSelections[1]->price); $this->assertSame(2, $dto->roomSelections[1]->maxQuantity); $this->assertSame(2, $dto->roomSelections[1]->capacity); $this->assertSame(2, $dto->roomSelections[2]->id); $this->assertSame(0, $dto->roomSelections[2]->quantity); } public function testSyncRoomSelectionsWithAvailableRoomsSynchronizesZeroQuantityRoomMetadata(): void { $travel = new Travel(); $travel->dateFrom = new \DateTimeImmutable('2025-06-01'); $travel->dateTo = new \DateTimeImmutable('2025-06-08'); $room = new Room(); $room->id = 1; $room->label = 'Aktualisiertes Zimmer'; $room->price = 125.0; $room->available = 1; $room->minPax = 2; $room->status = 'Anfrage'; $travel->rooms = [$room]; $dto = new BookingDto($travel, 1); $selection = new RoomSelectionDto(); $selection->id = 1; $selection->label = 'Veraltetes Zimmer'; $selection->price = 100.0; $selection->status = 'Frei'; $selection->maxQuantity = 5; $selection->capacity = 1; $selection->quantity = 0; $dto->roomSelections = [1 => $selection]; $changed = $dto->syncRoomSelectionsWithAvailableRooms(); $this->assertFalse($changed); $this->assertCount(1, $dto->roomSelections); $this->assertArrayHasKey(1, $dto->roomSelections); $this->assertSame('Aktualisiertes Zimmer', $dto->roomSelections[1]->label); $this->assertSame(125.0, $dto->roomSelections[1]->price); $this->assertSame('Anfrage', $dto->roomSelections[1]->status); $this->assertSame(1, $dto->roomSelections[1]->maxQuantity); $this->assertSame(2, $dto->roomSelections[1]->capacity); $this->assertSame(0, $dto->roomSelections[1]->quantity); } public function testSyncRoomSelectionsWithAvailableRoomsAddsNewAvailableRooms(): void { $travel = new Travel(); $travel->dateFrom = new \DateTimeImmutable('2025-06-01'); $travel->dateTo = new \DateTimeImmutable('2025-06-08'); $room = new Room(); $room->id = 5; $room->label = 'Familienzimmer'; $room->price = 250.0; $room->available = 3; $room->minPax = 4; $room->status = 'Frei'; $travel->rooms = [$room]; $dto = new BookingDto($travel, 1); $changed = $dto->syncRoomSelectionsWithAvailableRooms(); $this->assertFalse($changed); $this->assertArrayHasKey(5, $dto->roomSelections); $this->assertSame(5, $dto->roomSelections[5]->id); $this->assertSame('Familienzimmer', $dto->roomSelections[5]->label); $this->assertSame(250.0, $dto->roomSelections[5]->price); $this->assertSame('Frei', $dto->roomSelections[5]->status); $this->assertSame(0, $dto->roomSelections[5]->quantity); $this->assertSame(3, $dto->roomSelections[5]->maxQuantity); $this->assertSame(4, $dto->roomSelections[5]->capacity); } public function testCreateRoomSelectionSnapshotDetectsPriceOnlyChange(): void { $travel = new Travel(); $travel->dateFrom = new \DateTimeImmutable('2025-06-01'); $travel->dateTo = new \DateTimeImmutable('2025-06-08'); $dto = new BookingDto($travel, 1); $selection = new RoomSelectionDto(); $selection->id = 1; $selection->quantity = 2; $selection->price = 100.0; $dto->roomSelections = [$selection]; $before = $dto->createRoomSelectionSnapshot(); $selection->price = 120.0; $after = $dto->createRoomSelectionSnapshot(); $this->assertSame([[1, 2, 100.0]], $before); $this->assertSame([[1, 2, 120.0]], $after); $this->assertNotSame($before, $after); $this->assertTrue($dto->hasRoomSelectionChanged($before)); } public function testUnserializeNormalizesLegacyParticipantStringsOnLoad(): void { $travel = new Travel(); $travel->id = 42; $travel->dateFrom = new \DateTimeImmutable('2025-06-01'); $travel->dateTo = new \DateTimeImmutable('2025-06-08'); $participant = new ParticipantDto(); $participant->firstName = ' Max '; $participant->lastName = ' Mustermann '; $participant->email = ' max@example.com '; $participant->remarksRoom = ' '; $participant->licensePlate = ' B-AB 123 '; $participant->purchaseVoucherCode = ' ABC-123 '; $participant->promoVoucherCode = ' PROMO '; $participant->address = new Address(); $participant->address->street = ' Test Street 1 '; $participant->address->postCode = ' 12345 '; $participant->address->city = ' Test City '; $participant->address->country = ' DE '; $dto = new BookingDto($travel, 1); $dto->participants = [$participant]; $restored = unserialize(serialize($dto)); $this->assertInstanceOf(BookingDto::class, $restored); $this->assertSame('Max', $restored->participants[0]->firstName); $this->assertSame('Mustermann', $restored->participants[0]->lastName); $this->assertSame('max@example.com', $restored->participants[0]->email); $this->assertNull($restored->participants[0]->remarksRoom); $this->assertSame('B-AB 123', $restored->participants[0]->licensePlate); $this->assertSame('ABC-123', $restored->participants[0]->purchaseVoucherCode); $this->assertSame('PROMO', $restored->participants[0]->promoVoucherCode); $this->assertSame('Test Street 1', $restored->participants[0]->address->street); $this->assertSame('12345', $restored->participants[0]->address->postCode); $this->assertSame('Test City', $restored->participants[0]->address->city); $this->assertSame('DE', $restored->participants[0]->address->country); } }