UserStatusAutomationTest.php 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
  5. * SPDX-License-Identifier: AGPL-3.0-or-later
  6. */
  7. namespace OCA\DAV\Tests\unit\BackgroundJob;
  8. use OC\User\OutOfOfficeData;
  9. use OCA\DAV\BackgroundJob\UserStatusAutomation;
  10. use OCP\AppFramework\Utility\ITimeFactory;
  11. use OCP\BackgroundJob\IJobList;
  12. use OCP\IConfig;
  13. use OCP\IUser;
  14. use OCP\IUserManager;
  15. use OCP\User\IAvailabilityCoordinator;
  16. use OCP\UserStatus\IManager;
  17. use OCP\UserStatus\IUserStatus;
  18. use PHPUnit\Framework\MockObject\MockObject;
  19. use Psr\Log\LoggerInterface;
  20. use Test\TestCase;
  21. /**
  22. * @group DB
  23. */
  24. class UserStatusAutomationTest extends TestCase {
  25. protected MockObject|ITimeFactory $time;
  26. protected MockObject|IJobList $jobList;
  27. protected MockObject|LoggerInterface $logger;
  28. protected MockObject|IManager $statusManager;
  29. protected MockObject|IConfig $config;
  30. private IAvailabilityCoordinator|MockObject $coordinator;
  31. private IUserManager|MockObject $userManager;
  32. protected function setUp(): void {
  33. parent::setUp();
  34. $this->time = $this->createMock(ITimeFactory::class);
  35. $this->jobList = $this->createMock(IJobList::class);
  36. $this->logger = $this->createMock(LoggerInterface::class);
  37. $this->statusManager = $this->createMock(IManager::class);
  38. $this->config = $this->createMock(IConfig::class);
  39. $this->coordinator = $this->createMock(IAvailabilityCoordinator::class);
  40. $this->userManager = $this->createMock(IUserManager::class);
  41. }
  42. protected function getAutomationMock(array $methods): MockObject|UserStatusAutomation {
  43. if (empty($methods)) {
  44. return new UserStatusAutomation(
  45. $this->time,
  46. \OC::$server->getDatabaseConnection(),
  47. $this->jobList,
  48. $this->logger,
  49. $this->statusManager,
  50. $this->config,
  51. $this->coordinator,
  52. $this->userManager,
  53. );
  54. }
  55. return $this->getMockBuilder(UserStatusAutomation::class)
  56. ->setConstructorArgs([
  57. $this->time,
  58. \OC::$server->getDatabaseConnection(),
  59. $this->jobList,
  60. $this->logger,
  61. $this->statusManager,
  62. $this->config,
  63. $this->coordinator,
  64. $this->userManager,
  65. ])
  66. ->setMethods($methods)
  67. ->getMock();
  68. }
  69. public function dataRun(): array {
  70. return [
  71. ['20230217', '2023-02-24 10:49:36.613834', true],
  72. ['20230224', '2023-02-24 10:49:36.613834', true],
  73. ['20230217', '2023-02-24 13:58:24.479357', false],
  74. ['20230224', '2023-02-24 13:58:24.479357', false],
  75. ];
  76. }
  77. /**
  78. * @dataProvider dataRun
  79. */
  80. public function testRunNoOOO(string $ruleDay, string $currentTime, bool $isAvailable): void {
  81. $user = $this->createConfiguredMock(IUser::class, [
  82. 'getUID' => 'user'
  83. ]);
  84. $this->userManager->expects(self::once())
  85. ->method('get')
  86. ->willReturn($user);
  87. $this->coordinator->expects(self::once())
  88. ->method('getCurrentOutOfOfficeData')
  89. ->willReturn(null);
  90. $this->config->method('getUserValue')
  91. ->with('user', 'dav', 'user_status_automation', 'no')
  92. ->willReturn('yes');
  93. $this->time->method('getDateTime')
  94. ->willReturn(new \DateTime($currentTime, new \DateTimeZone('UTC')));
  95. $this->logger->expects(self::exactly(4))
  96. ->method('debug');
  97. $this->statusManager->expects(self::exactly(2))
  98. ->method('revertUserStatus');
  99. if (!$isAvailable) {
  100. $this->statusManager->expects(self::once())
  101. ->method('setUserStatus')
  102. ->with('user', IUserStatus::MESSAGE_AVAILABILITY, IUserStatus::DND, true);
  103. }
  104. $automation = $this->getAutomationMock(['getAvailabilityFromPropertiesTable']);
  105. $automation->method('getAvailabilityFromPropertiesTable')
  106. ->with('user')
  107. ->willReturn('BEGIN:VCALENDAR
  108. PRODID:Nextcloud DAV app
  109. BEGIN:VTIMEZONE
  110. TZID:Europe/Berlin
  111. BEGIN:STANDARD
  112. TZNAME:CET
  113. TZOFFSETFROM:+0200
  114. TZOFFSETTO:+0100
  115. DTSTART:19701025T030000
  116. RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
  117. END:STANDARD
  118. BEGIN:DAYLIGHT
  119. TZNAME:CEST
  120. TZOFFSETFROM:+0100
  121. TZOFFSETTO:+0200
  122. DTSTART:19700329T020000
  123. RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
  124. END:DAYLIGHT
  125. END:VTIMEZONE
  126. BEGIN:VAVAILABILITY
  127. BEGIN:AVAILABLE
  128. DTSTART;TZID=Europe/Berlin:' . $ruleDay . 'T090000
  129. DTEND;TZID=Europe/Berlin:' . $ruleDay . 'T170000
  130. UID:3e6feeec-8e00-4265-b822-b73174e8b39f
  131. RRULE:FREQ=WEEKLY;BYDAY=TH
  132. END:AVAILABLE
  133. BEGIN:AVAILABLE
  134. DTSTART;TZID=Europe/Berlin:' . $ruleDay . 'T090000
  135. DTEND;TZID=Europe/Berlin:' . $ruleDay . 'T120000
  136. UID:8a634e99-07cf-443b-b480-005a0e1db323
  137. RRULE:FREQ=WEEKLY;BYDAY=FR
  138. END:AVAILABLE
  139. END:VAVAILABILITY
  140. END:VCALENDAR');
  141. self::invokePrivate($automation, 'run', [['userId' => 'user']]);
  142. }
  143. public function testRunNoAvailabilityNoOOO(): void {
  144. $user = $this->createConfiguredMock(IUser::class, [
  145. 'getUID' => 'user'
  146. ]);
  147. $this->userManager->expects(self::once())
  148. ->method('get')
  149. ->willReturn($user);
  150. $this->coordinator->expects(self::once())
  151. ->method('getCurrentOutOfOfficeData')
  152. ->willReturn(null);
  153. $this->config->method('getUserValue')
  154. ->with('user', 'dav', 'user_status_automation', 'no')
  155. ->willReturn('yes');
  156. $this->time->method('getDateTime')
  157. ->willReturn(new \DateTime('2023-02-24 13:58:24.479357', new \DateTimeZone('UTC')));
  158. $this->statusManager->expects($this->exactly(3))
  159. ->method('revertUserStatus');
  160. $this->jobList->expects($this->once())
  161. ->method('remove')
  162. ->with(UserStatusAutomation::class, ['userId' => 'user']);
  163. $this->logger->expects(self::once())
  164. ->method('debug');
  165. $this->logger->expects(self::once())
  166. ->method('info');
  167. $automation = $this->getAutomationMock(['getAvailabilityFromPropertiesTable']);
  168. $automation->method('getAvailabilityFromPropertiesTable')
  169. ->with('user')
  170. ->willReturn(false);
  171. self::invokePrivate($automation, 'run', [['userId' => 'user']]);
  172. }
  173. public function testRunNoAvailabilityWithOOO(): void {
  174. $user = $this->createConfiguredMock(IUser::class, [
  175. 'getUID' => 'user'
  176. ]);
  177. $ooo = $this->createConfiguredMock(OutOfOfficeData::class, [
  178. 'getShortMessage' => 'On Vacation',
  179. 'getEndDate' => 123456,
  180. ]);
  181. $this->userManager->expects(self::once())
  182. ->method('get')
  183. ->willReturn($user);
  184. $this->coordinator->expects(self::once())
  185. ->method('getCurrentOutOfOfficeData')
  186. ->willReturn($ooo);
  187. $this->coordinator->expects(self::once())
  188. ->method('isInEffect')
  189. ->willReturn(true);
  190. $this->statusManager->expects($this->exactly(2))
  191. ->method('revertUserStatus');
  192. $this->statusManager->expects(self::once())
  193. ->method('setUserStatus')
  194. ->with('user', IUserStatus::MESSAGE_OUT_OF_OFFICE, IUserStatus::DND, true, $ooo->getShortMessage());
  195. $this->config->expects(self::never())
  196. ->method('getUserValue');
  197. $this->time->method('getDateTime')
  198. ->willReturn(new \DateTime('2023-02-24 13:58:24.479357', new \DateTimeZone('UTC')));
  199. $this->jobList->expects($this->never())
  200. ->method('remove');
  201. $this->logger->expects(self::exactly(2))
  202. ->method('debug');
  203. $automation = $this->getAutomationMock([]);
  204. self::invokePrivate($automation, 'run', [['userId' => 'user']]);
  205. }
  206. }