UpdateGroupsTest.php 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * @copyright Copyright (c) 2020 Arthur Schiwon <blizzz@arthur-schiwon.de>
  5. *
  6. * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
  7. * @author Joas Schilling <coding@schilljs.com>
  8. *
  9. * @license GNU AGPL version 3 or any later version
  10. *
  11. * This program is free software: you can redistribute it and/or modify
  12. * it under the terms of the GNU Affero General Public License as
  13. * published by the Free Software Foundation, either version 3 of the
  14. * License, or (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU Affero General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU Affero General Public License
  22. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  23. *
  24. */
  25. namespace OCA\user_ldap\tests\Jobs;
  26. use OCA\User_LDAP\Group_Proxy;
  27. use OCA\User_LDAP\Jobs\UpdateGroups;
  28. use OCP\AppFramework\Utility\ITimeFactory;
  29. use OCP\DB\IResult;
  30. use OCP\DB\QueryBuilder\IExpressionBuilder;
  31. use OCP\DB\QueryBuilder\IQueryBuilder;
  32. use OCP\EventDispatcher\IEventDispatcher;
  33. use OCP\Group\Events\UserAddedEvent;
  34. use OCP\Group\Events\UserRemovedEvent;
  35. use OCP\IConfig;
  36. use OCP\IDBConnection;
  37. use OCP\IGroup;
  38. use OCP\IGroupManager;
  39. use OCP\IUser;
  40. use OCP\IUserManager;
  41. use PHPUnit\Framework\MockObject\MockObject;
  42. use Psr\Log\LoggerInterface;
  43. use Test\TestCase;
  44. use function serialize;
  45. class UpdateGroupsTest extends TestCase {
  46. /** @var Group_Proxy|MockObject */
  47. protected $groupBackend;
  48. /** @var IEventDispatcher|MockObject */
  49. protected $dispatcher;
  50. /** @var IGroupManager|MockObject */
  51. protected $groupManager;
  52. /** @var IUserManager|MockObject */
  53. protected $userManager;
  54. /** @var LoggerInterface|MockObject */
  55. protected $logger;
  56. /** @var IDBConnection|MockObject */
  57. protected $dbc;
  58. /** @var IConfig|MockObject */
  59. protected $config;
  60. /** @var ITimeFactory|MockObject */
  61. protected $timeFactory;
  62. protected UpdateGroups $updateGroupsJob;
  63. public function setUp(): void {
  64. $this->groupBackend = $this->createMock(Group_Proxy::class);
  65. $this->dispatcher = $this->createMock(IEventDispatcher::class);
  66. $this->groupManager = $this->createMock(IGroupManager::class);
  67. $this->userManager = $this->createMock(IUserManager::class);
  68. $this->logger = $this->createMock(LoggerInterface::class);
  69. $this->dbc = $this->createMock(IDBConnection::class);
  70. $this->config = $this->createMock(IConfig::class);
  71. $this->timeFactory = $this->createMock(ITimeFactory::class);
  72. $this->updateGroupsJob = new UpdateGroups(
  73. $this->groupBackend,
  74. $this->dispatcher,
  75. $this->groupManager,
  76. $this->userManager,
  77. $this->logger,
  78. $this->dbc,
  79. $this->config,
  80. $this->timeFactory
  81. );
  82. }
  83. public function testHandleKnownGroups(): void {
  84. $knownGroups = [
  85. 'emptyGroup' => serialize([]),
  86. 'stableGroup' => serialize(['userA', 'userC', 'userE']),
  87. 'groupWithAdditions' => serialize(['userA', 'userC', 'userE']),
  88. 'groupWithRemovals' => serialize(['userA', 'userC', 'userDeleted', 'userE']),
  89. 'groupWithAdditionsAndRemovals' => serialize(['userA', 'userC', 'userE']),
  90. 'vanishedGroup' => serialize(['userB', 'userDeleted'])
  91. ];
  92. $knownGroupsDB = [];
  93. foreach ($knownGroups as $gid => $members) {
  94. $knownGroupsDB[] = [
  95. 'owncloudname' => $gid,
  96. 'owncloudusers' => $members
  97. ];
  98. }
  99. $actualGroups = [
  100. 'emptyGroup' => [],
  101. 'stableGroup' => ['userA', 'userC', 'userE'],
  102. 'groupWithAdditions' => ['userA', 'userC', 'userE', 'userF'],
  103. 'groupWithRemovals' => ['userA', 'userE'],
  104. 'groupWithAdditionsAndRemovals' => ['userC', 'userE', 'userF'],
  105. 'newGroup' => ['userB', 'userF'],
  106. ];
  107. $groups = array_intersect(array_keys($knownGroups), array_keys($actualGroups));
  108. /** @var IQueryBuilder|MockObject $updateQb */
  109. $updateQb = $this->createMock(IQueryBuilder::class);
  110. $updateQb->expects($this->once())
  111. ->method('update')
  112. ->willReturn($updateQb);
  113. $updateQb->expects($this->once())
  114. ->method('set')
  115. ->willReturn($updateQb);
  116. $updateQb->expects($this->once())
  117. ->method('where')
  118. ->willReturn($updateQb);
  119. // three groups need to be updated
  120. $updateQb->expects($this->exactly(3))
  121. ->method('setParameters');
  122. $updateQb->expects($this->exactly(3))
  123. ->method('executeStatement');
  124. $updateQb->expects($this->any())
  125. ->method('expr')
  126. ->willReturn($this->createMock(IExpressionBuilder::class));
  127. $stmt = $this->createMock(IResult::class);
  128. $stmt->expects($this->once())
  129. ->method('fetchAll')
  130. ->willReturn($knownGroupsDB);
  131. $selectQb = $this->createMock(IQueryBuilder::class);
  132. $selectQb->expects($this->once())
  133. ->method('select')
  134. ->willReturn($selectQb);
  135. $selectQb->expects($this->once())
  136. ->method('from')
  137. ->willReturn($selectQb);
  138. $selectQb->expects($this->once())
  139. ->method('executeQuery')
  140. ->willReturn($stmt);
  141. $this->dbc->expects($this->any())
  142. ->method('getQueryBuilder')
  143. ->willReturnOnConsecutiveCalls($updateQb, $selectQb);
  144. $this->groupBackend->expects($this->any())
  145. ->method('usersInGroup')
  146. ->willReturnCallback(function ($groupID) use ($actualGroups) {
  147. return $actualGroups[$groupID] ?? [];
  148. });
  149. $this->groupManager->expects($this->any())
  150. ->method('get')
  151. ->willReturnCallback(function (string $groupId): ?IGroup {
  152. if ($groupId === 'vanishedGroup') {
  153. return null;
  154. }
  155. return $this->createMock(IGroup::class);
  156. });
  157. $this->userManager->expects($this->exactly(5))
  158. ->method('get')
  159. ->willReturnCallback(function (string $userId) {
  160. if ($userId === 'userDeleted') {
  161. // user already deleted
  162. return null;
  163. }
  164. return $this->createMock(IUser::class);
  165. });
  166. $addedEvents = 0;
  167. $removedEvents = 0;
  168. $this->dispatcher->expects($this->exactly(4))
  169. ->method('dispatchTyped')
  170. ->willReturnCallback(function ($event) use (&$addedEvents, &$removedEvents) {
  171. if ($event instanceof UserRemovedEvent) {
  172. $removedEvents++;
  173. } elseif ($event instanceof UserAddedEvent) {
  174. $addedEvents++;
  175. }
  176. });
  177. $this->invokePrivate($this->updateGroupsJob, 'handleKnownGroups', [$groups]);
  178. $this->assertSame(2, $removedEvents);
  179. $this->assertSame(2, $addedEvents);
  180. // and no event for the user that is already deleted, the DB is nevertheless updated, hence 5
  181. }
  182. }