diff --git a/src/Model/Serializer/ValueObject/Calendar/CalendarSerializer.php b/src/Model/Serializer/ValueObject/Calendar/CalendarSerializer.php index 868fd47da..f7e542592 100644 --- a/src/Model/Serializer/ValueObject/Calendar/CalendarSerializer.php +++ b/src/Model/Serializer/ValueObject/Calendar/CalendarSerializer.php @@ -87,6 +87,15 @@ function ($openingHourData) { ); } + // There are cases where the calendar type does not match the number of sub events. + // For those cases the amount of sub events dictates the calendar type. + if ($calendarType->sameAs(CalendarType::single()) && count($subEvents) > 1) { + $calendarType = CalendarType::multiple(); + } + if ($calendarType->sameAs(CalendarType::multiple()) && count($subEvents) === 1) { + $calendarType = CalendarType::single(); + } + switch ($calendarType) { case CalendarType::single(): $calendar = new SingleSubEventCalendar($subEvents[0]); diff --git a/tests/Model/Serializer/ValueObject/Calendar/CalendarSerializerTest.php b/tests/Model/Serializer/ValueObject/Calendar/CalendarSerializerTest.php new file mode 100644 index 000000000..8de25e5a9 --- /dev/null +++ b/tests/Model/Serializer/ValueObject/Calendar/CalendarSerializerTest.php @@ -0,0 +1,237 @@ +assertEquals( + [ + 'type' => 'single', + 'status' => [ + 'type' => 'Available', + ], + 'bookingAvailability' => [ + 'type' => 'Available', + ], + 'timestamps' => [ + 0 => [ + 'startDate' => '2021-01-01T00:00:00+01:00', + 'endDate' => '2021-01-02T00:00:00+01:00', + 'status' => [ + 'type' => 'Available', + ], + 'bookingAvailability' => [ + 'type' => 'Available', + ], + ], + ], + 'startDate' => '2021-01-01T00:00:00+01:00', + 'endDate' => '2021-01-02T00:00:00+01:00', + ], + $serializer->serialize() + ); + } + + /** + * @test + */ + public function it_can_deserialize_a_calendar(): void + { + $data = [ + 'type' => 'multiple', + 'status' => [ + 'type' => 'Available', + ], + 'bookingAvailability' => [ + 'type' => 'Available', + ], + 'timestamps' => [ + 0 => [ + 'startDate' => '2021-01-01T00:00:00+01:00', + 'endDate' => '2021-01-02T00:00:00+01:00', + 'status' => [ + 'type' => 'Available', + ], + 'bookingAvailability' => [ + 'type' => 'Available', + ], + ], + 1 => [ + 'startDate' => '2021-01-04T00:00:00+01:00', + 'endDate' => '2021-01-05T00:00:00+01:00', + 'status' => [ + 'type' => 'Available', + ], + 'bookingAvailability' => [ + 'type' => 'Available', + ], + ], + ], + 'startDate' => '2021-01-01T00:00:00+01:00', + 'endDate' => '2021-01-05T00:00:00+01:00', + ]; + + $this->assertEquals( + new MultipleSubEventsCalendar( + new SubEvents( + new SubEvent( + new DateRange( + new DateTimeImmutable('2021-01-01T00:00:00+01:00'), + new DateTimeImmutable('2021-01-02T00:00:00+01:00') + ), + new Status(StatusType::Available()), + BookingAvailability::Available() + ), + new SubEvent( + new DateRange( + new DateTimeImmutable('2021-01-04T00:00:00+01:00'), + new DateTimeImmutable('2021-01-05T00:00:00+01:00') + ), + new Status(StatusType::Available()), + BookingAvailability::Available() + ) + ) + ), + CalendarSerializer::deserialize($data) + ); + } + + /** + * @test + */ + public function it_falls_back_to_single_calendar_on_single_timestamp(): void + { + $data = [ + 'type' => 'multiple', + 'status' => [ + 'type' => 'Available', + ], + 'bookingAvailability' => [ + 'type' => 'Available', + ], + 'timestamps' => [ + 0 => [ + 'startDate' => '2021-01-01T00:00:00+01:00', + 'endDate' => '2021-01-02T00:00:00+01:00', + 'status' => [ + 'type' => 'Available', + ], + 'bookingAvailability' => [ + 'type' => 'Available', + ], + ], + ], + 'startDate' => '2021-01-01T00:00:00+01:00', + 'endDate' => '2021-01-02T00:00:00+01:00', + ]; + + $this->assertEquals( + new SingleSubEventCalendar( + new SubEvent( + new DateRange( + new DateTimeImmutable('2021-01-01T00:00:00+01:00'), + new DateTimeImmutable('2021-01-02T00:00:00+01:00') + ), + new Status(StatusType::Available()), + BookingAvailability::Available() + ) + ), + CalendarSerializer::deserialize($data) + ); + } + + /** + * @test + */ + public function it_upgrades_to_multiple_calendar_on_multiple_timestamp(): void + { + $data = [ + 'type' => 'single', + 'status' => [ + 'type' => 'Available', + ], + 'bookingAvailability' => [ + 'type' => 'Available', + ], + 'timestamps' => [ + 0 => [ + 'startDate' => '2021-01-01T00:00:00+01:00', + 'endDate' => '2021-01-02T00:00:00+01:00', + 'status' => [ + 'type' => 'Available', + ], + 'bookingAvailability' => [ + 'type' => 'Available', + ], + ], + 1 => [ + 'startDate' => '2021-01-04T00:00:00+01:00', + 'endDate' => '2021-01-05T00:00:00+01:00', + 'status' => [ + 'type' => 'Available', + ], + 'bookingAvailability' => [ + 'type' => 'Available', + ], + ], + ], + 'startDate' => '2021-01-01T00:00:00+01:00', + 'endDate' => '2021-01-05T00:00:00+01:00', + ]; + + $this->assertEquals( + new MultipleSubEventsCalendar( + new SubEvents( + new SubEvent( + new DateRange( + new DateTimeImmutable('2021-01-01T00:00:00+01:00'), + new DateTimeImmutable('2021-01-02T00:00:00+01:00') + ), + new Status(StatusType::Available()), + BookingAvailability::Available() + ), + new SubEvent( + new DateRange( + new DateTimeImmutable('2021-01-04T00:00:00+01:00'), + new DateTimeImmutable('2021-01-05T00:00:00+01:00') + ), + new Status(StatusType::Available()), + BookingAvailability::Available() + ) + ) + ), + CalendarSerializer::deserialize($data) + ); + } +}