Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Pages/Export/CalendarSubscriptionPage.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ public function PageLoad(): void
header('Content-Disposition: inline; filename=calendar.ics');

$display = new CalendarExportDisplay();
echo $display->Render($this->reservations);
echo $display->Render($this->reservations, $this->calendarName);
}
}
2 changes: 2 additions & 0 deletions Pages/Export/ICalendarSubscriptionPage.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ public function GetUserId();
*/
public function SetReservations($reservations);

public function SetCalendarName(string $calendarName): void;

/**
* @return string
*/
Expand Down
7 changes: 7 additions & 0 deletions Pages/Export/SubscriptionPage.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ abstract class SubscriptionPage extends Page implements ICalendarSubscriptionPag
/** @var iCalendarReservationView[] */
protected array $reservations = [];

protected ?string $calendarName = null;

protected function __construct()
{
$authorization = new ReservationAuthorization(PluginManager::Instance()->LoadAuthorization());
Expand All @@ -44,6 +46,11 @@ public function SetReservations($reservations): void
$this->reservations = $reservations;
}

public function SetCalendarName(string $calendarName): void
{
$this->calendarName = $calendarName;
}

public function GetSubscriptionKey()
{
return $this->GetQuerystring(QueryStringKeys::SUBSCRIPTION_KEY);
Expand Down
15 changes: 11 additions & 4 deletions Presenters/CalendarSubscriptionPresenter.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,29 +84,36 @@ public function PageLoad(): bool
$summaryFormat = Configuration::Instance()->GetKey(ConfigKeys::RESERVATION_LABELS_ICS_SUMMARY);

$reservationUserLevel = ReservationUserLevel::OWNER;

if (!empty($scheduleId)) {
$schedule = $this->subscriptionService->GetSchedule($scheduleId);
$sid = $schedule->GetId();
$sid = $this->subscriptionService->GetSchedule($scheduleId)->GetId();
}
if (!empty($resourceId)) {
$resource = $this->subscriptionService->GetResource($resourceId);
$rid = $resource->GetId();
$rid = $this->subscriptionService->GetResource($resourceId)->GetId();
}
if (!empty($accessoryIds)) {
## No transformation is implemented. It is assumed the accessoryIds is provided as AccessoryName
## filter is defined by LIKE "PATTERN%"
$aid = $accessoryIds;
}

$calendarName = $this->subscriptionService->ResolveCalendarName($scheduleId, $resourceId, $resourceGroupId, $userId);

if (!empty($userId)) {
$user = $this->subscriptionService->GetUser($userId);
$uid = $user->Id();
$reservationUserLevel = ReservationUserLevel::ALL;
$summaryFormat = Configuration::Instance()->GetKey(ConfigKeys::RESERVATION_LABELS_ICS_MY_SUMMARY);
}

if (!empty($resourceGroupId)) {
$resourceIds = $this->subscriptionService->GetResourcesInGroup($resourceGroupId);
}

if ($calendarName !== null && $calendarName !== '') {
$this->page->SetCalendarName($calendarName);
}

if (!empty($uid) || !empty($sid) || !empty($rid) || !empty($resourceIds)) {
$res = $this->reservationViewRepository->GetReservations($weekAgo, $nextYear, $uid, $reservationUserLevel, $sid, $rid, true);
} elseif (!empty($aid)) {
Expand Down
57 changes: 56 additions & 1 deletion lib/Application/Schedule/CalendarSubscriptionService.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ public function ForSchedule($scheduleId);
* @return int[]
*/
public function GetResourcesInGroup($publicResourceGroupId);

public function GetResourceGroup(string $publicResourceGroupId): ?ResourceGroup;

public function ResolveCalendarName(
?string $publicScheduleId,
?string $publicResourceId,
?string $publicResourceGroupId,
?string $publicUserId = null
): ?string;
}

class CalendarSubscriptionDetails
Expand Down Expand Up @@ -106,6 +115,7 @@ public function Url()
class CalendarSubscriptionService implements ICalendarSubscriptionService
{
private $cache = [];
private $groupCache = [];

/**
* @var IUserRepository
Expand Down Expand Up @@ -177,7 +187,7 @@ public function GetUser($publicUserId)
public function GetResourcesInGroup($publicResourceGroupId)
{
if (!array_key_exists($publicResourceGroupId, $this->cache)) {
$group = $this->resourceRepository->LoadResourceGroupByPublicId($publicResourceGroupId);
$group = $this->LoadResourceGroup($publicResourceGroupId);

if ($group == null) {
return [];
Expand All @@ -190,6 +200,51 @@ public function GetResourcesInGroup($publicResourceGroupId)
return $this->cache[$publicResourceGroupId];
}

public function GetResourceGroup(string $publicResourceGroupId): ?ResourceGroup
{
return $this->LoadResourceGroup($publicResourceGroupId);
}

public function ResolveCalendarName(
?string $publicScheduleId,
?string $publicResourceId,
?string $publicResourceGroupId,
?string $publicUserId = null
): ?string {
$calendarName = null;

if (!empty($publicScheduleId)) {
$calendarName = $this->GetSchedule($publicScheduleId)->GetName();
}

if (!empty($publicResourceId)) {
$calendarName = $this->GetResource($publicResourceId)->GetName();
}

if (!empty($publicResourceGroupId)) {
$resourceGroup = $this->GetResourceGroup($publicResourceGroupId);
if ($resourceGroup !== null && $resourceGroup->name !== null && $resourceGroup->name !== '') {
$calendarName = $resourceGroup->name;
}
}

if (!empty($publicUserId)) {
$myCalendarName = Resources::GetInstance()->GetString('MyCalendar');
$calendarName = empty($calendarName) ? $myCalendarName : sprintf('%s - %s', $myCalendarName, $calendarName);
}

return $calendarName;
}

private function LoadResourceGroup(string $publicResourceGroupId): ?ResourceGroup
{
if (!array_key_exists($publicResourceGroupId, $this->groupCache)) {
$this->groupCache[$publicResourceGroupId] = $this->resourceRepository->LoadResourceGroupByPublicId($publicResourceGroupId);
}

return $this->groupCache[$publicResourceGroupId];
}

public function ForUser($userId, $resourceId = null, $scheduleId = null)
{
$user = $this->userRepository->LoadById($userId);
Expand Down
201 changes: 201 additions & 0 deletions tests/Application/Schedule/CalendarSubscriptionServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,207 @@ public function testGetsScheduleByPublicId()
$this->assertEquals($expected, $actual);
}

public function testGetsResourceGroupByPublicId()
{
$publicId = uniqid();
$group = new ResourceGroup(5, 'Engineering Rooms');

$this->resourceRepo->expects($this->once())
->method('LoadResourceGroupByPublicId')
->with($this->equalTo($publicId))
->willReturn($group);

$actual = $this->service->GetResourceGroup($publicId);

$this->assertEquals($group, $actual);
}

public function testGetsNullResourceGroupWhenGroupNotFound()
{
$publicId = uniqid();

$this->resourceRepo->expects($this->once())
->method('LoadResourceGroupByPublicId')
->with($this->equalTo($publicId))
->willReturn(null);

$actual = $this->service->GetResourceGroup($publicId);

$this->assertNull($actual);
}

public function testGetResourceGroupReusesGroupLoadedByGetResourcesInGroup()
{
$publicId = uniqid();
$group = new ResourceGroup(5, 'Engineering Rooms');
$groups = $this->createMock('ResourceGroupTree');

$this->resourceRepo->expects($this->once())
->method('LoadResourceGroupByPublicId')
->with($this->equalTo($publicId))
->willReturn($group);

$this->resourceRepo->expects($this->once())
->method('GetResourceGroups')
->willReturn($groups);

$groups->expects($this->once())
->method('GetResourceIds')
->with($this->equalTo($group->id))
->willReturn([1, 2]);

$this->service->GetResourcesInGroup($publicId);
$actual = $this->service->GetResourceGroup($publicId);

$this->assertEquals($group, $actual);
}

public function testResolveCalendarNameReturnsScheduleNameWhenOnlyScheduleIdIsSet()
{
$publicScheduleId = uniqid();
$schedule = new FakeSchedule(1, 'Engineering Schedule');

$this->scheduleRepo->expects($this->once())
->method('LoadByPublicId')
->with($this->equalTo($publicScheduleId))
->willReturn($schedule);

$actual = $this->service->ResolveCalendarName($publicScheduleId, null, null);

$this->assertEquals('Engineering Schedule', $actual);
}

public function testResolveCalendarNameReturnsResourceNameWhenOnlyResourceIdIsSet()
{
$publicResourceId = uniqid();
$resource = new FakeBookableResource(1, 'Meeting Room 3');

$this->resourceRepo->expects($this->once())
->method('LoadByPublicId')
->with($this->equalTo($publicResourceId))
->willReturn($resource);

$actual = $this->service->ResolveCalendarName(null, $publicResourceId, null);

$this->assertEquals('Meeting Room 3', $actual);
}

public function testResolveCalendarNameResourceOverridesSchedule()
{
$publicScheduleId = uniqid();
$publicResourceId = uniqid();
$schedule = new FakeSchedule(1, 'Engineering Schedule');
$resource = new FakeBookableResource(2, 'Meeting Room 3');

$this->scheduleRepo->method('LoadByPublicId')->willReturn($schedule);
$this->resourceRepo->method('LoadByPublicId')->willReturn($resource);

$actual = $this->service->ResolveCalendarName($publicScheduleId, $publicResourceId, null);

$this->assertEquals('Meeting Room 3', $actual);
}

public function testResolveCalendarNameResourceGroupOverridesScheduleWhenGroupNameIsNotEmpty()
{
$publicScheduleId = uniqid();
$publicGroupId = uniqid();
$schedule = new FakeSchedule(1, 'Engineering Schedule');
$group = new ResourceGroup(5, 'Engineering Rooms');

$this->scheduleRepo->expects($this->once())
->method('LoadByPublicId')
->with($this->equalTo($publicScheduleId))
->willReturn($schedule);

$this->resourceRepo->expects($this->once())
->method('LoadResourceGroupByPublicId')
->with($this->equalTo($publicGroupId))
->willReturn($group);

$actual = $this->service->ResolveCalendarName($publicScheduleId, null, $publicGroupId);

$this->assertEquals('Engineering Rooms', $actual);
}

public function testResolveCalendarNameFallsBackToScheduleWhenResourceGroupNameIsNull()
{
$publicScheduleId = uniqid();
$publicGroupId = uniqid();
$schedule = new FakeSchedule(1, 'Engineering Schedule');

$this->scheduleRepo->expects($this->once())
->method('LoadByPublicId')
->with($this->equalTo($publicScheduleId))
->willReturn($schedule);

$this->resourceRepo->expects($this->once())
->method('LoadResourceGroupByPublicId')
->with($this->equalTo($publicGroupId))
->willReturn(null);

$actual = $this->service->ResolveCalendarName($publicScheduleId, null, $publicGroupId);

$this->assertEquals('Engineering Schedule', $actual);
}

public function testResolveCalendarNameReturnsNullWhenNoIdsAreSet()
{
$actual = $this->service->ResolveCalendarName(null, null, null);

$this->assertNull($actual);
}

public function testResolveCalendarNameReturnsMyCalendarWhenOnlyUserIdIsSet()
{
$publicUserId = uniqid();

$actual = $this->service->ResolveCalendarName(null, null, null, $publicUserId);

$this->assertEquals(Resources::GetInstance()->GetString('MyCalendar'), $actual);
}

public function testResolveCalendarNameCombinesUserNameWithScheduleName()
{
$publicScheduleId = uniqid();
$publicUserId = uniqid();
$schedule = new FakeSchedule(1, 'Engineering Schedule');

$this->scheduleRepo->method('LoadByPublicId')->willReturn($schedule);

$actual = $this->service->ResolveCalendarName($publicScheduleId, null, null, $publicUserId);

$expected = sprintf('%s - %s', Resources::GetInstance()->GetString('MyCalendar'), 'Engineering Schedule');
$this->assertEquals($expected, $actual);
}

public function testResolveCalendarNameCombinesUserNameWithResourceName()
{
$publicResourceId = uniqid();
$publicUserId = uniqid();
$resource = new FakeBookableResource(1, 'Meeting Room 3');

$this->resourceRepo->method('LoadByPublicId')->willReturn($resource);

$actual = $this->service->ResolveCalendarName(null, $publicResourceId, null, $publicUserId);

$expected = sprintf('%s - %s', Resources::GetInstance()->GetString('MyCalendar'), 'Meeting Room 3');
$this->assertEquals($expected, $actual);
}

public function testResolveCalendarNameCombinesUserNameWithResourceGroupName()
{
$publicGroupId = uniqid();
$publicUserId = uniqid();
$group = new ResourceGroup(5, 'Engineering Rooms');

$this->resourceRepo->method('LoadResourceGroupByPublicId')->willReturn($group);

$actual = $this->service->ResolveCalendarName(null, null, $publicGroupId, $publicUserId);

$expected = sprintf('%s - %s', Resources::GetInstance()->GetString('MyCalendar'), 'Engineering Rooms');
$this->assertEquals($expected, $actual);
}

public function testSubscriptionDetailsAreNotEnabledWhenIcsFeatureIsDisabled()
{
$this->fakeConfig->SetKey(ConfigKeys::ICS_ENABLED, false);
Expand Down
Loading