Completed
Push — master ( 63b9ea...a1cf92 )
by
unknown
26:39 queued 02:20
created
tests/Core/Command/User/ProfileTest.php 1 patch
Indentation   +444 added lines, -444 removed lines patch added patch discarded remove patch
@@ -23,448 +23,448 @@
 block discarded – undo
23 23
 
24 24
 class ProfileTest extends TestCase {
25 25
 
26
-	protected IAccountManager&MockObject $accountManager;
27
-	protected IUserManager&MockObject $userManager;
28
-	protected IDBConnection&MockObject $connection;
29
-	protected InputInterface&MockObject $consoleInput;
30
-	protected OutputInterface&MockObject $consoleOutput;
31
-
32
-	protected function setUp(): void {
33
-		parent::setUp();
34
-
35
-		$this->accountManager = $this->createMock(IAccountManager::class);
36
-		$this->userManager = $this->createMock(IUserManager::class);
37
-		$this->connection = $this->createMock(IDBConnection::class);
38
-		$this->consoleInput = $this->createMock(InputInterface::class);
39
-		$this->consoleOutput = $this->createMock(OutputInterface::class);
40
-	}
41
-
42
-	public function getCommand(array $methods = []): Profile|MockObject {
43
-		if (empty($methods)) {
44
-			return new Profile($this->userManager, $this->accountManager);
45
-		} else {
46
-			return $this->getMockBuilder(Profile::class)
47
-				->setConstructorArgs([
48
-					$this->userManager,
49
-					$this->accountManager,
50
-				])
51
-				->onlyMethods($methods)
52
-				->getMock();
53
-		}
54
-	}
55
-
56
-	public static function dataCheckInput(): array {
57
-		return [
58
-			'Call with existing user should pass check' => [
59
-				[['uid', 'username']],
60
-				[],
61
-				[],
62
-				true,
63
-				null,
64
-			],
65
-			'Call with non-existing user should fail check' => [
66
-				[['uid', 'username']],
67
-				[],
68
-				[],
69
-				false,
70
-				'The user "username" does not exist.',
71
-			],
72
-
73
-			'Call with uid, key and --default value should pass check' => [
74
-				[['uid', 'username'], ['key', 'configkey']],
75
-				[],
76
-				[['--default-value', false, true]],
77
-				true,
78
-				null,
79
-			],
80
-			'Call with uid and empty key with default-value option should fail check' => [
81
-				[['uid', 'username'], ['key', '']],
82
-				[],
83
-				[['--default-value', false, true]],
84
-				true,
85
-				'The "default-value" option can only be used when specifying a key.',
86
-			],
87
-
88
-			'Call with uid, key, value should pass check' => [
89
-				[['uid', 'username'], ['key', 'configkey'], ['value', '']],
90
-				[],
91
-				[],
92
-				true,
93
-				null,
94
-			],
95
-			'Call with uid, empty key and empty value should fail check' => [
96
-				[['uid', 'username'], ['key', ''], ['value', '']],
97
-				[],
98
-				[],
99
-				true,
100
-				'The value argument can only be used when specifying a key.',
101
-			],
102
-			'Call with uid, key, empty value and default-value option should fail check' => [
103
-				[['uid', 'username'], ['key', 'configkey'], ['value', '']],
104
-				[],
105
-				[['--default-value', false, true]],
106
-				true,
107
-				'The value argument can not be used together with "default-value".',
108
-			],
109
-			'Call with uid, key, empty value and update-only option should pass check' => [
110
-				[['uid', 'username'], ['key', 'configkey'], ['value', '']],
111
-				[['update-only', true]],
112
-				[],
113
-				true,
114
-				null,
115
-			],
116
-			'Call with uid, key, null value and update-only option should fail check' => [
117
-				[['uid', 'username'], ['key', 'configkey'], ['value', null]],
118
-				[['update-only', true]],
119
-				[],
120
-				true,
121
-				'The "update-only" option can only be used together with "value".',
122
-			],
123
-
124
-			'Call with uid, key and delete option should pass check' => [
125
-				[['uid', 'username'], ['key', 'configkey']],
126
-				[['delete', true]],
127
-				[],
128
-				true,
129
-				null,
130
-			],
131
-			'Call with uid, empty key and delete option should fail check' => [
132
-				[['uid', 'username'], ['key', '']],
133
-				[['delete', true]],
134
-				[],
135
-				true,
136
-				'The "delete" option can only be used when specifying a key.',
137
-			],
138
-			'Call with uid, key, delete option and default-value should fail check' => [
139
-				[['uid', 'username'], ['key', 'configkey']],
140
-				[['delete', true]],
141
-				[['--default-value', false, true]],
142
-				true,
143
-				'The "delete" option can not be used together with "default-value".',
144
-			],
145
-			'Call with uid, key, empty value and delete option should fail check' => [
146
-				[['uid', 'username'], ['key', 'configkey'], ['value', '']],
147
-				[['delete', true]],
148
-				[],
149
-				true,
150
-				'The "delete" option can not be used together with "value".',
151
-			],
152
-			'Call with uid, key, delete and error-if-not-exists should pass check' => [
153
-				[['uid', 'username'], ['key', 'configkey']],
154
-				[['delete', true], ['error-if-not-exists', true]],
155
-				[],
156
-				true,
157
-				null,
158
-			],
159
-			'Call with uid, key and error-if-not-exists should fail check' => [
160
-				[['uid', 'username'], ['key', 'configkey']],
161
-				[['delete', false], ['error-if-not-exists', true]],
162
-				[],
163
-				true,
164
-				'The "error-if-not-exists" option can only be used together with "delete".',
165
-			],
166
-		];
167
-	}
168
-
169
-	/**
170
-	 * @dataProvider dataCheckInput
171
-	 */
172
-	public function testCheckInput(array $arguments, array $options, array $parameterOptions, bool $existingUser, ?string $expectedException): void {
173
-		$this->consoleInput->expects($this->any())
174
-			->method('getArgument')
175
-			->willReturnMap($arguments);
176
-		$this->consoleInput->expects($this->any())
177
-			->method('getOption')
178
-			->willReturnMap($options);
179
-		$this->consoleInput->expects($this->any())
180
-			->method('hasParameterOption')
181
-			->willReturnCallback(function (string|array $values, bool $onlyParams = false) use ($parameterOptions): bool {
182
-				$arguments = func_get_args();
183
-				foreach ($parameterOptions as $parameterOption) {
184
-					// check the arguments of the function, if they are the same, return the mocked value
185
-					if (array_diff($arguments, $parameterOption) === []) {
186
-						return end($parameterOption);
187
-					}
188
-				}
189
-
190
-				return false;
191
-			});
192
-
193
-		$returnedUser = null;
194
-		if ($existingUser) {
195
-			$mockUser = $this->createMock(IUser::class);
196
-			$mockUser->expects($this->once())->method('getUID')->willReturn('user');
197
-			$returnedUser = $mockUser;
198
-		}
199
-		$this->userManager->expects($this->once())
200
-			->method('get')
201
-			->willReturn($returnedUser);
202
-
203
-		$command = $this->getCommand();
204
-		try {
205
-			$this->invokePrivate($command, 'checkInput', [$this->consoleInput]);
206
-			$this->assertNull($expectedException);
207
-		} catch (\InvalidArgumentException $e) {
208
-			$this->assertEquals($expectedException, $e->getMessage());
209
-		}
210
-	}
211
-
212
-	public function testCheckInputExceptionCatch(): void {
213
-		$command = $this->getCommand(['checkInput']);
214
-		$command->expects($this->once())
215
-			->method('checkInput')
216
-			->willThrowException(new \InvalidArgumentException('test'));
217
-
218
-		$this->consoleOutput->expects($this->once())
219
-			->method('writeln')
220
-			->with('<error>test</error>');
221
-
222
-		$this->assertEquals(1, $this->invokePrivate($command, 'execute', [$this->consoleInput, $this->consoleOutput]));
223
-	}
224
-
225
-	public static function dataExecuteDeleteProfileProperty(): array {
226
-		return [
227
-			'Deleting existing property should succeed' => ['address', 'Berlin', false, null, Command::SUCCESS],
228
-			'Deleting existing property with error-if-not-exists should succeed' => ['address', 'Berlin', true, null, Command::SUCCESS],
229
-			'Deleting non-existing property should succeed' => ['address', '', false, null, Command::SUCCESS],
230
-			'Deleting non-existing property with error-if-not-exists should fail' => ['address', '', true, '<error>The property does not exist for user "username".</error>', Command::FAILURE],
231
-		];
232
-	}
233
-
234
-	/**
235
-	 * Tests the deletion mechanism on profile settings.
236
-	 *
237
-	 * @dataProvider dataExecuteDeleteProfileProperty
238
-	 */
239
-	public function testExecuteDeleteProfileProperty(string $configKey, string $value, bool $errorIfNotExists, ?string $expectedLine, int $expectedReturn): void {
240
-		$uid = 'username';
241
-		$appName = 'profile';
242
-		$command = $this->getCommand([
243
-			'writeArrayInOutputFormat',
244
-			'checkInput',
245
-		]);
246
-
247
-		$this->consoleInput->expects($this->any())
248
-			->method('getArgument')
249
-			->willReturnMap([
250
-				['uid', $uid],
251
-				['app', $appName],
252
-				['key', $configKey],
253
-			]);
254
-
255
-		$mocks = $this->setupProfilePropertiesMock([$configKey => $value]);
256
-
257
-		$command->expects($this->once())
258
-			->method('checkInput')
259
-			->willReturn($mocks['userMock']);
260
-
261
-		$this->consoleInput->expects($this->atLeastOnce())
262
-			->method('hasParameterOption')
263
-			->willReturnMap([
264
-				['--delete', false, true],
265
-				['--error-if-not-exists', false, $errorIfNotExists],
266
-			]);
267
-
268
-		if ($expectedLine === null) {
269
-			$this->consoleOutput->expects($this->never())
270
-				->method('writeln');
271
-			$mocks['profilePropertiesMocks'][0]->expects($this->once())
272
-				->method('setValue')
273
-				->with('');
274
-			$this->accountManager->expects($this->once())
275
-				->method('updateAccount')
276
-				->with($mocks['accountMock']);
277
-		} else {
278
-			$this->consoleOutput->expects($this->once())
279
-				->method('writeln')
280
-				->with($expectedLine);
281
-			$this->accountManager->expects($this->never())
282
-				->method('updateAccount');
283
-		}
284
-
285
-		$this->assertEquals($expectedReturn, $this->invokePrivate($command, 'execute', [$this->consoleInput, $this->consoleOutput]));
286
-	}
287
-
288
-	public function testExecuteSetProfileProperty(): void {
289
-		$command = $this->getCommand([
290
-			'writeArrayInOutputFormat',
291
-			'checkInput',
292
-		]);
293
-
294
-		$uid = 'username';
295
-		$propertyKey = 'address';
296
-		$propertyValue = 'Barcelona';
297
-
298
-		$this->consoleInput->expects($this->atLeast(3))
299
-			->method('getArgument')
300
-			->willReturnMap([
301
-				['uid', $uid],
302
-				['key', $propertyKey],
303
-				['value', $propertyValue],
304
-			]);
305
-
306
-		$mocks = $this->setupProfilePropertiesMock([$propertyKey => $propertyValue]);
307
-
308
-		$command->expects($this->once())
309
-			->method('checkInput')
310
-			->willReturn($mocks['userMock']);
311
-
312
-		$mocks['profilePropertiesMocks'][0]->expects($this->once())
313
-			->method('setValue')
314
-			->with($propertyValue);
315
-		$this->accountManager->expects($this->once())
316
-			->method('updateAccount')
317
-			->with($mocks['accountMock']);
318
-
319
-		$this->assertEquals(0, $this->invokePrivate($command, 'execute', [$this->consoleInput, $this->consoleOutput]));
320
-	}
321
-
322
-	public static function dataExecuteGet(): array {
323
-		return [
324
-			'Get property with set value should pass' => ['configkey', 'value', null, 'value', Command::SUCCESS],
325
-			'Get property with empty value and default-value option should pass' => ['configkey', '', 'default-value', 'default-value', Command::SUCCESS],
326
-			'Get property with empty value should fail' => ['configkey', '', null, '<error>The property does not exist for user "username".</error>', Command::FAILURE],
327
-		];
328
-	}
329
-
330
-	/**
331
-	 * @dataProvider dataExecuteGet
332
-	 */
333
-	public function testExecuteGet(string $key, string $value, ?string $defaultValue, string $expectedLine, int $expectedReturn): void {
334
-		$command = $this->getCommand([
335
-			'writeArrayInOutputFormat',
336
-			'checkInput',
337
-		]);
338
-
339
-		$uid = 'username';
340
-
341
-		$this->consoleInput->expects($this->any())
342
-			->method('getArgument')
343
-			->willReturnMap([
344
-				['uid', $uid],
345
-				['key', $key],
346
-			]);
347
-
348
-		$mocks = $this->setupProfilePropertiesMock([$key => $value]);
349
-
350
-		$command->expects($this->once())
351
-			->method('checkInput')
352
-			->willReturn($mocks['userMock']);
353
-
354
-		if ($value === '') {
355
-			if ($defaultValue === null) {
356
-				$this->consoleInput->expects($this->atLeastOnce())
357
-					->method('hasParameterOption')
358
-					->willReturn(false);
359
-			} else {
360
-				$this->consoleInput->expects($this->atLeastOnce())
361
-					->method('hasParameterOption')
362
-					->willReturnCallback(fn (string|array $values): bool => $values === '--default-value');
363
-				$this->consoleInput->expects($this->once())
364
-					->method('getOption')
365
-					->with('default-value')
366
-					->willReturn($defaultValue);
367
-			}
368
-		}
369
-
370
-		$this->consoleOutput->expects($this->once())
371
-			->method('writeln')
372
-			->with($expectedLine);
373
-
374
-		$this->assertEquals($expectedReturn, $this->invokePrivate($command, 'execute', [$this->consoleInput, $this->consoleOutput]));
375
-	}
376
-
377
-	public function testExecuteList(): void {
378
-		$uid = 'username';
379
-		$profileData = [
380
-			'pronouns' => 'they/them',
381
-			'address' => 'Berlin',
382
-		];
383
-
384
-		$command = $this->getCommand([
385
-			'writeArrayInOutputFormat',
386
-			'checkInput',
387
-		]);
388
-
389
-		$this->consoleInput->expects($this->any())
390
-			->method('getArgument')
391
-			->willReturnMap([
392
-				['uid', $uid],
393
-				['key', ''],
394
-			]);
395
-
396
-		$mocks = $this->setupProfilePropertiesMock(['address' => $profileData['address'], 'pronouns' => $profileData['pronouns']]);
397
-
398
-		$command->expects($this->once())
399
-			->method('checkInput')
400
-			->willReturn($mocks['userMock']);
401
-
402
-		$command->expects($this->once())
403
-			->method('writeArrayInOutputFormat')
404
-			->with($this->consoleInput, $this->consoleOutput, $profileData);
405
-
406
-
407
-		$this->assertEquals(0, $this->invokePrivate($command, 'execute', [$this->consoleInput, $this->consoleOutput]));
408
-	}
409
-
410
-	/**
411
-	 * Helper to avoid boilerplate in tests in this file when mocking objects
412
-	 * of IAccountProperty type.
413
-	 *
414
-	 * @param array<string, string> $properties the properties to be set up as key => value
415
-	 * @return array{
416
-	 *     userMock: IUser&MockObject,
417
-	 *     accountMock: IAccount&MockObject,
418
-	 *     profilePropertiesMocks: IAccountProperty&MockObject[]
419
-	 * }
420
-	 */
421
-	private function setupProfilePropertiesMock(array $properties): array {
422
-		$userMock = $this->createMock(IUser::class);
423
-		$accountMock = $this->createMock(IAccount::class);
424
-		$this->accountManager->expects($this->atLeastOnce())
425
-			->method('getAccount')
426
-			->with($userMock)
427
-			->willReturn($accountMock);
428
-
429
-		/** @var IAccountProperty&MockObject[] $propertiesMocks */
430
-		$propertiesMocks = [];
431
-		foreach ($properties as $key => $value) {
432
-			$propertiesMocks[] = $this->getAccountPropertyMock($key, $value);
433
-		}
434
-
435
-		if (count($properties) === 1) {
436
-			$accountMock->expects($this->atLeastOnce())
437
-				->method('getProperty')
438
-				->with(array_keys($properties)[0])
439
-				->willReturn($propertiesMocks[array_key_first($propertiesMocks)]);
440
-		} else {
441
-			$accountMock->expects($this->atLeastOnce())
442
-				->method('getAllProperties')
443
-				->willReturnCallback(function () use ($propertiesMocks) {
444
-					foreach ($propertiesMocks as $property) {
445
-						yield $property;
446
-					}
447
-				});
448
-		}
449
-
450
-		return [
451
-			'userMock' => $userMock,
452
-			'accountMock' => $accountMock,
453
-			'profilePropertiesMocks' => $propertiesMocks,
454
-		];
455
-	}
456
-
457
-	private function getAccountPropertyMock(string $name, string $value): IAccountProperty&MockObject {
458
-		$propertyMock = $this->getMockBuilder(IAccountProperty::class)
459
-			->disableOriginalConstructor()
460
-			->getMock();
461
-		$propertyMock->expects($this->any())
462
-			->method('getName')
463
-			->willReturn($name);
464
-		$propertyMock->expects($this->any())
465
-			->method('getValue')
466
-			->willReturn($value);
467
-
468
-		return $propertyMock;
469
-	}
26
+    protected IAccountManager&MockObject $accountManager;
27
+    protected IUserManager&MockObject $userManager;
28
+    protected IDBConnection&MockObject $connection;
29
+    protected InputInterface&MockObject $consoleInput;
30
+    protected OutputInterface&MockObject $consoleOutput;
31
+
32
+    protected function setUp(): void {
33
+        parent::setUp();
34
+
35
+        $this->accountManager = $this->createMock(IAccountManager::class);
36
+        $this->userManager = $this->createMock(IUserManager::class);
37
+        $this->connection = $this->createMock(IDBConnection::class);
38
+        $this->consoleInput = $this->createMock(InputInterface::class);
39
+        $this->consoleOutput = $this->createMock(OutputInterface::class);
40
+    }
41
+
42
+    public function getCommand(array $methods = []): Profile|MockObject {
43
+        if (empty($methods)) {
44
+            return new Profile($this->userManager, $this->accountManager);
45
+        } else {
46
+            return $this->getMockBuilder(Profile::class)
47
+                ->setConstructorArgs([
48
+                    $this->userManager,
49
+                    $this->accountManager,
50
+                ])
51
+                ->onlyMethods($methods)
52
+                ->getMock();
53
+        }
54
+    }
55
+
56
+    public static function dataCheckInput(): array {
57
+        return [
58
+            'Call with existing user should pass check' => [
59
+                [['uid', 'username']],
60
+                [],
61
+                [],
62
+                true,
63
+                null,
64
+            ],
65
+            'Call with non-existing user should fail check' => [
66
+                [['uid', 'username']],
67
+                [],
68
+                [],
69
+                false,
70
+                'The user "username" does not exist.',
71
+            ],
72
+
73
+            'Call with uid, key and --default value should pass check' => [
74
+                [['uid', 'username'], ['key', 'configkey']],
75
+                [],
76
+                [['--default-value', false, true]],
77
+                true,
78
+                null,
79
+            ],
80
+            'Call with uid and empty key with default-value option should fail check' => [
81
+                [['uid', 'username'], ['key', '']],
82
+                [],
83
+                [['--default-value', false, true]],
84
+                true,
85
+                'The "default-value" option can only be used when specifying a key.',
86
+            ],
87
+
88
+            'Call with uid, key, value should pass check' => [
89
+                [['uid', 'username'], ['key', 'configkey'], ['value', '']],
90
+                [],
91
+                [],
92
+                true,
93
+                null,
94
+            ],
95
+            'Call with uid, empty key and empty value should fail check' => [
96
+                [['uid', 'username'], ['key', ''], ['value', '']],
97
+                [],
98
+                [],
99
+                true,
100
+                'The value argument can only be used when specifying a key.',
101
+            ],
102
+            'Call with uid, key, empty value and default-value option should fail check' => [
103
+                [['uid', 'username'], ['key', 'configkey'], ['value', '']],
104
+                [],
105
+                [['--default-value', false, true]],
106
+                true,
107
+                'The value argument can not be used together with "default-value".',
108
+            ],
109
+            'Call with uid, key, empty value and update-only option should pass check' => [
110
+                [['uid', 'username'], ['key', 'configkey'], ['value', '']],
111
+                [['update-only', true]],
112
+                [],
113
+                true,
114
+                null,
115
+            ],
116
+            'Call with uid, key, null value and update-only option should fail check' => [
117
+                [['uid', 'username'], ['key', 'configkey'], ['value', null]],
118
+                [['update-only', true]],
119
+                [],
120
+                true,
121
+                'The "update-only" option can only be used together with "value".',
122
+            ],
123
+
124
+            'Call with uid, key and delete option should pass check' => [
125
+                [['uid', 'username'], ['key', 'configkey']],
126
+                [['delete', true]],
127
+                [],
128
+                true,
129
+                null,
130
+            ],
131
+            'Call with uid, empty key and delete option should fail check' => [
132
+                [['uid', 'username'], ['key', '']],
133
+                [['delete', true]],
134
+                [],
135
+                true,
136
+                'The "delete" option can only be used when specifying a key.',
137
+            ],
138
+            'Call with uid, key, delete option and default-value should fail check' => [
139
+                [['uid', 'username'], ['key', 'configkey']],
140
+                [['delete', true]],
141
+                [['--default-value', false, true]],
142
+                true,
143
+                'The "delete" option can not be used together with "default-value".',
144
+            ],
145
+            'Call with uid, key, empty value and delete option should fail check' => [
146
+                [['uid', 'username'], ['key', 'configkey'], ['value', '']],
147
+                [['delete', true]],
148
+                [],
149
+                true,
150
+                'The "delete" option can not be used together with "value".',
151
+            ],
152
+            'Call with uid, key, delete and error-if-not-exists should pass check' => [
153
+                [['uid', 'username'], ['key', 'configkey']],
154
+                [['delete', true], ['error-if-not-exists', true]],
155
+                [],
156
+                true,
157
+                null,
158
+            ],
159
+            'Call with uid, key and error-if-not-exists should fail check' => [
160
+                [['uid', 'username'], ['key', 'configkey']],
161
+                [['delete', false], ['error-if-not-exists', true]],
162
+                [],
163
+                true,
164
+                'The "error-if-not-exists" option can only be used together with "delete".',
165
+            ],
166
+        ];
167
+    }
168
+
169
+    /**
170
+     * @dataProvider dataCheckInput
171
+     */
172
+    public function testCheckInput(array $arguments, array $options, array $parameterOptions, bool $existingUser, ?string $expectedException): void {
173
+        $this->consoleInput->expects($this->any())
174
+            ->method('getArgument')
175
+            ->willReturnMap($arguments);
176
+        $this->consoleInput->expects($this->any())
177
+            ->method('getOption')
178
+            ->willReturnMap($options);
179
+        $this->consoleInput->expects($this->any())
180
+            ->method('hasParameterOption')
181
+            ->willReturnCallback(function (string|array $values, bool $onlyParams = false) use ($parameterOptions): bool {
182
+                $arguments = func_get_args();
183
+                foreach ($parameterOptions as $parameterOption) {
184
+                    // check the arguments of the function, if they are the same, return the mocked value
185
+                    if (array_diff($arguments, $parameterOption) === []) {
186
+                        return end($parameterOption);
187
+                    }
188
+                }
189
+
190
+                return false;
191
+            });
192
+
193
+        $returnedUser = null;
194
+        if ($existingUser) {
195
+            $mockUser = $this->createMock(IUser::class);
196
+            $mockUser->expects($this->once())->method('getUID')->willReturn('user');
197
+            $returnedUser = $mockUser;
198
+        }
199
+        $this->userManager->expects($this->once())
200
+            ->method('get')
201
+            ->willReturn($returnedUser);
202
+
203
+        $command = $this->getCommand();
204
+        try {
205
+            $this->invokePrivate($command, 'checkInput', [$this->consoleInput]);
206
+            $this->assertNull($expectedException);
207
+        } catch (\InvalidArgumentException $e) {
208
+            $this->assertEquals($expectedException, $e->getMessage());
209
+        }
210
+    }
211
+
212
+    public function testCheckInputExceptionCatch(): void {
213
+        $command = $this->getCommand(['checkInput']);
214
+        $command->expects($this->once())
215
+            ->method('checkInput')
216
+            ->willThrowException(new \InvalidArgumentException('test'));
217
+
218
+        $this->consoleOutput->expects($this->once())
219
+            ->method('writeln')
220
+            ->with('<error>test</error>');
221
+
222
+        $this->assertEquals(1, $this->invokePrivate($command, 'execute', [$this->consoleInput, $this->consoleOutput]));
223
+    }
224
+
225
+    public static function dataExecuteDeleteProfileProperty(): array {
226
+        return [
227
+            'Deleting existing property should succeed' => ['address', 'Berlin', false, null, Command::SUCCESS],
228
+            'Deleting existing property with error-if-not-exists should succeed' => ['address', 'Berlin', true, null, Command::SUCCESS],
229
+            'Deleting non-existing property should succeed' => ['address', '', false, null, Command::SUCCESS],
230
+            'Deleting non-existing property with error-if-not-exists should fail' => ['address', '', true, '<error>The property does not exist for user "username".</error>', Command::FAILURE],
231
+        ];
232
+    }
233
+
234
+    /**
235
+     * Tests the deletion mechanism on profile settings.
236
+     *
237
+     * @dataProvider dataExecuteDeleteProfileProperty
238
+     */
239
+    public function testExecuteDeleteProfileProperty(string $configKey, string $value, bool $errorIfNotExists, ?string $expectedLine, int $expectedReturn): void {
240
+        $uid = 'username';
241
+        $appName = 'profile';
242
+        $command = $this->getCommand([
243
+            'writeArrayInOutputFormat',
244
+            'checkInput',
245
+        ]);
246
+
247
+        $this->consoleInput->expects($this->any())
248
+            ->method('getArgument')
249
+            ->willReturnMap([
250
+                ['uid', $uid],
251
+                ['app', $appName],
252
+                ['key', $configKey],
253
+            ]);
254
+
255
+        $mocks = $this->setupProfilePropertiesMock([$configKey => $value]);
256
+
257
+        $command->expects($this->once())
258
+            ->method('checkInput')
259
+            ->willReturn($mocks['userMock']);
260
+
261
+        $this->consoleInput->expects($this->atLeastOnce())
262
+            ->method('hasParameterOption')
263
+            ->willReturnMap([
264
+                ['--delete', false, true],
265
+                ['--error-if-not-exists', false, $errorIfNotExists],
266
+            ]);
267
+
268
+        if ($expectedLine === null) {
269
+            $this->consoleOutput->expects($this->never())
270
+                ->method('writeln');
271
+            $mocks['profilePropertiesMocks'][0]->expects($this->once())
272
+                ->method('setValue')
273
+                ->with('');
274
+            $this->accountManager->expects($this->once())
275
+                ->method('updateAccount')
276
+                ->with($mocks['accountMock']);
277
+        } else {
278
+            $this->consoleOutput->expects($this->once())
279
+                ->method('writeln')
280
+                ->with($expectedLine);
281
+            $this->accountManager->expects($this->never())
282
+                ->method('updateAccount');
283
+        }
284
+
285
+        $this->assertEquals($expectedReturn, $this->invokePrivate($command, 'execute', [$this->consoleInput, $this->consoleOutput]));
286
+    }
287
+
288
+    public function testExecuteSetProfileProperty(): void {
289
+        $command = $this->getCommand([
290
+            'writeArrayInOutputFormat',
291
+            'checkInput',
292
+        ]);
293
+
294
+        $uid = 'username';
295
+        $propertyKey = 'address';
296
+        $propertyValue = 'Barcelona';
297
+
298
+        $this->consoleInput->expects($this->atLeast(3))
299
+            ->method('getArgument')
300
+            ->willReturnMap([
301
+                ['uid', $uid],
302
+                ['key', $propertyKey],
303
+                ['value', $propertyValue],
304
+            ]);
305
+
306
+        $mocks = $this->setupProfilePropertiesMock([$propertyKey => $propertyValue]);
307
+
308
+        $command->expects($this->once())
309
+            ->method('checkInput')
310
+            ->willReturn($mocks['userMock']);
311
+
312
+        $mocks['profilePropertiesMocks'][0]->expects($this->once())
313
+            ->method('setValue')
314
+            ->with($propertyValue);
315
+        $this->accountManager->expects($this->once())
316
+            ->method('updateAccount')
317
+            ->with($mocks['accountMock']);
318
+
319
+        $this->assertEquals(0, $this->invokePrivate($command, 'execute', [$this->consoleInput, $this->consoleOutput]));
320
+    }
321
+
322
+    public static function dataExecuteGet(): array {
323
+        return [
324
+            'Get property with set value should pass' => ['configkey', 'value', null, 'value', Command::SUCCESS],
325
+            'Get property with empty value and default-value option should pass' => ['configkey', '', 'default-value', 'default-value', Command::SUCCESS],
326
+            'Get property with empty value should fail' => ['configkey', '', null, '<error>The property does not exist for user "username".</error>', Command::FAILURE],
327
+        ];
328
+    }
329
+
330
+    /**
331
+     * @dataProvider dataExecuteGet
332
+     */
333
+    public function testExecuteGet(string $key, string $value, ?string $defaultValue, string $expectedLine, int $expectedReturn): void {
334
+        $command = $this->getCommand([
335
+            'writeArrayInOutputFormat',
336
+            'checkInput',
337
+        ]);
338
+
339
+        $uid = 'username';
340
+
341
+        $this->consoleInput->expects($this->any())
342
+            ->method('getArgument')
343
+            ->willReturnMap([
344
+                ['uid', $uid],
345
+                ['key', $key],
346
+            ]);
347
+
348
+        $mocks = $this->setupProfilePropertiesMock([$key => $value]);
349
+
350
+        $command->expects($this->once())
351
+            ->method('checkInput')
352
+            ->willReturn($mocks['userMock']);
353
+
354
+        if ($value === '') {
355
+            if ($defaultValue === null) {
356
+                $this->consoleInput->expects($this->atLeastOnce())
357
+                    ->method('hasParameterOption')
358
+                    ->willReturn(false);
359
+            } else {
360
+                $this->consoleInput->expects($this->atLeastOnce())
361
+                    ->method('hasParameterOption')
362
+                    ->willReturnCallback(fn (string|array $values): bool => $values === '--default-value');
363
+                $this->consoleInput->expects($this->once())
364
+                    ->method('getOption')
365
+                    ->with('default-value')
366
+                    ->willReturn($defaultValue);
367
+            }
368
+        }
369
+
370
+        $this->consoleOutput->expects($this->once())
371
+            ->method('writeln')
372
+            ->with($expectedLine);
373
+
374
+        $this->assertEquals($expectedReturn, $this->invokePrivate($command, 'execute', [$this->consoleInput, $this->consoleOutput]));
375
+    }
376
+
377
+    public function testExecuteList(): void {
378
+        $uid = 'username';
379
+        $profileData = [
380
+            'pronouns' => 'they/them',
381
+            'address' => 'Berlin',
382
+        ];
383
+
384
+        $command = $this->getCommand([
385
+            'writeArrayInOutputFormat',
386
+            'checkInput',
387
+        ]);
388
+
389
+        $this->consoleInput->expects($this->any())
390
+            ->method('getArgument')
391
+            ->willReturnMap([
392
+                ['uid', $uid],
393
+                ['key', ''],
394
+            ]);
395
+
396
+        $mocks = $this->setupProfilePropertiesMock(['address' => $profileData['address'], 'pronouns' => $profileData['pronouns']]);
397
+
398
+        $command->expects($this->once())
399
+            ->method('checkInput')
400
+            ->willReturn($mocks['userMock']);
401
+
402
+        $command->expects($this->once())
403
+            ->method('writeArrayInOutputFormat')
404
+            ->with($this->consoleInput, $this->consoleOutput, $profileData);
405
+
406
+
407
+        $this->assertEquals(0, $this->invokePrivate($command, 'execute', [$this->consoleInput, $this->consoleOutput]));
408
+    }
409
+
410
+    /**
411
+     * Helper to avoid boilerplate in tests in this file when mocking objects
412
+     * of IAccountProperty type.
413
+     *
414
+     * @param array<string, string> $properties the properties to be set up as key => value
415
+     * @return array{
416
+     *     userMock: IUser&MockObject,
417
+     *     accountMock: IAccount&MockObject,
418
+     *     profilePropertiesMocks: IAccountProperty&MockObject[]
419
+     * }
420
+     */
421
+    private function setupProfilePropertiesMock(array $properties): array {
422
+        $userMock = $this->createMock(IUser::class);
423
+        $accountMock = $this->createMock(IAccount::class);
424
+        $this->accountManager->expects($this->atLeastOnce())
425
+            ->method('getAccount')
426
+            ->with($userMock)
427
+            ->willReturn($accountMock);
428
+
429
+        /** @var IAccountProperty&MockObject[] $propertiesMocks */
430
+        $propertiesMocks = [];
431
+        foreach ($properties as $key => $value) {
432
+            $propertiesMocks[] = $this->getAccountPropertyMock($key, $value);
433
+        }
434
+
435
+        if (count($properties) === 1) {
436
+            $accountMock->expects($this->atLeastOnce())
437
+                ->method('getProperty')
438
+                ->with(array_keys($properties)[0])
439
+                ->willReturn($propertiesMocks[array_key_first($propertiesMocks)]);
440
+        } else {
441
+            $accountMock->expects($this->atLeastOnce())
442
+                ->method('getAllProperties')
443
+                ->willReturnCallback(function () use ($propertiesMocks) {
444
+                    foreach ($propertiesMocks as $property) {
445
+                        yield $property;
446
+                    }
447
+                });
448
+        }
449
+
450
+        return [
451
+            'userMock' => $userMock,
452
+            'accountMock' => $accountMock,
453
+            'profilePropertiesMocks' => $propertiesMocks,
454
+        ];
455
+    }
456
+
457
+    private function getAccountPropertyMock(string $name, string $value): IAccountProperty&MockObject {
458
+        $propertyMock = $this->getMockBuilder(IAccountProperty::class)
459
+            ->disableOriginalConstructor()
460
+            ->getMock();
461
+        $propertyMock->expects($this->any())
462
+            ->method('getName')
463
+            ->willReturn($name);
464
+        $propertyMock->expects($this->any())
465
+            ->method('getValue')
466
+            ->willReturn($value);
467
+
468
+        return $propertyMock;
469
+    }
470 470
 }
Please login to merge, or discard this patch.
tests/Core/Command/User/SettingTest.php 1 patch
Indentation   +430 added lines, -430 removed lines patch added patch discarded remove patch
@@ -18,434 +18,434 @@
 block discarded – undo
18 18
 use Test\TestCase;
19 19
 
20 20
 class SettingTest extends TestCase {
21
-	protected IUserManager&MockObject $userManager;
22
-	protected IConfig&MockObject $config;
23
-	protected IDBConnection&MockObject $connection;
24
-	protected InputInterface&MockObject $consoleInput;
25
-	protected MockObject&OutputInterface $consoleOutput;
26
-
27
-	protected function setUp(): void {
28
-		parent::setUp();
29
-
30
-		$this->userManager = $this->createMock(IUserManager::class);
31
-		$this->config = $this->createMock(IConfig::class);
32
-		$this->connection = $this->createMock(IDBConnection::class);
33
-		$this->consoleInput = $this->createMock(InputInterface::class);
34
-		$this->consoleOutput = $this->createMock(OutputInterface::class);
35
-	}
36
-
37
-	public function getCommand(array $methods = []) {
38
-		if (empty($methods)) {
39
-			return new Setting($this->userManager, $this->config);
40
-		} else {
41
-			$mock = $this->getMockBuilder(Setting::class)
42
-				->setConstructorArgs([
43
-					$this->userManager,
44
-					$this->config,
45
-				])
46
-				->onlyMethods($methods)
47
-				->getMock();
48
-			return $mock;
49
-		}
50
-	}
51
-
52
-	public static function dataCheckInput(): array {
53
-		return [
54
-			[
55
-				[['uid', 'username']],
56
-				[['ignore-missing-user', true]],
57
-				[],
58
-				false,
59
-				false,
60
-			],
61
-			[
62
-				[['uid', 'username']],
63
-				[['ignore-missing-user', false]],
64
-				[],
65
-				null,
66
-				'The user "username" does not exist.',
67
-			],
68
-
69
-			[
70
-				[['uid', 'username'], ['key', 'configkey']],
71
-				[['ignore-missing-user', true]],
72
-				[['--default-value', false, true]],
73
-				false,
74
-				false,
75
-			],
76
-			[
77
-				[['uid', 'username'], ['key', '']],
78
-				[['ignore-missing-user', true]],
79
-				[['--default-value', false, true]],
80
-				false,
81
-				'The "default-value" option can only be used when specifying a key.',
82
-			],
83
-
84
-			[
85
-				[['uid', 'username'], ['key', 'configkey'], ['value', '']],
86
-				[['ignore-missing-user', true]],
87
-				[],
88
-				false,
89
-				false,
90
-			],
91
-			[
92
-				[['uid', 'username'], ['key', ''], ['value', '']],
93
-				[['ignore-missing-user', true]],
94
-				[],
95
-				false,
96
-				'The value argument can only be used when specifying a key.',
97
-			],
98
-			[
99
-				[['uid', 'username'], ['key', 'configkey'], ['value', '']],
100
-				[['ignore-missing-user', true]],
101
-				[['--default-value', false, true]],
102
-				false,
103
-				'The value argument can not be used together with "default-value".',
104
-			],
105
-			[
106
-				[['uid', 'username'], ['key', 'configkey'], ['value', '']],
107
-				[['ignore-missing-user', true], ['update-only', true]],
108
-				[],
109
-				false,
110
-				false,
111
-			],
112
-			[
113
-				[['uid', 'username'], ['key', 'configkey'], ['value', null]],
114
-				[['ignore-missing-user', true], ['update-only', true]],
115
-				[],
116
-				false,
117
-				'The "update-only" option can only be used together with "value".',
118
-			],
119
-
120
-			[
121
-				[['uid', 'username'], ['key', 'configkey']],
122
-				[['ignore-missing-user', true], ['delete', true]],
123
-				[],
124
-				false,
125
-				false,
126
-			],
127
-			[
128
-				[['uid', 'username'], ['key', '']],
129
-				[['ignore-missing-user', true], ['delete', true]],
130
-				[],
131
-				false,
132
-				'The "delete" option can only be used when specifying a key.',
133
-			],
134
-			[
135
-				[['uid', 'username'], ['key', 'configkey']],
136
-				[['ignore-missing-user', true], ['delete', true]],
137
-				[['--default-value', false, true]],
138
-				false,
139
-				'The "delete" option can not be used together with "default-value".',
140
-			],
141
-			[
142
-				[['uid', 'username'], ['key', 'configkey'], ['value', '']],
143
-				[['ignore-missing-user', true], ['delete', true]],
144
-				[],
145
-				false,
146
-				'The "delete" option can not be used together with "value".',
147
-			],
148
-			[
149
-				[['uid', 'username'], ['key', 'configkey']],
150
-				[['ignore-missing-user', true], ['delete', true], ['error-if-not-exists', true]],
151
-				[],
152
-				false,
153
-				false,
154
-			],
155
-			[
156
-				[['uid', 'username'], ['key', 'configkey']],
157
-				[['ignore-missing-user', true], ['delete', false], ['error-if-not-exists', true]],
158
-				[],
159
-				false,
160
-				'The "error-if-not-exists" option can only be used together with "delete".',
161
-			],
162
-		];
163
-	}
164
-
165
-	/**
166
-	 * @dataProvider dataCheckInput
167
-	 *
168
-	 * @param array $arguments
169
-	 * @param array $options
170
-	 * @param array $parameterOptions
171
-	 * @param mixed $user
172
-	 * @param string $expectedException
173
-	 */
174
-	public function testCheckInput($arguments, $options, $parameterOptions, $user, $expectedException): void {
175
-		$this->consoleInput->expects($this->any())
176
-			->method('getArgument')
177
-			->willReturnMap($arguments);
178
-		$this->consoleInput->expects($this->any())
179
-			->method('getOption')
180
-			->willReturnMap($options);
181
-		$this->consoleInput->expects($this->any())
182
-			->method('hasParameterOption')
183
-			->willReturnCallback(function (string|array $config, bool $default = false) use ($parameterOptions): bool {
184
-				foreach ($parameterOptions as $parameterOption) {
185
-					if ($config === $parameterOption[0]
186
-						// Check the default value if the maps has 3 entries
187
-						&& (!isset($parameterOption[2]) || $default === $parameterOption[1])) {
188
-						return end($parameterOption);
189
-					}
190
-				}
191
-				return false;
192
-			});
193
-
194
-		if ($user !== false) {
195
-			$this->userManager->expects($this->once())
196
-				->method('get')
197
-				->willReturn($user);
198
-		} else {
199
-			$this->userManager->expects($this->never())
200
-				->method('get');
201
-		}
202
-
203
-		$command = $this->getCommand();
204
-		try {
205
-			$this->invokePrivate($command, 'checkInput', [$this->consoleInput]);
206
-			$this->assertFalse($expectedException);
207
-		} catch (InvalidArgumentException $e) {
208
-			$this->assertEquals($expectedException, $e->getMessage());
209
-		}
210
-	}
211
-
212
-	public function testCheckInputExceptionCatch(): void {
213
-		$command = $this->getCommand(['checkInput']);
214
-		$command->expects($this->once())
215
-			->method('checkInput')
216
-			->willThrowException(new InvalidArgumentException('test'));
217
-
218
-		$this->consoleOutput->expects($this->once())
219
-			->method('writeln')
220
-			->with('<error>test</error>');
221
-
222
-		$this->assertEquals(1, $this->invokePrivate($command, 'execute', [$this->consoleInput, $this->consoleOutput]));
223
-	}
224
-
225
-	public static function dataExecuteDelete(): array {
226
-		return [
227
-			['config', false, null, 0],
228
-			['config', true, null, 0],
229
-			[null, false, null, 0],
230
-			[null, true, '<error>The setting does not exist for user "username".</error>', 1],
231
-		];
232
-	}
233
-
234
-	/**
235
-	 * @dataProvider dataExecuteDelete
236
-	 *
237
-	 * @param string|null $value
238
-	 * @param bool $errorIfNotExists
239
-	 * @param string $expectedLine
240
-	 * @param int $expectedReturn
241
-	 */
242
-	public function testExecuteDelete($value, $errorIfNotExists, $expectedLine, $expectedReturn): void {
243
-		$command = $this->getCommand([
244
-			'writeArrayInOutputFormat',
245
-			'checkInput',
246
-			'getUserSettings',
247
-		]);
248
-
249
-		$this->consoleInput->expects($this->any())
250
-			->method('getArgument')
251
-			->willReturnMap([
252
-				['uid', 'username'],
253
-				['app', 'appname'],
254
-				['key', 'configkey'],
255
-			]);
256
-
257
-		$command->expects($this->once())
258
-			->method('checkInput');
259
-
260
-		$this->config->expects($this->once())
261
-			->method('getUserValue')
262
-			->with('username', 'appname', 'configkey', null)
263
-			->willReturn($value);
264
-
265
-		$this->consoleInput->expects($this->atLeastOnce())
266
-			->method('hasParameterOption')
267
-			->willReturnMap([
268
-				['--delete', false, true],
269
-				['--error-if-not-exists', false, $errorIfNotExists],
270
-			]);
271
-
272
-		if ($expectedLine === null) {
273
-			$this->consoleOutput->expects($this->never())
274
-				->method('writeln');
275
-			$this->config->expects($this->once())
276
-				->method('deleteUserValue')
277
-				->with('username', 'appname', 'configkey');
278
-		} else {
279
-			$this->consoleOutput->expects($this->once())
280
-				->method('writeln')
281
-				->with($expectedLine);
282
-			$this->config->expects($this->never())
283
-				->method('deleteUserValue');
284
-		}
285
-
286
-		$this->assertEquals($expectedReturn, $this->invokePrivate($command, 'execute', [$this->consoleInput, $this->consoleOutput]));
287
-	}
288
-
289
-	public static function dataExecuteSet(): array {
290
-		return [
291
-			['config', false, null, 0],
292
-			['config', true, null, 0],
293
-			[null, false, null, 0],
294
-			[null, true, '<error>The setting does not exist for user "username".</error>', 1],
295
-		];
296
-	}
297
-
298
-	/**
299
-	 * @dataProvider dataExecuteSet
300
-	 *
301
-	 * @param string|null $value
302
-	 * @param bool $updateOnly
303
-	 * @param string $expectedLine
304
-	 * @param int $expectedReturn
305
-	 */
306
-	public function testExecuteSet($value, $updateOnly, $expectedLine, $expectedReturn): void {
307
-		$command = $this->getCommand([
308
-			'writeArrayInOutputFormat',
309
-			'checkInput',
310
-			'getUserSettings',
311
-		]);
312
-
313
-		$this->consoleInput->expects($this->atLeast(4))
314
-			->method('getArgument')
315
-			->willReturnMap([
316
-				['uid', 'username'],
317
-				['app', 'appname'],
318
-				['key', 'configkey'],
319
-				['value', 'setValue'],
320
-			]);
321
-
322
-		$command->expects($this->once())
323
-			->method('checkInput');
324
-
325
-		$this->config->expects($this->once())
326
-			->method('getUserValue')
327
-			->with('username', 'appname', 'configkey', null)
328
-			->willReturn($value);
329
-
330
-		$this->consoleInput->expects($this->atLeastOnce())
331
-			->method('hasParameterOption')
332
-			->willReturnMap([
333
-				['--update-only', false, $updateOnly],
334
-			]);
335
-
336
-		if ($expectedLine === null) {
337
-			$this->consoleOutput->expects($this->never())
338
-				->method('writeln');
339
-
340
-			$this->consoleInput->expects($this->never())
341
-				->method('getOption');
342
-
343
-			$this->config->expects($this->once())
344
-				->method('setUserValue')
345
-				->with('username', 'appname', 'configkey', 'setValue');
346
-		} else {
347
-			$this->consoleOutput->expects($this->once())
348
-				->method('writeln')
349
-				->with($expectedLine);
350
-			$this->config->expects($this->never())
351
-				->method('setUserValue');
352
-		}
353
-
354
-		$this->assertEquals($expectedReturn, $this->invokePrivate($command, 'execute', [$this->consoleInput, $this->consoleOutput]));
355
-	}
356
-
357
-	public static function dataExecuteGet(): array {
358
-		return [
359
-			['config', null, 'config', 0],
360
-			[null, 'config', 'config', 0],
361
-			[null, null, '<error>The setting does not exist for user "username".</error>', 1],
362
-		];
363
-	}
364
-
365
-	/**
366
-	 * @dataProvider dataExecuteGet
367
-	 *
368
-	 * @param string|null $value
369
-	 * @param string|null $defaultValue
370
-	 * @param string $expectedLine
371
-	 * @param int $expectedReturn
372
-	 */
373
-	public function testExecuteGet($value, $defaultValue, $expectedLine, $expectedReturn): void {
374
-		$command = $this->getCommand([
375
-			'writeArrayInOutputFormat',
376
-			'checkInput',
377
-			'getUserSettings',
378
-		]);
379
-
380
-		$this->consoleInput->expects($this->any())
381
-			->method('getArgument')
382
-			->willReturnMap([
383
-				['uid', 'username'],
384
-				['app', 'appname'],
385
-				['key', 'configkey'],
386
-			]);
387
-
388
-		$command->expects($this->once())
389
-			->method('checkInput');
390
-
391
-		$this->config->expects($this->once())
392
-			->method('getUserValue')
393
-			->with('username', 'appname', 'configkey', null)
394
-			->willReturn($value);
395
-
396
-		if ($value === null) {
397
-			if ($defaultValue === null) {
398
-				$this->consoleInput->expects($this->atLeastOnce())
399
-					->method('hasParameterOption')
400
-					->willReturn(false);
401
-			} else {
402
-				$this->consoleInput->expects($this->atLeastOnce())
403
-					->method('hasParameterOption')
404
-					->willReturnCallback(function (string|array $config, bool $default = false): bool {
405
-						if ($config === '--default-value' && $default === false) {
406
-							return true;
407
-						}
408
-						return false;
409
-					});
410
-				$this->consoleInput->expects($this->once())
411
-					->method('getOption')
412
-					->with('default-value')
413
-					->willReturn($defaultValue);
414
-			}
415
-		}
416
-
417
-		$this->consoleOutput->expects($this->once())
418
-			->method('writeln')
419
-			->with($expectedLine);
420
-
421
-		$this->assertEquals($expectedReturn, $this->invokePrivate($command, 'execute', [$this->consoleInput, $this->consoleOutput]));
422
-	}
423
-
424
-	public function testExecuteList(): void {
425
-		$command = $this->getCommand([
426
-			'writeArrayInOutputFormat',
427
-			'checkInput',
428
-			'getUserSettings',
429
-		]);
430
-
431
-		$this->consoleInput->expects($this->any())
432
-			->method('getArgument')
433
-			->willReturnMap([
434
-				['uid', 'username'],
435
-				['app', 'appname'],
436
-				['key', ''],
437
-			]);
438
-
439
-		$command->expects($this->once())
440
-			->method('checkInput');
441
-		$command->expects($this->once())
442
-			->method('getUserSettings')
443
-			->willReturn(['settings']);
444
-		$command->expects($this->once())
445
-			->method('writeArrayInOutputFormat')
446
-			->with($this->consoleInput, $this->consoleOutput, ['settings']);
447
-
448
-
449
-		$this->assertEquals(0, $this->invokePrivate($command, 'execute', [$this->consoleInput, $this->consoleOutput]));
450
-	}
21
+    protected IUserManager&MockObject $userManager;
22
+    protected IConfig&MockObject $config;
23
+    protected IDBConnection&MockObject $connection;
24
+    protected InputInterface&MockObject $consoleInput;
25
+    protected MockObject&OutputInterface $consoleOutput;
26
+
27
+    protected function setUp(): void {
28
+        parent::setUp();
29
+
30
+        $this->userManager = $this->createMock(IUserManager::class);
31
+        $this->config = $this->createMock(IConfig::class);
32
+        $this->connection = $this->createMock(IDBConnection::class);
33
+        $this->consoleInput = $this->createMock(InputInterface::class);
34
+        $this->consoleOutput = $this->createMock(OutputInterface::class);
35
+    }
36
+
37
+    public function getCommand(array $methods = []) {
38
+        if (empty($methods)) {
39
+            return new Setting($this->userManager, $this->config);
40
+        } else {
41
+            $mock = $this->getMockBuilder(Setting::class)
42
+                ->setConstructorArgs([
43
+                    $this->userManager,
44
+                    $this->config,
45
+                ])
46
+                ->onlyMethods($methods)
47
+                ->getMock();
48
+            return $mock;
49
+        }
50
+    }
51
+
52
+    public static function dataCheckInput(): array {
53
+        return [
54
+            [
55
+                [['uid', 'username']],
56
+                [['ignore-missing-user', true]],
57
+                [],
58
+                false,
59
+                false,
60
+            ],
61
+            [
62
+                [['uid', 'username']],
63
+                [['ignore-missing-user', false]],
64
+                [],
65
+                null,
66
+                'The user "username" does not exist.',
67
+            ],
68
+
69
+            [
70
+                [['uid', 'username'], ['key', 'configkey']],
71
+                [['ignore-missing-user', true]],
72
+                [['--default-value', false, true]],
73
+                false,
74
+                false,
75
+            ],
76
+            [
77
+                [['uid', 'username'], ['key', '']],
78
+                [['ignore-missing-user', true]],
79
+                [['--default-value', false, true]],
80
+                false,
81
+                'The "default-value" option can only be used when specifying a key.',
82
+            ],
83
+
84
+            [
85
+                [['uid', 'username'], ['key', 'configkey'], ['value', '']],
86
+                [['ignore-missing-user', true]],
87
+                [],
88
+                false,
89
+                false,
90
+            ],
91
+            [
92
+                [['uid', 'username'], ['key', ''], ['value', '']],
93
+                [['ignore-missing-user', true]],
94
+                [],
95
+                false,
96
+                'The value argument can only be used when specifying a key.',
97
+            ],
98
+            [
99
+                [['uid', 'username'], ['key', 'configkey'], ['value', '']],
100
+                [['ignore-missing-user', true]],
101
+                [['--default-value', false, true]],
102
+                false,
103
+                'The value argument can not be used together with "default-value".',
104
+            ],
105
+            [
106
+                [['uid', 'username'], ['key', 'configkey'], ['value', '']],
107
+                [['ignore-missing-user', true], ['update-only', true]],
108
+                [],
109
+                false,
110
+                false,
111
+            ],
112
+            [
113
+                [['uid', 'username'], ['key', 'configkey'], ['value', null]],
114
+                [['ignore-missing-user', true], ['update-only', true]],
115
+                [],
116
+                false,
117
+                'The "update-only" option can only be used together with "value".',
118
+            ],
119
+
120
+            [
121
+                [['uid', 'username'], ['key', 'configkey']],
122
+                [['ignore-missing-user', true], ['delete', true]],
123
+                [],
124
+                false,
125
+                false,
126
+            ],
127
+            [
128
+                [['uid', 'username'], ['key', '']],
129
+                [['ignore-missing-user', true], ['delete', true]],
130
+                [],
131
+                false,
132
+                'The "delete" option can only be used when specifying a key.',
133
+            ],
134
+            [
135
+                [['uid', 'username'], ['key', 'configkey']],
136
+                [['ignore-missing-user', true], ['delete', true]],
137
+                [['--default-value', false, true]],
138
+                false,
139
+                'The "delete" option can not be used together with "default-value".',
140
+            ],
141
+            [
142
+                [['uid', 'username'], ['key', 'configkey'], ['value', '']],
143
+                [['ignore-missing-user', true], ['delete', true]],
144
+                [],
145
+                false,
146
+                'The "delete" option can not be used together with "value".',
147
+            ],
148
+            [
149
+                [['uid', 'username'], ['key', 'configkey']],
150
+                [['ignore-missing-user', true], ['delete', true], ['error-if-not-exists', true]],
151
+                [],
152
+                false,
153
+                false,
154
+            ],
155
+            [
156
+                [['uid', 'username'], ['key', 'configkey']],
157
+                [['ignore-missing-user', true], ['delete', false], ['error-if-not-exists', true]],
158
+                [],
159
+                false,
160
+                'The "error-if-not-exists" option can only be used together with "delete".',
161
+            ],
162
+        ];
163
+    }
164
+
165
+    /**
166
+     * @dataProvider dataCheckInput
167
+     *
168
+     * @param array $arguments
169
+     * @param array $options
170
+     * @param array $parameterOptions
171
+     * @param mixed $user
172
+     * @param string $expectedException
173
+     */
174
+    public function testCheckInput($arguments, $options, $parameterOptions, $user, $expectedException): void {
175
+        $this->consoleInput->expects($this->any())
176
+            ->method('getArgument')
177
+            ->willReturnMap($arguments);
178
+        $this->consoleInput->expects($this->any())
179
+            ->method('getOption')
180
+            ->willReturnMap($options);
181
+        $this->consoleInput->expects($this->any())
182
+            ->method('hasParameterOption')
183
+            ->willReturnCallback(function (string|array $config, bool $default = false) use ($parameterOptions): bool {
184
+                foreach ($parameterOptions as $parameterOption) {
185
+                    if ($config === $parameterOption[0]
186
+                        // Check the default value if the maps has 3 entries
187
+                        && (!isset($parameterOption[2]) || $default === $parameterOption[1])) {
188
+                        return end($parameterOption);
189
+                    }
190
+                }
191
+                return false;
192
+            });
193
+
194
+        if ($user !== false) {
195
+            $this->userManager->expects($this->once())
196
+                ->method('get')
197
+                ->willReturn($user);
198
+        } else {
199
+            $this->userManager->expects($this->never())
200
+                ->method('get');
201
+        }
202
+
203
+        $command = $this->getCommand();
204
+        try {
205
+            $this->invokePrivate($command, 'checkInput', [$this->consoleInput]);
206
+            $this->assertFalse($expectedException);
207
+        } catch (InvalidArgumentException $e) {
208
+            $this->assertEquals($expectedException, $e->getMessage());
209
+        }
210
+    }
211
+
212
+    public function testCheckInputExceptionCatch(): void {
213
+        $command = $this->getCommand(['checkInput']);
214
+        $command->expects($this->once())
215
+            ->method('checkInput')
216
+            ->willThrowException(new InvalidArgumentException('test'));
217
+
218
+        $this->consoleOutput->expects($this->once())
219
+            ->method('writeln')
220
+            ->with('<error>test</error>');
221
+
222
+        $this->assertEquals(1, $this->invokePrivate($command, 'execute', [$this->consoleInput, $this->consoleOutput]));
223
+    }
224
+
225
+    public static function dataExecuteDelete(): array {
226
+        return [
227
+            ['config', false, null, 0],
228
+            ['config', true, null, 0],
229
+            [null, false, null, 0],
230
+            [null, true, '<error>The setting does not exist for user "username".</error>', 1],
231
+        ];
232
+    }
233
+
234
+    /**
235
+     * @dataProvider dataExecuteDelete
236
+     *
237
+     * @param string|null $value
238
+     * @param bool $errorIfNotExists
239
+     * @param string $expectedLine
240
+     * @param int $expectedReturn
241
+     */
242
+    public function testExecuteDelete($value, $errorIfNotExists, $expectedLine, $expectedReturn): void {
243
+        $command = $this->getCommand([
244
+            'writeArrayInOutputFormat',
245
+            'checkInput',
246
+            'getUserSettings',
247
+        ]);
248
+
249
+        $this->consoleInput->expects($this->any())
250
+            ->method('getArgument')
251
+            ->willReturnMap([
252
+                ['uid', 'username'],
253
+                ['app', 'appname'],
254
+                ['key', 'configkey'],
255
+            ]);
256
+
257
+        $command->expects($this->once())
258
+            ->method('checkInput');
259
+
260
+        $this->config->expects($this->once())
261
+            ->method('getUserValue')
262
+            ->with('username', 'appname', 'configkey', null)
263
+            ->willReturn($value);
264
+
265
+        $this->consoleInput->expects($this->atLeastOnce())
266
+            ->method('hasParameterOption')
267
+            ->willReturnMap([
268
+                ['--delete', false, true],
269
+                ['--error-if-not-exists', false, $errorIfNotExists],
270
+            ]);
271
+
272
+        if ($expectedLine === null) {
273
+            $this->consoleOutput->expects($this->never())
274
+                ->method('writeln');
275
+            $this->config->expects($this->once())
276
+                ->method('deleteUserValue')
277
+                ->with('username', 'appname', 'configkey');
278
+        } else {
279
+            $this->consoleOutput->expects($this->once())
280
+                ->method('writeln')
281
+                ->with($expectedLine);
282
+            $this->config->expects($this->never())
283
+                ->method('deleteUserValue');
284
+        }
285
+
286
+        $this->assertEquals($expectedReturn, $this->invokePrivate($command, 'execute', [$this->consoleInput, $this->consoleOutput]));
287
+    }
288
+
289
+    public static function dataExecuteSet(): array {
290
+        return [
291
+            ['config', false, null, 0],
292
+            ['config', true, null, 0],
293
+            [null, false, null, 0],
294
+            [null, true, '<error>The setting does not exist for user "username".</error>', 1],
295
+        ];
296
+    }
297
+
298
+    /**
299
+     * @dataProvider dataExecuteSet
300
+     *
301
+     * @param string|null $value
302
+     * @param bool $updateOnly
303
+     * @param string $expectedLine
304
+     * @param int $expectedReturn
305
+     */
306
+    public function testExecuteSet($value, $updateOnly, $expectedLine, $expectedReturn): void {
307
+        $command = $this->getCommand([
308
+            'writeArrayInOutputFormat',
309
+            'checkInput',
310
+            'getUserSettings',
311
+        ]);
312
+
313
+        $this->consoleInput->expects($this->atLeast(4))
314
+            ->method('getArgument')
315
+            ->willReturnMap([
316
+                ['uid', 'username'],
317
+                ['app', 'appname'],
318
+                ['key', 'configkey'],
319
+                ['value', 'setValue'],
320
+            ]);
321
+
322
+        $command->expects($this->once())
323
+            ->method('checkInput');
324
+
325
+        $this->config->expects($this->once())
326
+            ->method('getUserValue')
327
+            ->with('username', 'appname', 'configkey', null)
328
+            ->willReturn($value);
329
+
330
+        $this->consoleInput->expects($this->atLeastOnce())
331
+            ->method('hasParameterOption')
332
+            ->willReturnMap([
333
+                ['--update-only', false, $updateOnly],
334
+            ]);
335
+
336
+        if ($expectedLine === null) {
337
+            $this->consoleOutput->expects($this->never())
338
+                ->method('writeln');
339
+
340
+            $this->consoleInput->expects($this->never())
341
+                ->method('getOption');
342
+
343
+            $this->config->expects($this->once())
344
+                ->method('setUserValue')
345
+                ->with('username', 'appname', 'configkey', 'setValue');
346
+        } else {
347
+            $this->consoleOutput->expects($this->once())
348
+                ->method('writeln')
349
+                ->with($expectedLine);
350
+            $this->config->expects($this->never())
351
+                ->method('setUserValue');
352
+        }
353
+
354
+        $this->assertEquals($expectedReturn, $this->invokePrivate($command, 'execute', [$this->consoleInput, $this->consoleOutput]));
355
+    }
356
+
357
+    public static function dataExecuteGet(): array {
358
+        return [
359
+            ['config', null, 'config', 0],
360
+            [null, 'config', 'config', 0],
361
+            [null, null, '<error>The setting does not exist for user "username".</error>', 1],
362
+        ];
363
+    }
364
+
365
+    /**
366
+     * @dataProvider dataExecuteGet
367
+     *
368
+     * @param string|null $value
369
+     * @param string|null $defaultValue
370
+     * @param string $expectedLine
371
+     * @param int $expectedReturn
372
+     */
373
+    public function testExecuteGet($value, $defaultValue, $expectedLine, $expectedReturn): void {
374
+        $command = $this->getCommand([
375
+            'writeArrayInOutputFormat',
376
+            'checkInput',
377
+            'getUserSettings',
378
+        ]);
379
+
380
+        $this->consoleInput->expects($this->any())
381
+            ->method('getArgument')
382
+            ->willReturnMap([
383
+                ['uid', 'username'],
384
+                ['app', 'appname'],
385
+                ['key', 'configkey'],
386
+            ]);
387
+
388
+        $command->expects($this->once())
389
+            ->method('checkInput');
390
+
391
+        $this->config->expects($this->once())
392
+            ->method('getUserValue')
393
+            ->with('username', 'appname', 'configkey', null)
394
+            ->willReturn($value);
395
+
396
+        if ($value === null) {
397
+            if ($defaultValue === null) {
398
+                $this->consoleInput->expects($this->atLeastOnce())
399
+                    ->method('hasParameterOption')
400
+                    ->willReturn(false);
401
+            } else {
402
+                $this->consoleInput->expects($this->atLeastOnce())
403
+                    ->method('hasParameterOption')
404
+                    ->willReturnCallback(function (string|array $config, bool $default = false): bool {
405
+                        if ($config === '--default-value' && $default === false) {
406
+                            return true;
407
+                        }
408
+                        return false;
409
+                    });
410
+                $this->consoleInput->expects($this->once())
411
+                    ->method('getOption')
412
+                    ->with('default-value')
413
+                    ->willReturn($defaultValue);
414
+            }
415
+        }
416
+
417
+        $this->consoleOutput->expects($this->once())
418
+            ->method('writeln')
419
+            ->with($expectedLine);
420
+
421
+        $this->assertEquals($expectedReturn, $this->invokePrivate($command, 'execute', [$this->consoleInput, $this->consoleOutput]));
422
+    }
423
+
424
+    public function testExecuteList(): void {
425
+        $command = $this->getCommand([
426
+            'writeArrayInOutputFormat',
427
+            'checkInput',
428
+            'getUserSettings',
429
+        ]);
430
+
431
+        $this->consoleInput->expects($this->any())
432
+            ->method('getArgument')
433
+            ->willReturnMap([
434
+                ['uid', 'username'],
435
+                ['app', 'appname'],
436
+                ['key', ''],
437
+            ]);
438
+
439
+        $command->expects($this->once())
440
+            ->method('checkInput');
441
+        $command->expects($this->once())
442
+            ->method('getUserSettings')
443
+            ->willReturn(['settings']);
444
+        $command->expects($this->once())
445
+            ->method('writeArrayInOutputFormat')
446
+            ->with($this->consoleInput, $this->consoleOutput, ['settings']);
447
+
448
+
449
+        $this->assertEquals(0, $this->invokePrivate($command, 'execute', [$this->consoleInput, $this->consoleOutput]));
450
+    }
451 451
 }
Please login to merge, or discard this patch.
core/register_command.php 1 patch
Indentation   +132 added lines, -132 removed lines patch added patch discarded remove patch
@@ -114,137 +114,137 @@
 block discarded – undo
114 114
 $config = Server::get(IConfig::class);
115 115
 
116 116
 if ($config->getSystemValueBool('installed', false)) {
117
-	$application->add(Server::get(Disable::class));
118
-	$application->add(Server::get(Enable::class));
119
-	$application->add(Server::get(Install::class));
120
-	$application->add(Server::get(GetPath::class));
121
-	$application->add(Server::get(ListApps::class));
122
-	$application->add(Server::get(Remove::class));
123
-	$application->add(Server::get(Update::class));
124
-
125
-	$application->add(Server::get(Cleanup::class));
126
-	$application->add(Server::get(Enforce::class));
127
-	$application->add(Server::get(Command\TwoFactorAuth\Enable::class));
128
-	$application->add(Server::get(Command\TwoFactorAuth\Disable::class));
129
-	$application->add(Server::get(State::class));
130
-
131
-	$application->add(Server::get(Mode::class));
132
-	$application->add(Server::get(Job::class));
133
-	$application->add(Server::get(ListCommand::class));
134
-	$application->add(Server::get(Delete::class));
135
-	$application->add(Server::get(JobWorker::class));
136
-
137
-	$application->add(Server::get(Test::class));
138
-
139
-	$application->add(Server::get(DeleteConfig::class));
140
-	$application->add(Server::get(GetConfig::class));
141
-	$application->add(Server::get(SetConfig::class));
142
-	$application->add(Server::get(Import::class));
143
-	$application->add(Server::get(ListConfigs::class));
144
-	$application->add(Server::get(Command\Config\System\DeleteConfig::class));
145
-	$application->add(Server::get(Command\Config\System\GetConfig::class));
146
-	$application->add(Server::get(Command\Config\System\SetConfig::class));
147
-
148
-	$application->add(Server::get(File::class));
149
-	$application->add(Server::get(Space::class));
150
-	$application->add(Server::get(Storage::class));
151
-	$application->add(Server::get(Storages::class));
152
-
153
-	$application->add(Server::get(ConvertType::class));
154
-	$application->add(Server::get(ConvertMysqlToMB4::class));
155
-	$application->add(Server::get(ConvertFilecacheBigInt::class));
156
-	$application->add(Server::get(AddMissingColumns::class));
157
-	$application->add(Server::get(AddMissingIndices::class));
158
-	$application->add(Server::get(AddMissingPrimaryKeys::class));
159
-	$application->add(Server::get(ExpectedSchema::class));
160
-	$application->add(Server::get(ExportSchema::class));
161
-
162
-	$application->add(Server::get(GenerateMetadataCommand::class));
163
-	$application->add(Server::get(PreviewCommand::class));
164
-	if ($config->getSystemValueBool('debug', false)) {
165
-		$application->add(Server::get(StatusCommand::class));
166
-		$application->add(Server::get(MigrateCommand::class));
167
-		$application->add(Server::get(GenerateCommand::class));
168
-		$application->add(Server::get(ExecuteCommand::class));
169
-	}
170
-
171
-	$application->add(Server::get(Command\Encryption\Disable::class));
172
-	$application->add(Server::get(Command\Encryption\Enable::class));
173
-	$application->add(Server::get(ListModules::class));
174
-	$application->add(Server::get(SetDefaultModule::class));
175
-	$application->add(Server::get(Command\Encryption\Status::class));
176
-	$application->add(Server::get(EncryptAll::class));
177
-	$application->add(Server::get(DecryptAll::class));
178
-
179
-	$application->add(Server::get(Manage::class));
180
-	$application->add(Server::get(Command\Log\File::class));
181
-
182
-	$application->add(Server::get(ChangeKeyStorageRoot::class));
183
-	$application->add(Server::get(ShowKeyStorageRoot::class));
184
-	$application->add(Server::get(MigrateKeyStorage::class));
185
-
186
-	$application->add(Server::get(DataFingerprint::class));
187
-	$application->add(Server::get(UpdateDB::class));
188
-	$application->add(Server::get(UpdateJS::class));
189
-	$application->add(Server::get(Command\Maintenance\Mode::class));
190
-	$application->add(Server::get(UpdateHtaccess::class));
191
-	$application->add(Server::get(UpdateTheme::class));
192
-
193
-	$application->add(Server::get(Upgrade::class));
194
-	$application->add(Server::get(Repair::class));
195
-	$application->add(Server::get(RepairShareOwnership::class));
196
-
197
-	$application->add(Server::get(Command\Preview\Cleanup::class));
198
-	$application->add(Server::get(Generate::class));
199
-	$application->add(Server::get(Command\Preview\Repair::class));
200
-	$application->add(Server::get(ResetRenderedTexts::class));
201
-
202
-	$application->add(Server::get(Add::class));
203
-	$application->add(Server::get(Command\User\Delete::class));
204
-	$application->add(Server::get(Command\User\Disable::class));
205
-	$application->add(Server::get(Command\User\Enable::class));
206
-	$application->add(Server::get(LastSeen::class));
207
-	$application->add(Server::get(Report::class));
208
-	$application->add(Server::get(ResetPassword::class));
209
-	$application->add(Server::get(Setting::class));
210
-	$application->add(Server::get(Profile::class));
211
-	$application->add(Server::get(Command\User\ListCommand::class));
212
-	$application->add(Server::get(ClearGeneratedAvatarCacheCommand::class));
213
-	$application->add(Server::get(Info::class));
214
-	$application->add(Server::get(SyncAccountDataCommand::class));
215
-	$application->add(Server::get(Command\User\AuthTokens\Add::class));
216
-	$application->add(Server::get(Command\User\AuthTokens\ListCommand::class));
217
-	$application->add(Server::get(Command\User\AuthTokens\Delete::class));
218
-	$application->add(Server::get(Verify::class));
219
-	$application->add(Server::get(Welcome::class));
220
-
221
-	$application->add(Server::get(Command\Group\Add::class));
222
-	$application->add(Server::get(Command\Group\Delete::class));
223
-	$application->add(Server::get(Command\Group\ListCommand::class));
224
-	$application->add(Server::get(AddUser::class));
225
-	$application->add(Server::get(RemoveUser::class));
226
-	$application->add(Server::get(Command\Group\Info::class));
227
-
228
-	$application->add(Server::get(Command\SystemTag\ListCommand::class));
229
-	$application->add(Server::get(Command\SystemTag\Delete::class));
230
-	$application->add(Server::get(Command\SystemTag\Add::class));
231
-	$application->add(Server::get(Edit::class));
232
-
233
-	$application->add(Server::get(ListCertificates::class));
234
-	$application->add(Server::get(ExportCertificates::class));
235
-	$application->add(Server::get(ImportCertificate::class));
236
-	$application->add(Server::get(RemoveCertificate::class));
237
-	$application->add(Server::get(BruteforceAttempts::class));
238
-	$application->add(Server::get(BruteforceResetAttempts::class));
239
-	$application->add(Server::get(SetupChecks::class));
240
-	$application->add(Server::get(Get::class));
241
-
242
-	$application->add(Server::get(GetCommand::class));
243
-	$application->add(Server::get(EnabledCommand::class));
244
-	$application->add(Server::get(Command\TaskProcessing\ListCommand::class));
245
-	$application->add(Server::get(Statistics::class));
246
-
247
-	$application->add(Server::get(RedisCommand::class));
117
+    $application->add(Server::get(Disable::class));
118
+    $application->add(Server::get(Enable::class));
119
+    $application->add(Server::get(Install::class));
120
+    $application->add(Server::get(GetPath::class));
121
+    $application->add(Server::get(ListApps::class));
122
+    $application->add(Server::get(Remove::class));
123
+    $application->add(Server::get(Update::class));
124
+
125
+    $application->add(Server::get(Cleanup::class));
126
+    $application->add(Server::get(Enforce::class));
127
+    $application->add(Server::get(Command\TwoFactorAuth\Enable::class));
128
+    $application->add(Server::get(Command\TwoFactorAuth\Disable::class));
129
+    $application->add(Server::get(State::class));
130
+
131
+    $application->add(Server::get(Mode::class));
132
+    $application->add(Server::get(Job::class));
133
+    $application->add(Server::get(ListCommand::class));
134
+    $application->add(Server::get(Delete::class));
135
+    $application->add(Server::get(JobWorker::class));
136
+
137
+    $application->add(Server::get(Test::class));
138
+
139
+    $application->add(Server::get(DeleteConfig::class));
140
+    $application->add(Server::get(GetConfig::class));
141
+    $application->add(Server::get(SetConfig::class));
142
+    $application->add(Server::get(Import::class));
143
+    $application->add(Server::get(ListConfigs::class));
144
+    $application->add(Server::get(Command\Config\System\DeleteConfig::class));
145
+    $application->add(Server::get(Command\Config\System\GetConfig::class));
146
+    $application->add(Server::get(Command\Config\System\SetConfig::class));
147
+
148
+    $application->add(Server::get(File::class));
149
+    $application->add(Server::get(Space::class));
150
+    $application->add(Server::get(Storage::class));
151
+    $application->add(Server::get(Storages::class));
152
+
153
+    $application->add(Server::get(ConvertType::class));
154
+    $application->add(Server::get(ConvertMysqlToMB4::class));
155
+    $application->add(Server::get(ConvertFilecacheBigInt::class));
156
+    $application->add(Server::get(AddMissingColumns::class));
157
+    $application->add(Server::get(AddMissingIndices::class));
158
+    $application->add(Server::get(AddMissingPrimaryKeys::class));
159
+    $application->add(Server::get(ExpectedSchema::class));
160
+    $application->add(Server::get(ExportSchema::class));
161
+
162
+    $application->add(Server::get(GenerateMetadataCommand::class));
163
+    $application->add(Server::get(PreviewCommand::class));
164
+    if ($config->getSystemValueBool('debug', false)) {
165
+        $application->add(Server::get(StatusCommand::class));
166
+        $application->add(Server::get(MigrateCommand::class));
167
+        $application->add(Server::get(GenerateCommand::class));
168
+        $application->add(Server::get(ExecuteCommand::class));
169
+    }
170
+
171
+    $application->add(Server::get(Command\Encryption\Disable::class));
172
+    $application->add(Server::get(Command\Encryption\Enable::class));
173
+    $application->add(Server::get(ListModules::class));
174
+    $application->add(Server::get(SetDefaultModule::class));
175
+    $application->add(Server::get(Command\Encryption\Status::class));
176
+    $application->add(Server::get(EncryptAll::class));
177
+    $application->add(Server::get(DecryptAll::class));
178
+
179
+    $application->add(Server::get(Manage::class));
180
+    $application->add(Server::get(Command\Log\File::class));
181
+
182
+    $application->add(Server::get(ChangeKeyStorageRoot::class));
183
+    $application->add(Server::get(ShowKeyStorageRoot::class));
184
+    $application->add(Server::get(MigrateKeyStorage::class));
185
+
186
+    $application->add(Server::get(DataFingerprint::class));
187
+    $application->add(Server::get(UpdateDB::class));
188
+    $application->add(Server::get(UpdateJS::class));
189
+    $application->add(Server::get(Command\Maintenance\Mode::class));
190
+    $application->add(Server::get(UpdateHtaccess::class));
191
+    $application->add(Server::get(UpdateTheme::class));
192
+
193
+    $application->add(Server::get(Upgrade::class));
194
+    $application->add(Server::get(Repair::class));
195
+    $application->add(Server::get(RepairShareOwnership::class));
196
+
197
+    $application->add(Server::get(Command\Preview\Cleanup::class));
198
+    $application->add(Server::get(Generate::class));
199
+    $application->add(Server::get(Command\Preview\Repair::class));
200
+    $application->add(Server::get(ResetRenderedTexts::class));
201
+
202
+    $application->add(Server::get(Add::class));
203
+    $application->add(Server::get(Command\User\Delete::class));
204
+    $application->add(Server::get(Command\User\Disable::class));
205
+    $application->add(Server::get(Command\User\Enable::class));
206
+    $application->add(Server::get(LastSeen::class));
207
+    $application->add(Server::get(Report::class));
208
+    $application->add(Server::get(ResetPassword::class));
209
+    $application->add(Server::get(Setting::class));
210
+    $application->add(Server::get(Profile::class));
211
+    $application->add(Server::get(Command\User\ListCommand::class));
212
+    $application->add(Server::get(ClearGeneratedAvatarCacheCommand::class));
213
+    $application->add(Server::get(Info::class));
214
+    $application->add(Server::get(SyncAccountDataCommand::class));
215
+    $application->add(Server::get(Command\User\AuthTokens\Add::class));
216
+    $application->add(Server::get(Command\User\AuthTokens\ListCommand::class));
217
+    $application->add(Server::get(Command\User\AuthTokens\Delete::class));
218
+    $application->add(Server::get(Verify::class));
219
+    $application->add(Server::get(Welcome::class));
220
+
221
+    $application->add(Server::get(Command\Group\Add::class));
222
+    $application->add(Server::get(Command\Group\Delete::class));
223
+    $application->add(Server::get(Command\Group\ListCommand::class));
224
+    $application->add(Server::get(AddUser::class));
225
+    $application->add(Server::get(RemoveUser::class));
226
+    $application->add(Server::get(Command\Group\Info::class));
227
+
228
+    $application->add(Server::get(Command\SystemTag\ListCommand::class));
229
+    $application->add(Server::get(Command\SystemTag\Delete::class));
230
+    $application->add(Server::get(Command\SystemTag\Add::class));
231
+    $application->add(Server::get(Edit::class));
232
+
233
+    $application->add(Server::get(ListCertificates::class));
234
+    $application->add(Server::get(ExportCertificates::class));
235
+    $application->add(Server::get(ImportCertificate::class));
236
+    $application->add(Server::get(RemoveCertificate::class));
237
+    $application->add(Server::get(BruteforceAttempts::class));
238
+    $application->add(Server::get(BruteforceResetAttempts::class));
239
+    $application->add(Server::get(SetupChecks::class));
240
+    $application->add(Server::get(Get::class));
241
+
242
+    $application->add(Server::get(GetCommand::class));
243
+    $application->add(Server::get(EnabledCommand::class));
244
+    $application->add(Server::get(Command\TaskProcessing\ListCommand::class));
245
+    $application->add(Server::get(Statistics::class));
246
+
247
+    $application->add(Server::get(RedisCommand::class));
248 248
 } else {
249
-	$application->add(Server::get(Command\Maintenance\Install::class));
249
+    $application->add(Server::get(Command\Maintenance\Install::class));
250 250
 }
Please login to merge, or discard this patch.
core/Command/User/Profile.php 1 patch
Indentation   +210 added lines, -210 removed lines patch added patch discarded remove patch
@@ -21,214 +21,214 @@
 block discarded – undo
21 21
 use Symfony\Component\Console\Output\OutputInterface;
22 22
 
23 23
 class Profile extends Base {
24
-	public function __construct(
25
-		protected IUserManager $userManager,
26
-		protected IAccountManager $accountManager,
27
-	) {
28
-		parent::__construct();
29
-	}
30
-
31
-	protected function configure() {
32
-		parent::configure();
33
-		$this
34
-			->setName('user:profile')
35
-			->setDescription('Read and modify user profile properties')
36
-			->addArgument(
37
-				'uid',
38
-				InputArgument::REQUIRED,
39
-				'Account ID used to login'
40
-			)
41
-			->addArgument(
42
-				'key',
43
-				InputArgument::OPTIONAL,
44
-				'Profile property to set, get or delete',
45
-				''
46
-			)
47
-
48
-			// Get
49
-			->addOption(
50
-				'default-value',
51
-				null,
52
-				InputOption::VALUE_REQUIRED,
53
-				'(Only applicable on get) If no default value is set and the property does not exist, the command will exit with 1'
54
-			)
55
-
56
-			// Set
57
-			->addArgument(
58
-				'value',
59
-				InputArgument::OPTIONAL,
60
-				'The new value of the property',
61
-				null
62
-			)
63
-			->addOption(
64
-				'update-only',
65
-				null,
66
-				InputOption::VALUE_NONE,
67
-				'Only updates the value, if it is not set before, it is not being added'
68
-			)
69
-
70
-			// Delete
71
-			->addOption(
72
-				'delete',
73
-				null,
74
-				InputOption::VALUE_NONE,
75
-				'Specify this option to delete the property value'
76
-			)
77
-			->addOption(
78
-				'error-if-not-exists',
79
-				null,
80
-				InputOption::VALUE_NONE,
81
-				'Checks whether the property exists before deleting it'
82
-			)
83
-		;
84
-	}
85
-
86
-	protected function checkInput(InputInterface $input): IUser {
87
-		$uid = $input->getArgument('uid');
88
-		$user = $this->userManager->get($uid);
89
-		if (!$user) {
90
-			throw new \InvalidArgumentException('The user "' . $uid . '" does not exist.');
91
-		}
92
-		// normalize uid
93
-		$input->setArgument('uid', $user->getUID());
94
-
95
-		$key = $input->getArgument('key');
96
-		if ($key === '') {
97
-			if ($input->hasParameterOption('--default-value')) {
98
-				throw new \InvalidArgumentException('The "default-value" option can only be used when specifying a key.');
99
-			}
100
-			if ($input->getArgument('value') !== null) {
101
-				throw new \InvalidArgumentException('The value argument can only be used when specifying a key.');
102
-			}
103
-			if ($input->getOption('delete')) {
104
-				throw new \InvalidArgumentException('The "delete" option can only be used when specifying a key.');
105
-			}
106
-		}
107
-
108
-		if ($input->getArgument('value') !== null && $input->hasParameterOption('--default-value')) {
109
-			throw new \InvalidArgumentException('The value argument can not be used together with "default-value".');
110
-		}
111
-		if ($input->getOption('update-only') && $input->getArgument('value') === null) {
112
-			throw new \InvalidArgumentException('The "update-only" option can only be used together with "value".');
113
-		}
114
-
115
-		if ($input->getOption('delete') && $input->hasParameterOption('--default-value')) {
116
-			throw new \InvalidArgumentException('The "delete" option can not be used together with "default-value".');
117
-		}
118
-		if ($input->getOption('delete') && $input->getArgument('value') !== null) {
119
-			throw new \InvalidArgumentException('The "delete" option can not be used together with "value".');
120
-		}
121
-		if ($input->getOption('error-if-not-exists') && !$input->getOption('delete')) {
122
-			throw new \InvalidArgumentException('The "error-if-not-exists" option can only be used together with "delete".');
123
-		}
124
-
125
-		return $user;
126
-	}
127
-
128
-	protected function execute(InputInterface $input, OutputInterface $output): int {
129
-		try {
130
-			$user = $this->checkInput($input);
131
-		} catch (\InvalidArgumentException $e) {
132
-			$output->writeln('<error>' . $e->getMessage() . '</error>');
133
-			return self::FAILURE;
134
-		}
135
-
136
-		$uid = $input->getArgument('uid');
137
-		$key = $input->getArgument('key');
138
-		$userAccount = $this->accountManager->getAccount($user);
139
-
140
-		if ($key === '') {
141
-			$settings = $this->getAllProfileProperties($userAccount);
142
-			$this->writeArrayInOutputFormat($input, $output, $settings);
143
-			return self::SUCCESS;
144
-		}
145
-
146
-		$value = $this->getStoredValue($userAccount, $key);
147
-		$inputValue = $input->getArgument('value');
148
-		if ($inputValue !== null) {
149
-			if ($input->hasParameterOption('--update-only') && $value === null) {
150
-				$output->writeln('<error>The property does not exist for user "' . $uid . '".</error>');
151
-				return self::FAILURE;
152
-			}
153
-
154
-			return $this->editProfileProperty($output, $userAccount, $key, $inputValue);
155
-		} elseif ($input->hasParameterOption('--delete')) {
156
-			if ($input->hasParameterOption('--error-if-not-exists') && $value === null) {
157
-				$output->writeln('<error>The property does not exist for user "' . $uid . '".</error>');
158
-				return self::FAILURE;
159
-			}
160
-
161
-			return $this->deleteProfileProperty($output, $userAccount, $key);
162
-		} elseif ($value !== null) {
163
-			$output->writeln($value);
164
-		} elseif ($input->hasParameterOption('--default-value')) {
165
-			$output->writeln($input->getOption('default-value'));
166
-		} else {
167
-			$output->writeln('<error>The property does not exist for user "' . $uid . '".</error>');
168
-			return self::FAILURE;
169
-		}
170
-
171
-		return self::SUCCESS;
172
-	}
173
-
174
-	private function deleteProfileProperty(OutputInterface $output, IAccount $userAccount, string $key): int {
175
-		return $this->editProfileProperty($output, $userAccount, $key, '');
176
-	}
177
-
178
-	private function editProfileProperty(OutputInterface $output, IAccount $userAccount, string $key, string $value): int {
179
-		try {
180
-			$userAccount->getProperty($key)->setValue($value);
181
-		} catch (PropertyDoesNotExistException $exception) {
182
-			$output->writeln('<error>' . $exception->getMessage() . '</error>');
183
-			return self::FAILURE;
184
-		}
185
-
186
-		$this->accountManager->updateAccount($userAccount);
187
-		return self::SUCCESS;
188
-	}
189
-
190
-	private function getStoredValue(IAccount $userAccount, string $key): ?string {
191
-		try {
192
-			$property = $userAccount->getProperty($key);
193
-		} catch (PropertyDoesNotExistException) {
194
-			return null;
195
-		}
196
-		return $property->getValue() === '' ? null : $property->getValue();
197
-	}
198
-
199
-	private function getAllProfileProperties(IAccount $userAccount): array {
200
-		$properties = [];
201
-
202
-		foreach ($userAccount->getAllProperties() as $property) {
203
-			if ($property->getValue() !== '') {
204
-				$properties[$property->getName()] = $property->getValue();
205
-			}
206
-		}
207
-
208
-		return $properties;
209
-	}
210
-
211
-	/**
212
-	 * @param string $argumentName
213
-	 * @param CompletionContext $context
214
-	 * @return string[]
215
-	 */
216
-	public function completeArgumentValues($argumentName, CompletionContext $context): array {
217
-		if ($argumentName === 'uid') {
218
-			return array_map(static fn (IUser $user) => $user->getUID(), $this->userManager->search($context->getCurrentWord()));
219
-		}
220
-		if ($argumentName === 'key') {
221
-			$userId = $context->getWordAtIndex($context->getWordIndex() - 1);
222
-			$user = $this->userManager->get($userId);
223
-			if (!($user instanceof IUser)) {
224
-				return [];
225
-			}
226
-
227
-			$account = $this->accountManager->getAccount($user);
228
-
229
-			$properties = $this->getAllProfileProperties($account);
230
-			return array_keys($properties);
231
-		}
232
-		return [];
233
-	}
24
+    public function __construct(
25
+        protected IUserManager $userManager,
26
+        protected IAccountManager $accountManager,
27
+    ) {
28
+        parent::__construct();
29
+    }
30
+
31
+    protected function configure() {
32
+        parent::configure();
33
+        $this
34
+            ->setName('user:profile')
35
+            ->setDescription('Read and modify user profile properties')
36
+            ->addArgument(
37
+                'uid',
38
+                InputArgument::REQUIRED,
39
+                'Account ID used to login'
40
+            )
41
+            ->addArgument(
42
+                'key',
43
+                InputArgument::OPTIONAL,
44
+                'Profile property to set, get or delete',
45
+                ''
46
+            )
47
+
48
+            // Get
49
+            ->addOption(
50
+                'default-value',
51
+                null,
52
+                InputOption::VALUE_REQUIRED,
53
+                '(Only applicable on get) If no default value is set and the property does not exist, the command will exit with 1'
54
+            )
55
+
56
+            // Set
57
+            ->addArgument(
58
+                'value',
59
+                InputArgument::OPTIONAL,
60
+                'The new value of the property',
61
+                null
62
+            )
63
+            ->addOption(
64
+                'update-only',
65
+                null,
66
+                InputOption::VALUE_NONE,
67
+                'Only updates the value, if it is not set before, it is not being added'
68
+            )
69
+
70
+            // Delete
71
+            ->addOption(
72
+                'delete',
73
+                null,
74
+                InputOption::VALUE_NONE,
75
+                'Specify this option to delete the property value'
76
+            )
77
+            ->addOption(
78
+                'error-if-not-exists',
79
+                null,
80
+                InputOption::VALUE_NONE,
81
+                'Checks whether the property exists before deleting it'
82
+            )
83
+        ;
84
+    }
85
+
86
+    protected function checkInput(InputInterface $input): IUser {
87
+        $uid = $input->getArgument('uid');
88
+        $user = $this->userManager->get($uid);
89
+        if (!$user) {
90
+            throw new \InvalidArgumentException('The user "' . $uid . '" does not exist.');
91
+        }
92
+        // normalize uid
93
+        $input->setArgument('uid', $user->getUID());
94
+
95
+        $key = $input->getArgument('key');
96
+        if ($key === '') {
97
+            if ($input->hasParameterOption('--default-value')) {
98
+                throw new \InvalidArgumentException('The "default-value" option can only be used when specifying a key.');
99
+            }
100
+            if ($input->getArgument('value') !== null) {
101
+                throw new \InvalidArgumentException('The value argument can only be used when specifying a key.');
102
+            }
103
+            if ($input->getOption('delete')) {
104
+                throw new \InvalidArgumentException('The "delete" option can only be used when specifying a key.');
105
+            }
106
+        }
107
+
108
+        if ($input->getArgument('value') !== null && $input->hasParameterOption('--default-value')) {
109
+            throw new \InvalidArgumentException('The value argument can not be used together with "default-value".');
110
+        }
111
+        if ($input->getOption('update-only') && $input->getArgument('value') === null) {
112
+            throw new \InvalidArgumentException('The "update-only" option can only be used together with "value".');
113
+        }
114
+
115
+        if ($input->getOption('delete') && $input->hasParameterOption('--default-value')) {
116
+            throw new \InvalidArgumentException('The "delete" option can not be used together with "default-value".');
117
+        }
118
+        if ($input->getOption('delete') && $input->getArgument('value') !== null) {
119
+            throw new \InvalidArgumentException('The "delete" option can not be used together with "value".');
120
+        }
121
+        if ($input->getOption('error-if-not-exists') && !$input->getOption('delete')) {
122
+            throw new \InvalidArgumentException('The "error-if-not-exists" option can only be used together with "delete".');
123
+        }
124
+
125
+        return $user;
126
+    }
127
+
128
+    protected function execute(InputInterface $input, OutputInterface $output): int {
129
+        try {
130
+            $user = $this->checkInput($input);
131
+        } catch (\InvalidArgumentException $e) {
132
+            $output->writeln('<error>' . $e->getMessage() . '</error>');
133
+            return self::FAILURE;
134
+        }
135
+
136
+        $uid = $input->getArgument('uid');
137
+        $key = $input->getArgument('key');
138
+        $userAccount = $this->accountManager->getAccount($user);
139
+
140
+        if ($key === '') {
141
+            $settings = $this->getAllProfileProperties($userAccount);
142
+            $this->writeArrayInOutputFormat($input, $output, $settings);
143
+            return self::SUCCESS;
144
+        }
145
+
146
+        $value = $this->getStoredValue($userAccount, $key);
147
+        $inputValue = $input->getArgument('value');
148
+        if ($inputValue !== null) {
149
+            if ($input->hasParameterOption('--update-only') && $value === null) {
150
+                $output->writeln('<error>The property does not exist for user "' . $uid . '".</error>');
151
+                return self::FAILURE;
152
+            }
153
+
154
+            return $this->editProfileProperty($output, $userAccount, $key, $inputValue);
155
+        } elseif ($input->hasParameterOption('--delete')) {
156
+            if ($input->hasParameterOption('--error-if-not-exists') && $value === null) {
157
+                $output->writeln('<error>The property does not exist for user "' . $uid . '".</error>');
158
+                return self::FAILURE;
159
+            }
160
+
161
+            return $this->deleteProfileProperty($output, $userAccount, $key);
162
+        } elseif ($value !== null) {
163
+            $output->writeln($value);
164
+        } elseif ($input->hasParameterOption('--default-value')) {
165
+            $output->writeln($input->getOption('default-value'));
166
+        } else {
167
+            $output->writeln('<error>The property does not exist for user "' . $uid . '".</error>');
168
+            return self::FAILURE;
169
+        }
170
+
171
+        return self::SUCCESS;
172
+    }
173
+
174
+    private function deleteProfileProperty(OutputInterface $output, IAccount $userAccount, string $key): int {
175
+        return $this->editProfileProperty($output, $userAccount, $key, '');
176
+    }
177
+
178
+    private function editProfileProperty(OutputInterface $output, IAccount $userAccount, string $key, string $value): int {
179
+        try {
180
+            $userAccount->getProperty($key)->setValue($value);
181
+        } catch (PropertyDoesNotExistException $exception) {
182
+            $output->writeln('<error>' . $exception->getMessage() . '</error>');
183
+            return self::FAILURE;
184
+        }
185
+
186
+        $this->accountManager->updateAccount($userAccount);
187
+        return self::SUCCESS;
188
+    }
189
+
190
+    private function getStoredValue(IAccount $userAccount, string $key): ?string {
191
+        try {
192
+            $property = $userAccount->getProperty($key);
193
+        } catch (PropertyDoesNotExistException) {
194
+            return null;
195
+        }
196
+        return $property->getValue() === '' ? null : $property->getValue();
197
+    }
198
+
199
+    private function getAllProfileProperties(IAccount $userAccount): array {
200
+        $properties = [];
201
+
202
+        foreach ($userAccount->getAllProperties() as $property) {
203
+            if ($property->getValue() !== '') {
204
+                $properties[$property->getName()] = $property->getValue();
205
+            }
206
+        }
207
+
208
+        return $properties;
209
+    }
210
+
211
+    /**
212
+     * @param string $argumentName
213
+     * @param CompletionContext $context
214
+     * @return string[]
215
+     */
216
+    public function completeArgumentValues($argumentName, CompletionContext $context): array {
217
+        if ($argumentName === 'uid') {
218
+            return array_map(static fn (IUser $user) => $user->getUID(), $this->userManager->search($context->getCurrentWord()));
219
+        }
220
+        if ($argumentName === 'key') {
221
+            $userId = $context->getWordAtIndex($context->getWordIndex() - 1);
222
+            $user = $this->userManager->get($userId);
223
+            if (!($user instanceof IUser)) {
224
+                return [];
225
+            }
226
+
227
+            $account = $this->accountManager->getAccount($user);
228
+
229
+            $properties = $this->getAllProfileProperties($account);
230
+            return array_keys($properties);
231
+        }
232
+        return [];
233
+    }
234 234
 }
Please login to merge, or discard this patch.