feat: accommodation booking type and status as dedicated properties

This commit is contained in:
Björn Fromme
2026-08-06 08:52:09 +02:00
parent 2cfa87f44b
commit aa8fa5c1b2
22 changed files with 218 additions and 151 deletions
@@ -25,32 +25,32 @@ use Symfony\Component\HttpFoundation\Response;
*/
class EditControllerTest extends TestCase
{
public function testTransitionToInquiryIssuesAccessLinkAndSendsCustomerEmail(): void
public function testTransitionToOpenIssuesAccessLinkAndSendsCustomerEmail(): void
{
$bookingService = $this->assertNotified(AccommodationBookingStatus::Inquiry);
$bookingService = $this->assertNotified(AccommodationBookingStatus::Open);
$this->submitStatusChange(AccommodationBookingStatus::Draft, AccommodationBookingStatus::Inquiry, $bookingService);
$this->submitStatusChange(AccommodationBookingStatus::Draft, AccommodationBookingStatus::Open, $bookingService);
}
public function testTransitionToBookingIssuesAccessLinkAndSendsCustomerEmail(): void
public function testTransitionToAcceptedIssuesAccessLinkAndSendsCustomerEmail(): void
{
$bookingService = $this->assertNotified(AccommodationBookingStatus::Booking);
$bookingService = $this->assertNotified(AccommodationBookingStatus::Accepted);
$this->submitStatusChange(AccommodationBookingStatus::Draft, AccommodationBookingStatus::Booking, $bookingService);
$this->submitStatusChange(AccommodationBookingStatus::Draft, AccommodationBookingStatus::Accepted, $bookingService);
}
public function testTransitionToDiscardedSendsNothing(): void
{
$bookingService = $this->assertNotNotified();
$this->submitStatusChange(AccommodationBookingStatus::Inquiry, AccommodationBookingStatus::Discarded, $bookingService);
$this->submitStatusChange(AccommodationBookingStatus::Open, AccommodationBookingStatus::Discarded, $bookingService);
}
public function testSavingWithoutStatusChangeSendsNothing(): void
{
$bookingService = $this->assertNotNotified();
$this->submitStatusChange(AccommodationBookingStatus::Booking, AccommodationBookingStatus::Booking, $bookingService);
$this->submitStatusChange(AccommodationBookingStatus::Accepted, AccommodationBookingStatus::Accepted, $bookingService);
}
private function assertNotified(AccommodationBookingStatus $expected): AccommodationBookingService
@@ -8,6 +8,7 @@ use App\Controller\Api\AccommodationBookingController;
use App\Entity\Groups\Accommodation;
use App\Entity\Groups\AccommodationBooking;
use App\Enum\Groups\AccommodationBookingStatus;
use App\Enum\Groups\AccommodationBookingType;
use App\Repository\Groups\AccommodationBookingRepository;
use App\Service\AccommodationBookingBreakdownCalculator;
use App\Service\AccommodationBookingService;
@@ -55,7 +56,8 @@ class AccommodationBookingControllerTest extends TestCase
$booking->setAccommodationDiscount(10);
$booking->setBoardServiceDiscount(20);
$booking->setAdditionalServicesDiscount(30);
$booking->setStatus(AccommodationBookingStatus::Booking);
$booking->setStatus(AccommodationBookingStatus::Accepted);
$booking->setType(AccommodationBookingType::Booking);
$booking->setAcceptedAt(new \DateTimeImmutable('2026-07-15T10:00:00+00:00'));
$bookingRepository = $this->createMock(AccommodationBookingRepository::class);
@@ -85,7 +87,8 @@ class AccommodationBookingControllerTest extends TestCase
self::assertSame(Response::HTTP_OK, $response->getStatusCode());
self::assertSame([
'uuid' => $booking->getUuid(),
'status' => 'booking',
'status' => 'accepted',
'type' => 'booking',
'dateFrom' => '2026-07-20',
'dateTo' => '2026-07-25',
'nights' => 5,
@@ -135,7 +138,7 @@ class AccommodationBookingControllerTest extends TestCase
self::assertArrayNotHasKey('currency', $payload['accommodation']);
}
public function testSingleReturnsInquiryStatusWhenBookingIsInquiry(): void
public function testSingleReturnsOpenStatusAndInquiryTypeForAnOffer(): void
{
$booking = new AccommodationBooking();
$booking->setDateFrom(new \DateTimeImmutable('2026-08-01'));
@@ -144,7 +147,8 @@ class AccommodationBookingControllerTest extends TestCase
$booking->setFirstName('Tom');
$booking->setLastName('Beispiel');
$booking->setEmail('[email protected]');
$booking->setStatus(AccommodationBookingStatus::Inquiry);
$booking->setStatus(AccommodationBookingStatus::Open);
$booking->setType(AccommodationBookingType::Inquiry);
$bookingRepository = $this->createMock(AccommodationBookingRepository::class);
$bookingRepository
@@ -160,7 +164,8 @@ class AccommodationBookingControllerTest extends TestCase
$response = $controller->single($booking->getUuid());
$payload = json_decode((string) $response->getContent(), true, 512, JSON_THROW_ON_ERROR);
self::assertSame('inquiry', $payload['status']);
self::assertSame('open', $payload['status']);
self::assertSame('inquiry', $payload['type']);
self::assertNull($payload['priceBreakdown']);
self::assertNull($payload['acceptedAt']);
}
@@ -186,7 +191,7 @@ class AccommodationBookingControllerTest extends TestCase
self::assertSame(['message' => 'Not found'], $payload);
}
public function testAcceptTransitionsInquiryToBookingAndSetsAcceptedAt(): void
public function testAcceptAcceptsOpenOfferAndSetsAcceptedAt(): void
{
$booking = new AccommodationBooking();
$booking->setDateFrom(new \DateTimeImmutable('2026-08-01'));
@@ -195,7 +200,7 @@ class AccommodationBookingControllerTest extends TestCase
$booking->setFirstName('Tom');
$booking->setLastName('Beispiel');
$booking->setEmail('[email protected]');
$booking->setStatus(AccommodationBookingStatus::Inquiry);
$booking->setStatus(AccommodationBookingStatus::Open);
$bookingRepository = $this->createMock(AccommodationBookingRepository::class);
$bookingRepository
@@ -213,7 +218,7 @@ class AccommodationBookingControllerTest extends TestCase
->method('acceptBooking')
->with($booking)
->willReturnCallback(static function (AccommodationBooking $b): void {
$b->setStatus(AccommodationBookingStatus::Booking);
$b->setStatus(AccommodationBookingStatus::Accepted);
$b->setAcceptedAt(new \DateTimeImmutable());
});
@@ -223,8 +228,9 @@ class AccommodationBookingControllerTest extends TestCase
$payload = json_decode((string) $response->getContent(), true, 512, JSON_THROW_ON_ERROR);
self::assertSame(Response::HTTP_OK, $response->getStatusCode());
self::assertSame('booking', $payload['status']);
self::assertSame(AccommodationBookingStatus::Booking, $booking->getStatus());
self::assertSame('accepted', $payload['status']);
self::assertSame('inquiry', $payload['type']);
self::assertSame(AccommodationBookingStatus::Accepted, $booking->getStatus());
self::assertNotNull($booking->getAcceptedAt());
self::assertSame($booking->getAcceptedAt()->format(\DATE_ATOM), $payload['acceptedAt']);
}
@@ -240,7 +246,7 @@ class AccommodationBookingControllerTest extends TestCase
$booking->setFirstName('Tom');
$booking->setLastName('Beispiel');
$booking->setEmail('[email protected]');
$booking->setStatus(AccommodationBookingStatus::Booking);
$booking->setStatus(AccommodationBookingStatus::Accepted);
$booking->setAcceptedAt($acceptedAt);
$bookingRepository = $this->createMock(AccommodationBookingRepository::class);
@@ -261,7 +267,7 @@ class AccommodationBookingControllerTest extends TestCase
$payload = json_decode((string) $response->getContent(), true, 512, JSON_THROW_ON_ERROR);
self::assertSame(Response::HTTP_OK, $response->getStatusCode());
self::assertSame('booking', $payload['status']);
self::assertSame('accepted', $payload['status']);
self::assertSame($acceptedAt, $booking->getAcceptedAt());
self::assertSame($acceptedAt->format(\DATE_ATOM), $payload['acceptedAt']);
}
@@ -26,7 +26,7 @@ class OfferControllerTest extends TestCase
public function testAccessAuthorizesSessionAndRedirectsToView(): void
{
$booking = new AccommodationBooking();
$booking->setStatus(AccommodationBookingStatus::Inquiry);
$booking->setStatus(AccommodationBookingStatus::Open);
$bookingRepository = $this->createMock(AccommodationBookingRepository::class);
$bookingRepository->method('findOneBy')->with(['uuid' => $booking->getUuid()])->willReturn($booking);
@@ -151,7 +151,7 @@ class OfferControllerTest extends TestCase
public function testViewRendersOfferWhenSessionAuthorized(): void
{
$booking = new AccommodationBooking();
$booking->setStatus(AccommodationBookingStatus::Inquiry);
$booking->setStatus(AccommodationBookingStatus::Open);
$booking->setAccommodation(new Accommodation());
$bookingRepository = $this->createMock(AccommodationBookingRepository::class);
@@ -207,7 +207,7 @@ class OfferControllerTest extends TestCase
public function testConfirmGetRendersModalWithFreshForm(): void
{
$booking = new AccommodationBooking();
$booking->setStatus(AccommodationBookingStatus::Inquiry);
$booking->setStatus(AccommodationBookingStatus::Open);
$bookingRepository = $this->createMock(AccommodationBookingRepository::class);
$bookingRepository->method('findOneBy')->with(['uuid' => $booking->getUuid()])->willReturn($booking);
@@ -238,7 +238,7 @@ class OfferControllerTest extends TestCase
public function testConfirmPostValidAcceptsBookingAndRedirects(): void
{
$booking = new AccommodationBooking();
$booking->setStatus(AccommodationBookingStatus::Inquiry);
$booking->setStatus(AccommodationBookingStatus::Open);
$bookingRepository = $this->createMock(AccommodationBookingRepository::class);
$bookingRepository->method('findOneBy')->willReturn($booking);
@@ -273,7 +273,7 @@ class OfferControllerTest extends TestCase
public function testConfirmPostValidViaHtmxReturnsHxRedirect(): void
{
$booking = new AccommodationBooking();
$booking->setStatus(AccommodationBookingStatus::Inquiry);
$booking->setStatus(AccommodationBookingStatus::Open);
$bookingRepository = $this->createMock(AccommodationBookingRepository::class);
$bookingRepository->method('findOneBy')->willReturn($booking);
@@ -308,7 +308,7 @@ class OfferControllerTest extends TestCase
public function testConfirmPostInvalidReRendersModalWithoutAccepting(): void
{
$booking = new AccommodationBooking();
$booking->setStatus(AccommodationBookingStatus::Inquiry);
$booking->setStatus(AccommodationBookingStatus::Open);
$bookingRepository = $this->createMock(AccommodationBookingRepository::class);
$bookingRepository->method('findOneBy')->willReturn($booking);
@@ -342,7 +342,7 @@ class OfferControllerTest extends TestCase
public function testConfirmRedirectsWhenAlreadyAccepted(): void
{
$booking = new AccommodationBooking();
$booking->setStatus(AccommodationBookingStatus::Booking);
$booking->setStatus(AccommodationBookingStatus::Accepted);
$bookingRepository = $this->createMock(AccommodationBookingRepository::class);
$bookingRepository->method('findOneBy')->willReturn($booking);
@@ -462,7 +462,7 @@ final class TestableOfferController extends OfferController
$this->renderedParameters = $parameters;
if ('groups/booking/offer.html.twig' === $view) {
$content = $parameters['booking']->isInquiry() ? '<html>offer</html>' : '<html>confirmed</html>';
$content = $parameters['booking']->isAccepted() ? '<html>confirmed</html>' : '<html>offer</html>';
} else {
$content = '<html>unavailable</html>';
}
@@ -7,7 +7,7 @@ namespace App\Tests\Controller\Groups;
use App\Controller\Groups\Step4Controller;
use App\Entity\Groups\Accommodation;
use App\Entity\Groups\AccommodationBooking;
use App\Enum\Groups\AccommodationBookingStatus;
use App\Enum\Groups\AccommodationBookingType;
use App\Form\Model\AccommodationBookingDto;
use App\Service\AccommodationBookingService;
use App\Service\AccommodationSessionManager;
@@ -102,7 +102,7 @@ class Step4ControllerTest extends TestCase
->setCalendarCode('HOTEL')
->setMaxAdolescentAge(17);
$booking = (new AccommodationBooking())->setStatus(AccommodationBookingStatus::Inquiry);
$booking = (new AccommodationBooking())->setType(AccommodationBookingType::Inquiry);
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService->method('loadAccommodation')->with(1)->willReturn($accommodation);
@@ -275,7 +275,7 @@ class Step4ControllerTest extends TestCase
->setCalendarCode('HOTEL')
->setMaxAdolescentAge(17);
$booking = (new AccommodationBooking())->setStatus(AccommodationBookingStatus::Booking);
$booking = (new AccommodationBooking())->setType(AccommodationBookingType::Booking);
$bookingService = $this->createMock(AccommodationBookingService::class);
$bookingService->method('loadAccommodation')->with(1)->willReturn($accommodation);