Skip to content

Commit 26f9a08

Browse files
authored
Merge pull request #60600 from nextcloud/backport/59271/stable32
[stable32] enh(occ): make it possible to add an arbitrary number of users to a g…
2 parents b9c22da + 0054c73 commit 26f9a08

4 files changed

Lines changed: 213 additions & 31 deletions

File tree

core/Command/Group/AddUser.php

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,24 +34,44 @@ protected function configure() {
3434
'group to add the user to'
3535
)->addArgument(
3636
'user',
37-
InputArgument::REQUIRED,
38-
'user to add to the group'
37+
InputArgument::REQUIRED + InputArgument::IS_ARRAY,
38+
'users to add to the group',
3939
);
4040
}
4141

4242
protected function execute(InputInterface $input, OutputInterface $output): int {
4343
$group = $this->groupManager->get($input->getArgument('group'));
4444
if (is_null($group)) {
4545
$output->writeln('<error>group not found</error>');
46-
return 1;
46+
return Base::FAILURE;
47+
}
48+
49+
$allUsersFound = true;
50+
$noUserFound = true;
51+
$users = (array)$input->getArgument('user');
52+
foreach ($users as $userId) {
53+
$user = $this->userManager->get($userId);
54+
if (is_null($user)) {
55+
$output->writeln('<error>user ' . $userId . ' not found</error>');
56+
$allUsersFound = false;
57+
continue;
58+
}
59+
$noUserFound = false;
60+
$group->addUser($user);
61+
unset($user);
62+
$output->writeln('<info>user ' . $userId . ' added</info>');
4763
}
48-
$user = $this->userManager->get($input->getArgument('user'));
49-
if (is_null($user)) {
50-
$output->writeln('<error>user not found</error>');
51-
return 1;
64+
65+
if (!$allUsersFound && !$noUserFound) {
66+
$output->writeln('<error>Some users were not found, all others where added to the group.</error>');
67+
return Base::FAILURE;
68+
}
69+
70+
if ($noUserFound) {
71+
return Base::FAILURE;
5272
}
53-
$group->addUser($user);
54-
return 0;
73+
74+
return Base::SUCCESS;
5575
}
5676

5777
/**

core/Command/Group/RemoveUser.php

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,24 +34,44 @@ protected function configure() {
3434
'group to remove the user from'
3535
)->addArgument(
3636
'user',
37-
InputArgument::REQUIRED,
38-
'user to remove from the group'
37+
InputArgument::REQUIRED + InputArgument::IS_ARRAY,
38+
'users to remove from the group'
3939
);
4040
}
4141

4242
protected function execute(InputInterface $input, OutputInterface $output): int {
4343
$group = $this->groupManager->get($input->getArgument('group'));
4444
if (is_null($group)) {
4545
$output->writeln('<error>group not found</error>');
46-
return 1;
46+
return Base::FAILURE;
47+
}
48+
49+
$allUsersFound = true;
50+
$noUserFound = true;
51+
$users = (array)$input->getArgument('user');
52+
foreach ($users as $userId) {
53+
$user = $this->userManager->get($userId);
54+
if (is_null($user)) {
55+
$output->writeln('<error>user ' . $userId . ' not found</error>');
56+
$allUsersFound = false;
57+
continue;
58+
}
59+
$noUserFound = false;
60+
$group->removeUser($user);
61+
unset($user);
62+
$output->writeln('<info>user ' . $userId . ' removed</info>');
4763
}
48-
$user = $this->userManager->get($input->getArgument('user'));
49-
if (is_null($user)) {
50-
$output->writeln('<error>user not found</error>');
51-
return 1;
64+
65+
if (!$allUsersFound && !$noUserFound) {
66+
$output->writeln('<error>Some users were not found, all others where removed from the group.</error>');
67+
return Base::FAILURE;
68+
}
69+
70+
if ($noUserFound) {
71+
return Base::FAILURE;
5272
}
53-
$group->removeUser($user);
54-
return 0;
73+
74+
return Base::SUCCESS;
5575
}
5676

5777
/**

tests/Core/Command/Group/AddUserTest.php

Lines changed: 77 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,21 +38,26 @@ protected function setUp(): void {
3838
$this->groupManager = $this->createMock(IGroupManager::class);
3939
$this->userManager = $this->createMock(IUserManager::class);
4040
$this->command = new AddUser($this->userManager, $this->groupManager);
41+
$this->output = $this->createMock(OutputInterface::class);
42+
}
4143

44+
protected function configureInput(array|string $returnGroup, array|string $returnUser): void {
4245
$this->input = $this->createMock(InputInterface::class);
4346
$this->input->method('getArgument')
44-
->willReturnCallback(function ($arg) {
47+
->willReturnCallback(function ($arg) use ($returnGroup, $returnUser) {
4548
if ($arg === 'group') {
46-
return 'myGroup';
47-
} elseif ($arg === 'user') {
48-
return 'myUser';
49+
return $returnGroup;
50+
}
51+
if ($arg === 'user') {
52+
return $returnUser;
4953
}
5054
throw new \Exception();
5155
});
52-
$this->output = $this->createMock(OutputInterface::class);
5356
}
5457

5558
public function testNoGroup(): void {
59+
$this->configureInput('myGroup', 'myUser');
60+
5661
$this->groupManager->method('get')
5762
->with('myGroup')
5863
->willReturn(null);
@@ -65,6 +70,8 @@ public function testNoGroup(): void {
6570
}
6671

6772
public function testNoUser(): void {
73+
$this->configureInput('myGroup', 'myUser');
74+
6875
$group = $this->createMock(IGroup::class);
6976
$this->groupManager->method('get')
7077
->with('myGroup')
@@ -76,12 +83,14 @@ public function testNoUser(): void {
7683

7784
$this->output->expects($this->once())
7885
->method('writeln')
79-
->with('<error>user not found</error>');
86+
->with('<error>user myUser not found</error>');
8087

8188
$this->invokePrivate($this->command, 'execute', [$this->input, $this->output]);
8289
}
8390

8491
public function testAdd(): void {
92+
$this->configureInput('myGroup', 'myUser');
93+
8594
$group = $this->createMock(IGroup::class);
8695
$this->groupManager->method('get')
8796
->with('myGroup')
@@ -98,4 +107,66 @@ public function testAdd(): void {
98107

99108
$this->invokePrivate($this->command, 'execute', [$this->input, $this->output]);
100109
}
110+
111+
public function testAddMultiple(): void {
112+
$this->configureInput('myGroup', ['myUser', 'myOtherUser']);
113+
114+
$group = $this->createMock(IGroup::class);
115+
$this->groupManager->method('get')
116+
->with('myGroup')
117+
->willReturn($group);
118+
119+
$user1 = $this->createMock(IUser::class);
120+
$user2 = $this->createMock(IUser::class);
121+
$this->userManager->method('get')
122+
->willReturnMap([
123+
['myUser', $user1],
124+
['myOtherUser', $user2],
125+
]);
126+
127+
$group->expects($this->exactly(2))
128+
->method('addUser')
129+
->with($this->callback(static fn (IUser $user): bool => in_array($user, [$user1, $user2], true)));
130+
131+
$this->output->expects($this->exactly(2))
132+
->method('writeln')
133+
->with($this->callback(static fn (string $message): bool => in_array($message,
134+
[
135+
'<info>user myUser added</info>',
136+
'<info>user myOtherUser added</info>',
137+
], true)));
138+
139+
$this->invokePrivate($this->command, 'execute', [$this->input, $this->output]);
140+
}
141+
142+
public function testAddMultiplePartialSuccess(): void {
143+
$this->configureInput('myGroup', ['myUser', 'myOtherUser']);
144+
145+
$group = $this->createMock(IGroup::class);
146+
$this->groupManager->method('get')
147+
->with('myGroup')
148+
->willReturn($group);
149+
150+
$user = $this->createMock(IUser::class);
151+
$this->userManager->method('get')
152+
->willReturnMap([
153+
['myUser', $user],
154+
['myOtherUser', null],
155+
]);
156+
157+
$group->expects($this->once())
158+
->method('addUser')
159+
->with($user);
160+
161+
$this->output->expects($this->exactly(3))
162+
->method('writeln')
163+
->with($this->callback(static fn (string $message): bool => in_array($message,
164+
[
165+
'<info>user myUser added</info>',
166+
'<error>user myOtherUser not found</error>',
167+
'<error>Some users were not found, all others where added to the group.</error>',
168+
], true)));
169+
170+
$this->invokePrivate($this->command, 'execute', [$this->input, $this->output]);
171+
}
101172
}

tests/Core/Command/Group/RemoveUserTest.php

Lines changed: 78 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,21 +38,26 @@ protected function setUp(): void {
3838
$this->groupManager = $this->createMock(IGroupManager::class);
3939
$this->userManager = $this->createMock(IUserManager::class);
4040
$this->command = new RemoveUser($this->userManager, $this->groupManager);
41+
$this->output = $this->createMock(OutputInterface::class);
42+
}
4143

44+
protected function configureInput(array|string $returnGroup, array|string $returnUser): void {
4245
$this->input = $this->createMock(InputInterface::class);
4346
$this->input->method('getArgument')
44-
->willReturnCallback(function ($arg) {
47+
->willReturnCallback(function ($arg) use ($returnGroup, $returnUser) {
4548
if ($arg === 'group') {
46-
return 'myGroup';
47-
} elseif ($arg === 'user') {
48-
return 'myUser';
49+
return $returnGroup;
50+
}
51+
if ($arg === 'user') {
52+
return $returnUser;
4953
}
5054
throw new \Exception();
5155
});
52-
$this->output = $this->createMock(OutputInterface::class);
5356
}
5457

5558
public function testNoGroup(): void {
59+
$this->configureInput('myGroup', 'myUser');
60+
5661
$this->groupManager->method('get')
5762
->with('myGroup')
5863
->willReturn(null);
@@ -65,6 +70,8 @@ public function testNoGroup(): void {
6570
}
6671

6772
public function testNoUser(): void {
73+
$this->configureInput('myGroup', 'myUser');
74+
6875
$group = $this->createMock(IGroup::class);
6976
$this->groupManager->method('get')
7077
->with('myGroup')
@@ -76,12 +83,14 @@ public function testNoUser(): void {
7683

7784
$this->output->expects($this->once())
7885
->method('writeln')
79-
->with('<error>user not found</error>');
86+
->with('<error>user myUser not found</error>');
8087

8188
$this->invokePrivate($this->command, 'execute', [$this->input, $this->output]);
8289
}
8390

84-
public function testAdd(): void {
91+
public function testRemove(): void {
92+
$this->configureInput('myGroup', 'myUser');
93+
8594
$group = $this->createMock(IGroup::class);
8695
$this->groupManager->method('get')
8796
->with('myGroup')
@@ -98,4 +107,66 @@ public function testAdd(): void {
98107

99108
$this->invokePrivate($this->command, 'execute', [$this->input, $this->output]);
100109
}
110+
111+
public function testRemoveMultiple(): void {
112+
$this->configureInput('myGroup', ['myUser', 'myOtherUser']);
113+
114+
$group = $this->createMock(IGroup::class);
115+
$this->groupManager->method('get')
116+
->with('myGroup')
117+
->willReturn($group);
118+
119+
$user1 = $this->createMock(IUser::class);
120+
$user2 = $this->createMock(IUser::class);
121+
$this->userManager->method('get')
122+
->willReturnMap([
123+
['myUser', $user1],
124+
['myOtherUser', $user2],
125+
]);
126+
127+
$group->expects($this->exactly(2))
128+
->method('removeUser')
129+
->with($this->callback(static fn (IUser $user): bool => in_array($user, [$user1, $user2], true)));
130+
131+
$this->output->expects($this->exactly(2))
132+
->method('writeln')
133+
->with($this->callback(static fn (string $message): bool => in_array($message,
134+
[
135+
'<info>user myUser removed</info>',
136+
'<info>user myOtherUser removed</info>',
137+
], true)));
138+
139+
$this->invokePrivate($this->command, 'execute', [$this->input, $this->output]);
140+
}
141+
142+
public function testRemoveMultiplePartialSuccess(): void {
143+
$this->configureInput('myGroup', ['myUser', 'myOtherUser']);
144+
145+
$group = $this->createMock(IGroup::class);
146+
$this->groupManager->method('get')
147+
->with('myGroup')
148+
->willReturn($group);
149+
150+
$user = $this->createMock(IUser::class);
151+
$this->userManager->method('get')
152+
->willReturnMap([
153+
['myUser', $user],
154+
['myOtherUser', null],
155+
]);
156+
157+
$group->expects($this->once())
158+
->method('removeUser')
159+
->with($user);
160+
161+
$this->output->expects($this->exactly(3))
162+
->method('writeln')
163+
->with($this->callback(static fn (string $message): bool => in_array($message,
164+
[
165+
'<info>user myUser removed</info>',
166+
'<error>user myOtherUser not found</error>',
167+
'<error>Some users were not found, all others where removed from the group.</error>',
168+
], true)));
169+
170+
$this->invokePrivate($this->command, 'execute', [$this->input, $this->output]);
171+
}
101172
}

0 commit comments

Comments
 (0)