You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

UserStatusControllerTest.php 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * @copyright Copyright (c) 2020, Georg Ehrke
  5. *
  6. * @author Georg Ehrke <oc.list@georgehrke.com>
  7. *
  8. * @license AGPL-3.0
  9. *
  10. * This code is free software: you can redistribute it and/or modify
  11. * it under the terms of the GNU Affero General Public License, version 3,
  12. * as published by the Free Software Foundation.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU Affero General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Affero General Public License, version 3,
  20. * along with this program. If not, see <http://www.gnu.org/licenses/>
  21. *
  22. */
  23. namespace OCA\UserStatus\Tests\Controller;
  24. use OCA\UserStatus\Controller\UserStatusController;
  25. use OCA\UserStatus\Db\UserStatus;
  26. use OCA\UserStatus\Exception\InvalidClearAtException;
  27. use OCA\UserStatus\Exception\InvalidMessageIdException;
  28. use OCA\UserStatus\Exception\InvalidStatusIconException;
  29. use OCA\UserStatus\Exception\InvalidStatusTypeException;
  30. use OCA\UserStatus\Exception\StatusMessageTooLongException;
  31. use OCA\UserStatus\Service\StatusService;
  32. use OCP\AppFramework\Db\DoesNotExistException;
  33. use OCP\AppFramework\OCS\OCSBadRequestException;
  34. use OCP\AppFramework\OCS\OCSNotFoundException;
  35. use OCP\ILogger;
  36. use OCP\IRequest;
  37. use Test\TestCase;
  38. use Throwable;
  39. class UserStatusControllerTest extends TestCase {
  40. /** @var ILogger|\PHPUnit\Framework\MockObject\MockObject */
  41. private $logger;
  42. /** @var StatusService|\PHPUnit\Framework\MockObject\MockObject */
  43. private $service;
  44. /** @var UserStatusController */
  45. private $controller;
  46. protected function setUp(): void {
  47. parent::setUp();
  48. $request = $this->createMock(IRequest::class);
  49. $userId = 'john.doe';
  50. $this->logger = $this->createMock(ILogger::class);
  51. $this->service = $this->createMock(StatusService::class);
  52. $this->controller = new UserStatusController('user_status', $request, $userId, $this->logger, $this->service);
  53. }
  54. public function testGetStatus(): void {
  55. $userStatus = $this->getUserStatus();
  56. $this->service->expects($this->once())
  57. ->method('findByUserId')
  58. ->with('john.doe')
  59. ->willReturn($userStatus);
  60. $response = $this->controller->getStatus();
  61. $this->assertEquals([
  62. 'userId' => 'john.doe',
  63. 'status' => 'invisible',
  64. 'icon' => '🏝',
  65. 'message' => 'On vacation',
  66. 'clearAt' => 60000,
  67. 'statusIsUserDefined' => true,
  68. 'messageIsPredefined' => false,
  69. 'messageId' => null,
  70. ], $response->getData());
  71. }
  72. public function testGetStatusDoesNotExist(): void {
  73. $this->service->expects($this->once())
  74. ->method('findByUserId')
  75. ->with('john.doe')
  76. ->willThrowException(new DoesNotExistException(''));
  77. $this->expectException(OCSNotFoundException::class);
  78. $this->expectExceptionMessage('No status for the current user');
  79. $this->controller->getStatus();
  80. }
  81. /**
  82. * @param string $statusType
  83. * @param string|null $statusIcon
  84. * @param string|null $message
  85. * @param int|null $clearAt
  86. * @param bool $expectSuccess
  87. * @param bool $expectException
  88. * @param Throwable|null $exception
  89. * @param bool $expectLogger
  90. * @param string|null $expectedLogMessage
  91. *
  92. * @dataProvider setStatusDataProvider
  93. */
  94. public function testSetStatus(string $statusType,
  95. ?string $statusIcon,
  96. ?string $message,
  97. ?int $clearAt,
  98. bool $expectSuccess,
  99. bool $expectException,
  100. ?Throwable $exception,
  101. bool $expectLogger,
  102. ?string $expectedLogMessage): void {
  103. $userStatus = $this->getUserStatus();
  104. if ($expectException) {
  105. $this->service->expects($this->once())
  106. ->method('setStatus')
  107. ->with('john.doe', $statusType, null, true)
  108. ->willThrowException($exception);
  109. } else {
  110. $this->service->expects($this->once())
  111. ->method('setStatus')
  112. ->with('john.doe', $statusType, null, true)
  113. ->willReturn($userStatus);
  114. }
  115. if ($expectLogger) {
  116. $this->logger->expects($this->once())
  117. ->method('debug')
  118. ->with($expectedLogMessage);
  119. }
  120. if ($expectException) {
  121. $this->expectException(OCSBadRequestException::class);
  122. $this->expectExceptionMessage('Original exception message');
  123. }
  124. $response = $this->controller->setStatus($statusType);
  125. if ($expectSuccess) {
  126. $this->assertEquals([
  127. 'userId' => 'john.doe',
  128. 'status' => 'invisible',
  129. 'icon' => '🏝',
  130. 'message' => 'On vacation',
  131. 'clearAt' => 60000,
  132. 'statusIsUserDefined' => true,
  133. 'messageIsPredefined' => false,
  134. 'messageId' => null,
  135. ], $response->getData());
  136. }
  137. }
  138. public function setStatusDataProvider(): array {
  139. return [
  140. ['busy', '👨🏽‍💻', 'Busy developing the status feature', 500, true, false, null, false, null],
  141. ['busy', '👨🏽‍💻', 'Busy developing the status feature', 500, false, true, new InvalidStatusTypeException('Original exception message'), true,
  142. 'New user-status for "john.doe" was rejected due to an invalid status type "busy"'],
  143. ];
  144. }
  145. /**
  146. * @param string $messageId
  147. * @param int|null $clearAt
  148. * @param bool $expectSuccess
  149. * @param bool $expectException
  150. * @param Throwable|null $exception
  151. * @param bool $expectLogger
  152. * @param string|null $expectedLogMessage
  153. *
  154. * @dataProvider setPredefinedMessageDataProvider
  155. */
  156. public function testSetPredefinedMessage(string $messageId,
  157. ?int $clearAt,
  158. bool $expectSuccess,
  159. bool $expectException,
  160. ?Throwable $exception,
  161. bool $expectLogger,
  162. ?string $expectedLogMessage): void {
  163. $userStatus = $this->getUserStatus();
  164. if ($expectException) {
  165. $this->service->expects($this->once())
  166. ->method('setPredefinedMessage')
  167. ->with('john.doe', $messageId, $clearAt)
  168. ->willThrowException($exception);
  169. } else {
  170. $this->service->expects($this->once())
  171. ->method('setPredefinedMessage')
  172. ->with('john.doe', $messageId, $clearAt)
  173. ->willReturn($userStatus);
  174. }
  175. if ($expectLogger) {
  176. $this->logger->expects($this->once())
  177. ->method('debug')
  178. ->with($expectedLogMessage);
  179. }
  180. if ($expectException) {
  181. $this->expectException(OCSBadRequestException::class);
  182. $this->expectExceptionMessage('Original exception message');
  183. }
  184. $response = $this->controller->setPredefinedMessage($messageId, $clearAt);
  185. if ($expectSuccess) {
  186. $this->assertEquals([
  187. 'userId' => 'john.doe',
  188. 'status' => 'invisible',
  189. 'icon' => '🏝',
  190. 'message' => 'On vacation',
  191. 'clearAt' => 60000,
  192. 'statusIsUserDefined' => true,
  193. 'messageIsPredefined' => false,
  194. 'messageId' => null,
  195. ], $response->getData());
  196. }
  197. }
  198. public function setPredefinedMessageDataProvider(): array {
  199. return [
  200. ['messageId-42', 500, true, false, null, false, null],
  201. ['messageId-42', 500, false, true, new InvalidClearAtException('Original exception message'), true,
  202. 'New user-status for "john.doe" was rejected due to an invalid clearAt value "500"'],
  203. ['messageId-42', 500, false, true, new InvalidMessageIdException('Original exception message'), true,
  204. 'New user-status for "john.doe" was rejected due to an invalid message-id "messageId-42"'],
  205. ];
  206. }
  207. /**
  208. * @param string|null $statusIcon
  209. * @param string $message
  210. * @param int|null $clearAt
  211. * @param bool $expectSuccess
  212. * @param bool $expectException
  213. * @param Throwable|null $exception
  214. * @param bool $expectLogger
  215. * @param string|null $expectedLogMessage
  216. *
  217. * @dataProvider setCustomMessageDataProvider
  218. */
  219. public function testSetCustomMessage(?string $statusIcon,
  220. string $message,
  221. ?int $clearAt,
  222. bool $expectSuccess,
  223. bool $expectException,
  224. ?Throwable $exception,
  225. bool $expectLogger,
  226. ?string $expectedLogMessage): void {
  227. $userStatus = $this->getUserStatus();
  228. if ($expectException) {
  229. $this->service->expects($this->once())
  230. ->method('setCustomMessage')
  231. ->with('john.doe', $statusIcon, $message, $clearAt)
  232. ->willThrowException($exception);
  233. } else {
  234. $this->service->expects($this->once())
  235. ->method('setCustomMessage')
  236. ->with('john.doe', $statusIcon, $message, $clearAt)
  237. ->willReturn($userStatus);
  238. }
  239. if ($expectLogger) {
  240. $this->logger->expects($this->once())
  241. ->method('debug')
  242. ->with($expectedLogMessage);
  243. }
  244. if ($expectException) {
  245. $this->expectException(OCSBadRequestException::class);
  246. $this->expectExceptionMessage('Original exception message');
  247. }
  248. $response = $this->controller->setCustomMessage($statusIcon, $message, $clearAt);
  249. if ($expectSuccess) {
  250. $this->assertEquals([
  251. 'userId' => 'john.doe',
  252. 'status' => 'invisible',
  253. 'icon' => '🏝',
  254. 'message' => 'On vacation',
  255. 'clearAt' => 60000,
  256. 'statusIsUserDefined' => true,
  257. 'messageIsPredefined' => false,
  258. 'messageId' => null,
  259. ], $response->getData());
  260. }
  261. }
  262. public function setCustomMessageDataProvider(): array {
  263. return [
  264. ['👨🏽‍💻', 'Busy developing the status feature', 500, true, false, null, false, null],
  265. ['👨🏽‍💻', 'Busy developing the status feature', 500, false, true, new InvalidClearAtException('Original exception message'), true,
  266. 'New user-status for "john.doe" was rejected due to an invalid clearAt value "500"'],
  267. ['👨🏽‍💻', 'Busy developing the status feature', 500, false, true, new InvalidStatusIconException('Original exception message'), true,
  268. 'New user-status for "john.doe" was rejected due to an invalid icon value "👨🏽‍💻"'],
  269. ['👨🏽‍💻', 'Busy developing the status feature', 500, false, true, new StatusMessageTooLongException('Original exception message'), true,
  270. 'New user-status for "john.doe" was rejected due to a too long status message.'],
  271. ];
  272. }
  273. public function testClearStatus(): void {
  274. $this->service->expects($this->once())
  275. ->method('clearStatus')
  276. ->with('john.doe');
  277. $response = $this->controller->clearStatus();
  278. $this->assertEquals([], $response->getData());
  279. }
  280. public function testClearMessage(): void {
  281. $this->service->expects($this->once())
  282. ->method('clearMessage')
  283. ->with('john.doe');
  284. $response = $this->controller->clearMessage();
  285. $this->assertEquals([], $response->getData());
  286. }
  287. private function getUserStatus(): UserStatus {
  288. $userStatus = new UserStatus();
  289. $userStatus->setId(1337);
  290. $userStatus->setUserId('john.doe');
  291. $userStatus->setStatus('invisible');
  292. $userStatus->setStatusTimestamp(5000);
  293. $userStatus->setIsUserDefined(true);
  294. $userStatus->setCustomIcon('🏝');
  295. $userStatus->setCustomMessage('On vacation');
  296. $userStatus->setClearAt(60000);
  297. return $userStatus;
  298. }
  299. }