Skip to content

Commit

Permalink
fix: appointment slots start and end time
Browse files Browse the repository at this point in the history
Signed-off-by: SebastianKrupinski <[email protected]>
  • Loading branch information
SebastianKrupinski committed Nov 19, 2024
1 parent f00f9e5 commit 9b88ea3
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 28 deletions.
18 changes: 9 additions & 9 deletions lib/Controller/BookingController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/
namespace OCA\Calendar\Controller;

use DateTime;
use DateTimeImmutable;
use DateTimeZone;
use InvalidArgumentException;
Expand Down Expand Up @@ -89,22 +90,21 @@ public function __construct(string $appName,
public function getBookableSlots(int $appointmentConfigId,
int $startTime,
string $timeZone): JsonResponse {
// Convert the timestamps to the beginning and end of the respective day in the specified timezone
try {
$tz = new DateTimeZone($timeZone);
} catch (Exception $e) {
$this->logger->error('Timezone invalid', ['exception' => $e]);
return JsonResponse::fail('Invalid time zone', Http::STATUS_UNPROCESSABLE_ENTITY);
}
$startTimeInTz = (new DateTimeImmutable())
->setTimestamp($startTime)
->setTimezone($tz)
->setTime(0, 0)
// UI sends epoch start of day adjusted for system users calendar
// E.g "Mon, 18 Nov 2024 05:00:00 +0000" (America/Toronto)
$startDate = (new DateTimeImmutable("@$startTime"));
// Convert start date to requesters selected timezone adjusted start and end of day in epoch
// E.g "Mon, 18 Nov 2024 06:00:00 +0000" (America/Mexico_City)
$startTimeInTz = (new DateTime($startDate->format('Y-m-d'), $tz))
->getTimestamp();
$endTimeInTz = (new DateTimeImmutable())
->setTimestamp($startTime)
->setTimezone($tz)
->setTime(23, 59, 59)
$endTimeInTz = (new DateTime($startDate->format('Y-m-d'), $tz))
->modify('+1 day')
->getTimestamp();

if ($startTimeInTz > $endTimeInTz) {
Expand Down
139 changes: 120 additions & 19 deletions tests/php/unit/Controller/BookingControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
namespace OCA\Calendar\Controller;

use ChristophWurst\Nextcloud\Testing\TestCase;
use DateTime;
use DateTimeImmutable;
use DateTimeZone;
use Exception;
Expand Down Expand Up @@ -108,15 +109,11 @@ protected function setUp():void {
public function testGetBookableSlots(): void {
$start = time();
$tz = new DateTimeZone('Europe/Berlin');
$sDT = (new DateTimeImmutable())
->setTimestamp($start)
->setTimezone($tz)
->setTime(0, 0)
$startDate = (new DateTimeImmutable("@$start"));
$sDT = (new DateTime($startDate->format('Y-m-d'), $tz))
->getTimestamp();
$eDT = (new DateTimeImmutable())
->setTimestamp($start)
->setTimezone($tz)
->setTime(23, 59, 59)
$eDT = (new DateTime($startDate->format('Y-m-d'), $tz))
->modify('+1 day')
->getTimestamp();

$apptConfg = new AppointmentConfig();
Expand All @@ -135,6 +132,25 @@ public function testGetBookableSlots(): void {
$this->controller->getBookableSlots($apptConfg->getId(), $start, 'Europe/Berlin');
}

public function testGetBookableSlotsDatesInPast(): void {
$start = time();
$fakeFutureTimestamp = time() + (100 * 24 * 60 * 60);
$apptConfg = new AppointmentConfig();
$apptConfg->setId(1);
$this->time->expects(self::once())
->method('getTime')
->willReturn($fakeFutureTimestamp);
$this->apptService->expects(self::never())
->method('findById')
->with(1);
$this->bookingService->expects(self::never())
->method('getAvailableSlots');
$this->logger->expects(self::once())
->method('warning');

$this->controller->getBookableSlots($apptConfg->getId(), $start, 'Europe/Berlin');
}

public function testGetBookableSlotsInvalidTimezone(): void {
$start = time();
$apptConfg = new AppointmentConfig();
Expand All @@ -151,23 +167,108 @@ public function testGetBookableSlotsInvalidTimezone(): void {
$this->controller->getBookableSlots($apptConfg->getId(), $start, 'Hook/Neverland');
}

public function testGetBookableSlotsDatesInPast(): void {
$start = time();
$fakeFutureTimestamp = time() + (100 * 24 * 60 * 60);
public function testGetBookableSlotsTimezoneIdentical(): void {

$now = (new DateTime('2024-6-30 8:00:00'))->getTimestamp();
$start = (new DateTime('2024-7-1 04:00:00'))->getTimestamp(); // Start date with America/Toronto offset
$timezone = 'America/Toronto';
$sDT = (new DateTime('2024-7-1 04:00:00'))->getTimestamp();
;
$eDT = (new DateTime('2024-7-2 04:00:00'))->getTimestamp();
;

$apptConfg = new AppointmentConfig();
$apptConfg->setId(1);
$this->time->expects(self::once())
->method('getTime')
->willReturn($fakeFutureTimestamp);
$this->apptService->expects(self::never())
->willReturn($now);
$this->apptService->expects(self::once())
->method('findById')
->with(1);
$this->bookingService->expects(self::never())
->method('getAvailableSlots');
$this->logger->expects(self::once())
->method('warning');
->with(1)
->willReturn($apptConfg);
$this->bookingService->expects(self::once())
->method('getAvailableSlots')
->with($apptConfg, $sDT, $eDT);

$this->controller->getBookableSlots($apptConfg->getId(), $start, 'Europe/Berlin');
$this->controller->getBookableSlots($apptConfg->getId(), $start, $timezone);
}

public function testGetBookableSlotsTimezoneMinus10(): void {

$now = (new DateTime('2024-6-30 8:00:00'))->getTimestamp();
$start = (new DateTime('2024-7-1 4:00:00'))->getTimestamp(); // Start date with America/Toronto offset
$timezone = 'Pacific/Pago_Pago';
$sDT = (new DateTime('2024-7-1 11:00:00'))->getTimestamp();
;
$eDT = (new DateTime('2024-7-2 11:00:00'))->getTimestamp();
;

$apptConfg = new AppointmentConfig();
$apptConfg->setId(1);
$this->time->expects(self::once())
->method('getTime')
->willReturn($now);
$this->apptService->expects(self::once())
->method('findById')
->with(1)
->willReturn($apptConfg);
$this->bookingService->expects(self::once())
->method('getAvailableSlots')
->with($apptConfg, $sDT, $eDT);

$this->controller->getBookableSlots($apptConfg->getId(), $start, $timezone);
}

public function testGetBookableSlotsTimezonePlus10(): void {

$now = (new DateTime('2024-6-30 8:00:00'))->getTimestamp();
$start = (new DateTime('2024-7-1 4:00:00'))->getTimestamp(); // Start date with America/Toronto offset
$timezone = 'Australia/Sydney';
$sDT = (new DateTime('2024-6-30 14:00:00'))->getTimestamp();
;
$eDT = (new DateTime('2024-7-1 14:00:00'))->getTimestamp();
;

$apptConfg = new AppointmentConfig();
$apptConfg->setId(1);
$this->time->expects(self::once())
->method('getTime')
->willReturn($now);
$this->apptService->expects(self::once())
->method('findById')
->with(1)
->willReturn($apptConfg);
$this->bookingService->expects(self::once())
->method('getAvailableSlots')
->with($apptConfg, $sDT, $eDT);

$this->controller->getBookableSlots($apptConfg->getId(), $start, $timezone);
}

public function testGetBookableSlotsTimezonePlus14(): void {

$now = (new DateTime('2024-6-30 8:00:00'))->getTimestamp();
$start = (new DateTime('2024-7-1 4:00:00'))->getTimestamp(); // Start date with America/Toronto offset
$timezone = 'Pacific/Kiritimati';
$sDT = (new DateTime('2024-6-30 10:00:00'))->getTimestamp();
;
$eDT = (new DateTime('2024-7-1 10:00:00'))->getTimestamp();
;

$apptConfg = new AppointmentConfig();
$apptConfg->setId(1);
$this->time->expects(self::once())
->method('getTime')
->willReturn($now);
$this->apptService->expects(self::once())
->method('findById')
->with(1)
->willReturn($apptConfg);
$this->bookingService->expects(self::once())
->method('getAvailableSlots')
->with($apptConfg, $sDT, $eDT);

$this->controller->getBookableSlots($apptConfg->getId(), $start, $timezone);
}

public function testBook(): void {
Expand Down

0 comments on commit 9b88ea3

Please sign in to comment.