0
0
mirror of https://github.com/nextcloud/server.git synced 2025-01-01 18:00:09 +00:00
nextcloud_server/apps/dav/tests/unit/Service/AbsenceServiceTest.php
Christoph Wurst 49dd79eabb
refactor: Add void return type to PHPUnit test methods
Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
2024-09-15 22:32:31 +02:00

455 lines
14 KiB
PHP

<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\dav\tests\unit\Service;
use DateTimeImmutable;
use DateTimeZone;
use OCA\DAV\BackgroundJob\OutOfOfficeEventDispatcherJob;
use OCA\DAV\CalDAV\TimezoneService;
use OCA\DAV\Db\Absence;
use OCA\DAV\Db\AbsenceMapper;
use OCA\DAV\Service\AbsenceService;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\BackgroundJob\IJobList;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\IUser;
use OCP\User\Events\OutOfOfficeChangedEvent;
use OCP\User\Events\OutOfOfficeScheduledEvent;
use PHPUnit\Framework\TestCase;
class AbsenceServiceTest extends TestCase {
private AbsenceService $absenceService;
/** @var MockObject|AbsenceMapper */
private $absenceMapper;
/** @var MockObject|IEventDispatcher */
private $eventDispatcher;
/** @var MockObject|IJobList */
private $jobList;
/** @var MockObject|TimezoneService */
private $timezoneService;
/** @var MockObject|ITimeFactory */
private $timeFactory;
protected function setUp(): void {
parent::setUp();
$this->absenceMapper = $this->createMock(AbsenceMapper::class);
$this->eventDispatcher = $this->createMock(IEventDispatcher::class);
$this->jobList = $this->createMock(IJobList::class);
$this->timezoneService = $this->createMock(TimezoneService::class);
$this->timeFactory = $this->createMock(ITimeFactory::class);
$this->absenceService = new AbsenceService(
$this->absenceMapper,
$this->eventDispatcher,
$this->jobList,
$this->timezoneService,
$this->timeFactory,
);
}
public function testCreateAbsenceEmitsScheduledEvent(): void {
$tz = new DateTimeZone('Europe/Berlin');
$user = $this->createMock(IUser::class);
$user->method('getUID')
->willReturn('user');
$this->absenceMapper->expects(self::once())
->method('findByUserId')
->with('user')
->willThrowException(new DoesNotExistException('foo bar'));
$this->absenceMapper->expects(self::once())
->method('insert')
->willReturnCallback(function (Absence $absence): Absence {
$absence->setId(1);
return $absence;
});
$this->timezoneService->expects(self::once())
->method('getUserTimezone')
->with('user')
->willReturn('Europe/Berlin');
$this->eventDispatcher->expects(self::once())
->method('dispatchTyped')
->with(self::callback(static function (Event $event) use ($user, $tz): bool {
self::assertInstanceOf(OutOfOfficeScheduledEvent::class, $event);
/** @var OutOfOfficeScheduledEvent $event */
$data = $event->getData();
self::assertEquals('1', $data->getId());
self::assertEquals($user, $data->getUser());
self::assertEquals(
(new DateTimeImmutable('2023-01-05', $tz))->getTimeStamp(),
$data->getStartDate(),
);
self::assertEquals(
(new DateTimeImmutable('2023-01-10', $tz))->getTimeStamp() + 3600 * 23 + 59 * 60,
$data->getEndDate(),
);
self::assertEquals('status', $data->getShortMessage());
self::assertEquals('message', $data->getMessage());
return true;
}));
$this->timeFactory->expects(self::once())
->method('getTime')
->willReturn(PHP_INT_MAX);
$this->jobList->expects(self::never())
->method('scheduleAfter');
$this->absenceService->createOrUpdateAbsence(
$user,
'2023-01-05',
'2023-01-10',
'status',
'message',
);
}
public function testUpdateAbsenceEmitsChangedEvent(): void {
$tz = new DateTimeZone('Europe/Berlin');
$user = $this->createMock(IUser::class);
$user->method('getUID')
->willReturn('user');
$absence = new Absence();
$absence->setId(1);
$absence->setFirstDay('1970-01-01');
$absence->setLastDay('1970-01-10');
$absence->setStatus('old status');
$absence->setMessage('old message');
$this->absenceMapper->expects(self::once())
->method('findByUserId')
->with('user')
->willReturn($absence);
$this->absenceMapper->expects(self::once())
->method('update')
->willReturnCallback(static function (Absence $absence): Absence {
self::assertEquals('2023-01-05', $absence->getFirstDay());
self::assertEquals('2023-01-10', $absence->getLastDay());
self::assertEquals('status', $absence->getStatus());
self::assertEquals('message', $absence->getMessage());
return $absence;
});
$this->timezoneService->expects(self::once())
->method('getUserTimezone')
->with('user')
->willReturn('Europe/Berlin');
$this->eventDispatcher->expects(self::once())
->method('dispatchTyped')
->with(self::callback(static function (Event $event) use ($user, $tz): bool {
self::assertInstanceOf(OutOfOfficeChangedEvent::class, $event);
/** @var OutOfOfficeChangedEvent $event */
$data = $event->getData();
self::assertEquals('1', $data->getId());
self::assertEquals($user, $data->getUser());
self::assertEquals(
(new DateTimeImmutable('2023-01-05', $tz))->getTimeStamp(),
$data->getStartDate(),
);
self::assertEquals(
(new DateTimeImmutable('2023-01-10', $tz))->getTimeStamp() + 3600 * 23 + 59 * 60,
$data->getEndDate(),
);
self::assertEquals('status', $data->getShortMessage());
self::assertEquals('message', $data->getMessage());
return true;
}));
$this->timeFactory->expects(self::once())
->method('getTime')
->willReturn(PHP_INT_MAX);
$this->jobList->expects(self::never())
->method('scheduleAfter');
$this->absenceService->createOrUpdateAbsence(
$user,
'2023-01-05',
'2023-01-10',
'status',
'message',
);
}
public function testCreateAbsenceSchedulesBothJobs(): void {
$tz = new DateTimeZone('Europe/Berlin');
$startDateString = '2023-01-05';
$startDate = new DateTimeImmutable($startDateString, $tz);
$endDateString = '2023-01-10';
$endDate = new DateTimeImmutable($endDateString, $tz);
$user = $this->createMock(IUser::class);
$user->method('getUID')
->willReturn('user');
$this->absenceMapper->expects(self::once())
->method('findByUserId')
->with('user')
->willThrowException(new DoesNotExistException('foo bar'));
$this->absenceMapper->expects(self::once())
->method('insert')
->willReturnCallback(function (Absence $absence): Absence {
$absence->setId(1);
return $absence;
});
$this->timezoneService->expects(self::once())
->method('getUserTimezone')
->with('user')
->willReturn($tz->getName());
$this->timeFactory->expects(self::once())
->method('getTime')
->willReturn((new DateTimeImmutable('2023-01-01', $tz))->getTimestamp());
$this->jobList->expects(self::exactly(2))
->method('scheduleAfter')
->willReturnMap([
[OutOfOfficeEventDispatcherJob::class, $startDate->getTimestamp(), [
'id' => '1',
'event' => OutOfOfficeEventDispatcherJob::EVENT_START,
]],
[OutOfOfficeEventDispatcherJob::class, $endDate->getTimestamp() + 3600 * 23 + 59 * 60, [
'id' => '1',
'event' => OutOfOfficeEventDispatcherJob::EVENT_END,
]],
]);
$this->absenceService->createOrUpdateAbsence(
$user,
$startDateString,
$endDateString,
'',
'',
);
}
public function testCreateAbsenceSchedulesOnlyEndJob(): void {
$tz = new DateTimeZone('Europe/Berlin');
$endDateString = '2023-01-10';
$endDate = new DateTimeImmutable($endDateString, $tz);
$user = $this->createMock(IUser::class);
$user->method('getUID')
->willReturn('user');
$this->absenceMapper->expects(self::once())
->method('findByUserId')
->with('user')
->willThrowException(new DoesNotExistException('foo bar'));
$this->absenceMapper->expects(self::once())
->method('insert')
->willReturnCallback(function (Absence $absence): Absence {
$absence->setId(1);
return $absence;
});
$this->timezoneService->expects(self::once())
->method('getUserTimezone')
->with('user')
->willReturn($tz->getName());
$this->timeFactory->expects(self::once())
->method('getTime')
->willReturn((new DateTimeImmutable('2023-01-07', $tz))->getTimestamp());
$this->jobList->expects(self::once())
->method('scheduleAfter')
->with(OutOfOfficeEventDispatcherJob::class, $endDate->getTimestamp() + 3600 * 23 + 59 * 60, [
'id' => '1',
'event' => OutOfOfficeEventDispatcherJob::EVENT_END,
]);
$this->absenceService->createOrUpdateAbsence(
$user,
'2023-01-05',
$endDateString,
'',
'',
);
}
public function testCreateAbsenceSchedulesNoJob(): void {
$tz = new DateTimeZone('Europe/Berlin');
$user = $this->createMock(IUser::class);
$user->method('getUID')
->willReturn('user');
$this->absenceMapper->expects(self::once())
->method('findByUserId')
->with('user')
->willThrowException(new DoesNotExistException('foo bar'));
$this->absenceMapper->expects(self::once())
->method('insert')
->willReturnCallback(function (Absence $absence): Absence {
$absence->setId(1);
return $absence;
});
$this->timezoneService->expects(self::once())
->method('getUserTimezone')
->with('user')
->willReturn($tz->getName());
$this->timeFactory->expects(self::once())
->method('getTime')
->willReturn((new DateTimeImmutable('2023-01-12', $tz))->getTimestamp());
$this->jobList->expects(self::never())
->method('scheduleAfter');
$this->absenceService->createOrUpdateAbsence(
$user,
'2023-01-05',
'2023-01-10',
'',
'',
);
}
public function testUpdateAbsenceSchedulesBothJobs(): void {
$tz = new DateTimeZone('Europe/Berlin');
$startDateString = '2023-01-05';
$startDate = new DateTimeImmutable($startDateString, $tz);
$endDateString = '2023-01-10';
$endDate = new DateTimeImmutable($endDateString, $tz);
$user = $this->createMock(IUser::class);
$user->method('getUID')
->willReturn('user');
$absence = new Absence();
$absence->setId(1);
$absence->setFirstDay('1970-01-01');
$absence->setLastDay('1970-01-10');
$absence->setStatus('old status');
$absence->setMessage('old message');
$this->absenceMapper->expects(self::once())
->method('findByUserId')
->with('user')
->willReturn($absence);
$this->absenceMapper->expects(self::once())
->method('update')
->willReturnCallback(static function (Absence $absence) use ($startDateString, $endDateString): Absence {
self::assertEquals($startDateString, $absence->getFirstDay());
self::assertEquals($endDateString, $absence->getLastDay());
return $absence;
});
$this->timezoneService->expects(self::once())
->method('getUserTimezone')
->with('user')
->willReturn($tz->getName());
$this->timeFactory->expects(self::once())
->method('getTime')
->willReturn((new DateTimeImmutable('2023-01-01', $tz))->getTimestamp());
$this->jobList->expects(self::exactly(2))
->method('scheduleAfter')
->willReturnMap([
[OutOfOfficeEventDispatcherJob::class, $startDate->getTimestamp(), [
'id' => '1',
'event' => OutOfOfficeEventDispatcherJob::EVENT_START,
]],
[OutOfOfficeEventDispatcherJob::class, $endDate->getTimestamp() + 3600 * 23 + 59 * 60, [
'id' => '1',
'event' => OutOfOfficeEventDispatcherJob::EVENT_END,
]],
]);
$this->absenceService->createOrUpdateAbsence(
$user,
$startDateString,
$endDateString,
'',
'',
);
}
public function testUpdateSchedulesOnlyEndJob(): void {
$tz = new DateTimeZone('Europe/Berlin');
$endDateString = '2023-01-10';
$endDate = new DateTimeImmutable($endDateString, $tz);
$user = $this->createMock(IUser::class);
$user->method('getUID')
->willReturn('user');
$absence = new Absence();
$absence->setId(1);
$absence->setFirstDay('1970-01-01');
$absence->setLastDay('1970-01-10');
$absence->setStatus('old status');
$absence->setMessage('old message');
$this->absenceMapper->expects(self::once())
->method('findByUserId')
->with('user')
->willReturn($absence);
$this->absenceMapper->expects(self::once())
->method('update')
->willReturnCallback(static function (Absence $absence) use ($endDateString): Absence {
self::assertEquals('2023-01-05', $absence->getFirstDay());
self::assertEquals($endDateString, $absence->getLastDay());
return $absence;
});
$this->timezoneService->expects(self::once())
->method('getUserTimezone')
->with('user')
->willReturn($tz->getName());
$this->timeFactory->expects(self::once())
->method('getTime')
->willReturn((new DateTimeImmutable('2023-01-07', $tz))->getTimestamp());
$this->jobList->expects(self::once())
->method('scheduleAfter')
->with(OutOfOfficeEventDispatcherJob::class, $endDate->getTimestamp() + 23 * 3600 + 59 * 60, [
'id' => '1',
'event' => OutOfOfficeEventDispatcherJob::EVENT_END,
]);
$this->absenceService->createOrUpdateAbsence(
$user,
'2023-01-05',
$endDateString,
'',
'',
);
}
public function testUpdateAbsenceSchedulesNoJob(): void {
$tz = new DateTimeZone('Europe/Berlin');
$user = $this->createMock(IUser::class);
$user->method('getUID')
->willReturn('user');
$absence = new Absence();
$absence->setId(1);
$absence->setFirstDay('1970-01-01');
$absence->setLastDay('1970-01-10');
$absence->setStatus('old status');
$absence->setMessage('old message');
$this->absenceMapper->expects(self::once())
->method('findByUserId')
->with('user')
->willReturn($absence);
$this->absenceMapper->expects(self::once())
->method('update')
->willReturnCallback(static function (Absence $absence): Absence {
self::assertEquals('2023-01-05', $absence->getFirstDay());
self::assertEquals('2023-01-10', $absence->getLastDay());
return $absence;
});
$this->timezoneService->expects(self::once())
->method('getUserTimezone')
->with('user')
->willReturn($tz->getName());
$this->timeFactory->expects(self::once())
->method('getTime')
->willReturn((new DateTimeImmutable('2023-01-12', $tz))->getTimestamp());
$this->jobList->expects(self::never())
->method('scheduleAfter');
$this->absenceService->createOrUpdateAbsence(
$user,
'2023-01-05',
'2023-01-10',
'',
'',
);
}
}