UserStatusAutomationTest.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  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. if (!$isAvailable) {
  98. $this->statusManager->expects(self::once())
  99. ->method('setUserStatus')
  100. ->with('user', IUserStatus::MESSAGE_AVAILABILITY, IUserStatus::DND, true);
  101. }
  102. $automation = $this->getAutomationMock(['getAvailabilityFromPropertiesTable']);
  103. $automation->method('getAvailabilityFromPropertiesTable')
  104. ->with('user')
  105. ->willReturn('BEGIN:VCALENDAR
  106. PRODID:Nextcloud DAV app
  107. BEGIN:VTIMEZONE
  108. TZID:Europe/Berlin
  109. BEGIN:STANDARD
  110. TZNAME:CET
  111. TZOFFSETFROM:+0200
  112. TZOFFSETTO:+0100
  113. DTSTART:19701025T030000
  114. RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
  115. END:STANDARD
  116. BEGIN:DAYLIGHT
  117. TZNAME:CEST
  118. TZOFFSETFROM:+0100
  119. TZOFFSETTO:+0200
  120. DTSTART:19700329T020000
  121. RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
  122. END:DAYLIGHT
  123. END:VTIMEZONE
  124. BEGIN:VAVAILABILITY
  125. BEGIN:AVAILABLE
  126. DTSTART;TZID=Europe/Berlin:' . $ruleDay . 'T090000
  127. DTEND;TZID=Europe/Berlin:' . $ruleDay . 'T170000
  128. UID:3e6feeec-8e00-4265-b822-b73174e8b39f
  129. RRULE:FREQ=WEEKLY;BYDAY=TH
  130. END:AVAILABLE
  131. BEGIN:AVAILABLE
  132. DTSTART;TZID=Europe/Berlin:' . $ruleDay . 'T090000
  133. DTEND;TZID=Europe/Berlin:' . $ruleDay . 'T120000
  134. UID:8a634e99-07cf-443b-b480-005a0e1db323
  135. RRULE:FREQ=WEEKLY;BYDAY=FR
  136. END:AVAILABLE
  137. END:VAVAILABILITY
  138. END:VCALENDAR');
  139. self::invokePrivate($automation, 'run', [['userId' => 'user']]);
  140. }
  141. public function testRunNoAvailabilityNoOOO(): void {
  142. $user = $this->createConfiguredMock(IUser::class, [
  143. 'getUID' => 'user'
  144. ]);
  145. $this->userManager->expects(self::once())
  146. ->method('get')
  147. ->willReturn($user);
  148. $this->coordinator->expects(self::once())
  149. ->method('getCurrentOutOfOfficeData')
  150. ->willReturn(null);
  151. $this->config->method('getUserValue')
  152. ->with('user', 'dav', 'user_status_automation', 'no')
  153. ->willReturn('yes');
  154. $this->time->method('getDateTime')
  155. ->willReturn(new \DateTime('2023-02-24 13:58:24.479357', new \DateTimeZone('UTC')));
  156. $this->jobList->expects($this->once())
  157. ->method('remove')
  158. ->with(UserStatusAutomation::class, ['userId' => 'user']);
  159. $this->logger->expects(self::once())
  160. ->method('debug');
  161. $this->logger->expects(self::once())
  162. ->method('info');
  163. $automation = $this->getAutomationMock(['getAvailabilityFromPropertiesTable']);
  164. $automation->method('getAvailabilityFromPropertiesTable')
  165. ->with('user')
  166. ->willReturn(false);
  167. self::invokePrivate($automation, 'run', [['userId' => 'user']]);
  168. }
  169. public function testRunNoAvailabilityWithOOO(): void {
  170. $user = $this->createConfiguredMock(IUser::class, [
  171. 'getUID' => 'user'
  172. ]);
  173. $ooo = $this->createConfiguredMock(OutOfOfficeData::class, [
  174. 'getShortMessage' => 'On Vacation',
  175. 'getEndDate' => 123456,
  176. ]);
  177. $this->userManager->expects(self::once())
  178. ->method('get')
  179. ->willReturn($user);
  180. $this->coordinator->expects(self::once())
  181. ->method('getCurrentOutOfOfficeData')
  182. ->willReturn($ooo);
  183. $this->coordinator->expects(self::once())
  184. ->method('isInEffect')
  185. ->willReturn(true);
  186. $this->statusManager->expects(self::once())
  187. ->method('setUserStatus')
  188. ->with('user', IUserStatus::MESSAGE_OUT_OF_OFFICE, IUserStatus::DND, true, $ooo->getShortMessage());
  189. $this->config->expects(self::never())
  190. ->method('getUserValue');
  191. $this->time->method('getDateTime')
  192. ->willReturn(new \DateTime('2023-02-24 13:58:24.479357', new \DateTimeZone('UTC')));
  193. $this->jobList->expects($this->never())
  194. ->method('remove');
  195. $this->logger->expects(self::exactly(2))
  196. ->method('debug');
  197. $automation = $this->getAutomationMock([]);
  198. self::invokePrivate($automation, 'run', [['userId' => 'user']]);
  199. }
  200. }