GroupsControllerTest.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016, ownCloud, Inc.
  4. *
  5. * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
  6. * @author Christoph Wurst <christoph@winzerhof-wurst.at>
  7. * @author Joas Schilling <coding@schilljs.com>
  8. * @author John Molakvoæ <skjnldsv@protonmail.com>
  9. * @author Julius Härtl <jus@bitgrid.net>
  10. * @author Lukas Reschke <lukas@statuscode.ch>
  11. * @author Morris Jobke <hey@morrisjobke.de>
  12. * @author Roeland Jago Douma <roeland@famdouma.nl>
  13. * @author Tom Needham <tom@owncloud.com>
  14. *
  15. * @license AGPL-3.0
  16. *
  17. * This code is free software: you can redistribute it and/or modify
  18. * it under the terms of the GNU Affero General Public License, version 3,
  19. * as published by the Free Software Foundation.
  20. *
  21. * This program is distributed in the hope that it will be useful,
  22. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  23. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  24. * GNU Affero General Public License for more details.
  25. *
  26. * You should have received a copy of the GNU Affero General Public License, version 3,
  27. * along with this program. If not, see <http://www.gnu.org/licenses/>
  28. *
  29. */
  30. namespace OCA\Provisioning_API\Tests\Controller;
  31. use OC\Group\Manager;
  32. use OC\SubAdmin;
  33. use OC\User\NoUserException;
  34. use OCA\Provisioning_API\Controller\GroupsController;
  35. use OCP\Accounts\IAccountManager;
  36. use OCP\IConfig;
  37. use OCP\IRequest;
  38. use OCP\IUser;
  39. use OCP\IUserManager;
  40. use OCP\IUserSession;
  41. use OCP\L10N\IFactory;
  42. use OCP\UserInterface;
  43. use Psr\Log\LoggerInterface;
  44. class GroupsControllerTest extends \Test\TestCase {
  45. /** @var IRequest|\PHPUnit\Framework\MockObject\MockObject */
  46. protected $request;
  47. /** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */
  48. protected $userManager;
  49. /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
  50. protected $config;
  51. /** @var Manager|\PHPUnit\Framework\MockObject\MockObject */
  52. protected $groupManager;
  53. /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */
  54. protected $userSession;
  55. /** @var IAccountManager|\PHPUnit\Framework\MockObject\MockObject */
  56. protected $accountManager;
  57. /** @var IFactory|\PHPUnit\Framework\MockObject\MockObject */
  58. protected $l10nFactory;
  59. /** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */
  60. protected $logger;
  61. /** @var SubAdmin|\PHPUnit\Framework\MockObject\MockObject */
  62. protected $subAdminManager;
  63. /** @var GroupsController|\PHPUnit\Framework\MockObject\MockObject */
  64. protected $api;
  65. protected function setUp(): void {
  66. parent::setUp();
  67. $this->request = $this->createMock(IRequest::class);
  68. $this->userManager = $this->createMock(IUserManager::class);
  69. $this->config = $this->createMock(IConfig::class);
  70. $this->groupManager = $this->createMock(Manager::class);
  71. $this->userSession = $this->createMock(IUserSession::class);
  72. $this->accountManager = $this->createMock(IAccountManager::class);
  73. $this->l10nFactory = $this->createMock(IFactory::class);
  74. $this->logger = $this->createMock(LoggerInterface::class);
  75. $this->subAdminManager = $this->createMock(SubAdmin::class);
  76. $this->groupManager
  77. ->method('getSubAdmin')
  78. ->willReturn($this->subAdminManager);
  79. $this->api = $this->getMockBuilder(GroupsController::class)
  80. ->setConstructorArgs([
  81. 'provisioning_api',
  82. $this->request,
  83. $this->userManager,
  84. $this->config,
  85. $this->groupManager,
  86. $this->userSession,
  87. $this->accountManager,
  88. $this->l10nFactory,
  89. $this->logger
  90. ])
  91. ->setMethods(['fillStorageInfo'])
  92. ->getMock();
  93. }
  94. /**
  95. * @param string $gid
  96. * @return \OCP\IGroup|\PHPUnit\Framework\MockObject\MockObject
  97. */
  98. private function createGroup($gid) {
  99. $group = $this->getMockBuilder('\OCP\IGroup')->disableOriginalConstructor()->getMock();
  100. $group
  101. ->method('getGID')
  102. ->willReturn($gid);
  103. $group
  104. ->method('getDisplayName')
  105. ->willReturn($gid.'-name');
  106. $group
  107. ->method('count')
  108. ->willReturn(123);
  109. $group
  110. ->method('countDisabled')
  111. ->willReturn(11);
  112. $group
  113. ->method('canAddUser')
  114. ->willReturn(true);
  115. $group
  116. ->method('canRemoveUser')
  117. ->willReturn(true);
  118. return $group;
  119. }
  120. /**
  121. * @param string $uid
  122. * @return \OCP\IUser|\PHPUnit\Framework\MockObject\MockObject
  123. */
  124. private function createUser($uid) {
  125. $user = $this->getMockBuilder(IUser::class)->disableOriginalConstructor()->getMock();
  126. $user
  127. ->method('getUID')
  128. ->willReturn($uid);
  129. $backendMock = $this->createMock(UserInterface::class);
  130. $user
  131. ->method('getBackend')
  132. ->willReturn($backendMock);
  133. return $user;
  134. }
  135. private function asUser() {
  136. $user = $this->createUser('user');
  137. $this->userSession
  138. ->method('getUser')
  139. ->willReturn($user);
  140. }
  141. private function asAdmin() {
  142. $user = $this->createUser('admin');
  143. $this->userSession
  144. ->method('getUser')
  145. ->willReturn($user);
  146. $this->groupManager
  147. ->method('isAdmin')
  148. ->with('admin')
  149. ->willReturn(true);
  150. }
  151. private function asSubAdminOfGroup($group) {
  152. $user = $this->createUser('subAdmin');
  153. $this->userSession
  154. ->method('getUser')
  155. ->willReturn($user);
  156. $this->subAdminManager
  157. ->method('isSubAdminOfGroup')
  158. ->willReturnCallback(function ($_user, $_group) use ($user, $group) {
  159. if ($_user === $user && $_group === $group) {
  160. return true;
  161. }
  162. return false;
  163. });
  164. }
  165. public function dataGetGroups() {
  166. return [
  167. [null, 0, 0],
  168. ['foo', 0, 0],
  169. [null, 1, 0],
  170. [null, 0, 2],
  171. ['foo', 1, 2],
  172. ];
  173. }
  174. /**
  175. * @dataProvider dataGetGroups
  176. *
  177. * @param string|null $search
  178. * @param int|null $limit
  179. * @param int|null $offset
  180. */
  181. public function testGetGroups($search, $limit, $offset) {
  182. $groups = [$this->createGroup('group1'), $this->createGroup('group2')];
  183. $search = $search === null ? '' : $search;
  184. $this->groupManager
  185. ->expects($this->once())
  186. ->method('search')
  187. ->with($search, $limit, $offset)
  188. ->willReturn($groups);
  189. $result = $this->api->getGroups($search, $limit, $offset);
  190. $this->assertEquals(['groups' => ['group1', 'group2']], $result->getData());
  191. }
  192. /**
  193. * @dataProvider dataGetGroups
  194. *
  195. * @param string|null $search
  196. * @param int|null $limit
  197. * @param int|null $offset
  198. */
  199. public function testGetGroupsDetails($search, $limit, $offset) {
  200. $groups = [$this->createGroup('group1'), $this->createGroup('group2')];
  201. $search = $search === null ? '' : $search;
  202. $this->groupManager
  203. ->expects($this->once())
  204. ->method('search')
  205. ->with($search, $limit, $offset)
  206. ->willReturn($groups);
  207. $result = $this->api->getGroupsDetails($search, $limit, $offset);
  208. $this->assertEquals(['groups' => [
  209. [
  210. 'id' => 'group1',
  211. 'displayname' => 'group1-name',
  212. 'usercount' => 123,
  213. 'disabled' => 11,
  214. 'canAdd' => true,
  215. 'canRemove' => true
  216. ],
  217. [
  218. 'id' => 'group2',
  219. 'displayname' => 'group2-name',
  220. 'usercount' => 123,
  221. 'disabled' => 11,
  222. 'canAdd' => true,
  223. 'canRemove' => true
  224. ]
  225. ]], $result->getData());
  226. }
  227. public function testGetGroupAsSubadmin() {
  228. $group = $this->createGroup('group');
  229. $this->asSubAdminOfGroup($group);
  230. $this->groupManager
  231. ->method('get')
  232. ->with('group')
  233. ->willReturn($group);
  234. $this->groupManager
  235. ->method('groupExists')
  236. ->with('group')
  237. ->willReturn(true);
  238. $group
  239. ->method('getUsers')
  240. ->willReturn([
  241. $this->createUser('user1'),
  242. $this->createUser('user2')
  243. ]);
  244. $result = $this->api->getGroup('group');
  245. $this->assertEquals(['users' => ['user1', 'user2']], $result->getData());
  246. }
  247. public function testGetGroupAsIrrelevantSubadmin() {
  248. $this->expectException(\OCP\AppFramework\OCS\OCSException::class);
  249. $this->expectExceptionCode(403);
  250. $group = $this->createGroup('group');
  251. $otherGroup = $this->createGroup('otherGroup');
  252. $this->asSubAdminOfGroup($otherGroup);
  253. $this->groupManager
  254. ->method('get')
  255. ->with('group')
  256. ->willReturn($group);
  257. $this->groupManager
  258. ->method('groupExists')
  259. ->with('group')
  260. ->willReturn(true);
  261. $this->api->getGroup('group');
  262. }
  263. public function testGetGroupAsAdmin() {
  264. $group = $this->createGroup('group');
  265. $this->asAdmin();
  266. $this->groupManager
  267. ->method('get')
  268. ->with('group')
  269. ->willReturn($group);
  270. $this->groupManager
  271. ->method('groupExists')
  272. ->with('group')
  273. ->willReturn(true);
  274. $group
  275. ->method('getUsers')
  276. ->willReturn([
  277. $this->createUser('user1'),
  278. $this->createUser('user2')
  279. ]);
  280. $result = $this->api->getGroup('group');
  281. $this->assertEquals(['users' => ['user1', 'user2']], $result->getData());
  282. }
  283. public function testGetGroupNonExisting() {
  284. $this->expectException(\OCP\AppFramework\OCS\OCSException::class);
  285. $this->expectExceptionMessage('The requested group could not be found');
  286. $this->expectExceptionCode(404);
  287. $this->asUser();
  288. $this->api->getGroup($this->getUniqueID());
  289. }
  290. public function testGetSubAdminsOfGroupsNotExists() {
  291. $this->expectException(\OCP\AppFramework\OCS\OCSException::class);
  292. $this->expectExceptionMessage('Group does not exist');
  293. $this->expectExceptionCode(101);
  294. $this->api->getSubAdminsOfGroup('NonExistingGroup');
  295. }
  296. public function testGetSubAdminsOfGroup() {
  297. $group = $this->createGroup('GroupWithSubAdmins');
  298. $this->groupManager
  299. ->method('get')
  300. ->with('GroupWithSubAdmins')
  301. ->willReturn($group);
  302. $this->subAdminManager
  303. ->expects($this->once())
  304. ->method('getGroupsSubAdmins')
  305. ->with($group)
  306. ->willReturn([
  307. $this->createUser('SubAdmin1'),
  308. $this->createUser('SubAdmin2'),
  309. ]);
  310. $result = $this->api->getSubAdminsOfGroup('GroupWithSubAdmins');
  311. $this->assertEquals(['SubAdmin1', 'SubAdmin2'], $result->getData());
  312. }
  313. public function testGetSubAdminsOfGroupEmptyList() {
  314. $group = $this->createGroup('GroupWithOutSubAdmins');
  315. $this->groupManager
  316. ->method('get')
  317. ->with('GroupWithOutSubAdmins')
  318. ->willReturn($group);
  319. $this->subAdminManager
  320. ->expects($this->once())
  321. ->method('getGroupsSubAdmins')
  322. ->with($group)
  323. ->willReturn([
  324. ]);
  325. $result = $this->api->getSubAdminsOfGroup('GroupWithOutSubAdmins');
  326. $this->assertEquals([], $result->getData());
  327. }
  328. public function testAddGroupEmptyGroup() {
  329. $this->expectException(\OCP\AppFramework\OCS\OCSException::class);
  330. $this->expectExceptionMessage('Invalid group name');
  331. $this->expectExceptionCode(101);
  332. $this->api->addGroup('');
  333. }
  334. public function testAddGroupExistingGroup() {
  335. $this->expectException(\OCP\AppFramework\OCS\OCSException::class);
  336. $this->expectExceptionCode(102);
  337. $this->groupManager
  338. ->method('groupExists')
  339. ->with('ExistingGroup')
  340. ->willReturn(true);
  341. $this->api->addGroup('ExistingGroup');
  342. }
  343. public function testAddGroup() {
  344. $this->groupManager
  345. ->method('groupExists')
  346. ->with('NewGroup')
  347. ->willReturn(false);
  348. $group = $this->createGroup('NewGroup');
  349. $this->groupManager
  350. ->expects($this->once())
  351. ->method('createGroup')
  352. ->with('NewGroup')
  353. ->willReturn($group);
  354. $this->api->addGroup('NewGroup');
  355. }
  356. public function testAddGroupWithSpecialChar() {
  357. $this->groupManager
  358. ->method('groupExists')
  359. ->with('Iñtërnâtiônàlizætiøn')
  360. ->willReturn(false);
  361. $group = $this->createGroup('Iñtërnâtiônàlizætiøn');
  362. $this->groupManager
  363. ->expects($this->once())
  364. ->method('createGroup')
  365. ->with('Iñtërnâtiônàlizætiøn')
  366. ->willReturn($group);
  367. $this->api->addGroup('Iñtërnâtiônàlizætiøn');
  368. }
  369. public function testDeleteGroupNonExisting() {
  370. $this->expectException(\OCP\AppFramework\OCS\OCSException::class);
  371. $this->expectExceptionCode(101);
  372. $this->api->deleteGroup('NonExistingGroup');
  373. }
  374. public function testDeleteAdminGroup() {
  375. $this->expectException(\OCP\AppFramework\OCS\OCSException::class);
  376. $this->expectExceptionCode(102);
  377. $this->groupManager
  378. ->method('groupExists')
  379. ->with('admin')
  380. ->willReturn('true');
  381. $this->api->deleteGroup('admin');
  382. }
  383. public function testDeleteGroup() {
  384. $this->groupManager
  385. ->method('groupExists')
  386. ->with('ExistingGroup')
  387. ->willReturn('true');
  388. $group = $this->createGroup('ExistingGroup');
  389. $this->groupManager
  390. ->method('get')
  391. ->with('ExistingGroup')
  392. ->willReturn($group);
  393. $group
  394. ->expects($this->once())
  395. ->method('delete')
  396. ->willReturn(true);
  397. $this->api->deleteGroup('ExistingGroup');
  398. }
  399. public function testDeleteGroupEncoding() {
  400. $this->groupManager
  401. ->method('groupExists')
  402. ->with('ExistingGroup A/B')
  403. ->willReturn('true');
  404. $group = $this->createGroup('ExistingGroup');
  405. $this->groupManager
  406. ->method('get')
  407. ->with('ExistingGroup A/B')
  408. ->willReturn($group);
  409. $group
  410. ->expects($this->once())
  411. ->method('delete')
  412. ->willReturn(true);
  413. $this->api->deleteGroup(urlencode('ExistingGroup A/B'));
  414. }
  415. public function testGetGroupUsersDetails() {
  416. $gid = 'ncg1';
  417. $this->asAdmin();
  418. $users = [
  419. 'ncu1' => $this->createUser('ncu1'), # regular
  420. 'ncu2' => $this->createUser('ncu2'), # the zombie
  421. ];
  422. $users['ncu2']->expects($this->atLeastOnce())
  423. ->method('getHome')
  424. ->willThrowException(new NoUserException());
  425. $this->userManager->expects($this->any())
  426. ->method('get')
  427. ->willReturnCallback(function (string $uid) use ($users) {
  428. return $users[$uid] ?? null;
  429. });
  430. $group = $this->createGroup($gid);
  431. $group->expects($this->once())
  432. ->method('searchUsers')
  433. ->with('', null, 0)
  434. ->willReturn(array_values($users));
  435. $this->groupManager
  436. ->method('get')
  437. ->with($gid)
  438. ->willReturn($group);
  439. $this->groupManager->expects($this->any())
  440. ->method('getUserGroups')
  441. ->willReturn([$group]);
  442. /** @var \PHPUnit\Framework\MockObject\MockObject */
  443. $this->subAdminManager->expects($this->any())
  444. ->method('isSubAdminOfGroup')
  445. ->willReturn(false);
  446. $this->subAdminManager->expects($this->any())
  447. ->method('getSubAdminsGroups')
  448. ->willReturn([]);
  449. $this->api->getGroupUsersDetails($gid);
  450. }
  451. public function testGetGroupUsersDetailsEncoded() {
  452. $gid = 'Department A/B C/D';
  453. $this->asAdmin();
  454. $users = [
  455. 'ncu1' => $this->createUser('ncu1'), # regular
  456. 'ncu2' => $this->createUser('ncu2'), # the zombie
  457. ];
  458. $users['ncu2']->expects($this->atLeastOnce())
  459. ->method('getHome')
  460. ->willThrowException(new NoUserException());
  461. $this->userManager->expects($this->any())
  462. ->method('get')
  463. ->willReturnCallback(function (string $uid) use ($users) {
  464. return $users[$uid] ?? null;
  465. });
  466. $group = $this->createGroup($gid);
  467. $group->expects($this->once())
  468. ->method('searchUsers')
  469. ->with('', null, 0)
  470. ->willReturn(array_values($users));
  471. $this->groupManager
  472. ->method('get')
  473. ->with($gid)
  474. ->willReturn($group);
  475. $this->groupManager->expects($this->any())
  476. ->method('getUserGroups')
  477. ->willReturn([$group]);
  478. /** @var \PHPUnit\Framework\MockObject\MockObject */
  479. $this->subAdminManager->expects($this->any())
  480. ->method('isSubAdminOfGroup')
  481. ->willReturn(false);
  482. $this->subAdminManager->expects($this->any())
  483. ->method('getSubAdminsGroups')
  484. ->willReturn([]);
  485. $this->api->getGroupUsersDetails(urlencode($gid));
  486. }
  487. }