UserStatusAutomationTest.php 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * @copyright Copyright (c) 2023 Joas Schilling <coding@schilljs.com>
  5. *
  6. * @author Joas Schilling <coding@schilljs.com>
  7. *
  8. * @license GNU AGPL version 3 or any later version
  9. *
  10. * This program is free software: you can redistribute it and/or modify
  11. * it under the terms of the GNU Affero General Public License as
  12. * published by the Free Software Foundation, either version 3 of the
  13. * License, or (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU Affero General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Affero General Public License
  21. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  22. *
  23. */
  24. namespace OCA\DAV\Tests\unit\BackgroundJob;
  25. use OC\User\OutOfOfficeData;
  26. use OCA\DAV\BackgroundJob\UserStatusAutomation;
  27. use OCP\AppFramework\Utility\ITimeFactory;
  28. use OCP\BackgroundJob\IJobList;
  29. use OCP\IConfig;
  30. use OCP\IUser;
  31. use OCP\IUserManager;
  32. use OCP\User\IAvailabilityCoordinator;
  33. use OCP\UserStatus\IManager;
  34. use OCP\UserStatus\IUserStatus;
  35. use PHPUnit\Framework\MockObject\MockObject;
  36. use Psr\Log\LoggerInterface;
  37. use Test\TestCase;
  38. /**
  39. * @group DB
  40. */
  41. class UserStatusAutomationTest extends TestCase {
  42. protected MockObject|ITimeFactory $time;
  43. protected MockObject|IJobList $jobList;
  44. protected MockObject|LoggerInterface $logger;
  45. protected MockObject|IManager $statusManager;
  46. protected MockObject|IConfig $config;
  47. private IAvailabilityCoordinator|MockObject $coordinator;
  48. private IUserManager|MockObject $userManager;
  49. protected function setUp(): void {
  50. parent::setUp();
  51. $this->time = $this->createMock(ITimeFactory::class);
  52. $this->jobList = $this->createMock(IJobList::class);
  53. $this->logger = $this->createMock(LoggerInterface::class);
  54. $this->statusManager = $this->createMock(IManager::class);
  55. $this->config = $this->createMock(IConfig::class);
  56. $this->coordinator = $this->createMock(IAvailabilityCoordinator::class);
  57. $this->userManager = $this->createMock(IUserManager::class);
  58. }
  59. protected function getAutomationMock(array $methods): MockObject|UserStatusAutomation {
  60. if (empty($methods)) {
  61. return new UserStatusAutomation(
  62. $this->time,
  63. \OC::$server->getDatabaseConnection(),
  64. $this->jobList,
  65. $this->logger,
  66. $this->statusManager,
  67. $this->config,
  68. $this->coordinator,
  69. $this->userManager,
  70. );
  71. }
  72. return $this->getMockBuilder(UserStatusAutomation::class)
  73. ->setConstructorArgs([
  74. $this->time,
  75. \OC::$server->getDatabaseConnection(),
  76. $this->jobList,
  77. $this->logger,
  78. $this->statusManager,
  79. $this->config,
  80. $this->coordinator,
  81. $this->userManager,
  82. ])
  83. ->setMethods($methods)
  84. ->getMock();
  85. }
  86. public function dataRun(): array {
  87. return [
  88. ['20230217', '2023-02-24 10:49:36.613834', true],
  89. ['20230224', '2023-02-24 10:49:36.613834', true],
  90. ['20230217', '2023-02-24 13:58:24.479357', false],
  91. ['20230224', '2023-02-24 13:58:24.479357', false],
  92. ];
  93. }
  94. /**
  95. * @dataProvider dataRun
  96. */
  97. public function testRunNoOOO(string $ruleDay, string $currentTime, bool $isAvailable): void {
  98. $user = $this->createConfiguredMock(IUser::class, [
  99. 'getUID' => 'user'
  100. ]);
  101. $this->userManager->expects(self::once())
  102. ->method('get')
  103. ->willReturn($user);
  104. $this->coordinator->expects(self::once())
  105. ->method('getCurrentOutOfOfficeData')
  106. ->willReturn(null);
  107. $this->config->method('getUserValue')
  108. ->with('user', 'dav', 'user_status_automation', 'no')
  109. ->willReturn('yes');
  110. $this->time->method('getDateTime')
  111. ->willReturn(new \DateTime($currentTime, new \DateTimeZone('UTC')));
  112. $this->logger->expects(self::exactly(4))
  113. ->method('debug');
  114. $this->statusManager->expects(self::exactly(2))
  115. ->method('revertUserStatus');
  116. if (!$isAvailable) {
  117. $this->statusManager->expects(self::once())
  118. ->method('setUserStatus')
  119. ->with('user', IUserStatus::MESSAGE_AVAILABILITY, IUserStatus::DND, true);
  120. }
  121. $automation = $this->getAutomationMock(['getAvailabilityFromPropertiesTable']);
  122. $automation->method('getAvailabilityFromPropertiesTable')
  123. ->with('user')
  124. ->willReturn('BEGIN:VCALENDAR
  125. PRODID:Nextcloud DAV app
  126. BEGIN:VTIMEZONE
  127. TZID:Europe/Berlin
  128. BEGIN:STANDARD
  129. TZNAME:CET
  130. TZOFFSETFROM:+0200
  131. TZOFFSETTO:+0100
  132. DTSTART:19701025T030000
  133. RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
  134. END:STANDARD
  135. BEGIN:DAYLIGHT
  136. TZNAME:CEST
  137. TZOFFSETFROM:+0100
  138. TZOFFSETTO:+0200
  139. DTSTART:19700329T020000
  140. RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
  141. END:DAYLIGHT
  142. END:VTIMEZONE
  143. BEGIN:VAVAILABILITY
  144. BEGIN:AVAILABLE
  145. DTSTART;TZID=Europe/Berlin:' . $ruleDay . 'T090000
  146. DTEND;TZID=Europe/Berlin:' . $ruleDay . 'T170000
  147. UID:3e6feeec-8e00-4265-b822-b73174e8b39f
  148. RRULE:FREQ=WEEKLY;BYDAY=TH
  149. END:AVAILABLE
  150. BEGIN:AVAILABLE
  151. DTSTART;TZID=Europe/Berlin:' . $ruleDay . 'T090000
  152. DTEND;TZID=Europe/Berlin:' . $ruleDay . 'T120000
  153. UID:8a634e99-07cf-443b-b480-005a0e1db323
  154. RRULE:FREQ=WEEKLY;BYDAY=FR
  155. END:AVAILABLE
  156. END:VAVAILABILITY
  157. END:VCALENDAR');
  158. self::invokePrivate($automation, 'run', [['userId' => 'user']]);
  159. }
  160. public function testRunNoAvailabilityNoOOO(): void {
  161. $user = $this->createConfiguredMock(IUser::class, [
  162. 'getUID' => 'user'
  163. ]);
  164. $this->userManager->expects(self::once())
  165. ->method('get')
  166. ->willReturn($user);
  167. $this->coordinator->expects(self::once())
  168. ->method('getCurrentOutOfOfficeData')
  169. ->willReturn(null);
  170. $this->config->method('getUserValue')
  171. ->with('user', 'dav', 'user_status_automation', 'no')
  172. ->willReturn('yes');
  173. $this->time->method('getDateTime')
  174. ->willReturn(new \DateTime('2023-02-24 13:58:24.479357', new \DateTimeZone('UTC')));
  175. $this->statusManager->expects($this->exactly(3))
  176. ->method('revertUserStatus');
  177. $this->jobList->expects($this->once())
  178. ->method('remove')
  179. ->with(UserStatusAutomation::class, ['userId' => 'user']);
  180. $this->logger->expects(self::once())
  181. ->method('debug');
  182. $this->logger->expects(self::once())
  183. ->method('info');
  184. $automation = $this->getAutomationMock(['getAvailabilityFromPropertiesTable']);
  185. $automation->method('getAvailabilityFromPropertiesTable')
  186. ->with('user')
  187. ->willReturn(false);
  188. self::invokePrivate($automation, 'run', [['userId' => 'user']]);
  189. }
  190. public function testRunNoAvailabilityWithOOO(): void {
  191. $user = $this->createConfiguredMock(IUser::class, [
  192. 'getUID' => 'user'
  193. ]);
  194. $ooo = $this->createConfiguredMock(OutOfOfficeData::class, [
  195. 'getShortMessage' => 'On Vacation',
  196. 'getEndDate' => 123456,
  197. ]);
  198. $this->userManager->expects(self::once())
  199. ->method('get')
  200. ->willReturn($user);
  201. $this->coordinator->expects(self::once())
  202. ->method('getCurrentOutOfOfficeData')
  203. ->willReturn($ooo);
  204. $this->coordinator->expects(self::once())
  205. ->method('isInEffect')
  206. ->willReturn(true);
  207. $this->statusManager->expects($this->exactly(2))
  208. ->method('revertUserStatus');
  209. $this->statusManager->expects(self::once())
  210. ->method('setUserStatus')
  211. ->with('user', IUserStatus::MESSAGE_OUT_OF_OFFICE, IUserStatus::DND, true, $ooo->getShortMessage());
  212. $this->config->expects(self::never())
  213. ->method('getUserValue');
  214. $this->time->method('getDateTime')
  215. ->willReturn(new \DateTime('2023-02-24 13:58:24.479357', new \DateTimeZone('UTC')));
  216. $this->jobList->expects($this->never())
  217. ->method('remove');
  218. $this->logger->expects(self::exactly(2))
  219. ->method('debug');
  220. $automation = $this->getAutomationMock([]);
  221. self::invokePrivate($automation, 'run', [['userId' => 'user']]);
  222. }
  223. }