feat: additional status

This commit is contained in:
Björn Fromme
2026-08-04 18:09:40 +02:00
parent dc86e715cb
commit 2c381ee741
20 changed files with 588 additions and 64 deletions
@@ -8,6 +8,7 @@ use App\Email\Mailer;
use App\Entity\Groups\Accommodation;
use App\Entity\Groups\AccommodationBooking;
use App\Entity\Groups\AccommodationPrice;
use App\Enum\Groups\AccommodationBookingStatus;
use App\Model\AccommodationBookingQueryParams;
use App\Repository\Groups\AccommodationPriceRepository;
use App\Repository\Groups\AccommodationRepository;
@@ -65,7 +66,7 @@ class AccommodationBookingServiceTest extends TestCase
$service = $this->createServiceWithAccommodation(entityManager: $entityManager);
$booking = new AccommodationBooking();
$booking->setIsInquiry(false);
$booking->setStatus(AccommodationBookingStatus::Booking);
$service->issueAccessLinkForDirectBooking($booking);
@@ -80,7 +81,7 @@ class AccommodationBookingServiceTest extends TestCase
$service = $this->createServiceWithAccommodation(entityManager: $entityManager);
$booking = new AccommodationBooking();
$booking->setIsInquiry(true);
$booking->setStatus(AccommodationBookingStatus::Inquiry);
$service->issueAccessLinkForDirectBooking($booking);
@@ -95,7 +96,7 @@ class AccommodationBookingServiceTest extends TestCase
$service = $this->createServiceWithAccommodation(entityManager: $entityManager);
$booking = new AccommodationBooking();
$booking->setIsInquiry(false);
$booking->setStatus(AccommodationBookingStatus::Booking);
$issuedAt = new \DateTimeImmutable('2026-01-01');
$booking->setAccessLinkIssuedAt($issuedAt);
@@ -104,11 +105,70 @@ class AccommodationBookingServiceTest extends TestCase
self::assertSame($issuedAt, $booking->getAccessLinkIssuedAt());
}
public function testIssueAccessLinkSetsTimestampRegardlessOfStatus(): void
{
$entityManager = $this->createMock(EntityManagerInterface::class);
$entityManager->expects(self::once())->method('flush');
$service = $this->createServiceWithAccommodation(entityManager: $entityManager);
$booking = new AccommodationBooking();
$booking->setStatus(AccommodationBookingStatus::Inquiry);
$service->issueAccessLink($booking);
self::assertNotNull($booking->getAccessLinkIssuedAt());
}
public function testIssueAccessLinkNoOpsWhenAlreadySet(): void
{
$entityManager = $this->createMock(EntityManagerInterface::class);
$entityManager->expects(self::never())->method('flush');
$service = $this->createServiceWithAccommodation(entityManager: $entityManager);
$booking = new AccommodationBooking();
$booking->setStatus(AccommodationBookingStatus::Inquiry);
$issuedAt = new \DateTimeImmutable('2026-01-01');
$booking->setAccessLinkIssuedAt($issuedAt);
$service->issueAccessLink($booking);
self::assertSame($issuedAt, $booking->getAccessLinkIssuedAt());
}
public function testSendCustomerConfirmationEmailUsesOfferSubjectForInquiryWithLink(): void
{
$booking = new AccommodationBooking();
$booking->setEmail('[email protected]');
$booking->setStatus(AccommodationBookingStatus::Inquiry);
$booking->setAccessLinkIssuedAt(new \DateTimeImmutable());
$linkSigner = $this->createMock(AccommodationBookingLinkSigner::class);
$linkSigner->method('sign')->willReturn('https://example.com/offer/signed-link');
$breakdownCalculator = $this->createMock(AccommodationBookingBreakdownCalculator::class);
$breakdownCalculator->method('compute')->willReturn(null);
$mailer = $this->createMock(Mailer::class);
$mailer
->expects(self::once())
->method('createAndSendEmail')
->with(
self::anything(),
self::callback(static fn (array $options) => 'Dein Angebot ist bereit' === $options['subject']),
);
$service = $this->createServiceWithAccommodation(mailer: $mailer, linkSigner: $linkSigner, breakdownCalculator: $breakdownCalculator);
$service->sendCustomerConfirmationEmail($booking);
}
public function testSendCustomerConfirmationEmailAlwaysSendsWithLinkWhenIssued(): void
{
$booking = new AccommodationBooking();
$booking->setEmail('[email protected]');
$booking->setIsInquiry(false);
$booking->setStatus(AccommodationBookingStatus::Booking);
$booking->setAccessLinkIssuedAt(new \DateTimeImmutable());
$linkSigner = $this->createMock(AccommodationBookingLinkSigner::class);
@@ -137,7 +197,7 @@ class AccommodationBookingServiceTest extends TestCase
{
$booking = new AccommodationBooking();
$booking->setEmail('[email protected]');
$booking->setIsInquiry(true);
$booking->setStatus(AccommodationBookingStatus::Inquiry);
$breakdownCalculator = $this->createMock(AccommodationBookingBreakdownCalculator::class);
$breakdownCalculator->method('compute')->willReturn(null);
@@ -160,7 +220,7 @@ class AccommodationBookingServiceTest extends TestCase
{
$booking = new AccommodationBooking();
$booking->setEmail('[email protected]');
$booking->setIsInquiry(true);
$booking->setStatus(AccommodationBookingStatus::Inquiry);
$breakdownCalculator = $this->createMock(AccommodationBookingBreakdownCalculator::class);
$breakdownCalculator->method('compute')->willReturn(null);
@@ -180,7 +240,7 @@ class AccommodationBookingServiceTest extends TestCase
{
$booking = new AccommodationBooking();
$booking->setEmail('[email protected]');
$booking->setIsInquiry(true);
$booking->setStatus(AccommodationBookingStatus::Inquiry);
$previousIssuedAt = new \DateTimeImmutable('2026-01-01');
$booking->setAccessLinkIssuedAt($previousIssuedAt);
@@ -210,7 +270,7 @@ class AccommodationBookingServiceTest extends TestCase
$entityManager->expects(self::once())->method('flush');
$booking = new AccommodationBooking();
$booking->setIsInquiry(true);
$booking->setStatus(AccommodationBookingStatus::Inquiry);
$booking->setEmail('[email protected]');
$mailer = $this->createMock(Mailer::class);
@@ -228,7 +288,7 @@ class AccommodationBookingServiceTest extends TestCase
$service->acceptBooking($booking);
self::assertFalse($booking->isInquiry());
self::assertSame(AccommodationBookingStatus::Booking, $booking->getStatus());
self::assertNotNull($booking->getAcceptedAt());
}
@@ -243,7 +303,7 @@ class AccommodationBookingServiceTest extends TestCase
$service = $this->createServiceWithAccommodation(entityManager: $entityManager, mailer: $mailer);
$booking = new AccommodationBooking();
$booking->setIsInquiry(false);
$booking->setStatus(AccommodationBookingStatus::Booking);
$service->acceptBooking($booking);
@@ -253,7 +313,7 @@ class AccommodationBookingServiceTest extends TestCase
public function testSendOfferAcceptedNotificationEmailLogsAndSwallowsMailerFailures(): void
{
$booking = new AccommodationBooking();
$booking->setIsInquiry(false);
$booking->setStatus(AccommodationBookingStatus::Booking);
$mailer = $this->createMock(Mailer::class);
$mailer->method('createAndSendEmail')->willThrowException(new \RuntimeException('SMTP down'));
@@ -270,7 +330,7 @@ class AccommodationBookingServiceTest extends TestCase
{
$booking = new AccommodationBooking();
$booking->setEmail('[email protected]');
$booking->setIsInquiry(false);
$booking->setStatus(AccommodationBookingStatus::Booking);
$mailer = $this->createMock(Mailer::class);
$mailer->method('createAndSendEmail')->willThrowException(new \RuntimeException('SMTP down'));