Skip to content

Commit

Permalink
Merge pull request #100 from itk-dev/feature/booking-247-add-tests
Browse files Browse the repository at this point in the history
Add acceptConflict tests.
  • Loading branch information
tuj authored Jul 7, 2023
2 parents db3af92 + 3019336 commit b8ee34d
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 46 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ See [keep a changelog](https://keepachangelog.com/en/1.0.0/) for information abo
### Added

- Added acceptConflict field to resource.
- Added tests for acceptConflict.

### Changed

Expand Down
48 changes: 3 additions & 45 deletions src/Service/MicrosoftGraphBookingService.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public function createBookingForResource(string $resourceEmail, string $resource
$token = $this->graphHelperService->authenticateAsServiceAccount();

if (!$acceptConflict) {
$bookingConflict = $this->isBookingConflict($resourceEmail, $startTime, $endTime, $token);
$bookingConflict = $this->graphHelperService->isBookingConflict($resourceEmail, $startTime, $endTime, $token);

if ($bookingConflict) {
throw new BookingCreateConflictException('Booking interval conflict.', 409);
Expand Down Expand Up @@ -137,7 +137,7 @@ public function createBookingForResource(string $resourceEmail, string $resource
$iCalUId = $content['iCalUId'];

if (!$acceptConflict) {
if ($this->isBookingConflict($resourceEmail, $startTime, $endTime, $token, [$iCalUId])) {
if ($this->graphHelperService->isBookingConflict($resourceEmail, $startTime, $endTime, $token, [$iCalUId])) {
$bookingId = $content['id'];

// If another booking has been created at the same time, remove this booking.
Expand Down Expand Up @@ -232,7 +232,7 @@ public function updateBooking(UserBooking $booking): ?string

$resourceMail = $booking->resourceMail;

$bookingConflict = $this->isBookingConflict($resourceMail, $booking->start, $booking->end, $token, [$booking->iCalUId]);
$bookingConflict = $this->graphHelperService->isBookingConflict($resourceMail, $booking->start, $booking->end, $token, [$booking->iCalUId]);

if ($bookingConflict) {
throw new UserBookingException('Booking interval conflict.', 409);
Expand Down Expand Up @@ -546,46 +546,4 @@ private function getEventFromResourceByICalUid(string $resourceEmail, string $iC

return null;
}

/**
* Check that there is no interval conflict.
*
* @param string $resourceEmail resource to check for conflict in
* @param DateTime $startTime start of interval
* @param DateTime $endTime end of interval
* @param string|null $accessToken access token
* @param array|null $ignoreICalUIds Ignore bookings with these ICalUIds in the evaluation. Use to allow editing an existing booking.
*
* @return bool whether there is a booking conflict for the given interval
*
* @throws MicrosoftGraphCommunicationException
*/
private function isBookingConflict(string $resourceEmail, DateTime $startTime, DateTime $endTime, string $accessToken = null, array $ignoreICalUIds = null): bool
{
$token = $accessToken ?: $this->graphHelperService->authenticateAsServiceAccount();
$startString = $startTime->setTimezone(new \DateTimeZone('UTC'))->format(MicrosoftGraphBookingService::DATE_FORMAT).'Z';
$endString = $endTime->setTimezone(new \DateTimeZone('UTC'))->format(MicrosoftGraphBookingService::DATE_FORMAT).'Z';

$filterString = "\$filter=start/dateTime lt '$endString' and end/dateTime gt '$startString'";

$response = $this->graphHelperService->request("/users/$resourceEmail/calendar/events?$filterString", $token);

$body = $response->getBody();

$entries = $body['value'];

if (count($entries) > 0) {
if (null != $ignoreICalUIds) {
foreach ($entries as $entry) {
if (!in_array($entry['iCalUId'], $ignoreICalUIds)) {
return true;
}
}
} else {
return true;
}
}

return false;
}
}
43 changes: 43 additions & 0 deletions src/Service/MicrosoftGraphHelperService.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Exception\MicrosoftGraphCommunicationException;
use App\Factory\ClientFactory;
use DateTime;
use GuzzleHttp\Exception\GuzzleException;
use JsonException;
use Microsoft\Graph\Exception\GraphException;
Expand Down Expand Up @@ -79,4 +80,46 @@ public function request(string $path, string $accessToken, string $requestType =
throw new MicrosoftGraphCommunicationException($e->getMessage(), $e->getCode());
}
}

/**
* Check that there is no interval conflict.
*
* @param string $resourceEmail resource to check for conflict in
* @param DateTime $startTime start of interval
* @param DateTime $endTime end of interval
* @param string|null $accessToken access token
* @param array|null $ignoreICalUIds Ignore bookings with these ICalUIds in the evaluation. Use to allow editing an existing booking.
*
* @return bool whether there is a booking conflict for the given interval
*
* @throws MicrosoftGraphCommunicationException
*/
public function isBookingConflict(string $resourceEmail, DateTime $startTime, DateTime $endTime, string $accessToken = null, array $ignoreICalUIds = null): bool
{
$token = $accessToken ?: $this->authenticateAsServiceAccount();
$startString = $startTime->setTimezone(new \DateTimeZone('UTC'))->format(MicrosoftGraphBookingService::DATE_FORMAT).'Z';
$endString = $endTime->setTimezone(new \DateTimeZone('UTC'))->format(MicrosoftGraphBookingService::DATE_FORMAT).'Z';

$filterString = "\$filter=start/dateTime lt '$endString' and end/dateTime gt '$startString'";

$response = $this->request("/users/$resourceEmail/calendar/events?$filterString", $token);

$body = $response->getBody();

$entries = $body['value'];

if (count($entries) > 0) {
if (null != $ignoreICalUIds) {
foreach ($entries as $entry) {
if (!in_array($entry['iCalUId'], $ignoreICalUIds)) {
return true;
}
}
} else {
return true;
}
}

return false;
}
}
2 changes: 1 addition & 1 deletion tests/Api/BookingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ public function testCreateBookingHandler(): void
$booking->setResourceEmail('[email protected]');
$booking->setStartTime(new \DateTime());
$booking->setEndTime(new \DateTime());
$booking->setUserName('auther1');
$booking->setUserName('author1');
$booking->setUserMail('[email protected]');
$booking->setMetaData([
'meta_data_4' => '1, 2, 3',
Expand Down
55 changes: 55 additions & 0 deletions tests/Service/MicrosoftGraphBookingServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -553,4 +553,59 @@ public function testCreateBookingInviteResource(): void
$this->assertEquals(400, $e->getCode());
}
}

/**
* @throws MicrosoftGraphCommunicationException
* @throws BookingCreateConflictException
*/
public function testAcceptConflict(): void
{
$microsoftGraphServiceHelperMock = $this->getMockBuilder(MicrosoftGraphHelperService::class)
->disableOriginalConstructor()
->onlyMethods(['isBookingConflict', 'request', 'authenticateAsServiceAccount'])
->getMock();
$microsoftGraphServiceHelperMock->expects($this->exactly(1))->method('isBookingConflict')->willReturn(true);
$microsoftGraphServiceHelperMock->method('authenticateAsServiceAccount')->willReturn('1234');

$microsoftGraphServiceHelperMock->expects($this->exactly(1))->method('request')->willReturn(
new GraphResponse(
new GraphRequest('GET', '/', '123', 'http://localhost', 'v1'),
json_encode([
'iCalUId' => '123',
]),
201,
),
);

$microsoftGraphService = new MicrosoftGraphBookingService('test', 'test', $microsoftGraphServiceHelperMock);

// Accept conflict.
$microsoftGraphService->createBookingForResource(
'[email protected]',
'test resource',
'test',
'',
new \DateTime('2040-08-18T10:00:00.000Z'),
new \DateTime('2040-08-18T12:00:00.000Z'),
true,
);

$exceptionCode = null;

// Do not accept conflict.
try {
$microsoftGraphService->createBookingForResource(
'[email protected]',
'test resource',
'test',
'',
new \DateTime('2040-08-18T10:00:00.000Z'),
new \DateTime('2040-08-18T12:00:00.000Z'),
);
} catch (BookingCreateConflictException $e) {
$exceptionCode = $e->getCode();
}

$this->assertEquals(409, $exceptionCode);
}
}

0 comments on commit b8ee34d

Please sign in to comment.