Completed
Push — master ( 158b3e...c62fa5 )
by Joas
29:53 queued 14s
created
tests/lib/User/UserTest.php 1 patch
Indentation   +996 added lines, -996 removed lines patch added patch discarded remove patch
@@ -33,1000 +33,1000 @@
 block discarded – undo
33 33
  * @package Test\User
34 34
  */
35 35
 class UserTest extends TestCase {
36
-	/** @var IEventDispatcher|MockObject */
37
-	protected $dispatcher;
38
-
39
-	protected function setUp(): void {
40
-		parent::setUp();
41
-		$this->dispatcher = Server::get(IEventDispatcher::class);
42
-	}
43
-
44
-	public function testDisplayName(): void {
45
-		/**
46
-		 * @var \OC\User\Backend | MockObject $backend
47
-		 */
48
-		$backend = $this->createMock(\OC\User\Backend::class);
49
-		$backend->expects($this->once())
50
-			->method('getDisplayName')
51
-			->with($this->equalTo('foo'))
52
-			->willReturn('Foo');
53
-
54
-		$backend->expects($this->any())
55
-			->method('implementsActions')
56
-			->with($this->equalTo(\OC\User\Backend::GET_DISPLAYNAME))
57
-			->willReturn(true);
58
-
59
-		$user = new User('foo', $backend, $this->dispatcher);
60
-		$this->assertEquals('Foo', $user->getDisplayName());
61
-	}
62
-
63
-	/**
64
-	 * if the display name contain whitespaces only, we expect the uid as result
65
-	 */
66
-	public function testDisplayNameEmpty(): void {
67
-		/**
68
-		 * @var \OC\User\Backend | MockObject $backend
69
-		 */
70
-		$backend = $this->createMock(\OC\User\Backend::class);
71
-		$backend->expects($this->once())
72
-			->method('getDisplayName')
73
-			->with($this->equalTo('foo'))
74
-			->willReturn('  ');
75
-
76
-		$backend->expects($this->any())
77
-			->method('implementsActions')
78
-			->with($this->equalTo(\OC\User\Backend::GET_DISPLAYNAME))
79
-			->willReturn(true);
80
-
81
-		$user = new User('foo', $backend, $this->dispatcher);
82
-		$this->assertEquals('foo', $user->getDisplayName());
83
-	}
84
-
85
-	public function testDisplayNameNotSupported(): void {
86
-		/**
87
-		 * @var \OC\User\Backend | MockObject $backend
88
-		 */
89
-		$backend = $this->createMock(\OC\User\Backend::class);
90
-		$backend->expects($this->never())
91
-			->method('getDisplayName');
92
-
93
-		$backend->expects($this->any())
94
-			->method('implementsActions')
95
-			->with($this->equalTo(\OC\User\Backend::GET_DISPLAYNAME))
96
-			->willReturn(false);
97
-
98
-		$user = new User('foo', $backend, $this->dispatcher);
99
-		$this->assertEquals('foo', $user->getDisplayName());
100
-	}
101
-
102
-	public function testSetPassword(): void {
103
-		/**
104
-		 * @var Backend | MockObject $backend
105
-		 */
106
-		$backend = $this->createMock(\Test\Util\User\Dummy::class);
107
-		$backend->expects($this->once())
108
-			->method('setPassword')
109
-			->with($this->equalTo('foo'), $this->equalTo('bar'));
110
-
111
-		$backend->expects($this->any())
112
-			->method('implementsActions')
113
-			->willReturnCallback(function ($actions) {
114
-				if ($actions === \OC\User\Backend::SET_PASSWORD) {
115
-					return true;
116
-				} else {
117
-					return false;
118
-				}
119
-			});
120
-
121
-		$user = new User('foo', $backend, $this->dispatcher);
122
-		$this->assertTrue($user->setPassword('bar', ''));
123
-	}
124
-
125
-	public function testSetPasswordNotSupported(): void {
126
-		/**
127
-		 * @var Backend | MockObject $backend
128
-		 */
129
-		$backend = $this->createMock(\Test\Util\User\Dummy::class);
130
-		$backend->expects($this->never())
131
-			->method('setPassword');
132
-
133
-		$backend->expects($this->any())
134
-			->method('implementsActions')
135
-			->willReturn(false);
136
-
137
-		$user = new User('foo', $backend, $this->dispatcher);
138
-		$this->assertFalse($user->setPassword('bar', ''));
139
-	}
140
-
141
-	public function testChangeAvatarSupportedYes(): void {
142
-		/**
143
-		 * @var Backend | MockObject $backend
144
-		 */
145
-		$backend = $this->createMock(AvatarUserDummy::class);
146
-		$backend->expects($this->once())
147
-			->method('canChangeAvatar')
148
-			->with($this->equalTo('foo'))
149
-			->willReturn(true);
150
-
151
-		$backend->expects($this->any())
152
-			->method('implementsActions')
153
-			->willReturnCallback(function ($actions) {
154
-				if ($actions === \OC\User\Backend::PROVIDE_AVATAR) {
155
-					return true;
156
-				} else {
157
-					return false;
158
-				}
159
-			});
160
-
161
-		$user = new User('foo', $backend, $this->dispatcher);
162
-		$this->assertTrue($user->canChangeAvatar());
163
-	}
164
-
165
-	public function testChangeAvatarSupportedNo(): void {
166
-		/**
167
-		 * @var Backend | MockObject $backend
168
-		 */
169
-		$backend = $this->createMock(AvatarUserDummy::class);
170
-		$backend->expects($this->once())
171
-			->method('canChangeAvatar')
172
-			->with($this->equalTo('foo'))
173
-			->willReturn(false);
174
-
175
-		$backend->expects($this->any())
176
-			->method('implementsActions')
177
-			->willReturnCallback(function ($actions) {
178
-				if ($actions === \OC\User\Backend::PROVIDE_AVATAR) {
179
-					return true;
180
-				} else {
181
-					return false;
182
-				}
183
-			});
184
-
185
-		$user = new User('foo', $backend, $this->dispatcher);
186
-		$this->assertFalse($user->canChangeAvatar());
187
-	}
188
-
189
-	public function testChangeAvatarNotSupported(): void {
190
-		/**
191
-		 * @var Backend | MockObject $backend
192
-		 */
193
-		$backend = $this->createMock(AvatarUserDummy::class);
194
-		$backend->expects($this->never())
195
-			->method('canChangeAvatar');
196
-
197
-		$backend->expects($this->any())
198
-			->method('implementsActions')
199
-			->willReturn(false);
200
-
201
-		$user = new User('foo', $backend, $this->dispatcher);
202
-		$this->assertTrue($user->canChangeAvatar());
203
-	}
204
-
205
-	public function testDelete(): void {
206
-		/**
207
-		 * @var Backend | MockObject $backend
208
-		 */
209
-		$backend = $this->createMock(\Test\Util\User\Dummy::class);
210
-		$backend->expects($this->once())
211
-			->method('deleteUser')
212
-			->with($this->equalTo('foo'));
213
-
214
-		$user = new User('foo', $backend, $this->dispatcher);
215
-		$this->assertTrue($user->delete());
216
-	}
217
-
218
-	public function testDeleteWithDifferentHome(): void {
219
-		/** @var ObjectHomeMountProvider $homeProvider */
220
-		$homeProvider = \OC::$server->get(ObjectHomeMountProvider::class);
221
-		$user = $this->createMock(IUser::class);
222
-		$user->method('getUID')
223
-			->willReturn('foo');
224
-		if ($homeProvider->getHomeMountForUser($user, $this->createMock(IStorageFactory::class)) !== null) {
225
-			$this->markTestSkipped('Skipping test for non local home storage');
226
-		}
227
-
228
-		/**
229
-		 * @var Backend | MockObject $backend
230
-		 */
231
-		$backend = $this->createMock(\Test\Util\User\Dummy::class);
232
-
233
-		$backend->expects($this->once())
234
-			->method('implementsActions')
235
-			->willReturnCallback(function ($actions) {
236
-				if ($actions === \OC\User\Backend::GET_HOME) {
237
-					return true;
238
-				} else {
239
-					return false;
240
-				}
241
-			});
242
-
243
-		// important: getHome MUST be called before deleteUser because
244
-		// once the user is deleted, getHome implementations might not
245
-		// return anything
246
-		$backend->expects($this->once())
247
-			->method('getHome')
248
-			->with($this->equalTo('foo'))
249
-			->willReturn('/home/foo');
250
-
251
-		$backend->expects($this->once())
252
-			->method('deleteUser')
253
-			->with($this->equalTo('foo'));
254
-
255
-		$user = new User('foo', $backend, $this->dispatcher);
256
-		$this->assertTrue($user->delete());
257
-	}
258
-
259
-	public function testGetHome(): void {
260
-		/**
261
-		 * @var Backend | MockObject $backend
262
-		 */
263
-		$backend = $this->createMock(\Test\Util\User\Dummy::class);
264
-		$backend->expects($this->once())
265
-			->method('getHome')
266
-			->with($this->equalTo('foo'))
267
-			->willReturn('/home/foo');
268
-
269
-		$backend->expects($this->any())
270
-			->method('implementsActions')
271
-			->willReturnCallback(function ($actions) {
272
-				if ($actions === \OC\User\Backend::GET_HOME) {
273
-					return true;
274
-				} else {
275
-					return false;
276
-				}
277
-			});
278
-
279
-		$user = new User('foo', $backend, $this->dispatcher);
280
-		$this->assertEquals('/home/foo', $user->getHome());
281
-	}
282
-
283
-	public function testGetBackendClassName(): void {
284
-		$user = new User('foo', new \Test\Util\User\Dummy(), $this->dispatcher);
285
-		$this->assertEquals('Dummy', $user->getBackendClassName());
286
-		$user = new User('foo', new \OC\User\Database(), $this->dispatcher);
287
-		$this->assertEquals('Database', $user->getBackendClassName());
288
-	}
289
-
290
-	public function testGetHomeNotSupported(): void {
291
-		/**
292
-		 * @var Backend | MockObject $backend
293
-		 */
294
-		$backend = $this->createMock(\Test\Util\User\Dummy::class);
295
-		$backend->expects($this->never())
296
-			->method('getHome');
297
-
298
-		$backend->expects($this->any())
299
-			->method('implementsActions')
300
-			->willReturn(false);
301
-
302
-		$allConfig = $this->getMockBuilder(IConfig::class)
303
-			->disableOriginalConstructor()
304
-			->getMock();
305
-		$allConfig->expects($this->any())
306
-			->method('getUserValue')
307
-			->willReturn(true);
308
-		$allConfig->expects($this->any())
309
-			->method('getSystemValueString')
310
-			->with($this->equalTo('datadirectory'))
311
-			->willReturn('arbitrary/path');
312
-
313
-		$user = new User('foo', $backend, $this->dispatcher, null, $allConfig);
314
-		$this->assertEquals('arbitrary/path/foo', $user->getHome());
315
-	}
316
-
317
-	public function testCanChangePassword(): void {
318
-		/**
319
-		 * @var Backend | MockObject $backend
320
-		 */
321
-		$backend = $this->createMock(\Test\Util\User\Dummy::class);
322
-
323
-		$backend->expects($this->any())
324
-			->method('implementsActions')
325
-			->willReturnCallback(function ($actions) {
326
-				if ($actions === \OC\User\Backend::SET_PASSWORD) {
327
-					return true;
328
-				} else {
329
-					return false;
330
-				}
331
-			});
332
-
333
-		$user = new User('foo', $backend, $this->dispatcher);
334
-		$this->assertTrue($user->canChangePassword());
335
-	}
336
-
337
-	public function testCanChangePasswordNotSupported(): void {
338
-		/**
339
-		 * @var Backend | MockObject $backend
340
-		 */
341
-		$backend = $this->createMock(\Test\Util\User\Dummy::class);
342
-
343
-		$backend->expects($this->any())
344
-			->method('implementsActions')
345
-			->willReturn(false);
346
-
347
-		$user = new User('foo', $backend, $this->dispatcher);
348
-		$this->assertFalse($user->canChangePassword());
349
-	}
350
-
351
-	public function testCanChangeDisplayName(): void {
352
-		/**
353
-		 * @var Backend | MockObject $backend
354
-		 */
355
-		$backend = $this->createMock(\Test\Util\User\Dummy::class);
356
-
357
-		$backend->expects($this->any())
358
-			->method('implementsActions')
359
-			->willReturnCallback(function ($actions) {
360
-				if ($actions === \OC\User\Backend::SET_DISPLAYNAME) {
361
-					return true;
362
-				} else {
363
-					return false;
364
-				}
365
-			});
366
-
367
-		$config = $this->createMock(IConfig::class);
368
-		$config->method('getSystemValueBool')
369
-			->with('allow_user_to_change_display_name')
370
-			->willReturn(true);
371
-
372
-		$user = new User('foo', $backend, $this->dispatcher, null, $config);
373
-		$this->assertTrue($user->canChangeDisplayName());
374
-	}
375
-
376
-	public function testCanChangeDisplayNameNotSupported(): void {
377
-		/**
378
-		 * @var Backend | MockObject $backend
379
-		 */
380
-		$backend = $this->createMock(\Test\Util\User\Dummy::class);
381
-
382
-		$backend->expects($this->any())
383
-			->method('implementsActions')
384
-			->willReturn(false);
385
-
386
-		$user = new User('foo', $backend, $this->dispatcher);
387
-		$this->assertFalse($user->canChangeDisplayName());
388
-	}
389
-
390
-	public function testSetDisplayNameSupported(): void {
391
-		/**
392
-		 * @var Backend | MockObject $backend
393
-		 */
394
-		$backend = $this->createMock(\OC\User\Database::class);
395
-
396
-		$backend->expects($this->any())
397
-			->method('implementsActions')
398
-			->willReturnCallback(function ($actions) {
399
-				if ($actions === \OC\User\Backend::SET_DISPLAYNAME) {
400
-					return true;
401
-				} else {
402
-					return false;
403
-				}
404
-			});
405
-
406
-		$backend->expects($this->once())
407
-			->method('setDisplayName')
408
-			->with('foo', 'Foo')
409
-			->willReturn(true);
410
-
411
-		$user = new User('foo', $backend, $this->createMock(IEventDispatcher::class));
412
-		$this->assertTrue($user->setDisplayName('Foo'));
413
-		$this->assertEquals('Foo', $user->getDisplayName());
414
-	}
415
-
416
-	/**
417
-	 * don't allow display names containing whitespaces only
418
-	 */
419
-	public function testSetDisplayNameEmpty(): void {
420
-		/**
421
-		 * @var Backend | MockObject $backend
422
-		 */
423
-		$backend = $this->createMock(\OC\User\Database::class);
424
-
425
-		$backend->expects($this->any())
426
-			->method('implementsActions')
427
-			->willReturnCallback(function ($actions) {
428
-				if ($actions === \OC\User\Backend::SET_DISPLAYNAME) {
429
-					return true;
430
-				} else {
431
-					return false;
432
-				}
433
-			});
434
-
435
-		$user = new User('foo', $backend, $this->dispatcher);
436
-		$this->assertFalse($user->setDisplayName(' '));
437
-		$this->assertEquals('foo', $user->getDisplayName());
438
-	}
439
-
440
-	public function testSetDisplayNameNotSupported(): void {
441
-		/**
442
-		 * @var Backend | MockObject $backend
443
-		 */
444
-		$backend = $this->createMock(\OC\User\Database::class);
445
-
446
-		$backend->expects($this->any())
447
-			->method('implementsActions')
448
-			->willReturn(false);
449
-
450
-		$backend->expects($this->never())
451
-			->method('setDisplayName');
452
-
453
-		$user = new User('foo', $backend, $this->dispatcher);
454
-		$this->assertFalse($user->setDisplayName('Foo'));
455
-		$this->assertEquals('foo', $user->getDisplayName());
456
-	}
457
-
458
-	public function testSetPasswordHooks(): void {
459
-		$hooksCalled = 0;
460
-		$test = $this;
461
-
462
-		/**
463
-		 * @var Backend | MockObject $backend
464
-		 */
465
-		$backend = $this->createMock(\Test\Util\User\Dummy::class);
466
-		$backend->expects($this->once())
467
-			->method('setPassword');
468
-
469
-		/**
470
-		 * @param User $user
471
-		 * @param string $password
472
-		 */
473
-		$hook = function ($user, $password) use ($test, &$hooksCalled) {
474
-			$hooksCalled++;
475
-			$test->assertEquals('foo', $user->getUID());
476
-			$test->assertEquals('bar', $password);
477
-		};
478
-
479
-		$emitter = new PublicEmitter();
480
-		$emitter->listen('\OC\User', 'preSetPassword', $hook);
481
-		$emitter->listen('\OC\User', 'postSetPassword', $hook);
482
-
483
-		$backend->expects($this->any())
484
-			->method('implementsActions')
485
-			->willReturnCallback(function ($actions) {
486
-				if ($actions === \OC\User\Backend::SET_PASSWORD) {
487
-					return true;
488
-				} else {
489
-					return false;
490
-				}
491
-			});
492
-
493
-		$user = new User('foo', $backend, $this->dispatcher, $emitter);
494
-
495
-		$user->setPassword('bar', '');
496
-		$this->assertEquals(2, $hooksCalled);
497
-	}
498
-
499
-	public static function dataDeleteHooks(): array {
500
-		return [
501
-			[true, 2],
502
-			[false, 1],
503
-		];
504
-	}
505
-
506
-	/**
507
-	 * @dataProvider dataDeleteHooks
508
-	 * @param bool $result
509
-	 * @param int $expectedHooks
510
-	 */
511
-	public function testDeleteHooks($result, $expectedHooks): void {
512
-		$hooksCalled = 0;
513
-		$test = $this;
514
-
515
-		/**
516
-		 * @var UserInterface&MockObject $backend
517
-		 */
518
-		$backend = $this->createMock(\Test\Util\User\Dummy::class);
519
-		$backend->expects($this->once())
520
-			->method('deleteUser')
521
-			->willReturn($result);
522
-
523
-		$config = $this->createMock(IConfig::class);
524
-		$config->method('getSystemValue')
525
-			->willReturnArgument(1);
526
-		$config->method('getSystemValueString')
527
-			->willReturnArgument(1);
528
-		$config->method('getSystemValueBool')
529
-			->willReturnArgument(1);
530
-		$config->method('getSystemValueInt')
531
-			->willReturnArgument(1);
532
-
533
-		$emitter = new PublicEmitter();
534
-		$user = new User('foo', $backend, $this->dispatcher, $emitter, $config);
535
-
536
-		/**
537
-		 * @param User $user
538
-		 */
539
-		$hook = function ($user) use ($test, &$hooksCalled) {
540
-			$hooksCalled++;
541
-			$test->assertEquals('foo', $user->getUID());
542
-		};
543
-
544
-		$emitter->listen('\OC\User', 'preDelete', $hook);
545
-		$emitter->listen('\OC\User', 'postDelete', $hook);
546
-
547
-		$commentsManager = $this->createMock(ICommentsManager::class);
548
-		$notificationManager = $this->createMock(INotificationManager::class);
549
-
550
-		if ($result) {
551
-			$config->expects($this->atLeastOnce())
552
-				->method('deleteAllUserValues')
553
-				->with('foo');
554
-
555
-			$commentsManager->expects($this->once())
556
-				->method('deleteReferencesOfActor')
557
-				->with('users', 'foo');
558
-			$commentsManager->expects($this->once())
559
-				->method('deleteReadMarksFromUser')
560
-				->with($user);
561
-
562
-			$notification = $this->createMock(INotification::class);
563
-			$notification->expects($this->once())
564
-				->method('setUser')
565
-				->with('foo');
566
-
567
-			$notificationManager->expects($this->once())
568
-				->method('createNotification')
569
-				->willReturn($notification);
570
-			$notificationManager->expects($this->once())
571
-				->method('markProcessed')
572
-				->with($notification);
573
-		} else {
574
-			$config->expects($this->never())
575
-				->method('deleteAllUserValues');
576
-
577
-			$commentsManager->expects($this->never())
578
-				->method('deleteReferencesOfActor');
579
-			$commentsManager->expects($this->never())
580
-				->method('deleteReadMarksFromUser');
581
-
582
-			$notificationManager->expects($this->never())
583
-				->method('createNotification');
584
-			$notificationManager->expects($this->never())
585
-				->method('markProcessed');
586
-		}
587
-
588
-		$this->overwriteService(\OCP\Notification\IManager::class, $notificationManager);
589
-		$this->overwriteService(\OCP\Comments\ICommentsManager::class, $commentsManager);
590
-
591
-		$this->assertSame($result, $user->delete());
592
-
593
-		$this->restoreService(AllConfig::class);
594
-		$this->restoreService(\OCP\Comments\ICommentsManager::class);
595
-		$this->restoreService(\OCP\Notification\IManager::class);
596
-
597
-		$this->assertEquals($expectedHooks, $hooksCalled);
598
-	}
599
-
600
-	public function testDeleteRecoverState() {
601
-		$backend = $this->createMock(\Test\Util\User\Dummy::class);
602
-		$backend->expects($this->once())
603
-			->method('deleteUser')
604
-			->willReturn(true);
605
-
606
-		$config = $this->createMock(IConfig::class);
607
-		$config->method('getSystemValue')
608
-			->willReturnArgument(1);
609
-		$config->method('getSystemValueString')
610
-			->willReturnArgument(1);
611
-		$config->method('getSystemValueBool')
612
-			->willReturnArgument(1);
613
-		$config->method('getSystemValueInt')
614
-			->willReturnArgument(1);
615
-
616
-		$userConfig = [];
617
-		$config->expects(self::atLeast(2))
618
-			->method('setUserValue')
619
-			->willReturnCallback(function () {
620
-				$userConfig[] = func_get_args();
621
-			});
622
-
623
-		$commentsManager = $this->createMock(ICommentsManager::class);
624
-		$commentsManager->expects($this->once())
625
-			->method('deleteReferencesOfActor')
626
-			->willThrowException(new \Error('Test exception'));
627
-
628
-		$this->overwriteService(\OCP\Comments\ICommentsManager::class, $commentsManager);
629
-		$this->expectException(\Error::class);
630
-
631
-		$user = $this->getMockBuilder(User::class)
632
-			->onlyMethods(['getHome'])
633
-			->setConstructorArgs(['foo', $backend, $this->dispatcher, null, $config])
634
-			->getMock();
635
-
636
-		$user->expects(self::atLeastOnce())
637
-			->method('getHome')
638
-			->willReturn('/home/path');
639
-
640
-		$user->delete();
641
-
642
-		$this->assertEqualsCanonicalizing(
643
-			[
644
-				['foo', 'core', 'deleted', 'true', null],
645
-				['foo', 'core', 'deleted.backup-home', '/home/path', null],
646
-			],
647
-			$userConfig,
648
-		);
649
-
650
-		$this->restoreService(\OCP\Comments\ICommentsManager::class);
651
-	}
652
-
653
-	public static function dataGetCloudId(): array {
654
-		return [
655
-			['https://localhost:8888/nextcloud', 'foo@localhost:8888/nextcloud'],
656
-			['http://localhost:8888/nextcloud', 'foo@http://localhost:8888/nextcloud'],
657
-		];
658
-	}
659
-
660
-	/**
661
-	 * @dataProvider dataGetCloudId
662
-	 */
663
-	public function testGetCloudId(string $absoluteUrl, string $cloudId): void {
664
-		/** @var Backend|MockObject $backend */
665
-		$backend = $this->createMock(\Test\Util\User\Dummy::class);
666
-		$urlGenerator = $this->createMock(IURLGenerator::class);
667
-		$urlGenerator->method('getAbsoluteURL')
668
-			->withAnyParameters()
669
-			->willReturn($absoluteUrl);
670
-		$user = new User('foo', $backend, $this->dispatcher, null, null, $urlGenerator);
671
-		$this->assertEquals($cloudId, $user->getCloudId());
672
-	}
673
-
674
-	public function testSetEMailAddressEmpty(): void {
675
-		/**
676
-		 * @var Backend | MockObject $backend
677
-		 */
678
-		$backend = $this->createMock(\Test\Util\User\Dummy::class);
679
-
680
-		$test = $this;
681
-		$hooksCalled = 0;
682
-
683
-		/**
684
-		 * @param IUser $user
685
-		 * @param string $feature
686
-		 * @param string $value
687
-		 */
688
-		$hook = function (IUser $user, $feature, $value) use ($test, &$hooksCalled) {
689
-			$hooksCalled++;
690
-			$test->assertEquals('eMailAddress', $feature);
691
-			$test->assertEquals('', $value);
692
-		};
693
-
694
-		$emitter = new PublicEmitter();
695
-		$emitter->listen('\OC\User', 'changeUser', $hook);
696
-
697
-		$config = $this->createMock(IConfig::class);
698
-		$config->expects($this->once())
699
-			->method('deleteUserValue')
700
-			->with(
701
-				'foo',
702
-				'settings',
703
-				'email'
704
-			);
705
-
706
-		$user = new User('foo', $backend, $this->dispatcher, $emitter, $config);
707
-		$user->setEMailAddress('');
708
-	}
709
-
710
-	public function testSetEMailAddress(): void {
711
-		/**
712
-		 * @var UserInterface | MockObject $backend
713
-		 */
714
-		$backend = $this->createMock(\Test\Util\User\Dummy::class);
715
-
716
-		$test = $this;
717
-		$hooksCalled = 0;
718
-
719
-		/**
720
-		 * @param IUser $user
721
-		 * @param string $feature
722
-		 * @param string $value
723
-		 */
724
-		$hook = function (IUser $user, $feature, $value) use ($test, &$hooksCalled) {
725
-			$hooksCalled++;
726
-			$test->assertEquals('eMailAddress', $feature);
727
-			$test->assertEquals('[email protected]', $value);
728
-		};
729
-
730
-		$emitter = new PublicEmitter();
731
-		$emitter->listen('\OC\User', 'changeUser', $hook);
732
-
733
-		$config = $this->createMock(IConfig::class);
734
-		$config->expects($this->once())
735
-			->method('setUserValue')
736
-			->with(
737
-				'foo',
738
-				'settings',
739
-				'email',
740
-				'[email protected]'
741
-			);
742
-
743
-		$user = new User('foo', $backend, $this->dispatcher, $emitter, $config);
744
-		$user->setEMailAddress('[email protected]');
745
-	}
746
-
747
-	public function testSetEMailAddressNoChange(): void {
748
-		/**
749
-		 * @var UserInterface | MockObject $backend
750
-		 */
751
-		$backend = $this->createMock(\Test\Util\User\Dummy::class);
752
-
753
-		/** @var PublicEmitter|MockObject $emitter */
754
-		$emitter = $this->createMock(PublicEmitter::class);
755
-		$emitter->expects($this->never())
756
-			->method('emit');
757
-
758
-		$dispatcher = $this->createMock(IEventDispatcher::class);
759
-		$dispatcher->expects($this->never())
760
-			->method('dispatch');
761
-
762
-		$config = $this->createMock(IConfig::class);
763
-		$config->expects($this->any())
764
-			->method('getUserValue')
765
-			->willReturn('[email protected]');
766
-		$config->expects($this->any())
767
-			->method('setUserValue');
768
-
769
-		$user = new User('foo', $backend, $dispatcher, $emitter, $config);
770
-		$user->setEMailAddress('[email protected]');
771
-	}
772
-
773
-	public function testSetQuota(): void {
774
-		/**
775
-		 * @var UserInterface | MockObject $backend
776
-		 */
777
-		$backend = $this->createMock(\Test\Util\User\Dummy::class);
778
-
779
-		$test = $this;
780
-		$hooksCalled = 0;
781
-
782
-		/**
783
-		 * @param IUser $user
784
-		 * @param string $feature
785
-		 * @param string $value
786
-		 */
787
-		$hook = function (IUser $user, $feature, $value) use ($test, &$hooksCalled) {
788
-			$hooksCalled++;
789
-			$test->assertEquals('quota', $feature);
790
-			$test->assertEquals('23 TB', $value);
791
-		};
792
-
793
-		$emitter = new PublicEmitter();
794
-		$emitter->listen('\OC\User', 'changeUser', $hook);
795
-
796
-		$config = $this->createMock(IConfig::class);
797
-		$config->expects($this->once())
798
-			->method('setUserValue')
799
-			->with(
800
-				'foo',
801
-				'files',
802
-				'quota',
803
-				'23 TB'
804
-			);
805
-
806
-		$user = new User('foo', $backend, $this->dispatcher, $emitter, $config);
807
-		$user->setQuota('23 TB');
808
-	}
809
-
810
-	public function testGetDefaultUnlimitedQuota(): void {
811
-		/**
812
-		 * @var UserInterface | MockObject $backend
813
-		 */
814
-		$backend = $this->createMock(\Test\Util\User\Dummy::class);
815
-
816
-		/** @var PublicEmitter|MockObject $emitter */
817
-		$emitter = $this->createMock(PublicEmitter::class);
818
-		$emitter->expects($this->never())
819
-			->method('emit');
820
-
821
-		$config = $this->createMock(IConfig::class);
822
-		$user = new User('foo', $backend, $this->dispatcher, $emitter, $config);
823
-
824
-		$userValueMap = [
825
-			['foo', 'files', 'quota', 'default', 'default'],
826
-		];
827
-		$appValueMap = [
828
-			['files', 'default_quota', 'none', 'none'],
829
-			// allow unlimited quota
830
-			['files', 'allow_unlimited_quota', '1', '1'],
831
-		];
832
-		$config->method('getUserValue')
833
-			->will($this->returnValueMap($userValueMap));
834
-		$config->method('getAppValue')
835
-			->will($this->returnValueMap($appValueMap));
836
-
837
-		$quota = $user->getQuota();
838
-		$this->assertEquals('none', $quota);
839
-	}
840
-
841
-	public function testGetDefaultUnlimitedQuotaForbidden(): void {
842
-		/**
843
-		 * @var UserInterface | MockObject $backend
844
-		 */
845
-		$backend = $this->createMock(\Test\Util\User\Dummy::class);
846
-
847
-		/** @var PublicEmitter|MockObject $emitter */
848
-		$emitter = $this->createMock(PublicEmitter::class);
849
-		$emitter->expects($this->never())
850
-			->method('emit');
851
-
852
-		$config = $this->createMock(IConfig::class);
853
-		$user = new User('foo', $backend, $this->dispatcher, $emitter, $config);
854
-
855
-		$userValueMap = [
856
-			['foo', 'files', 'quota', 'default', 'default'],
857
-		];
858
-		$appValueMap = [
859
-			['files', 'default_quota', 'none', 'none'],
860
-			// do not allow unlimited quota
861
-			['files', 'allow_unlimited_quota', '1', '0'],
862
-			['files', 'quota_preset', '1 GB, 5 GB, 10 GB', '1 GB, 5 GB, 10 GB'],
863
-			// expect seeing 1 GB used as fallback value
864
-			['files', 'default_quota', '1 GB', '1 GB'],
865
-		];
866
-		$config->method('getUserValue')
867
-			->will($this->returnValueMap($userValueMap));
868
-		$config->method('getAppValue')
869
-			->will($this->returnValueMap($appValueMap));
870
-
871
-		$quota = $user->getQuota();
872
-		$this->assertEquals('1 GB', $quota);
873
-	}
874
-
875
-	public function testSetQuotaAddressNoChange(): void {
876
-		/**
877
-		 * @var UserInterface | MockObject $backend
878
-		 */
879
-		$backend = $this->createMock(\Test\Util\User\Dummy::class);
880
-
881
-		/** @var PublicEmitter|MockObject $emitter */
882
-		$emitter = $this->createMock(PublicEmitter::class);
883
-		$emitter->expects($this->never())
884
-			->method('emit');
885
-
886
-		$config = $this->createMock(IConfig::class);
887
-		$config->expects($this->any())
888
-			->method('getUserValue')
889
-			->willReturn('23 TB');
890
-		$config->expects($this->never())
891
-			->method('setUserValue');
892
-
893
-		$user = new User('foo', $backend, $this->dispatcher, $emitter, $config);
894
-		$user->setQuota('23 TB');
895
-	}
896
-
897
-	public function testGetLastLogin(): void {
898
-		/**
899
-		 * @var Backend | MockObject $backend
900
-		 */
901
-		$backend = $this->createMock(\Test\Util\User\Dummy::class);
902
-
903
-		$config = $this->createMock(IConfig::class);
904
-		$config->method('getUserValue')
905
-			->willReturnCallback(function ($uid, $app, $key, $default) {
906
-				if ($uid === 'foo' && $app === 'login' && $key === 'lastLogin') {
907
-					return 42;
908
-				} else {
909
-					return $default;
910
-				}
911
-			});
912
-
913
-		$user = new User('foo', $backend, $this->dispatcher, null, $config);
914
-		$this->assertSame(42, $user->getLastLogin());
915
-	}
916
-
917
-	public function testSetEnabled(): void {
918
-		/**
919
-		 * @var Backend | MockObject $backend
920
-		 */
921
-		$backend = $this->createMock(\Test\Util\User\Dummy::class);
922
-
923
-		$config = $this->createMock(IConfig::class);
924
-		$config->expects($this->once())
925
-			->method('setUserValue')
926
-			->with(
927
-				$this->equalTo('foo'),
928
-				$this->equalTo('core'),
929
-				$this->equalTo('enabled'),
930
-				'true'
931
-			);
932
-		/* dav event listener gets the manager list from config */
933
-		$config->expects(self::any())
934
-			->method('getUserValue')
935
-			->willReturnCallback(
936
-				fn ($user, $app, $key, $default) => ($key === 'enabled' ? 'false' : $default)
937
-			);
938
-
939
-		$user = new User('foo', $backend, $this->dispatcher, null, $config);
940
-		$user->setEnabled(true);
941
-	}
942
-
943
-	public function testSetDisabled(): void {
944
-		/**
945
-		 * @var Backend | MockObject $backend
946
-		 */
947
-		$backend = $this->createMock(\Test\Util\User\Dummy::class);
948
-
949
-		$config = $this->createMock(IConfig::class);
950
-		$config->expects($this->once())
951
-			->method('setUserValue')
952
-			->with(
953
-				$this->equalTo('foo'),
954
-				$this->equalTo('core'),
955
-				$this->equalTo('enabled'),
956
-				'false'
957
-			);
958
-
959
-		$user = $this->getMockBuilder(User::class)
960
-			->setConstructorArgs([
961
-				'foo',
962
-				$backend,
963
-				$this->dispatcher,
964
-				null,
965
-				$config,
966
-			])
967
-			->onlyMethods(['isEnabled', 'triggerChange'])
968
-			->getMock();
969
-
970
-		$user->expects($this->once())
971
-			->method('isEnabled')
972
-			->willReturn(true);
973
-		$user->expects($this->once())
974
-			->method('triggerChange')
975
-			->with(
976
-				'enabled',
977
-				false
978
-			);
979
-
980
-		$user->setEnabled(false);
981
-	}
982
-
983
-	public function testSetDisabledAlreadyDisabled(): void {
984
-		/**
985
-		 * @var Backend | MockObject $backend
986
-		 */
987
-		$backend = $this->createMock(\Test\Util\User\Dummy::class);
988
-
989
-		$config = $this->createMock(IConfig::class);
990
-		$config->expects($this->never())
991
-			->method('setUserValue');
992
-
993
-		$user = $this->getMockBuilder(User::class)
994
-			->setConstructorArgs([
995
-				'foo',
996
-				$backend,
997
-				$this->dispatcher,
998
-				null,
999
-				$config,
1000
-			])
1001
-			->onlyMethods(['isEnabled', 'triggerChange'])
1002
-			->getMock();
1003
-
1004
-		$user->expects($this->once())
1005
-			->method('isEnabled')
1006
-			->willReturn(false);
1007
-		$user->expects($this->never())
1008
-			->method('triggerChange');
1009
-
1010
-		$user->setEnabled(false);
1011
-	}
1012
-
1013
-	public function testGetEMailAddress(): void {
1014
-		/**
1015
-		 * @var Backend | MockObject $backend
1016
-		 */
1017
-		$backend = $this->createMock(\Test\Util\User\Dummy::class);
1018
-
1019
-		$config = $this->createMock(IConfig::class);
1020
-		$config->method('getUserValue')
1021
-			->willReturnCallback(function ($uid, $app, $key, $default) {
1022
-				if ($uid === 'foo' && $app === 'settings' && $key === 'email') {
1023
-					return '[email protected]';
1024
-				} else {
1025
-					return $default;
1026
-				}
1027
-			});
1028
-
1029
-		$user = new User('foo', $backend, $this->dispatcher, null, $config);
1030
-		$this->assertSame('[email protected]', $user->getEMailAddress());
1031
-	}
36
+    /** @var IEventDispatcher|MockObject */
37
+    protected $dispatcher;
38
+
39
+    protected function setUp(): void {
40
+        parent::setUp();
41
+        $this->dispatcher = Server::get(IEventDispatcher::class);
42
+    }
43
+
44
+    public function testDisplayName(): void {
45
+        /**
46
+         * @var \OC\User\Backend | MockObject $backend
47
+         */
48
+        $backend = $this->createMock(\OC\User\Backend::class);
49
+        $backend->expects($this->once())
50
+            ->method('getDisplayName')
51
+            ->with($this->equalTo('foo'))
52
+            ->willReturn('Foo');
53
+
54
+        $backend->expects($this->any())
55
+            ->method('implementsActions')
56
+            ->with($this->equalTo(\OC\User\Backend::GET_DISPLAYNAME))
57
+            ->willReturn(true);
58
+
59
+        $user = new User('foo', $backend, $this->dispatcher);
60
+        $this->assertEquals('Foo', $user->getDisplayName());
61
+    }
62
+
63
+    /**
64
+     * if the display name contain whitespaces only, we expect the uid as result
65
+     */
66
+    public function testDisplayNameEmpty(): void {
67
+        /**
68
+         * @var \OC\User\Backend | MockObject $backend
69
+         */
70
+        $backend = $this->createMock(\OC\User\Backend::class);
71
+        $backend->expects($this->once())
72
+            ->method('getDisplayName')
73
+            ->with($this->equalTo('foo'))
74
+            ->willReturn('  ');
75
+
76
+        $backend->expects($this->any())
77
+            ->method('implementsActions')
78
+            ->with($this->equalTo(\OC\User\Backend::GET_DISPLAYNAME))
79
+            ->willReturn(true);
80
+
81
+        $user = new User('foo', $backend, $this->dispatcher);
82
+        $this->assertEquals('foo', $user->getDisplayName());
83
+    }
84
+
85
+    public function testDisplayNameNotSupported(): void {
86
+        /**
87
+         * @var \OC\User\Backend | MockObject $backend
88
+         */
89
+        $backend = $this->createMock(\OC\User\Backend::class);
90
+        $backend->expects($this->never())
91
+            ->method('getDisplayName');
92
+
93
+        $backend->expects($this->any())
94
+            ->method('implementsActions')
95
+            ->with($this->equalTo(\OC\User\Backend::GET_DISPLAYNAME))
96
+            ->willReturn(false);
97
+
98
+        $user = new User('foo', $backend, $this->dispatcher);
99
+        $this->assertEquals('foo', $user->getDisplayName());
100
+    }
101
+
102
+    public function testSetPassword(): void {
103
+        /**
104
+         * @var Backend | MockObject $backend
105
+         */
106
+        $backend = $this->createMock(\Test\Util\User\Dummy::class);
107
+        $backend->expects($this->once())
108
+            ->method('setPassword')
109
+            ->with($this->equalTo('foo'), $this->equalTo('bar'));
110
+
111
+        $backend->expects($this->any())
112
+            ->method('implementsActions')
113
+            ->willReturnCallback(function ($actions) {
114
+                if ($actions === \OC\User\Backend::SET_PASSWORD) {
115
+                    return true;
116
+                } else {
117
+                    return false;
118
+                }
119
+            });
120
+
121
+        $user = new User('foo', $backend, $this->dispatcher);
122
+        $this->assertTrue($user->setPassword('bar', ''));
123
+    }
124
+
125
+    public function testSetPasswordNotSupported(): void {
126
+        /**
127
+         * @var Backend | MockObject $backend
128
+         */
129
+        $backend = $this->createMock(\Test\Util\User\Dummy::class);
130
+        $backend->expects($this->never())
131
+            ->method('setPassword');
132
+
133
+        $backend->expects($this->any())
134
+            ->method('implementsActions')
135
+            ->willReturn(false);
136
+
137
+        $user = new User('foo', $backend, $this->dispatcher);
138
+        $this->assertFalse($user->setPassword('bar', ''));
139
+    }
140
+
141
+    public function testChangeAvatarSupportedYes(): void {
142
+        /**
143
+         * @var Backend | MockObject $backend
144
+         */
145
+        $backend = $this->createMock(AvatarUserDummy::class);
146
+        $backend->expects($this->once())
147
+            ->method('canChangeAvatar')
148
+            ->with($this->equalTo('foo'))
149
+            ->willReturn(true);
150
+
151
+        $backend->expects($this->any())
152
+            ->method('implementsActions')
153
+            ->willReturnCallback(function ($actions) {
154
+                if ($actions === \OC\User\Backend::PROVIDE_AVATAR) {
155
+                    return true;
156
+                } else {
157
+                    return false;
158
+                }
159
+            });
160
+
161
+        $user = new User('foo', $backend, $this->dispatcher);
162
+        $this->assertTrue($user->canChangeAvatar());
163
+    }
164
+
165
+    public function testChangeAvatarSupportedNo(): void {
166
+        /**
167
+         * @var Backend | MockObject $backend
168
+         */
169
+        $backend = $this->createMock(AvatarUserDummy::class);
170
+        $backend->expects($this->once())
171
+            ->method('canChangeAvatar')
172
+            ->with($this->equalTo('foo'))
173
+            ->willReturn(false);
174
+
175
+        $backend->expects($this->any())
176
+            ->method('implementsActions')
177
+            ->willReturnCallback(function ($actions) {
178
+                if ($actions === \OC\User\Backend::PROVIDE_AVATAR) {
179
+                    return true;
180
+                } else {
181
+                    return false;
182
+                }
183
+            });
184
+
185
+        $user = new User('foo', $backend, $this->dispatcher);
186
+        $this->assertFalse($user->canChangeAvatar());
187
+    }
188
+
189
+    public function testChangeAvatarNotSupported(): void {
190
+        /**
191
+         * @var Backend | MockObject $backend
192
+         */
193
+        $backend = $this->createMock(AvatarUserDummy::class);
194
+        $backend->expects($this->never())
195
+            ->method('canChangeAvatar');
196
+
197
+        $backend->expects($this->any())
198
+            ->method('implementsActions')
199
+            ->willReturn(false);
200
+
201
+        $user = new User('foo', $backend, $this->dispatcher);
202
+        $this->assertTrue($user->canChangeAvatar());
203
+    }
204
+
205
+    public function testDelete(): void {
206
+        /**
207
+         * @var Backend | MockObject $backend
208
+         */
209
+        $backend = $this->createMock(\Test\Util\User\Dummy::class);
210
+        $backend->expects($this->once())
211
+            ->method('deleteUser')
212
+            ->with($this->equalTo('foo'));
213
+
214
+        $user = new User('foo', $backend, $this->dispatcher);
215
+        $this->assertTrue($user->delete());
216
+    }
217
+
218
+    public function testDeleteWithDifferentHome(): void {
219
+        /** @var ObjectHomeMountProvider $homeProvider */
220
+        $homeProvider = \OC::$server->get(ObjectHomeMountProvider::class);
221
+        $user = $this->createMock(IUser::class);
222
+        $user->method('getUID')
223
+            ->willReturn('foo');
224
+        if ($homeProvider->getHomeMountForUser($user, $this->createMock(IStorageFactory::class)) !== null) {
225
+            $this->markTestSkipped('Skipping test for non local home storage');
226
+        }
227
+
228
+        /**
229
+         * @var Backend | MockObject $backend
230
+         */
231
+        $backend = $this->createMock(\Test\Util\User\Dummy::class);
232
+
233
+        $backend->expects($this->once())
234
+            ->method('implementsActions')
235
+            ->willReturnCallback(function ($actions) {
236
+                if ($actions === \OC\User\Backend::GET_HOME) {
237
+                    return true;
238
+                } else {
239
+                    return false;
240
+                }
241
+            });
242
+
243
+        // important: getHome MUST be called before deleteUser because
244
+        // once the user is deleted, getHome implementations might not
245
+        // return anything
246
+        $backend->expects($this->once())
247
+            ->method('getHome')
248
+            ->with($this->equalTo('foo'))
249
+            ->willReturn('/home/foo');
250
+
251
+        $backend->expects($this->once())
252
+            ->method('deleteUser')
253
+            ->with($this->equalTo('foo'));
254
+
255
+        $user = new User('foo', $backend, $this->dispatcher);
256
+        $this->assertTrue($user->delete());
257
+    }
258
+
259
+    public function testGetHome(): void {
260
+        /**
261
+         * @var Backend | MockObject $backend
262
+         */
263
+        $backend = $this->createMock(\Test\Util\User\Dummy::class);
264
+        $backend->expects($this->once())
265
+            ->method('getHome')
266
+            ->with($this->equalTo('foo'))
267
+            ->willReturn('/home/foo');
268
+
269
+        $backend->expects($this->any())
270
+            ->method('implementsActions')
271
+            ->willReturnCallback(function ($actions) {
272
+                if ($actions === \OC\User\Backend::GET_HOME) {
273
+                    return true;
274
+                } else {
275
+                    return false;
276
+                }
277
+            });
278
+
279
+        $user = new User('foo', $backend, $this->dispatcher);
280
+        $this->assertEquals('/home/foo', $user->getHome());
281
+    }
282
+
283
+    public function testGetBackendClassName(): void {
284
+        $user = new User('foo', new \Test\Util\User\Dummy(), $this->dispatcher);
285
+        $this->assertEquals('Dummy', $user->getBackendClassName());
286
+        $user = new User('foo', new \OC\User\Database(), $this->dispatcher);
287
+        $this->assertEquals('Database', $user->getBackendClassName());
288
+    }
289
+
290
+    public function testGetHomeNotSupported(): void {
291
+        /**
292
+         * @var Backend | MockObject $backend
293
+         */
294
+        $backend = $this->createMock(\Test\Util\User\Dummy::class);
295
+        $backend->expects($this->never())
296
+            ->method('getHome');
297
+
298
+        $backend->expects($this->any())
299
+            ->method('implementsActions')
300
+            ->willReturn(false);
301
+
302
+        $allConfig = $this->getMockBuilder(IConfig::class)
303
+            ->disableOriginalConstructor()
304
+            ->getMock();
305
+        $allConfig->expects($this->any())
306
+            ->method('getUserValue')
307
+            ->willReturn(true);
308
+        $allConfig->expects($this->any())
309
+            ->method('getSystemValueString')
310
+            ->with($this->equalTo('datadirectory'))
311
+            ->willReturn('arbitrary/path');
312
+
313
+        $user = new User('foo', $backend, $this->dispatcher, null, $allConfig);
314
+        $this->assertEquals('arbitrary/path/foo', $user->getHome());
315
+    }
316
+
317
+    public function testCanChangePassword(): void {
318
+        /**
319
+         * @var Backend | MockObject $backend
320
+         */
321
+        $backend = $this->createMock(\Test\Util\User\Dummy::class);
322
+
323
+        $backend->expects($this->any())
324
+            ->method('implementsActions')
325
+            ->willReturnCallback(function ($actions) {
326
+                if ($actions === \OC\User\Backend::SET_PASSWORD) {
327
+                    return true;
328
+                } else {
329
+                    return false;
330
+                }
331
+            });
332
+
333
+        $user = new User('foo', $backend, $this->dispatcher);
334
+        $this->assertTrue($user->canChangePassword());
335
+    }
336
+
337
+    public function testCanChangePasswordNotSupported(): void {
338
+        /**
339
+         * @var Backend | MockObject $backend
340
+         */
341
+        $backend = $this->createMock(\Test\Util\User\Dummy::class);
342
+
343
+        $backend->expects($this->any())
344
+            ->method('implementsActions')
345
+            ->willReturn(false);
346
+
347
+        $user = new User('foo', $backend, $this->dispatcher);
348
+        $this->assertFalse($user->canChangePassword());
349
+    }
350
+
351
+    public function testCanChangeDisplayName(): void {
352
+        /**
353
+         * @var Backend | MockObject $backend
354
+         */
355
+        $backend = $this->createMock(\Test\Util\User\Dummy::class);
356
+
357
+        $backend->expects($this->any())
358
+            ->method('implementsActions')
359
+            ->willReturnCallback(function ($actions) {
360
+                if ($actions === \OC\User\Backend::SET_DISPLAYNAME) {
361
+                    return true;
362
+                } else {
363
+                    return false;
364
+                }
365
+            });
366
+
367
+        $config = $this->createMock(IConfig::class);
368
+        $config->method('getSystemValueBool')
369
+            ->with('allow_user_to_change_display_name')
370
+            ->willReturn(true);
371
+
372
+        $user = new User('foo', $backend, $this->dispatcher, null, $config);
373
+        $this->assertTrue($user->canChangeDisplayName());
374
+    }
375
+
376
+    public function testCanChangeDisplayNameNotSupported(): void {
377
+        /**
378
+         * @var Backend | MockObject $backend
379
+         */
380
+        $backend = $this->createMock(\Test\Util\User\Dummy::class);
381
+
382
+        $backend->expects($this->any())
383
+            ->method('implementsActions')
384
+            ->willReturn(false);
385
+
386
+        $user = new User('foo', $backend, $this->dispatcher);
387
+        $this->assertFalse($user->canChangeDisplayName());
388
+    }
389
+
390
+    public function testSetDisplayNameSupported(): void {
391
+        /**
392
+         * @var Backend | MockObject $backend
393
+         */
394
+        $backend = $this->createMock(\OC\User\Database::class);
395
+
396
+        $backend->expects($this->any())
397
+            ->method('implementsActions')
398
+            ->willReturnCallback(function ($actions) {
399
+                if ($actions === \OC\User\Backend::SET_DISPLAYNAME) {
400
+                    return true;
401
+                } else {
402
+                    return false;
403
+                }
404
+            });
405
+
406
+        $backend->expects($this->once())
407
+            ->method('setDisplayName')
408
+            ->with('foo', 'Foo')
409
+            ->willReturn(true);
410
+
411
+        $user = new User('foo', $backend, $this->createMock(IEventDispatcher::class));
412
+        $this->assertTrue($user->setDisplayName('Foo'));
413
+        $this->assertEquals('Foo', $user->getDisplayName());
414
+    }
415
+
416
+    /**
417
+     * don't allow display names containing whitespaces only
418
+     */
419
+    public function testSetDisplayNameEmpty(): void {
420
+        /**
421
+         * @var Backend | MockObject $backend
422
+         */
423
+        $backend = $this->createMock(\OC\User\Database::class);
424
+
425
+        $backend->expects($this->any())
426
+            ->method('implementsActions')
427
+            ->willReturnCallback(function ($actions) {
428
+                if ($actions === \OC\User\Backend::SET_DISPLAYNAME) {
429
+                    return true;
430
+                } else {
431
+                    return false;
432
+                }
433
+            });
434
+
435
+        $user = new User('foo', $backend, $this->dispatcher);
436
+        $this->assertFalse($user->setDisplayName(' '));
437
+        $this->assertEquals('foo', $user->getDisplayName());
438
+    }
439
+
440
+    public function testSetDisplayNameNotSupported(): void {
441
+        /**
442
+         * @var Backend | MockObject $backend
443
+         */
444
+        $backend = $this->createMock(\OC\User\Database::class);
445
+
446
+        $backend->expects($this->any())
447
+            ->method('implementsActions')
448
+            ->willReturn(false);
449
+
450
+        $backend->expects($this->never())
451
+            ->method('setDisplayName');
452
+
453
+        $user = new User('foo', $backend, $this->dispatcher);
454
+        $this->assertFalse($user->setDisplayName('Foo'));
455
+        $this->assertEquals('foo', $user->getDisplayName());
456
+    }
457
+
458
+    public function testSetPasswordHooks(): void {
459
+        $hooksCalled = 0;
460
+        $test = $this;
461
+
462
+        /**
463
+         * @var Backend | MockObject $backend
464
+         */
465
+        $backend = $this->createMock(\Test\Util\User\Dummy::class);
466
+        $backend->expects($this->once())
467
+            ->method('setPassword');
468
+
469
+        /**
470
+         * @param User $user
471
+         * @param string $password
472
+         */
473
+        $hook = function ($user, $password) use ($test, &$hooksCalled) {
474
+            $hooksCalled++;
475
+            $test->assertEquals('foo', $user->getUID());
476
+            $test->assertEquals('bar', $password);
477
+        };
478
+
479
+        $emitter = new PublicEmitter();
480
+        $emitter->listen('\OC\User', 'preSetPassword', $hook);
481
+        $emitter->listen('\OC\User', 'postSetPassword', $hook);
482
+
483
+        $backend->expects($this->any())
484
+            ->method('implementsActions')
485
+            ->willReturnCallback(function ($actions) {
486
+                if ($actions === \OC\User\Backend::SET_PASSWORD) {
487
+                    return true;
488
+                } else {
489
+                    return false;
490
+                }
491
+            });
492
+
493
+        $user = new User('foo', $backend, $this->dispatcher, $emitter);
494
+
495
+        $user->setPassword('bar', '');
496
+        $this->assertEquals(2, $hooksCalled);
497
+    }
498
+
499
+    public static function dataDeleteHooks(): array {
500
+        return [
501
+            [true, 2],
502
+            [false, 1],
503
+        ];
504
+    }
505
+
506
+    /**
507
+     * @dataProvider dataDeleteHooks
508
+     * @param bool $result
509
+     * @param int $expectedHooks
510
+     */
511
+    public function testDeleteHooks($result, $expectedHooks): void {
512
+        $hooksCalled = 0;
513
+        $test = $this;
514
+
515
+        /**
516
+         * @var UserInterface&MockObject $backend
517
+         */
518
+        $backend = $this->createMock(\Test\Util\User\Dummy::class);
519
+        $backend->expects($this->once())
520
+            ->method('deleteUser')
521
+            ->willReturn($result);
522
+
523
+        $config = $this->createMock(IConfig::class);
524
+        $config->method('getSystemValue')
525
+            ->willReturnArgument(1);
526
+        $config->method('getSystemValueString')
527
+            ->willReturnArgument(1);
528
+        $config->method('getSystemValueBool')
529
+            ->willReturnArgument(1);
530
+        $config->method('getSystemValueInt')
531
+            ->willReturnArgument(1);
532
+
533
+        $emitter = new PublicEmitter();
534
+        $user = new User('foo', $backend, $this->dispatcher, $emitter, $config);
535
+
536
+        /**
537
+         * @param User $user
538
+         */
539
+        $hook = function ($user) use ($test, &$hooksCalled) {
540
+            $hooksCalled++;
541
+            $test->assertEquals('foo', $user->getUID());
542
+        };
543
+
544
+        $emitter->listen('\OC\User', 'preDelete', $hook);
545
+        $emitter->listen('\OC\User', 'postDelete', $hook);
546
+
547
+        $commentsManager = $this->createMock(ICommentsManager::class);
548
+        $notificationManager = $this->createMock(INotificationManager::class);
549
+
550
+        if ($result) {
551
+            $config->expects($this->atLeastOnce())
552
+                ->method('deleteAllUserValues')
553
+                ->with('foo');
554
+
555
+            $commentsManager->expects($this->once())
556
+                ->method('deleteReferencesOfActor')
557
+                ->with('users', 'foo');
558
+            $commentsManager->expects($this->once())
559
+                ->method('deleteReadMarksFromUser')
560
+                ->with($user);
561
+
562
+            $notification = $this->createMock(INotification::class);
563
+            $notification->expects($this->once())
564
+                ->method('setUser')
565
+                ->with('foo');
566
+
567
+            $notificationManager->expects($this->once())
568
+                ->method('createNotification')
569
+                ->willReturn($notification);
570
+            $notificationManager->expects($this->once())
571
+                ->method('markProcessed')
572
+                ->with($notification);
573
+        } else {
574
+            $config->expects($this->never())
575
+                ->method('deleteAllUserValues');
576
+
577
+            $commentsManager->expects($this->never())
578
+                ->method('deleteReferencesOfActor');
579
+            $commentsManager->expects($this->never())
580
+                ->method('deleteReadMarksFromUser');
581
+
582
+            $notificationManager->expects($this->never())
583
+                ->method('createNotification');
584
+            $notificationManager->expects($this->never())
585
+                ->method('markProcessed');
586
+        }
587
+
588
+        $this->overwriteService(\OCP\Notification\IManager::class, $notificationManager);
589
+        $this->overwriteService(\OCP\Comments\ICommentsManager::class, $commentsManager);
590
+
591
+        $this->assertSame($result, $user->delete());
592
+
593
+        $this->restoreService(AllConfig::class);
594
+        $this->restoreService(\OCP\Comments\ICommentsManager::class);
595
+        $this->restoreService(\OCP\Notification\IManager::class);
596
+
597
+        $this->assertEquals($expectedHooks, $hooksCalled);
598
+    }
599
+
600
+    public function testDeleteRecoverState() {
601
+        $backend = $this->createMock(\Test\Util\User\Dummy::class);
602
+        $backend->expects($this->once())
603
+            ->method('deleteUser')
604
+            ->willReturn(true);
605
+
606
+        $config = $this->createMock(IConfig::class);
607
+        $config->method('getSystemValue')
608
+            ->willReturnArgument(1);
609
+        $config->method('getSystemValueString')
610
+            ->willReturnArgument(1);
611
+        $config->method('getSystemValueBool')
612
+            ->willReturnArgument(1);
613
+        $config->method('getSystemValueInt')
614
+            ->willReturnArgument(1);
615
+
616
+        $userConfig = [];
617
+        $config->expects(self::atLeast(2))
618
+            ->method('setUserValue')
619
+            ->willReturnCallback(function () {
620
+                $userConfig[] = func_get_args();
621
+            });
622
+
623
+        $commentsManager = $this->createMock(ICommentsManager::class);
624
+        $commentsManager->expects($this->once())
625
+            ->method('deleteReferencesOfActor')
626
+            ->willThrowException(new \Error('Test exception'));
627
+
628
+        $this->overwriteService(\OCP\Comments\ICommentsManager::class, $commentsManager);
629
+        $this->expectException(\Error::class);
630
+
631
+        $user = $this->getMockBuilder(User::class)
632
+            ->onlyMethods(['getHome'])
633
+            ->setConstructorArgs(['foo', $backend, $this->dispatcher, null, $config])
634
+            ->getMock();
635
+
636
+        $user->expects(self::atLeastOnce())
637
+            ->method('getHome')
638
+            ->willReturn('/home/path');
639
+
640
+        $user->delete();
641
+
642
+        $this->assertEqualsCanonicalizing(
643
+            [
644
+                ['foo', 'core', 'deleted', 'true', null],
645
+                ['foo', 'core', 'deleted.backup-home', '/home/path', null],
646
+            ],
647
+            $userConfig,
648
+        );
649
+
650
+        $this->restoreService(\OCP\Comments\ICommentsManager::class);
651
+    }
652
+
653
+    public static function dataGetCloudId(): array {
654
+        return [
655
+            ['https://localhost:8888/nextcloud', 'foo@localhost:8888/nextcloud'],
656
+            ['http://localhost:8888/nextcloud', 'foo@http://localhost:8888/nextcloud'],
657
+        ];
658
+    }
659
+
660
+    /**
661
+     * @dataProvider dataGetCloudId
662
+     */
663
+    public function testGetCloudId(string $absoluteUrl, string $cloudId): void {
664
+        /** @var Backend|MockObject $backend */
665
+        $backend = $this->createMock(\Test\Util\User\Dummy::class);
666
+        $urlGenerator = $this->createMock(IURLGenerator::class);
667
+        $urlGenerator->method('getAbsoluteURL')
668
+            ->withAnyParameters()
669
+            ->willReturn($absoluteUrl);
670
+        $user = new User('foo', $backend, $this->dispatcher, null, null, $urlGenerator);
671
+        $this->assertEquals($cloudId, $user->getCloudId());
672
+    }
673
+
674
+    public function testSetEMailAddressEmpty(): void {
675
+        /**
676
+         * @var Backend | MockObject $backend
677
+         */
678
+        $backend = $this->createMock(\Test\Util\User\Dummy::class);
679
+
680
+        $test = $this;
681
+        $hooksCalled = 0;
682
+
683
+        /**
684
+         * @param IUser $user
685
+         * @param string $feature
686
+         * @param string $value
687
+         */
688
+        $hook = function (IUser $user, $feature, $value) use ($test, &$hooksCalled) {
689
+            $hooksCalled++;
690
+            $test->assertEquals('eMailAddress', $feature);
691
+            $test->assertEquals('', $value);
692
+        };
693
+
694
+        $emitter = new PublicEmitter();
695
+        $emitter->listen('\OC\User', 'changeUser', $hook);
696
+
697
+        $config = $this->createMock(IConfig::class);
698
+        $config->expects($this->once())
699
+            ->method('deleteUserValue')
700
+            ->with(
701
+                'foo',
702
+                'settings',
703
+                'email'
704
+            );
705
+
706
+        $user = new User('foo', $backend, $this->dispatcher, $emitter, $config);
707
+        $user->setEMailAddress('');
708
+    }
709
+
710
+    public function testSetEMailAddress(): void {
711
+        /**
712
+         * @var UserInterface | MockObject $backend
713
+         */
714
+        $backend = $this->createMock(\Test\Util\User\Dummy::class);
715
+
716
+        $test = $this;
717
+        $hooksCalled = 0;
718
+
719
+        /**
720
+         * @param IUser $user
721
+         * @param string $feature
722
+         * @param string $value
723
+         */
724
+        $hook = function (IUser $user, $feature, $value) use ($test, &$hooksCalled) {
725
+            $hooksCalled++;
726
+            $test->assertEquals('eMailAddress', $feature);
727
+            $test->assertEquals('[email protected]', $value);
728
+        };
729
+
730
+        $emitter = new PublicEmitter();
731
+        $emitter->listen('\OC\User', 'changeUser', $hook);
732
+
733
+        $config = $this->createMock(IConfig::class);
734
+        $config->expects($this->once())
735
+            ->method('setUserValue')
736
+            ->with(
737
+                'foo',
738
+                'settings',
739
+                'email',
740
+                '[email protected]'
741
+            );
742
+
743
+        $user = new User('foo', $backend, $this->dispatcher, $emitter, $config);
744
+        $user->setEMailAddress('[email protected]');
745
+    }
746
+
747
+    public function testSetEMailAddressNoChange(): void {
748
+        /**
749
+         * @var UserInterface | MockObject $backend
750
+         */
751
+        $backend = $this->createMock(\Test\Util\User\Dummy::class);
752
+
753
+        /** @var PublicEmitter|MockObject $emitter */
754
+        $emitter = $this->createMock(PublicEmitter::class);
755
+        $emitter->expects($this->never())
756
+            ->method('emit');
757
+
758
+        $dispatcher = $this->createMock(IEventDispatcher::class);
759
+        $dispatcher->expects($this->never())
760
+            ->method('dispatch');
761
+
762
+        $config = $this->createMock(IConfig::class);
763
+        $config->expects($this->any())
764
+            ->method('getUserValue')
765
+            ->willReturn('[email protected]');
766
+        $config->expects($this->any())
767
+            ->method('setUserValue');
768
+
769
+        $user = new User('foo', $backend, $dispatcher, $emitter, $config);
770
+        $user->setEMailAddress('[email protected]');
771
+    }
772
+
773
+    public function testSetQuota(): void {
774
+        /**
775
+         * @var UserInterface | MockObject $backend
776
+         */
777
+        $backend = $this->createMock(\Test\Util\User\Dummy::class);
778
+
779
+        $test = $this;
780
+        $hooksCalled = 0;
781
+
782
+        /**
783
+         * @param IUser $user
784
+         * @param string $feature
785
+         * @param string $value
786
+         */
787
+        $hook = function (IUser $user, $feature, $value) use ($test, &$hooksCalled) {
788
+            $hooksCalled++;
789
+            $test->assertEquals('quota', $feature);
790
+            $test->assertEquals('23 TB', $value);
791
+        };
792
+
793
+        $emitter = new PublicEmitter();
794
+        $emitter->listen('\OC\User', 'changeUser', $hook);
795
+
796
+        $config = $this->createMock(IConfig::class);
797
+        $config->expects($this->once())
798
+            ->method('setUserValue')
799
+            ->with(
800
+                'foo',
801
+                'files',
802
+                'quota',
803
+                '23 TB'
804
+            );
805
+
806
+        $user = new User('foo', $backend, $this->dispatcher, $emitter, $config);
807
+        $user->setQuota('23 TB');
808
+    }
809
+
810
+    public function testGetDefaultUnlimitedQuota(): void {
811
+        /**
812
+         * @var UserInterface | MockObject $backend
813
+         */
814
+        $backend = $this->createMock(\Test\Util\User\Dummy::class);
815
+
816
+        /** @var PublicEmitter|MockObject $emitter */
817
+        $emitter = $this->createMock(PublicEmitter::class);
818
+        $emitter->expects($this->never())
819
+            ->method('emit');
820
+
821
+        $config = $this->createMock(IConfig::class);
822
+        $user = new User('foo', $backend, $this->dispatcher, $emitter, $config);
823
+
824
+        $userValueMap = [
825
+            ['foo', 'files', 'quota', 'default', 'default'],
826
+        ];
827
+        $appValueMap = [
828
+            ['files', 'default_quota', 'none', 'none'],
829
+            // allow unlimited quota
830
+            ['files', 'allow_unlimited_quota', '1', '1'],
831
+        ];
832
+        $config->method('getUserValue')
833
+            ->will($this->returnValueMap($userValueMap));
834
+        $config->method('getAppValue')
835
+            ->will($this->returnValueMap($appValueMap));
836
+
837
+        $quota = $user->getQuota();
838
+        $this->assertEquals('none', $quota);
839
+    }
840
+
841
+    public function testGetDefaultUnlimitedQuotaForbidden(): void {
842
+        /**
843
+         * @var UserInterface | MockObject $backend
844
+         */
845
+        $backend = $this->createMock(\Test\Util\User\Dummy::class);
846
+
847
+        /** @var PublicEmitter|MockObject $emitter */
848
+        $emitter = $this->createMock(PublicEmitter::class);
849
+        $emitter->expects($this->never())
850
+            ->method('emit');
851
+
852
+        $config = $this->createMock(IConfig::class);
853
+        $user = new User('foo', $backend, $this->dispatcher, $emitter, $config);
854
+
855
+        $userValueMap = [
856
+            ['foo', 'files', 'quota', 'default', 'default'],
857
+        ];
858
+        $appValueMap = [
859
+            ['files', 'default_quota', 'none', 'none'],
860
+            // do not allow unlimited quota
861
+            ['files', 'allow_unlimited_quota', '1', '0'],
862
+            ['files', 'quota_preset', '1 GB, 5 GB, 10 GB', '1 GB, 5 GB, 10 GB'],
863
+            // expect seeing 1 GB used as fallback value
864
+            ['files', 'default_quota', '1 GB', '1 GB'],
865
+        ];
866
+        $config->method('getUserValue')
867
+            ->will($this->returnValueMap($userValueMap));
868
+        $config->method('getAppValue')
869
+            ->will($this->returnValueMap($appValueMap));
870
+
871
+        $quota = $user->getQuota();
872
+        $this->assertEquals('1 GB', $quota);
873
+    }
874
+
875
+    public function testSetQuotaAddressNoChange(): void {
876
+        /**
877
+         * @var UserInterface | MockObject $backend
878
+         */
879
+        $backend = $this->createMock(\Test\Util\User\Dummy::class);
880
+
881
+        /** @var PublicEmitter|MockObject $emitter */
882
+        $emitter = $this->createMock(PublicEmitter::class);
883
+        $emitter->expects($this->never())
884
+            ->method('emit');
885
+
886
+        $config = $this->createMock(IConfig::class);
887
+        $config->expects($this->any())
888
+            ->method('getUserValue')
889
+            ->willReturn('23 TB');
890
+        $config->expects($this->never())
891
+            ->method('setUserValue');
892
+
893
+        $user = new User('foo', $backend, $this->dispatcher, $emitter, $config);
894
+        $user->setQuota('23 TB');
895
+    }
896
+
897
+    public function testGetLastLogin(): void {
898
+        /**
899
+         * @var Backend | MockObject $backend
900
+         */
901
+        $backend = $this->createMock(\Test\Util\User\Dummy::class);
902
+
903
+        $config = $this->createMock(IConfig::class);
904
+        $config->method('getUserValue')
905
+            ->willReturnCallback(function ($uid, $app, $key, $default) {
906
+                if ($uid === 'foo' && $app === 'login' && $key === 'lastLogin') {
907
+                    return 42;
908
+                } else {
909
+                    return $default;
910
+                }
911
+            });
912
+
913
+        $user = new User('foo', $backend, $this->dispatcher, null, $config);
914
+        $this->assertSame(42, $user->getLastLogin());
915
+    }
916
+
917
+    public function testSetEnabled(): void {
918
+        /**
919
+         * @var Backend | MockObject $backend
920
+         */
921
+        $backend = $this->createMock(\Test\Util\User\Dummy::class);
922
+
923
+        $config = $this->createMock(IConfig::class);
924
+        $config->expects($this->once())
925
+            ->method('setUserValue')
926
+            ->with(
927
+                $this->equalTo('foo'),
928
+                $this->equalTo('core'),
929
+                $this->equalTo('enabled'),
930
+                'true'
931
+            );
932
+        /* dav event listener gets the manager list from config */
933
+        $config->expects(self::any())
934
+            ->method('getUserValue')
935
+            ->willReturnCallback(
936
+                fn ($user, $app, $key, $default) => ($key === 'enabled' ? 'false' : $default)
937
+            );
938
+
939
+        $user = new User('foo', $backend, $this->dispatcher, null, $config);
940
+        $user->setEnabled(true);
941
+    }
942
+
943
+    public function testSetDisabled(): void {
944
+        /**
945
+         * @var Backend | MockObject $backend
946
+         */
947
+        $backend = $this->createMock(\Test\Util\User\Dummy::class);
948
+
949
+        $config = $this->createMock(IConfig::class);
950
+        $config->expects($this->once())
951
+            ->method('setUserValue')
952
+            ->with(
953
+                $this->equalTo('foo'),
954
+                $this->equalTo('core'),
955
+                $this->equalTo('enabled'),
956
+                'false'
957
+            );
958
+
959
+        $user = $this->getMockBuilder(User::class)
960
+            ->setConstructorArgs([
961
+                'foo',
962
+                $backend,
963
+                $this->dispatcher,
964
+                null,
965
+                $config,
966
+            ])
967
+            ->onlyMethods(['isEnabled', 'triggerChange'])
968
+            ->getMock();
969
+
970
+        $user->expects($this->once())
971
+            ->method('isEnabled')
972
+            ->willReturn(true);
973
+        $user->expects($this->once())
974
+            ->method('triggerChange')
975
+            ->with(
976
+                'enabled',
977
+                false
978
+            );
979
+
980
+        $user->setEnabled(false);
981
+    }
982
+
983
+    public function testSetDisabledAlreadyDisabled(): void {
984
+        /**
985
+         * @var Backend | MockObject $backend
986
+         */
987
+        $backend = $this->createMock(\Test\Util\User\Dummy::class);
988
+
989
+        $config = $this->createMock(IConfig::class);
990
+        $config->expects($this->never())
991
+            ->method('setUserValue');
992
+
993
+        $user = $this->getMockBuilder(User::class)
994
+            ->setConstructorArgs([
995
+                'foo',
996
+                $backend,
997
+                $this->dispatcher,
998
+                null,
999
+                $config,
1000
+            ])
1001
+            ->onlyMethods(['isEnabled', 'triggerChange'])
1002
+            ->getMock();
1003
+
1004
+        $user->expects($this->once())
1005
+            ->method('isEnabled')
1006
+            ->willReturn(false);
1007
+        $user->expects($this->never())
1008
+            ->method('triggerChange');
1009
+
1010
+        $user->setEnabled(false);
1011
+    }
1012
+
1013
+    public function testGetEMailAddress(): void {
1014
+        /**
1015
+         * @var Backend | MockObject $backend
1016
+         */
1017
+        $backend = $this->createMock(\Test\Util\User\Dummy::class);
1018
+
1019
+        $config = $this->createMock(IConfig::class);
1020
+        $config->method('getUserValue')
1021
+            ->willReturnCallback(function ($uid, $app, $key, $default) {
1022
+                if ($uid === 'foo' && $app === 'settings' && $key === 'email') {
1023
+                    return '[email protected]';
1024
+                } else {
1025
+                    return $default;
1026
+                }
1027
+            });
1028
+
1029
+        $user = new User('foo', $backend, $this->dispatcher, null, $config);
1030
+        $this->assertSame('[email protected]', $user->getEMailAddress());
1031
+    }
1032 1032
 }
Please login to merge, or discard this patch.
tests/lib/Mail/MailerTest.php 1 patch
Indentation   +336 added lines, -336 removed lines patch added patch discarded remove patch
@@ -27,340 +27,340 @@
 block discarded – undo
27 27
 use Test\TestCase;
28 28
 
29 29
 class MailerTest extends TestCase {
30
-	/** @var IConfig|MockObject */
31
-	private $config;
32
-	/** @var Defaults|MockObject */
33
-	private $defaults;
34
-	/** @var LoggerInterface|MockObject */
35
-	private $logger;
36
-	/** @var IURLGenerator|MockObject */
37
-	private $urlGenerator;
38
-	/** @var IL10N|MockObject */
39
-	private $l10n;
40
-	/** @var Mailer */
41
-	private $mailer;
42
-	/** @var IEventDispatcher&MockObject */
43
-	private $dispatcher;
44
-
45
-
46
-	protected function setUp(): void {
47
-		parent::setUp();
48
-
49
-		$this->config = $this->createMock(IConfig::class);
50
-		$this->defaults = $this->createMock(Defaults::class);
51
-		$this->logger = $this->createMock(LoggerInterface::class);
52
-		$this->urlGenerator = $this->createMock(IURLGenerator::class);
53
-		$this->l10n = $this->createMock(IL10N::class);
54
-		$this->dispatcher = $this->createMock(IEventDispatcher::class);
55
-		$this->mailer = new Mailer(
56
-			$this->config,
57
-			$this->logger,
58
-			$this->defaults,
59
-			$this->urlGenerator,
60
-			$this->l10n,
61
-			$this->dispatcher,
62
-			$this->createMock(IFactory::class)
63
-		);
64
-	}
65
-
66
-	/**
67
-	 * @return array
68
-	 */
69
-	public static function sendmailModeProvider(): array {
70
-		return [
71
-			'smtp' => ['smtp', ' -bs'],
72
-			'pipe' => ['pipe', ' -t -i'],
73
-		];
74
-	}
75
-
76
-	/**
77
-	 * @dataProvider sendmailModeProvider
78
-	 * @param $sendmailMode
79
-	 * @param $binaryParam
80
-	 */
81
-	public function testGetSendmailInstanceSendMail($sendmailMode, $binaryParam): void {
82
-		$this->config
83
-			->expects($this->exactly(2))
84
-			->method('getSystemValueString')
85
-			->willReturnMap([
86
-				['mail_smtpmode', 'smtp', 'sendmail'],
87
-				['mail_sendmailmode', 'smtp', $sendmailMode],
88
-			]);
89
-
90
-		$path = \OCP\Server::get(IBinaryFinder::class)->findBinaryPath('sendmail');
91
-		if ($path === false) {
92
-			$path = '/usr/sbin/sendmail';
93
-		}
94
-
95
-		$expected = new SendmailTransport($path . $binaryParam, null, $this->logger);
96
-		$this->assertEquals($expected, self::invokePrivate($this->mailer, 'getSendMailInstance'));
97
-	}
98
-
99
-	/**
100
-	 * @dataProvider sendmailModeProvider
101
-	 * @param $sendmailMode
102
-	 * @param $binaryParam
103
-	 */
104
-	public function testGetSendmailInstanceSendMailQmail($sendmailMode, $binaryParam): void {
105
-		$this->config
106
-			->expects($this->exactly(2))
107
-			->method('getSystemValueString')
108
-			->willReturnMap([
109
-				['mail_smtpmode', 'smtp', 'qmail'],
110
-				['mail_sendmailmode', 'smtp', $sendmailMode],
111
-			]);
112
-
113
-		$sendmail = new SendmailTransport('/var/qmail/bin/sendmail' . $binaryParam, null, $this->logger);
114
-		$this->assertEquals($sendmail, self::invokePrivate($this->mailer, 'getSendMailInstance'));
115
-	}
116
-
117
-	public function testEventForNullTransport(): void {
118
-		$this->config
119
-			->expects($this->exactly(1))
120
-			->method('getSystemValueString')
121
-			->with('mail_smtpmode', 'smtp')
122
-			->willReturn('null');
123
-
124
-		$message = $this->createMock(Message::class);
125
-		$message->expects($this->once())
126
-			->method('getSymfonyEmail')
127
-			->willReturn((new Email())->to('[email protected]')->from('[email protected]')->text(''));
128
-
129
-		$event = new BeforeMessageSent($message);
130
-		$this->dispatcher->expects($this->once())
131
-			->method('dispatchTyped')
132
-			->with($this->equalTo($event));
133
-
134
-		$this->mailer->send($message);
135
-	}
136
-
137
-	public function testGetInstanceDefault(): void {
138
-		$this->config
139
-			->method('getSystemValue')
140
-			->willReturnMap([
141
-				['mail_smtphost', '127.0.0.1', '127.0.0.1'],
142
-				['mail_smtpport', 25, 25],
143
-				['mail_smtptimeout', 10, 10],
144
-			]);
145
-		$mailer = self::invokePrivate($this->mailer, 'getInstance');
146
-		$this->assertInstanceOf(SymfonyMailer::class, $mailer);
147
-		$transport = self::invokePrivate($mailer, 'transport');
148
-		$this->assertInstanceOf(EsmtpTransport::class, $transport);
149
-	}
150
-
151
-	public function testGetInstanceSendmail(): void {
152
-		$this->config
153
-			->method('getSystemValueString')
154
-			->willReturnMap([
155
-				['mail_smtpmode', 'smtp', 'sendmail'],
156
-				['mail_sendmailmode', 'smtp', 'smtp'],
157
-			]);
158
-
159
-		$mailer = self::invokePrivate($this->mailer, 'getInstance');
160
-		$this->assertInstanceOf(SymfonyMailer::class, $mailer);
161
-		$transport = self::invokePrivate($mailer, 'transport');
162
-		$this->assertInstanceOf(SendmailTransport::class, $transport);
163
-	}
164
-
165
-	public function testEvents(): void {
166
-		$this->config
167
-			->method('getSystemValue')
168
-			->willReturnMap([
169
-				['mail_smtphost', '127.0.0.1', '127.0.0.1'],
170
-				['mail_smtpport', 25, 25],
171
-			]);
172
-		$this->mailer = $this->getMockBuilder(Mailer::class)
173
-			->onlyMethods(['getInstance'])
174
-			->setConstructorArgs(
175
-				[
176
-					$this->config,
177
-					$this->logger,
178
-					$this->defaults,
179
-					$this->urlGenerator,
180
-					$this->l10n,
181
-					$this->dispatcher,
182
-					$this->createMock(IFactory::class)
183
-				]
184
-			)
185
-			->getMock();
186
-
187
-		$message = $this->createMock(Message::class);
188
-
189
-		$event = new BeforeMessageSent($message);
190
-		$this->dispatcher->expects($this->once())
191
-			->method('dispatchTyped')
192
-			->with($this->equalTo($event));
193
-
194
-		$this->mailer->send($message);
195
-	}
196
-
197
-	public function testCreateMessage(): void {
198
-		$this->config
199
-			->expects($this->any())
200
-			->method('getSystemValueBool')
201
-			->with('mail_send_plaintext_only', false)
202
-			->willReturn(false);
203
-		$this->assertInstanceOf('\OC\Mail\Message', $this->mailer->createMessage());
204
-	}
205
-
206
-
207
-	public function testSendInvalidMailException(): void {
208
-		$this->config
209
-			->method('getSystemValue')
210
-			->willReturnMap([
211
-				['mail_smtphost', '127.0.0.1', '127.0.0.1'],
212
-				['mail_smtpport', 25, 25],
213
-				['mail_smtptimeout', 10, 10],
214
-			]);
215
-		$this->expectException(\Exception::class);
216
-
217
-		/** @var Message&MockObject */
218
-		$message = $this->getMockBuilder('\OC\Mail\Message')
219
-			->disableOriginalConstructor()->getMock();
220
-		$message->expects($this->once())
221
-			->method('getSymfonyEmail')
222
-			->willReturn(new Email());
223
-
224
-		$this->mailer->send($message);
225
-	}
226
-
227
-	/**
228
-	 * @return array
229
-	 */
230
-	public static function mailAddressProvider(): array {
231
-		return [
232
-			['[email protected]', true, false],
233
-			['lukas@localhost', true, false],
234
-			['[email protected]', true, false],
235
-			['lukas@éxämplè.com', true, false],
236
-			['asdf', false, false],
237
-			['', false, false],
238
-			['[email protected]@owncloud.com', false, false],
239
-			['test@localhost', true, false],
240
-			['test@localhost', false, true],
241
-		];
242
-	}
243
-
244
-	/**
245
-	 * @dataProvider mailAddressProvider
246
-	 */
247
-	public function testValidateMailAddress($email, $expected, $strict): void {
248
-		$this->config
249
-			->expects($this->atMost(1))
250
-			->method('getAppValue')
251
-			->with('core', 'enforce_strict_email_check')
252
-			->willReturn($strict ? 'yes' : 'no');
253
-		$this->assertSame($expected, $this->mailer->validateMailAddress($email));
254
-	}
255
-
256
-	public function testCreateEMailTemplate(): void {
257
-		$this->config->method('getSystemValueString')
258
-			->with('mail_template_class', '')
259
-			->willReturnArgument(1);
260
-		$this->config->method('getAppValue')
261
-			->with('theming', 'logoDimensions', Mailer::DEFAULT_DIMENSIONS)
262
-			->willReturn(Mailer::DEFAULT_DIMENSIONS);
263
-
264
-		$this->assertSame(EMailTemplate::class, get_class($this->mailer->createEMailTemplate('tests.MailerTest')));
265
-	}
266
-
267
-	public function testStreamingOptions(): void {
268
-		$this->config->method('getSystemValue')
269
-			->willReturnMap([
270
-				['mail_smtpstreamoptions', [], ['foo' => 1]],
271
-			]);
272
-		$this->config->method('getSystemValueString')
273
-			->willReturnMap([
274
-				['mail_smtpmode', 'smtp', 'smtp'],
275
-				['overwrite.cli.url', '', ''],
276
-				['mail_smtphost', '127.0.0.1', '127.0.0.1'],
277
-			]);
278
-		$this->config->method('getSystemValueInt')
279
-			->willReturnMap([
280
-				['mail_smtpport', 25, 25],
281
-				['mail_smtptimeout', 10, 10],
282
-			]);
283
-		$mailer = self::invokePrivate($this->mailer, 'getInstance');
284
-		/** @var EsmtpTransport $transport */
285
-		$transport = self::invokePrivate($mailer, 'transport');
286
-		$this->assertInstanceOf(EsmtpTransport::class, $transport);
287
-		$this->assertEquals(1, count($transport->getStream()->getStreamOptions()));
288
-		$this->assertTrue(isset($transport->getStream()->getStreamOptions()['foo']));
289
-	}
290
-
291
-	public function testStreamingOptionsWrongType(): void {
292
-		$this->config->method('getSystemValue')
293
-			->willReturnMap([
294
-				['mail_smtpstreamoptions', [], 'bar'],
295
-			]);
296
-		$this->config->method('getSystemValueString')
297
-			->willReturnMap([
298
-				['mail_smtpmode', 'smtp', 'smtp'],
299
-				['overwrite.cli.url', '', ''],
300
-				['mail_smtphost', '127.0.0.1', '127.0.0.1'],
301
-			]);
302
-		$this->config->method('getSystemValueInt')
303
-			->willReturnMap([
304
-				['mail_smtpport', 25, 25],
305
-				['mail_smtptimeout', 10, 10],
306
-			]);
307
-
308
-		$mailer = self::invokePrivate($this->mailer, 'getInstance');
309
-		/** @var EsmtpTransport $transport */
310
-		$transport = self::invokePrivate($mailer, 'transport');
311
-		$this->assertInstanceOf(EsmtpTransport::class, $transport);
312
-		$this->assertEquals(0, count($transport->getStream()->getStreamOptions()));
313
-	}
314
-
315
-	public function testLocalDomain(): void {
316
-		$this->config->method('getSystemValueString')
317
-			->willReturnMap([
318
-				['mail_smtpmode', 'smtp', 'smtp'],
319
-				['overwrite.cli.url', '', 'https://some.valid.url.com:8080'],
320
-				['mail_smtphost', '127.0.0.1', '127.0.0.1'],
321
-			]);
322
-		$this->config->method('getSystemValueInt')
323
-			->willReturnMap([
324
-				['mail_smtpport', 25, 25],
325
-				['mail_smtptimeout', 10, 10],
326
-			]);
327
-
328
-		/** @var SymfonyMailer $mailer */
329
-		$mailer = self::invokePrivate($this->mailer, 'getInstance');
330
-		self::assertInstanceOf(SymfonyMailer::class, $mailer);
331
-
332
-		/** @var EsmtpTransport $transport */
333
-		$transport = self::invokePrivate($mailer, 'transport');
334
-		self::assertInstanceOf(EsmtpTransport::class, $transport);
335
-		self::assertEquals('some.valid.url.com', $transport->getLocalDomain());
336
-	}
337
-
338
-	public function testLocalDomainInvalidUrl(): void {
339
-		$this->config->method('getSystemValueString')
340
-			->willReturnMap([
341
-				['mail_smtpmode', 'smtp', 'smtp'],
342
-				['overwrite.cli.url', '', 'https:only.slash.does.not.work:8080'],
343
-				['mail_smtphost', '127.0.0.1', '127.0.0.1'],
344
-			]);
345
-		$this->config->method('getSystemValueInt')
346
-			->willReturnMap([
347
-				['mail_smtpport', 25, 25],
348
-				['mail_smtptimeout', 10, 10],
349
-			]);
350
-
351
-		/** @var SymfonyMailer $mailer */
352
-		$mailer = self::invokePrivate($this->mailer, 'getInstance');
353
-		self::assertInstanceOf(SymfonyMailer::class, $mailer);
354
-
355
-		/** @var EsmtpTransport $transport */
356
-		$transport = self::invokePrivate($mailer, 'transport');
357
-		self::assertInstanceOf(EsmtpTransport::class, $transport);
358
-		self::assertEquals('[127.0.0.1]', $transport->getLocalDomain());
359
-	}
360
-
361
-	public function testCaching(): void {
362
-		$symfonyMailer1 = self::invokePrivate($this->mailer, 'getInstance');
363
-		$symfonyMailer2 = self::invokePrivate($this->mailer, 'getInstance');
364
-		self::assertSame($symfonyMailer1, $symfonyMailer2);
365
-	}
30
+    /** @var IConfig|MockObject */
31
+    private $config;
32
+    /** @var Defaults|MockObject */
33
+    private $defaults;
34
+    /** @var LoggerInterface|MockObject */
35
+    private $logger;
36
+    /** @var IURLGenerator|MockObject */
37
+    private $urlGenerator;
38
+    /** @var IL10N|MockObject */
39
+    private $l10n;
40
+    /** @var Mailer */
41
+    private $mailer;
42
+    /** @var IEventDispatcher&MockObject */
43
+    private $dispatcher;
44
+
45
+
46
+    protected function setUp(): void {
47
+        parent::setUp();
48
+
49
+        $this->config = $this->createMock(IConfig::class);
50
+        $this->defaults = $this->createMock(Defaults::class);
51
+        $this->logger = $this->createMock(LoggerInterface::class);
52
+        $this->urlGenerator = $this->createMock(IURLGenerator::class);
53
+        $this->l10n = $this->createMock(IL10N::class);
54
+        $this->dispatcher = $this->createMock(IEventDispatcher::class);
55
+        $this->mailer = new Mailer(
56
+            $this->config,
57
+            $this->logger,
58
+            $this->defaults,
59
+            $this->urlGenerator,
60
+            $this->l10n,
61
+            $this->dispatcher,
62
+            $this->createMock(IFactory::class)
63
+        );
64
+    }
65
+
66
+    /**
67
+     * @return array
68
+     */
69
+    public static function sendmailModeProvider(): array {
70
+        return [
71
+            'smtp' => ['smtp', ' -bs'],
72
+            'pipe' => ['pipe', ' -t -i'],
73
+        ];
74
+    }
75
+
76
+    /**
77
+     * @dataProvider sendmailModeProvider
78
+     * @param $sendmailMode
79
+     * @param $binaryParam
80
+     */
81
+    public function testGetSendmailInstanceSendMail($sendmailMode, $binaryParam): void {
82
+        $this->config
83
+            ->expects($this->exactly(2))
84
+            ->method('getSystemValueString')
85
+            ->willReturnMap([
86
+                ['mail_smtpmode', 'smtp', 'sendmail'],
87
+                ['mail_sendmailmode', 'smtp', $sendmailMode],
88
+            ]);
89
+
90
+        $path = \OCP\Server::get(IBinaryFinder::class)->findBinaryPath('sendmail');
91
+        if ($path === false) {
92
+            $path = '/usr/sbin/sendmail';
93
+        }
94
+
95
+        $expected = new SendmailTransport($path . $binaryParam, null, $this->logger);
96
+        $this->assertEquals($expected, self::invokePrivate($this->mailer, 'getSendMailInstance'));
97
+    }
98
+
99
+    /**
100
+     * @dataProvider sendmailModeProvider
101
+     * @param $sendmailMode
102
+     * @param $binaryParam
103
+     */
104
+    public function testGetSendmailInstanceSendMailQmail($sendmailMode, $binaryParam): void {
105
+        $this->config
106
+            ->expects($this->exactly(2))
107
+            ->method('getSystemValueString')
108
+            ->willReturnMap([
109
+                ['mail_smtpmode', 'smtp', 'qmail'],
110
+                ['mail_sendmailmode', 'smtp', $sendmailMode],
111
+            ]);
112
+
113
+        $sendmail = new SendmailTransport('/var/qmail/bin/sendmail' . $binaryParam, null, $this->logger);
114
+        $this->assertEquals($sendmail, self::invokePrivate($this->mailer, 'getSendMailInstance'));
115
+    }
116
+
117
+    public function testEventForNullTransport(): void {
118
+        $this->config
119
+            ->expects($this->exactly(1))
120
+            ->method('getSystemValueString')
121
+            ->with('mail_smtpmode', 'smtp')
122
+            ->willReturn('null');
123
+
124
+        $message = $this->createMock(Message::class);
125
+        $message->expects($this->once())
126
+            ->method('getSymfonyEmail')
127
+            ->willReturn((new Email())->to('[email protected]')->from('[email protected]')->text(''));
128
+
129
+        $event = new BeforeMessageSent($message);
130
+        $this->dispatcher->expects($this->once())
131
+            ->method('dispatchTyped')
132
+            ->with($this->equalTo($event));
133
+
134
+        $this->mailer->send($message);
135
+    }
136
+
137
+    public function testGetInstanceDefault(): void {
138
+        $this->config
139
+            ->method('getSystemValue')
140
+            ->willReturnMap([
141
+                ['mail_smtphost', '127.0.0.1', '127.0.0.1'],
142
+                ['mail_smtpport', 25, 25],
143
+                ['mail_smtptimeout', 10, 10],
144
+            ]);
145
+        $mailer = self::invokePrivate($this->mailer, 'getInstance');
146
+        $this->assertInstanceOf(SymfonyMailer::class, $mailer);
147
+        $transport = self::invokePrivate($mailer, 'transport');
148
+        $this->assertInstanceOf(EsmtpTransport::class, $transport);
149
+    }
150
+
151
+    public function testGetInstanceSendmail(): void {
152
+        $this->config
153
+            ->method('getSystemValueString')
154
+            ->willReturnMap([
155
+                ['mail_smtpmode', 'smtp', 'sendmail'],
156
+                ['mail_sendmailmode', 'smtp', 'smtp'],
157
+            ]);
158
+
159
+        $mailer = self::invokePrivate($this->mailer, 'getInstance');
160
+        $this->assertInstanceOf(SymfonyMailer::class, $mailer);
161
+        $transport = self::invokePrivate($mailer, 'transport');
162
+        $this->assertInstanceOf(SendmailTransport::class, $transport);
163
+    }
164
+
165
+    public function testEvents(): void {
166
+        $this->config
167
+            ->method('getSystemValue')
168
+            ->willReturnMap([
169
+                ['mail_smtphost', '127.0.0.1', '127.0.0.1'],
170
+                ['mail_smtpport', 25, 25],
171
+            ]);
172
+        $this->mailer = $this->getMockBuilder(Mailer::class)
173
+            ->onlyMethods(['getInstance'])
174
+            ->setConstructorArgs(
175
+                [
176
+                    $this->config,
177
+                    $this->logger,
178
+                    $this->defaults,
179
+                    $this->urlGenerator,
180
+                    $this->l10n,
181
+                    $this->dispatcher,
182
+                    $this->createMock(IFactory::class)
183
+                ]
184
+            )
185
+            ->getMock();
186
+
187
+        $message = $this->createMock(Message::class);
188
+
189
+        $event = new BeforeMessageSent($message);
190
+        $this->dispatcher->expects($this->once())
191
+            ->method('dispatchTyped')
192
+            ->with($this->equalTo($event));
193
+
194
+        $this->mailer->send($message);
195
+    }
196
+
197
+    public function testCreateMessage(): void {
198
+        $this->config
199
+            ->expects($this->any())
200
+            ->method('getSystemValueBool')
201
+            ->with('mail_send_plaintext_only', false)
202
+            ->willReturn(false);
203
+        $this->assertInstanceOf('\OC\Mail\Message', $this->mailer->createMessage());
204
+    }
205
+
206
+
207
+    public function testSendInvalidMailException(): void {
208
+        $this->config
209
+            ->method('getSystemValue')
210
+            ->willReturnMap([
211
+                ['mail_smtphost', '127.0.0.1', '127.0.0.1'],
212
+                ['mail_smtpport', 25, 25],
213
+                ['mail_smtptimeout', 10, 10],
214
+            ]);
215
+        $this->expectException(\Exception::class);
216
+
217
+        /** @var Message&MockObject */
218
+        $message = $this->getMockBuilder('\OC\Mail\Message')
219
+            ->disableOriginalConstructor()->getMock();
220
+        $message->expects($this->once())
221
+            ->method('getSymfonyEmail')
222
+            ->willReturn(new Email());
223
+
224
+        $this->mailer->send($message);
225
+    }
226
+
227
+    /**
228
+     * @return array
229
+     */
230
+    public static function mailAddressProvider(): array {
231
+        return [
232
+            ['[email protected]', true, false],
233
+            ['lukas@localhost', true, false],
234
+            ['[email protected]', true, false],
235
+            ['lukas@éxämplè.com', true, false],
236
+            ['asdf', false, false],
237
+            ['', false, false],
238
+            ['[email protected]@owncloud.com', false, false],
239
+            ['test@localhost', true, false],
240
+            ['test@localhost', false, true],
241
+        ];
242
+    }
243
+
244
+    /**
245
+     * @dataProvider mailAddressProvider
246
+     */
247
+    public function testValidateMailAddress($email, $expected, $strict): void {
248
+        $this->config
249
+            ->expects($this->atMost(1))
250
+            ->method('getAppValue')
251
+            ->with('core', 'enforce_strict_email_check')
252
+            ->willReturn($strict ? 'yes' : 'no');
253
+        $this->assertSame($expected, $this->mailer->validateMailAddress($email));
254
+    }
255
+
256
+    public function testCreateEMailTemplate(): void {
257
+        $this->config->method('getSystemValueString')
258
+            ->with('mail_template_class', '')
259
+            ->willReturnArgument(1);
260
+        $this->config->method('getAppValue')
261
+            ->with('theming', 'logoDimensions', Mailer::DEFAULT_DIMENSIONS)
262
+            ->willReturn(Mailer::DEFAULT_DIMENSIONS);
263
+
264
+        $this->assertSame(EMailTemplate::class, get_class($this->mailer->createEMailTemplate('tests.MailerTest')));
265
+    }
266
+
267
+    public function testStreamingOptions(): void {
268
+        $this->config->method('getSystemValue')
269
+            ->willReturnMap([
270
+                ['mail_smtpstreamoptions', [], ['foo' => 1]],
271
+            ]);
272
+        $this->config->method('getSystemValueString')
273
+            ->willReturnMap([
274
+                ['mail_smtpmode', 'smtp', 'smtp'],
275
+                ['overwrite.cli.url', '', ''],
276
+                ['mail_smtphost', '127.0.0.1', '127.0.0.1'],
277
+            ]);
278
+        $this->config->method('getSystemValueInt')
279
+            ->willReturnMap([
280
+                ['mail_smtpport', 25, 25],
281
+                ['mail_smtptimeout', 10, 10],
282
+            ]);
283
+        $mailer = self::invokePrivate($this->mailer, 'getInstance');
284
+        /** @var EsmtpTransport $transport */
285
+        $transport = self::invokePrivate($mailer, 'transport');
286
+        $this->assertInstanceOf(EsmtpTransport::class, $transport);
287
+        $this->assertEquals(1, count($transport->getStream()->getStreamOptions()));
288
+        $this->assertTrue(isset($transport->getStream()->getStreamOptions()['foo']));
289
+    }
290
+
291
+    public function testStreamingOptionsWrongType(): void {
292
+        $this->config->method('getSystemValue')
293
+            ->willReturnMap([
294
+                ['mail_smtpstreamoptions', [], 'bar'],
295
+            ]);
296
+        $this->config->method('getSystemValueString')
297
+            ->willReturnMap([
298
+                ['mail_smtpmode', 'smtp', 'smtp'],
299
+                ['overwrite.cli.url', '', ''],
300
+                ['mail_smtphost', '127.0.0.1', '127.0.0.1'],
301
+            ]);
302
+        $this->config->method('getSystemValueInt')
303
+            ->willReturnMap([
304
+                ['mail_smtpport', 25, 25],
305
+                ['mail_smtptimeout', 10, 10],
306
+            ]);
307
+
308
+        $mailer = self::invokePrivate($this->mailer, 'getInstance');
309
+        /** @var EsmtpTransport $transport */
310
+        $transport = self::invokePrivate($mailer, 'transport');
311
+        $this->assertInstanceOf(EsmtpTransport::class, $transport);
312
+        $this->assertEquals(0, count($transport->getStream()->getStreamOptions()));
313
+    }
314
+
315
+    public function testLocalDomain(): void {
316
+        $this->config->method('getSystemValueString')
317
+            ->willReturnMap([
318
+                ['mail_smtpmode', 'smtp', 'smtp'],
319
+                ['overwrite.cli.url', '', 'https://some.valid.url.com:8080'],
320
+                ['mail_smtphost', '127.0.0.1', '127.0.0.1'],
321
+            ]);
322
+        $this->config->method('getSystemValueInt')
323
+            ->willReturnMap([
324
+                ['mail_smtpport', 25, 25],
325
+                ['mail_smtptimeout', 10, 10],
326
+            ]);
327
+
328
+        /** @var SymfonyMailer $mailer */
329
+        $mailer = self::invokePrivate($this->mailer, 'getInstance');
330
+        self::assertInstanceOf(SymfonyMailer::class, $mailer);
331
+
332
+        /** @var EsmtpTransport $transport */
333
+        $transport = self::invokePrivate($mailer, 'transport');
334
+        self::assertInstanceOf(EsmtpTransport::class, $transport);
335
+        self::assertEquals('some.valid.url.com', $transport->getLocalDomain());
336
+    }
337
+
338
+    public function testLocalDomainInvalidUrl(): void {
339
+        $this->config->method('getSystemValueString')
340
+            ->willReturnMap([
341
+                ['mail_smtpmode', 'smtp', 'smtp'],
342
+                ['overwrite.cli.url', '', 'https:only.slash.does.not.work:8080'],
343
+                ['mail_smtphost', '127.0.0.1', '127.0.0.1'],
344
+            ]);
345
+        $this->config->method('getSystemValueInt')
346
+            ->willReturnMap([
347
+                ['mail_smtpport', 25, 25],
348
+                ['mail_smtptimeout', 10, 10],
349
+            ]);
350
+
351
+        /** @var SymfonyMailer $mailer */
352
+        $mailer = self::invokePrivate($this->mailer, 'getInstance');
353
+        self::assertInstanceOf(SymfonyMailer::class, $mailer);
354
+
355
+        /** @var EsmtpTransport $transport */
356
+        $transport = self::invokePrivate($mailer, 'transport');
357
+        self::assertInstanceOf(EsmtpTransport::class, $transport);
358
+        self::assertEquals('[127.0.0.1]', $transport->getLocalDomain());
359
+    }
360
+
361
+    public function testCaching(): void {
362
+        $symfonyMailer1 = self::invokePrivate($this->mailer, 'getInstance');
363
+        $symfonyMailer2 = self::invokePrivate($this->mailer, 'getInstance');
364
+        self::assertSame($symfonyMailer1, $symfonyMailer2);
365
+    }
366 366
 }
Please login to merge, or discard this patch.
tests/lib/Mail/MessageTest.php 1 patch
Indentation   +263 added lines, -263 removed lines patch added patch discarded remove patch
@@ -19,275 +19,275 @@
 block discarded – undo
19 19
 use Test\TestCase;
20 20
 
21 21
 class MessageTest extends TestCase {
22
-	/** @var Email */
23
-	private $symfonyEmail;
24
-	/** @var Message */
25
-	private $message;
26
-
27
-	/**
28
-	 * @return array
29
-	 */
30
-	public static function mailAddressProvider(): array {
31
-		return [
32
-			[
33
-				['[email protected]' => 'Lukas Reschke'],
34
-				[new Address('[email protected]', 'Lukas Reschke')]
35
-			],
36
-			[
37
-				[
38
-					'[email protected]' => 'Lukas Reschke',
39
-					'lukas@öwnclöüd.com',
40
-					'lukäs@owncloud.örg' => 'Lükäs Réschke'
41
-				],
42
-				[
43
-					new Address('[email protected]', 'Lukas Reschke'),
44
-					new Address('lukas@öwnclöüd.com'),
45
-					new Address('lukäs@owncloud.örg', 'Lükäs Réschke')
46
-				]
47
-			],
48
-			[
49
-				['lukas@öwnclöüd.com'],
50
-				[new Address('lukas@öwnclöüd.com')]
51
-			],
52
-		];
53
-	}
54
-
55
-	/**
56
-	 * @return array
57
-	 */
58
-	public function getMailAddressProvider() {
59
-		return [
60
-			[[], []],
61
-			[['[email protected]' => 'Lukas Reschke'], ['[email protected]' => 'Lukas Reschke']],
62
-		];
63
-	}
64
-
65
-	protected function setUp(): void {
66
-		parent::setUp();
67
-
68
-		$this->symfonyEmail = $this->createMock(Email::class);
69
-
70
-		$this->message = new Message($this->symfonyEmail, false);
71
-	}
72
-
73
-	/**
74
-	 * @dataProvider mailAddressProvider
75
-	 *
76
-	 * @param string $unconverted
77
-	 * @param string $expected
78
-	 */
79
-	public function testConvertAddresses($unconverted, $expected): void {
80
-		$this->assertEquals($expected, self::invokePrivate($this->message, 'convertAddresses', [$unconverted]));
81
-	}
82
-
83
-	public function testSetRecipients(): void {
84
-		$this->message = $this->message->setFrom(['[email protected]' => 'Pierres General Store']);
85
-		$this->message = $this->message->setTo(['[email protected]' => "Lewis' Tent Life"]);
86
-		$this->message = $this->message->setReplyTo(['[email protected]' => 'Penny']);
87
-		$this->message = $this->message->setCc(['[email protected]' => 'Gunther']);
88
-		$this->message = $this->message->setBcc(['[email protected]' => 'Pam']);
89
-
90
-		$this->symfonyEmail
91
-			->expects($this->once())
92
-			->method('from')
93
-			->with(new Address('[email protected]', 'Pierres General Store'));
94
-		$this->symfonyEmail
95
-			->expects($this->once())
96
-			->method('to')
97
-			->with(new Address('[email protected]', "Lewis' Tent Life"));
98
-		$this->symfonyEmail
99
-			->expects($this->once())
100
-			->method('replyTo')
101
-			->with(new Address('[email protected]', 'Penny'));
102
-		$this->symfonyEmail
103
-			->expects($this->once())
104
-			->method('cc')
105
-			->with(new Address('[email protected]', 'Gunther'));
106
-		$this->symfonyEmail
107
-			->expects($this->once())
108
-			->method('bcc')
109
-			->with(new Address('[email protected]', 'Pam'));
110
-
111
-		$this->message->setRecipients();
112
-	}
113
-
114
-	public function testSetTo(): void {
115
-		$expected = ['[email protected]' => 'Pierres General Store'];
116
-
117
-		$message = $this->message->setTo(['[email protected]' => 'Pierres General Store']);
118
-
119
-		$this->assertEquals($expected, $message->getTo());
120
-	}
121
-	public function testSetRecipientsException(): void {
122
-		$message = $this->message->setTo(['lewis-tent@~~~~.com' => "Lewis' Tent Life"]);
123
-
124
-		$this->symfonyEmail
125
-			->expects($this->once())
126
-			->method('to')
127
-			->willThrowException(new RfcComplianceException());
128
-
129
-		$this->expectException(RfcComplianceException::class);
130
-		$message->setRecipients();
131
-	}
132
-
133
-	public function testSetRecipientsEmptyValues(): void {
134
-		$message = $this->message->setTo([]);
135
-
136
-		$this->symfonyEmail
137
-			->expects($this->once())
138
-			->method('to');
139
-
140
-		$message->setRecipients();
141
-	}
142
-
143
-	public function testSetGetFrom(): void {
144
-		$expected = ['[email protected]' => 'Pierres General Store'];
145
-
146
-		$message = $this->message->setFrom(['[email protected]' => 'Pierres General Store']);
147
-
148
-		$this->assertEquals($expected, $message->getFrom());
149
-	}
150
-
151
-	public function testSetGetTo(): void {
152
-		$expected = ['[email protected]' => "Lewis' Tent Life"];
153
-
154
-		$message = $this->message->setTo(['[email protected]' => "Lewis' Tent Life"]);
155
-
156
-		$this->assertEquals($expected, $message->getTo());
157
-	}
158
-
159
-	public function testSetGetReplyTo(): void {
160
-		$expected = ['[email protected]' => 'Penny'];
161
-
162
-		$message = $this->message->setReplyTo(['[email protected]' => 'Penny']);
163
-
164
-		$this->assertEquals($expected, $message->getReplyTo());
165
-	}
166
-
167
-	public function testSetGetCC(): void {
168
-		$expected = ['[email protected]' => 'Gunther'];
169
-
170
-		$message = $this->message->setCc(['[email protected]' => 'Gunther']);
171
-
172
-		$this->assertEquals($expected, $message->getCc());
173
-	}
174
-
175
-	public function testSetGetBCC(): void {
176
-		$expected = ['[email protected]' => 'Pam'];
177
-
178
-		$message = $this->message->setBcc(['[email protected]' => 'Pam']);
179
-
180
-		$this->assertEquals($expected, $message->getBcc());
181
-	}
182
-
183
-	public function testSetPlainBody(): void {
184
-		$this->symfonyEmail
185
-			->expects($this->once())
186
-			->method('text')
187
-			->with('Fancy Body');
188
-
189
-		$this->message->setPlainBody('Fancy Body');
190
-	}
191
-
192
-	public function testGetPlainBody(): void {
193
-		$this->symfonyEmail
194
-			->expects($this->once())
195
-			->method('getTextBody')
196
-			->willReturn('Fancy Body');
197
-
198
-		$this->assertSame('Fancy Body', $this->message->getPlainBody());
199
-	}
200
-
201
-	public function testSetHtmlBody(): void {
202
-		$this->symfonyEmail
203
-			->expects($this->once())
204
-			->method('html')
205
-			->with('<blink>Fancy Body</blink>', 'utf-8');
22
+    /** @var Email */
23
+    private $symfonyEmail;
24
+    /** @var Message */
25
+    private $message;
26
+
27
+    /**
28
+     * @return array
29
+     */
30
+    public static function mailAddressProvider(): array {
31
+        return [
32
+            [
33
+                ['[email protected]' => 'Lukas Reschke'],
34
+                [new Address('[email protected]', 'Lukas Reschke')]
35
+            ],
36
+            [
37
+                [
38
+                    '[email protected]' => 'Lukas Reschke',
39
+                    'lukas@öwnclöüd.com',
40
+                    'lukäs@owncloud.örg' => 'Lükäs Réschke'
41
+                ],
42
+                [
43
+                    new Address('[email protected]', 'Lukas Reschke'),
44
+                    new Address('lukas@öwnclöüd.com'),
45
+                    new Address('lukäs@owncloud.örg', 'Lükäs Réschke')
46
+                ]
47
+            ],
48
+            [
49
+                ['lukas@öwnclöüd.com'],
50
+                [new Address('lukas@öwnclöüd.com')]
51
+            ],
52
+        ];
53
+    }
54
+
55
+    /**
56
+     * @return array
57
+     */
58
+    public function getMailAddressProvider() {
59
+        return [
60
+            [[], []],
61
+            [['[email protected]' => 'Lukas Reschke'], ['[email protected]' => 'Lukas Reschke']],
62
+        ];
63
+    }
64
+
65
+    protected function setUp(): void {
66
+        parent::setUp();
67
+
68
+        $this->symfonyEmail = $this->createMock(Email::class);
69
+
70
+        $this->message = new Message($this->symfonyEmail, false);
71
+    }
72
+
73
+    /**
74
+     * @dataProvider mailAddressProvider
75
+     *
76
+     * @param string $unconverted
77
+     * @param string $expected
78
+     */
79
+    public function testConvertAddresses($unconverted, $expected): void {
80
+        $this->assertEquals($expected, self::invokePrivate($this->message, 'convertAddresses', [$unconverted]));
81
+    }
82
+
83
+    public function testSetRecipients(): void {
84
+        $this->message = $this->message->setFrom(['[email protected]' => 'Pierres General Store']);
85
+        $this->message = $this->message->setTo(['[email protected]' => "Lewis' Tent Life"]);
86
+        $this->message = $this->message->setReplyTo(['[email protected]' => 'Penny']);
87
+        $this->message = $this->message->setCc(['[email protected]' => 'Gunther']);
88
+        $this->message = $this->message->setBcc(['[email protected]' => 'Pam']);
89
+
90
+        $this->symfonyEmail
91
+            ->expects($this->once())
92
+            ->method('from')
93
+            ->with(new Address('[email protected]', 'Pierres General Store'));
94
+        $this->symfonyEmail
95
+            ->expects($this->once())
96
+            ->method('to')
97
+            ->with(new Address('[email protected]', "Lewis' Tent Life"));
98
+        $this->symfonyEmail
99
+            ->expects($this->once())
100
+            ->method('replyTo')
101
+            ->with(new Address('[email protected]', 'Penny'));
102
+        $this->symfonyEmail
103
+            ->expects($this->once())
104
+            ->method('cc')
105
+            ->with(new Address('[email protected]', 'Gunther'));
106
+        $this->symfonyEmail
107
+            ->expects($this->once())
108
+            ->method('bcc')
109
+            ->with(new Address('[email protected]', 'Pam'));
110
+
111
+        $this->message->setRecipients();
112
+    }
113
+
114
+    public function testSetTo(): void {
115
+        $expected = ['[email protected]' => 'Pierres General Store'];
116
+
117
+        $message = $this->message->setTo(['[email protected]' => 'Pierres General Store']);
118
+
119
+        $this->assertEquals($expected, $message->getTo());
120
+    }
121
+    public function testSetRecipientsException(): void {
122
+        $message = $this->message->setTo(['lewis-tent@~~~~.com' => "Lewis' Tent Life"]);
123
+
124
+        $this->symfonyEmail
125
+            ->expects($this->once())
126
+            ->method('to')
127
+            ->willThrowException(new RfcComplianceException());
128
+
129
+        $this->expectException(RfcComplianceException::class);
130
+        $message->setRecipients();
131
+    }
132
+
133
+    public function testSetRecipientsEmptyValues(): void {
134
+        $message = $this->message->setTo([]);
135
+
136
+        $this->symfonyEmail
137
+            ->expects($this->once())
138
+            ->method('to');
139
+
140
+        $message->setRecipients();
141
+    }
142
+
143
+    public function testSetGetFrom(): void {
144
+        $expected = ['[email protected]' => 'Pierres General Store'];
145
+
146
+        $message = $this->message->setFrom(['[email protected]' => 'Pierres General Store']);
147
+
148
+        $this->assertEquals($expected, $message->getFrom());
149
+    }
150
+
151
+    public function testSetGetTo(): void {
152
+        $expected = ['[email protected]' => "Lewis' Tent Life"];
153
+
154
+        $message = $this->message->setTo(['[email protected]' => "Lewis' Tent Life"]);
155
+
156
+        $this->assertEquals($expected, $message->getTo());
157
+    }
158
+
159
+    public function testSetGetReplyTo(): void {
160
+        $expected = ['[email protected]' => 'Penny'];
161
+
162
+        $message = $this->message->setReplyTo(['[email protected]' => 'Penny']);
163
+
164
+        $this->assertEquals($expected, $message->getReplyTo());
165
+    }
166
+
167
+    public function testSetGetCC(): void {
168
+        $expected = ['[email protected]' => 'Gunther'];
169
+
170
+        $message = $this->message->setCc(['[email protected]' => 'Gunther']);
171
+
172
+        $this->assertEquals($expected, $message->getCc());
173
+    }
174
+
175
+    public function testSetGetBCC(): void {
176
+        $expected = ['[email protected]' => 'Pam'];
177
+
178
+        $message = $this->message->setBcc(['[email protected]' => 'Pam']);
179
+
180
+        $this->assertEquals($expected, $message->getBcc());
181
+    }
182
+
183
+    public function testSetPlainBody(): void {
184
+        $this->symfonyEmail
185
+            ->expects($this->once())
186
+            ->method('text')
187
+            ->with('Fancy Body');
188
+
189
+        $this->message->setPlainBody('Fancy Body');
190
+    }
191
+
192
+    public function testGetPlainBody(): void {
193
+        $this->symfonyEmail
194
+            ->expects($this->once())
195
+            ->method('getTextBody')
196
+            ->willReturn('Fancy Body');
197
+
198
+        $this->assertSame('Fancy Body', $this->message->getPlainBody());
199
+    }
200
+
201
+    public function testSetHtmlBody(): void {
202
+        $this->symfonyEmail
203
+            ->expects($this->once())
204
+            ->method('html')
205
+            ->with('<blink>Fancy Body</blink>', 'utf-8');
206 206
 
207
-		$this->message->setHtmlBody('<blink>Fancy Body</blink>');
208
-	}
207
+        $this->message->setHtmlBody('<blink>Fancy Body</blink>');
208
+    }
209 209
 
210
-	public function testPlainTextRenderOption(): void {
211
-		/** @var MockObject|Email $symfonyEmail */
212
-		$symfonyEmail = $this->getMockBuilder(Email::class)
213
-			->disableOriginalConstructor()->getMock();
214
-		/** @var MockObject|IEMailTemplate $template */
215
-		$template = $this->getMockBuilder(IEMailTemplate::class)
216
-			->disableOriginalConstructor()->getMock();
210
+    public function testPlainTextRenderOption(): void {
211
+        /** @var MockObject|Email $symfonyEmail */
212
+        $symfonyEmail = $this->getMockBuilder(Email::class)
213
+            ->disableOriginalConstructor()->getMock();
214
+        /** @var MockObject|IEMailTemplate $template */
215
+        $template = $this->getMockBuilder(IEMailTemplate::class)
216
+            ->disableOriginalConstructor()->getMock();
217 217
 
218
-		$message = new Message($symfonyEmail, true);
218
+        $message = new Message($symfonyEmail, true);
219 219
 
220
-		$template
221
-			->expects($this->never())
222
-			->method('renderHTML');
223
-		$template
224
-			->expects($this->once())
225
-			->method('renderText');
226
-		$template
227
-			->expects($this->once())
228
-			->method('renderSubject');
220
+        $template
221
+            ->expects($this->never())
222
+            ->method('renderHTML');
223
+        $template
224
+            ->expects($this->once())
225
+            ->method('renderText');
226
+        $template
227
+            ->expects($this->once())
228
+            ->method('renderSubject');
229 229
 
230
-		$message->useTemplate($template);
231
-	}
230
+        $message->useTemplate($template);
231
+    }
232 232
 
233
-	public function testBothRenderingOptions(): void {
234
-		/** @var MockObject|Email $symfonyEmail */
235
-		$symfonyEmail = $this->getMockBuilder(Email::class)
236
-			->disableOriginalConstructor()->getMock();
237
-		/** @var MockObject|IEMailTemplate $template */
238
-		$template = $this->getMockBuilder(IEMailTemplate::class)
239
-			->disableOriginalConstructor()->getMock();
233
+    public function testBothRenderingOptions(): void {
234
+        /** @var MockObject|Email $symfonyEmail */
235
+        $symfonyEmail = $this->getMockBuilder(Email::class)
236
+            ->disableOriginalConstructor()->getMock();
237
+        /** @var MockObject|IEMailTemplate $template */
238
+        $template = $this->getMockBuilder(IEMailTemplate::class)
239
+            ->disableOriginalConstructor()->getMock();
240 240
 
241
-		$message = new Message($symfonyEmail, false);
241
+        $message = new Message($symfonyEmail, false);
242 242
 
243
-		$template
244
-			->expects($this->once())
245
-			->method('renderHTML');
246
-		$template
247
-			->expects($this->once())
248
-			->method('renderText');
249
-		$template
250
-			->expects($this->once())
251
-			->method('renderSubject');
252
-
253
-		$message->useTemplate($template);
254
-	}
255
-
256
-	public function testSetAutoSubmitted1(): void {
257
-		$headers = new Headers($this->createMock(HeaderInterface::class));
258
-		$headers->addTextHeader(AutoSubmitted::HEADER, 'yes');
259
-		$symfonyEmail = $this->createMock(Email::class);
260
-
261
-		$symfonyEmail->method('getHeaders')
262
-			->willReturn($headers);
263
-
264
-		$message = new Message($symfonyEmail, false);
265
-		$message->setAutoSubmitted(AutoSubmitted::VALUE_AUTO_GENERATED);
266
-		$this->assertNotSame('no', $message->getAutoSubmitted());
267
-	}
268
-
269
-	public function testSetAutoSubmitted2(): void {
270
-		$headers = new Headers($this->createMock(HeaderInterface::class));
271
-		$headers->addTextHeader(AutoSubmitted::HEADER, 'no');
272
-		$symfonyEmail = $this->createMock(Email::class);
273
-
274
-		$symfonyEmail->method('getHeaders')
275
-			->willReturn($headers);
276
-
277
-		$message = new Message($symfonyEmail, false);
278
-		$message->setAutoSubmitted(AutoSubmitted::VALUE_AUTO_GENERATED);
279
-		$this->assertSame('auto-generated', $message->getAutoSubmitted());
280
-	}
281
-
282
-	public function testGetAutoSubmitted(): void {
283
-		$headers = new Headers($this->createMock(HeaderInterface::class));
284
-		$headers->addTextHeader(AutoSubmitted::HEADER, 'no');
285
-		$symfonyEmail = $this->createMock(Email::class);
286
-
287
-		$symfonyEmail->method('getHeaders')
288
-			->willReturn($headers);
289
-
290
-		$message = new Message($symfonyEmail, false);
291
-		$this->assertSame('no', $message->getAutoSubmitted());
292
-	}
243
+        $template
244
+            ->expects($this->once())
245
+            ->method('renderHTML');
246
+        $template
247
+            ->expects($this->once())
248
+            ->method('renderText');
249
+        $template
250
+            ->expects($this->once())
251
+            ->method('renderSubject');
252
+
253
+        $message->useTemplate($template);
254
+    }
255
+
256
+    public function testSetAutoSubmitted1(): void {
257
+        $headers = new Headers($this->createMock(HeaderInterface::class));
258
+        $headers->addTextHeader(AutoSubmitted::HEADER, 'yes');
259
+        $symfonyEmail = $this->createMock(Email::class);
260
+
261
+        $symfonyEmail->method('getHeaders')
262
+            ->willReturn($headers);
263
+
264
+        $message = new Message($symfonyEmail, false);
265
+        $message->setAutoSubmitted(AutoSubmitted::VALUE_AUTO_GENERATED);
266
+        $this->assertNotSame('no', $message->getAutoSubmitted());
267
+    }
268
+
269
+    public function testSetAutoSubmitted2(): void {
270
+        $headers = new Headers($this->createMock(HeaderInterface::class));
271
+        $headers->addTextHeader(AutoSubmitted::HEADER, 'no');
272
+        $symfonyEmail = $this->createMock(Email::class);
273
+
274
+        $symfonyEmail->method('getHeaders')
275
+            ->willReturn($headers);
276
+
277
+        $message = new Message($symfonyEmail, false);
278
+        $message->setAutoSubmitted(AutoSubmitted::VALUE_AUTO_GENERATED);
279
+        $this->assertSame('auto-generated', $message->getAutoSubmitted());
280
+    }
281
+
282
+    public function testGetAutoSubmitted(): void {
283
+        $headers = new Headers($this->createMock(HeaderInterface::class));
284
+        $headers->addTextHeader(AutoSubmitted::HEADER, 'no');
285
+        $symfonyEmail = $this->createMock(Email::class);
286
+
287
+        $symfonyEmail->method('getHeaders')
288
+            ->willReturn($headers);
289
+
290
+        $message = new Message($symfonyEmail, false);
291
+        $this->assertSame('no', $message->getAutoSubmitted());
292
+    }
293 293
 }
Please login to merge, or discard this patch.
tests/lib/Collaboration/Collaborators/UserPluginTest.php 1 patch
Indentation   +779 added lines, -779 removed lines patch added patch discarded remove patch
@@ -22,790 +22,790 @@
 block discarded – undo
22 22
 use Test\TestCase;
23 23
 
24 24
 class UserPluginTest extends TestCase {
25
-	/** @var IConfig|MockObject */
26
-	protected $config;
25
+    /** @var IConfig|MockObject */
26
+    protected $config;
27 27
 
28
-	/** @var IUserManager|MockObject */
29
-	protected $userManager;
28
+    /** @var IUserManager|MockObject */
29
+    protected $userManager;
30 30
 
31
-	/** @var IGroupManager|MockObject */
32
-	protected $groupManager;
31
+    /** @var IGroupManager|MockObject */
32
+    protected $groupManager;
33 33
 
34
-	/** @var IUserSession|MockObject */
35
-	protected $session;
34
+    /** @var IUserSession|MockObject */
35
+    protected $session;
36 36
 
37
-	/** @var KnownUserService|MockObject */
38
-	protected $knownUserService;
37
+    /** @var KnownUserService|MockObject */
38
+    protected $knownUserService;
39 39
 
40
-	/** @var IUserStatusManager|MockObject */
41
-	protected $userStatusManager;
40
+    /** @var IUserStatusManager|MockObject */
41
+    protected $userStatusManager;
42 42
 
43
-	/** @var UserPlugin */
44
-	protected $plugin;
43
+    /** @var UserPlugin */
44
+    protected $plugin;
45 45
 
46
-	/** @var ISearchResult */
47
-	protected $searchResult;
48
-
49
-	protected int $limit = 2;
50
-
51
-	protected int $offset = 0;
52
-
53
-	/** @var IUser|MockObject */
54
-	protected $user;
55
-
56
-	protected function setUp(): void {
57
-		parent::setUp();
58
-
59
-		$this->config = $this->createMock(IConfig::class);
60
-
61
-		$this->userManager = $this->createMock(IUserManager::class);
62
-
63
-		$this->groupManager = $this->createMock(IGroupManager::class);
64
-
65
-		$this->session = $this->createMock(IUserSession::class);
66
-
67
-		$this->knownUserService = $this->createMock(KnownUserService::class);
68
-
69
-		$this->userStatusManager = $this->createMock(IUserStatusManager::class);
70
-
71
-		$this->searchResult = new SearchResult();
72
-
73
-		$this->user = $this->getUserMock('admin', 'Administrator');
74
-	}
75
-
76
-	public function instantiatePlugin() {
77
-		// cannot be done within setUp, because dependent mocks needs to be set
78
-		// up with configuration etc. first
79
-		$this->plugin = new UserPlugin(
80
-			$this->config,
81
-			$this->userManager,
82
-			$this->groupManager,
83
-			$this->session,
84
-			$this->knownUserService,
85
-			$this->userStatusManager
86
-		);
87
-	}
88
-
89
-	public function mockConfig($mockedSettings) {
90
-		$this->config->expects($this->any())
91
-			->method('getAppValue')
92
-			->willReturnCallback(
93
-				function ($appName, $key, $default) use ($mockedSettings) {
94
-					return $mockedSettings[$appName][$key] ?? $default;
95
-				}
96
-			);
97
-	}
98
-
99
-	public function getUserMock($uid, $displayName, $enabled = true, $groups = []) {
100
-		$user = $this->createMock(IUser::class);
101
-
102
-		$user->expects($this->any())
103
-			->method('getUID')
104
-			->willReturn($uid);
105
-
106
-		$user->expects($this->any())
107
-			->method('getDisplayName')
108
-			->willReturn($displayName);
109
-
110
-		$user->expects($this->any())
111
-			->method('isEnabled')
112
-			->willReturn($enabled);
113
-
114
-		return $user;
115
-	}
116
-
117
-	public function getGroupMock($gid) {
118
-		$group = $this->createMock(IGroup::class);
119
-
120
-		$group->expects($this->any())
121
-			->method('getGID')
122
-			->willReturn($gid);
123
-
124
-		return $group;
125
-	}
126
-
127
-	public function dataGetUsers(): array {
128
-		return [
129
-			['test', false, true, [], [], [], [], true, false],
130
-			['test', false, false, [], [], [], [], true, false],
131
-			['test', true, true, [], [], [], [], true, false],
132
-			['test', true, false, [], [], [], [], true, false],
133
-			[
134
-				'test', false, true, [], [],
135
-				[
136
-					['label' => 'Test', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test'],
137
-				], [], true, $this->getUserMock('test', 'Test'),
138
-			],
139
-			[
140
-				'test', false, false, [], [],
141
-				[
142
-					['label' => 'Test', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test'],
143
-				], [], true, $this->getUserMock('test', 'Test'),
144
-			],
145
-			[
146
-				'test', true, true, [], [],
147
-				[], [], true, $this->getUserMock('test', 'Test'),
148
-			],
149
-			[
150
-				'test', true, false, [], [],
151
-				[], [], true, $this->getUserMock('test', 'Test'),
152
-			],
153
-			[
154
-				'test', true, true, ['test-group'], [['test-group', 'test', 2, 0, []]],
155
-				[
156
-					['label' => 'Test', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test'],
157
-				], [], true, $this->getUserMock('test', 'Test'),
158
-			],
159
-			[
160
-				'test', true, false, ['test-group'], [['test-group', 'test', 2, 0, []]],
161
-				[
162
-					['label' => 'Test', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test'],
163
-				], [], true, $this->getUserMock('test', 'Test'),
164
-			],
165
-			[
166
-				'test',
167
-				false,
168
-				true,
169
-				[],
170
-				[
171
-					$this->getUserMock('test1', 'Test One'),
172
-				],
173
-				[],
174
-				[
175
-					['label' => 'Test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test1'],
176
-				],
177
-				true,
178
-				false,
179
-			],
180
-			[
181
-				'test',
182
-				false,
183
-				false,
184
-				[],
185
-				[
186
-					$this->getUserMock('test1', 'Test One'),
187
-				],
188
-				[],
189
-				[],
190
-				true,
191
-				false,
192
-			],
193
-			[
194
-				'test',
195
-				false,
196
-				true,
197
-				[],
198
-				[
199
-					$this->getUserMock('test1', 'Test One'),
200
-					$this->getUserMock('test2', 'Test Two'),
201
-				],
202
-				[],
203
-				[
204
-					['label' => 'Test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test1'],
205
-					['label' => 'Test Two', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test2'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test2'],
206
-				],
207
-				false,
208
-				false,
209
-			],
210
-			[
211
-				'test',
212
-				false,
213
-				false,
214
-				[],
215
-				[
216
-					$this->getUserMock('test1', 'Test One'),
217
-					$this->getUserMock('test2', 'Test Two'),
218
-				],
219
-				[],
220
-				[],
221
-				true,
222
-				false,
223
-			],
224
-			[
225
-				'test',
226
-				false,
227
-				true,
228
-				[],
229
-				[
230
-					$this->getUserMock('test0', 'Test'),
231
-					$this->getUserMock('test1', 'Test One'),
232
-					$this->getUserMock('test2', 'Test Two'),
233
-				],
234
-				[
235
-					['label' => 'Test', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test0'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test0'],
236
-				],
237
-				[
238
-					['label' => 'Test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test1'],
239
-					['label' => 'Test Two', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test2'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test2'],
240
-				],
241
-				false,
242
-				false,
243
-			],
244
-			[
245
-				'test',
246
-				false,
247
-				true,
248
-				[],
249
-				[
250
-					$this->getUserMock('test0', 'Test'),
251
-					$this->getUserMock('test1', 'Test One'),
252
-					$this->getUserMock('test2', 'Test Two'),
253
-				],
254
-				[
255
-					['label' => 'Test', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test0'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test0'],
256
-				],
257
-				[
258
-					['label' => 'Test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test1'],
259
-					['label' => 'Test Two', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test2'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test2'],
260
-				],
261
-				false,
262
-				false,
263
-				[],
264
-				true,
265
-			],
266
-			[
267
-				'test',
268
-				false,
269
-				false,
270
-				[],
271
-				[
272
-					$this->getUserMock('test0', 'Test'),
273
-					$this->getUserMock('test1', 'Test One'),
274
-					$this->getUserMock('test2', 'Test Two'),
275
-				],
276
-				[
277
-					['label' => 'Test', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test0'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test0'],
278
-				],
279
-				[],
280
-				true,
281
-				false,
282
-			],
283
-			[
284
-				'test',
285
-				true,
286
-				true,
287
-				['abc', 'xyz'],
288
-				[
289
-					['abc', 'test', 2, 0, ['test1' => 'Test One']],
290
-					['xyz', 'test', 2, 0, []],
291
-				],
292
-				[],
293
-				[
294
-					['label' => 'Test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test1'],
295
-				],
296
-				true,
297
-				false,
298
-				[['test1', $this->getUserMock('test1', 'Test One')]],
299
-			],
300
-			[
301
-				'test',
302
-				true,
303
-				false,
304
-				['abc', 'xyz'],
305
-				[
306
-					['abc', 'test', 2, 0, ['test1' => 'Test One']],
307
-					['xyz', 'test', 2, 0, []],
308
-				],
309
-				[],
310
-				[],
311
-				true,
312
-				false,
313
-				[['test1', $this->getUserMock('test1', 'Test One')]],
314
-			],
315
-			[
316
-				'test',
317
-				true,
318
-				true,
319
-				['abc', 'xyz'],
320
-				[
321
-					['abc', 'test', 2, 0, [
322
-						'test1' => 'Test One',
323
-						'test2' => 'Test Two',
324
-					]],
325
-					['xyz', 'test', 2, 0, [
326
-						'test1' => 'Test One',
327
-						'test2' => 'Test Two',
328
-					]],
329
-				],
330
-				[],
331
-				[
332
-					['label' => 'Test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test1'],
333
-					['label' => 'Test Two', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test2'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test2'],
334
-				],
335
-				true,
336
-				false,
337
-				[
338
-					['test1', $this->getUserMock('test1', 'Test One')],
339
-					['test2', $this->getUserMock('test2', 'Test Two')],
340
-				],
341
-			],
342
-			[
343
-				'test',
344
-				true,
345
-				false,
346
-				['abc', 'xyz'],
347
-				[
348
-					['abc', 'test', 2, 0, [
349
-						'test1' => 'Test One',
350
-						'test2' => 'Test Two',
351
-					]],
352
-					['xyz', 'test', 2, 0, [
353
-						'test1' => 'Test One',
354
-						'test2' => 'Test Two',
355
-					]],
356
-				],
357
-				[],
358
-				[],
359
-				true,
360
-				false,
361
-				[
362
-					['test1', $this->getUserMock('test1', 'Test One')],
363
-					['test2', $this->getUserMock('test2', 'Test Two')],
364
-				],
365
-			],
366
-			[
367
-				'test',
368
-				true,
369
-				true,
370
-				['abc', 'xyz'],
371
-				[
372
-					['abc', 'test', 2, 0, [
373
-						'test' => 'Test One',
374
-					]],
375
-					['xyz', 'test', 2, 0, [
376
-						'test2' => 'Test Two',
377
-					]],
378
-				],
379
-				[
380
-					['label' => 'Test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test'],
381
-				],
382
-				[
383
-					['label' => 'Test Two', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test2'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test2'],
384
-				],
385
-				false,
386
-				false,
387
-				[
388
-					['test', $this->getUserMock('test', 'Test One')],
389
-					['test2', $this->getUserMock('test2', 'Test Two')],
390
-				],
391
-			],
392
-			[
393
-				'test',
394
-				true,
395
-				false,
396
-				['abc', 'xyz'],
397
-				[
398
-					['abc', 'test', 2, 0, [
399
-						'test' => 'Test One',
400
-					]],
401
-					['xyz', 'test', 2, 0, [
402
-						'test2' => 'Test Two',
403
-					]],
404
-				],
405
-				[
406
-					['label' => 'Test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test'],
407
-				],
408
-				[],
409
-				true,
410
-				false,
411
-				[
412
-					['test', $this->getUserMock('test', 'Test One')],
413
-					['test2', $this->getUserMock('test2', 'Test Two')],
414
-				],
415
-			],
416
-		];
417
-	}
418
-
419
-	/**
420
-	 * @dataProvider dataGetUsers
421
-	 *
422
-	 * @param string $searchTerm
423
-	 * @param bool $shareWithGroupOnly
424
-	 * @param bool $shareeEnumeration
425
-	 * @param array $groupResponse
426
-	 * @param array $userResponse
427
-	 * @param array $exactExpected
428
-	 * @param array $expected
429
-	 * @param bool $reachedEnd
430
-	 * @param bool|IUser $singleUser
431
-	 * @param array $users
432
-	 */
433
-	public function testSearch(
434
-		$searchTerm,
435
-		$shareWithGroupOnly,
436
-		$shareeEnumeration,
437
-		array $groupResponse,
438
-		array $userResponse,
439
-		array $exactExpected,
440
-		array $expected,
441
-		$reachedEnd,
442
-		$singleUser,
443
-		array $users = [],
444
-		$shareeEnumerationPhone = false,
445
-	): void {
446
-		$this->mockConfig(['core' => [
447
-			'shareapi_only_share_with_group_members' => $shareWithGroupOnly ? 'yes' : 'no',
448
-			'shareapi_allow_share_dialog_user_enumeration' => $shareeEnumeration? 'yes' : 'no',
449
-			'shareapi_restrict_user_enumeration_to_group' => false ? 'yes' : 'no',
450
-			'shareapi_restrict_user_enumeration_to_phone' => $shareeEnumerationPhone ? 'yes' : 'no',
451
-		]]);
452
-
453
-		$this->instantiatePlugin();
454
-
455
-		$this->session->expects($this->any())
456
-			->method('getUser')
457
-			->willReturn($this->user);
458
-
459
-		if (!$shareWithGroupOnly) {
460
-			if ($shareeEnumerationPhone) {
461
-				$this->userManager->expects($this->once())
462
-					->method('searchKnownUsersByDisplayName')
463
-					->with($this->user->getUID(), $searchTerm, $this->limit, $this->offset)
464
-					->willReturn($userResponse);
465
-
466
-				$this->knownUserService->method('isKnownToUser')
467
-					->willReturnMap([
468
-						[$this->user->getUID(), 'test0', true],
469
-						[$this->user->getUID(), 'test1', true],
470
-						[$this->user->getUID(), 'test2', true],
471
-					]);
472
-			} else {
473
-				$this->userManager->expects($this->once())
474
-					->method('searchDisplayName')
475
-					->with($searchTerm, $this->limit, $this->offset)
476
-					->willReturn($userResponse);
477
-			}
478
-		} else {
479
-			$this->groupManager->method('getUserGroupIds')
480
-				->with($this->user)
481
-				->willReturn($groupResponse);
482
-
483
-			if ($singleUser !== false) {
484
-				$this->groupManager->method('getUserGroupIds')
485
-					->with($singleUser)
486
-					->willReturn($groupResponse);
487
-			}
488
-
489
-			$this->groupManager->method('displayNamesInGroup')
490
-				->willReturnMap($userResponse);
491
-		}
492
-
493
-		if ($singleUser !== false) {
494
-			$users[] = [$searchTerm, $singleUser];
495
-		}
496
-
497
-		if (!empty($users)) {
498
-			$this->userManager->expects($this->atLeastOnce())
499
-				->method('get')
500
-				->willReturnMap($users);
501
-		}
502
-
503
-		$moreResults = $this->plugin->search($searchTerm, $this->limit, $this->offset, $this->searchResult);
504
-		$result = $this->searchResult->asArray();
505
-
506
-		$this->assertEquals($exactExpected, $result['exact']['users']);
507
-		$this->assertEquals($expected, $result['users']);
508
-		$this->assertSame($reachedEnd, $moreResults);
509
-	}
510
-
511
-	public static function takeOutCurrentUserProvider(): array {
512
-		$inputUsers = [
513
-			'alice' => 'Alice',
514
-			'bob' => 'Bob',
515
-			'carol' => 'Carol',
516
-		];
517
-		return [
518
-			[
519
-				$inputUsers,
520
-				['alice', 'carol'],
521
-				'bob',
522
-			],
523
-			[
524
-				$inputUsers,
525
-				['alice', 'bob', 'carol'],
526
-				'dave',
527
-			],
528
-			[
529
-				$inputUsers,
530
-				['alice', 'bob', 'carol'],
531
-				null,
532
-			],
533
-		];
534
-	}
535
-
536
-	/**
537
-	 * @dataProvider takeOutCurrentUserProvider
538
-	 * @param array $users
539
-	 * @param array $expectedUIDs
540
-	 * @param $currentUserId
541
-	 */
542
-	public function testTakeOutCurrentUser(array $users, array $expectedUIDs, $currentUserId): void {
543
-		$this->instantiatePlugin();
544
-
545
-		$this->session->expects($this->once())
546
-			->method('getUser')
547
-			->willReturnCallback(function () use ($currentUserId) {
548
-				if ($currentUserId !== null) {
549
-					return $this->getUserMock($currentUserId, $currentUserId);
550
-				}
551
-				return null;
552
-			});
553
-
554
-		$this->plugin->takeOutCurrentUser($users);
555
-		$this->assertSame($expectedUIDs, array_keys($users));
556
-	}
557
-
558
-	public static function dataSearchEnumeration(): array {
559
-		return [
560
-			[
561
-				'test',
562
-				['groupA'],
563
-				[
564
-					['uid' => 'test1', 'groups' => ['groupA']],
565
-					['uid' => 'test2', 'groups' => ['groupB']],
566
-				],
567
-				['exact' => [], 'wide' => ['test1']],
568
-				['core' => ['shareapi_restrict_user_enumeration_to_group' => 'yes']],
569
-			],
570
-			[
571
-				'test',
572
-				['groupA'],
573
-				[
574
-					['uid' => 'test1', 'displayName' => 'Test user 1', 'groups' => ['groupA']],
575
-					['uid' => 'test2', 'displayName' => 'Test user 2', 'groups' => ['groupA']],
576
-				],
577
-				['exact' => [], 'wide' => []],
578
-				['core' => ['shareapi_allow_share_dialog_user_enumeration' => 'no']],
579
-			],
580
-			[
581
-				'test1',
582
-				['groupA'],
583
-				[
584
-					['uid' => 'test1', 'displayName' => 'Test user 1', 'groups' => ['groupA']],
585
-					['uid' => 'test2', 'displayName' => 'Test user 2', 'groups' => ['groupA']],
586
-				],
587
-				['exact' => ['test1'], 'wide' => []],
588
-				['core' => ['shareapi_allow_share_dialog_user_enumeration' => 'no']],
589
-			],
590
-			[
591
-				'test1',
592
-				['groupA'],
593
-				[
594
-					['uid' => 'test1', 'displayName' => 'Test user 1', 'groups' => ['groupA']],
595
-					['uid' => 'test2', 'displayName' => 'Test user 2', 'groups' => ['groupA']],
596
-				],
597
-				['exact' => [], 'wide' => []],
598
-				[
599
-					'core' => [
600
-						'shareapi_allow_share_dialog_user_enumeration' => 'no',
601
-						'shareapi_restrict_user_enumeration_full_match_userid' => 'no',
602
-					],
603
-				]
604
-			],
605
-			[
606
-				'Test user 1',
607
-				['groupA'],
608
-				[
609
-					['uid' => 'test1', 'displayName' => 'Test user 1', 'groups' => ['groupA']],
610
-					['uid' => 'test2', 'displayName' => 'Test user 2', 'groups' => ['groupA']],
611
-				],
612
-				['exact' => ['test1'], 'wide' => []],
613
-				[
614
-					'core' => [
615
-						'shareapi_allow_share_dialog_user_enumeration' => 'no',
616
-						'shareapi_restrict_user_enumeration_full_match_userid' => 'no',
617
-					],
618
-				]
619
-			],
620
-			[
621
-				'Test user 1',
622
-				['groupA'],
623
-				[
624
-					['uid' => 'test1', 'displayName' => 'Test user 1 (Second displayName for user 1)', 'groups' => ['groupA']],
625
-					['uid' => 'test2', 'displayName' => 'Test user 2 (Second displayName for user 2)', 'groups' => ['groupA']],
626
-				],
627
-				['exact' => [], 'wide' => []],
628
-				['core' => ['shareapi_allow_share_dialog_user_enumeration' => 'no'],
629
-				]
630
-			],
631
-			[
632
-				'Test user 1',
633
-				['groupA'],
634
-				[
635
-					['uid' => 'test1', 'displayName' => 'Test user 1 (Second displayName for user 1)', 'groups' => ['groupA']],
636
-					['uid' => 'test2', 'displayName' => 'Test user 2 (Second displayName for user 2)', 'groups' => ['groupA']],
637
-				],
638
-				['exact' => ['test1'], 'wide' => []],
639
-				[
640
-					'core' => [
641
-						'shareapi_allow_share_dialog_user_enumeration' => 'no',
642
-						'shareapi_restrict_user_enumeration_full_match_ignore_second_dn' => 'yes',
643
-					],
644
-				]
645
-			],
646
-			[
647
-				'test1',
648
-				['groupA'],
649
-				[
650
-					['uid' => 'test1', 'groups' => ['groupA']],
651
-					['uid' => 'test2', 'groups' => ['groupB']],
652
-				],
653
-				['exact' => ['test1'], 'wide' => []],
654
-				['core' => ['shareapi_restrict_user_enumeration_to_group' => 'yes']],
655
-			],
656
-			[
657
-				'test',
658
-				['groupA'],
659
-				[
660
-					['uid' => 'test1', 'groups' => ['groupA']],
661
-					['uid' => 'test2', 'groups' => ['groupB', 'groupA']],
662
-				],
663
-				['exact' => [], 'wide' => ['test1', 'test2']],
664
-				['core' => ['shareapi_restrict_user_enumeration_to_group' => 'yes']],
665
-			],
666
-			[
667
-				'test',
668
-				['groupA'],
669
-				[
670
-					['uid' => 'test1', 'groups' => ['groupA', 'groupC']],
671
-					['uid' => 'test2', 'groups' => ['groupB', 'groupA']],
672
-				],
673
-				['exact' => [], 'wide' => ['test1', 'test2']],
674
-				['core' => ['shareapi_restrict_user_enumeration_to_group' => 'yes']],
675
-			],
676
-			[
677
-				'test',
678
-				['groupC', 'groupB'],
679
-				[
680
-					['uid' => 'test1', 'groups' => ['groupA', 'groupC']],
681
-					['uid' => 'test2', 'groups' => ['groupB', 'groupA']],
682
-				],
683
-				['exact' => [], 'wide' => ['test1', 'test2']],
684
-				['core' => ['shareapi_restrict_user_enumeration_to_group' => 'yes']],
685
-			],
686
-			[
687
-				'test',
688
-				[],
689
-				[
690
-					['uid' => 'test1', 'groups' => ['groupA']],
691
-					['uid' => 'test2', 'groups' => ['groupB', 'groupA']],
692
-				],
693
-				['exact' => [], 'wide' => []],
694
-				['core' => ['shareapi_restrict_user_enumeration_to_group' => 'yes']],
695
-			],
696
-			[
697
-				'test',
698
-				['groupC', 'groupB'],
699
-				[
700
-					['uid' => 'test1', 'groups' => []],
701
-					['uid' => 'test2', 'groups' => []],
702
-				],
703
-				['exact' => [], 'wide' => []],
704
-				['core' => ['shareapi_restrict_user_enumeration_to_group' => 'yes']],
705
-			],
706
-			[
707
-				'test',
708
-				['groupC', 'groupB'],
709
-				[
710
-					['uid' => 'test1', 'groups' => []],
711
-					['uid' => 'test2', 'groups' => []],
712
-				],
713
-				['exact' => [], 'wide' => []],
714
-				['core' => ['shareapi_restrict_user_enumeration_to_group' => 'yes']],
715
-			],
716
-		];
717
-	}
718
-
719
-	/**
720
-	 * @dataProvider dataSearchEnumeration
721
-	 */
722
-	public function testSearchEnumerationLimit($search, $userGroups, $matchingUsers, $result, $mockedSettings): void {
723
-		$this->mockConfig($mockedSettings);
724
-
725
-		$userResults = [];
726
-		foreach ($matchingUsers as $user) {
727
-			$userResults[$user['uid']] = $user['uid'];
728
-		}
729
-
730
-		$usersById = [];
731
-		foreach ($matchingUsers as $user) {
732
-			$usersById[$user['uid']] = $user;
733
-		}
734
-
735
-		$mappedResultExact = array_map(function ($user) use ($usersById, $search) {
736
-			return [
737
-				'label' => $search === $user ? $user : $usersById[$user]['displayName'],
738
-				'value' => ['shareType' => 0, 'shareWith' => $user],
739
-				'icon' => 'icon-user',
740
-				'subline' => null,
741
-				'status' => [],
742
-				'shareWithDisplayNameUnique' => $user,
743
-			];
744
-		}, $result['exact']);
745
-		$mappedResultWide = array_map(function ($user) {
746
-			return [
747
-				'label' => $user,
748
-				'value' => ['shareType' => 0, 'shareWith' => $user],
749
-				'icon' => 'icon-user',
750
-				'subline' => null,
751
-				'status' => [],
752
-				'shareWithDisplayNameUnique' => $user,
753
-			];
754
-		}, $result['wide']);
755
-
756
-		$this->userManager
757
-			->method('get')
758
-			->willReturnCallback(function ($userId) use ($userResults) {
759
-				if (isset($userResults[$userId])) {
760
-					return $this->getUserMock($userId, $userId);
761
-				}
762
-				return null;
763
-			});
764
-		$this->userManager
765
-			->method('searchDisplayName')
766
-			->willReturnCallback(function ($search) use ($matchingUsers) {
767
-				$users = array_filter(
768
-					$matchingUsers,
769
-					fn ($user) => str_contains(strtolower($user['displayName']), strtolower($search))
770
-				);
771
-				return array_map(
772
-					fn ($user) => $this->getUserMock($user['uid'], $user['displayName']),
773
-					$users);
774
-			});
775
-
776
-		$this->groupManager->method('displayNamesInGroup')
777
-			->willReturn($userResults);
778
-
779
-
780
-		$this->session->expects($this->any())
781
-			->method('getUser')
782
-			->willReturn($this->getUserMock('test', 'foo'));
783
-		$this->groupManager->expects($this->any())
784
-			->method('getUserGroupIds')
785
-			->willReturnCallback(function ($user) use ($matchingUsers, $userGroups) {
786
-				static $firstCall = true;
787
-				if ($firstCall) {
788
-					$firstCall = false;
789
-					// current user
790
-					return $userGroups;
791
-				}
792
-				$neededObject = array_filter(
793
-					$matchingUsers,
794
-					function ($e) use ($user) {
795
-						return $user->getUID() === $e['uid'];
796
-					}
797
-				);
798
-				if (count($neededObject) > 0) {
799
-					return array_shift($neededObject)['groups'];
800
-				}
801
-				return [];
802
-			});
803
-
804
-		$this->instantiatePlugin();
805
-		$this->plugin->search($search, $this->limit, $this->offset, $this->searchResult);
806
-		$result = $this->searchResult->asArray();
807
-
808
-		$this->assertEquals($mappedResultExact, $result['exact']['users']);
809
-		$this->assertEquals($mappedResultWide, $result['users']);
810
-	}
46
+    /** @var ISearchResult */
47
+    protected $searchResult;
48
+
49
+    protected int $limit = 2;
50
+
51
+    protected int $offset = 0;
52
+
53
+    /** @var IUser|MockObject */
54
+    protected $user;
55
+
56
+    protected function setUp(): void {
57
+        parent::setUp();
58
+
59
+        $this->config = $this->createMock(IConfig::class);
60
+
61
+        $this->userManager = $this->createMock(IUserManager::class);
62
+
63
+        $this->groupManager = $this->createMock(IGroupManager::class);
64
+
65
+        $this->session = $this->createMock(IUserSession::class);
66
+
67
+        $this->knownUserService = $this->createMock(KnownUserService::class);
68
+
69
+        $this->userStatusManager = $this->createMock(IUserStatusManager::class);
70
+
71
+        $this->searchResult = new SearchResult();
72
+
73
+        $this->user = $this->getUserMock('admin', 'Administrator');
74
+    }
75
+
76
+    public function instantiatePlugin() {
77
+        // cannot be done within setUp, because dependent mocks needs to be set
78
+        // up with configuration etc. first
79
+        $this->plugin = new UserPlugin(
80
+            $this->config,
81
+            $this->userManager,
82
+            $this->groupManager,
83
+            $this->session,
84
+            $this->knownUserService,
85
+            $this->userStatusManager
86
+        );
87
+    }
88
+
89
+    public function mockConfig($mockedSettings) {
90
+        $this->config->expects($this->any())
91
+            ->method('getAppValue')
92
+            ->willReturnCallback(
93
+                function ($appName, $key, $default) use ($mockedSettings) {
94
+                    return $mockedSettings[$appName][$key] ?? $default;
95
+                }
96
+            );
97
+    }
98
+
99
+    public function getUserMock($uid, $displayName, $enabled = true, $groups = []) {
100
+        $user = $this->createMock(IUser::class);
101
+
102
+        $user->expects($this->any())
103
+            ->method('getUID')
104
+            ->willReturn($uid);
105
+
106
+        $user->expects($this->any())
107
+            ->method('getDisplayName')
108
+            ->willReturn($displayName);
109
+
110
+        $user->expects($this->any())
111
+            ->method('isEnabled')
112
+            ->willReturn($enabled);
113
+
114
+        return $user;
115
+    }
116
+
117
+    public function getGroupMock($gid) {
118
+        $group = $this->createMock(IGroup::class);
119
+
120
+        $group->expects($this->any())
121
+            ->method('getGID')
122
+            ->willReturn($gid);
123
+
124
+        return $group;
125
+    }
126
+
127
+    public function dataGetUsers(): array {
128
+        return [
129
+            ['test', false, true, [], [], [], [], true, false],
130
+            ['test', false, false, [], [], [], [], true, false],
131
+            ['test', true, true, [], [], [], [], true, false],
132
+            ['test', true, false, [], [], [], [], true, false],
133
+            [
134
+                'test', false, true, [], [],
135
+                [
136
+                    ['label' => 'Test', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test'],
137
+                ], [], true, $this->getUserMock('test', 'Test'),
138
+            ],
139
+            [
140
+                'test', false, false, [], [],
141
+                [
142
+                    ['label' => 'Test', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test'],
143
+                ], [], true, $this->getUserMock('test', 'Test'),
144
+            ],
145
+            [
146
+                'test', true, true, [], [],
147
+                [], [], true, $this->getUserMock('test', 'Test'),
148
+            ],
149
+            [
150
+                'test', true, false, [], [],
151
+                [], [], true, $this->getUserMock('test', 'Test'),
152
+            ],
153
+            [
154
+                'test', true, true, ['test-group'], [['test-group', 'test', 2, 0, []]],
155
+                [
156
+                    ['label' => 'Test', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test'],
157
+                ], [], true, $this->getUserMock('test', 'Test'),
158
+            ],
159
+            [
160
+                'test', true, false, ['test-group'], [['test-group', 'test', 2, 0, []]],
161
+                [
162
+                    ['label' => 'Test', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test'],
163
+                ], [], true, $this->getUserMock('test', 'Test'),
164
+            ],
165
+            [
166
+                'test',
167
+                false,
168
+                true,
169
+                [],
170
+                [
171
+                    $this->getUserMock('test1', 'Test One'),
172
+                ],
173
+                [],
174
+                [
175
+                    ['label' => 'Test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test1'],
176
+                ],
177
+                true,
178
+                false,
179
+            ],
180
+            [
181
+                'test',
182
+                false,
183
+                false,
184
+                [],
185
+                [
186
+                    $this->getUserMock('test1', 'Test One'),
187
+                ],
188
+                [],
189
+                [],
190
+                true,
191
+                false,
192
+            ],
193
+            [
194
+                'test',
195
+                false,
196
+                true,
197
+                [],
198
+                [
199
+                    $this->getUserMock('test1', 'Test One'),
200
+                    $this->getUserMock('test2', 'Test Two'),
201
+                ],
202
+                [],
203
+                [
204
+                    ['label' => 'Test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test1'],
205
+                    ['label' => 'Test Two', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test2'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test2'],
206
+                ],
207
+                false,
208
+                false,
209
+            ],
210
+            [
211
+                'test',
212
+                false,
213
+                false,
214
+                [],
215
+                [
216
+                    $this->getUserMock('test1', 'Test One'),
217
+                    $this->getUserMock('test2', 'Test Two'),
218
+                ],
219
+                [],
220
+                [],
221
+                true,
222
+                false,
223
+            ],
224
+            [
225
+                'test',
226
+                false,
227
+                true,
228
+                [],
229
+                [
230
+                    $this->getUserMock('test0', 'Test'),
231
+                    $this->getUserMock('test1', 'Test One'),
232
+                    $this->getUserMock('test2', 'Test Two'),
233
+                ],
234
+                [
235
+                    ['label' => 'Test', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test0'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test0'],
236
+                ],
237
+                [
238
+                    ['label' => 'Test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test1'],
239
+                    ['label' => 'Test Two', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test2'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test2'],
240
+                ],
241
+                false,
242
+                false,
243
+            ],
244
+            [
245
+                'test',
246
+                false,
247
+                true,
248
+                [],
249
+                [
250
+                    $this->getUserMock('test0', 'Test'),
251
+                    $this->getUserMock('test1', 'Test One'),
252
+                    $this->getUserMock('test2', 'Test Two'),
253
+                ],
254
+                [
255
+                    ['label' => 'Test', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test0'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test0'],
256
+                ],
257
+                [
258
+                    ['label' => 'Test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test1'],
259
+                    ['label' => 'Test Two', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test2'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test2'],
260
+                ],
261
+                false,
262
+                false,
263
+                [],
264
+                true,
265
+            ],
266
+            [
267
+                'test',
268
+                false,
269
+                false,
270
+                [],
271
+                [
272
+                    $this->getUserMock('test0', 'Test'),
273
+                    $this->getUserMock('test1', 'Test One'),
274
+                    $this->getUserMock('test2', 'Test Two'),
275
+                ],
276
+                [
277
+                    ['label' => 'Test', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test0'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test0'],
278
+                ],
279
+                [],
280
+                true,
281
+                false,
282
+            ],
283
+            [
284
+                'test',
285
+                true,
286
+                true,
287
+                ['abc', 'xyz'],
288
+                [
289
+                    ['abc', 'test', 2, 0, ['test1' => 'Test One']],
290
+                    ['xyz', 'test', 2, 0, []],
291
+                ],
292
+                [],
293
+                [
294
+                    ['label' => 'Test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test1'],
295
+                ],
296
+                true,
297
+                false,
298
+                [['test1', $this->getUserMock('test1', 'Test One')]],
299
+            ],
300
+            [
301
+                'test',
302
+                true,
303
+                false,
304
+                ['abc', 'xyz'],
305
+                [
306
+                    ['abc', 'test', 2, 0, ['test1' => 'Test One']],
307
+                    ['xyz', 'test', 2, 0, []],
308
+                ],
309
+                [],
310
+                [],
311
+                true,
312
+                false,
313
+                [['test1', $this->getUserMock('test1', 'Test One')]],
314
+            ],
315
+            [
316
+                'test',
317
+                true,
318
+                true,
319
+                ['abc', 'xyz'],
320
+                [
321
+                    ['abc', 'test', 2, 0, [
322
+                        'test1' => 'Test One',
323
+                        'test2' => 'Test Two',
324
+                    ]],
325
+                    ['xyz', 'test', 2, 0, [
326
+                        'test1' => 'Test One',
327
+                        'test2' => 'Test Two',
328
+                    ]],
329
+                ],
330
+                [],
331
+                [
332
+                    ['label' => 'Test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test1'],
333
+                    ['label' => 'Test Two', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test2'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test2'],
334
+                ],
335
+                true,
336
+                false,
337
+                [
338
+                    ['test1', $this->getUserMock('test1', 'Test One')],
339
+                    ['test2', $this->getUserMock('test2', 'Test Two')],
340
+                ],
341
+            ],
342
+            [
343
+                'test',
344
+                true,
345
+                false,
346
+                ['abc', 'xyz'],
347
+                [
348
+                    ['abc', 'test', 2, 0, [
349
+                        'test1' => 'Test One',
350
+                        'test2' => 'Test Two',
351
+                    ]],
352
+                    ['xyz', 'test', 2, 0, [
353
+                        'test1' => 'Test One',
354
+                        'test2' => 'Test Two',
355
+                    ]],
356
+                ],
357
+                [],
358
+                [],
359
+                true,
360
+                false,
361
+                [
362
+                    ['test1', $this->getUserMock('test1', 'Test One')],
363
+                    ['test2', $this->getUserMock('test2', 'Test Two')],
364
+                ],
365
+            ],
366
+            [
367
+                'test',
368
+                true,
369
+                true,
370
+                ['abc', 'xyz'],
371
+                [
372
+                    ['abc', 'test', 2, 0, [
373
+                        'test' => 'Test One',
374
+                    ]],
375
+                    ['xyz', 'test', 2, 0, [
376
+                        'test2' => 'Test Two',
377
+                    ]],
378
+                ],
379
+                [
380
+                    ['label' => 'Test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test'],
381
+                ],
382
+                [
383
+                    ['label' => 'Test Two', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test2'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test2'],
384
+                ],
385
+                false,
386
+                false,
387
+                [
388
+                    ['test', $this->getUserMock('test', 'Test One')],
389
+                    ['test2', $this->getUserMock('test2', 'Test Two')],
390
+                ],
391
+            ],
392
+            [
393
+                'test',
394
+                true,
395
+                false,
396
+                ['abc', 'xyz'],
397
+                [
398
+                    ['abc', 'test', 2, 0, [
399
+                        'test' => 'Test One',
400
+                    ]],
401
+                    ['xyz', 'test', 2, 0, [
402
+                        'test2' => 'Test Two',
403
+                    ]],
404
+                ],
405
+                [
406
+                    ['label' => 'Test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test'], 'icon' => 'icon-user', 'subline' => null, 'status' => [], 'shareWithDisplayNameUnique' => 'test'],
407
+                ],
408
+                [],
409
+                true,
410
+                false,
411
+                [
412
+                    ['test', $this->getUserMock('test', 'Test One')],
413
+                    ['test2', $this->getUserMock('test2', 'Test Two')],
414
+                ],
415
+            ],
416
+        ];
417
+    }
418
+
419
+    /**
420
+     * @dataProvider dataGetUsers
421
+     *
422
+     * @param string $searchTerm
423
+     * @param bool $shareWithGroupOnly
424
+     * @param bool $shareeEnumeration
425
+     * @param array $groupResponse
426
+     * @param array $userResponse
427
+     * @param array $exactExpected
428
+     * @param array $expected
429
+     * @param bool $reachedEnd
430
+     * @param bool|IUser $singleUser
431
+     * @param array $users
432
+     */
433
+    public function testSearch(
434
+        $searchTerm,
435
+        $shareWithGroupOnly,
436
+        $shareeEnumeration,
437
+        array $groupResponse,
438
+        array $userResponse,
439
+        array $exactExpected,
440
+        array $expected,
441
+        $reachedEnd,
442
+        $singleUser,
443
+        array $users = [],
444
+        $shareeEnumerationPhone = false,
445
+    ): void {
446
+        $this->mockConfig(['core' => [
447
+            'shareapi_only_share_with_group_members' => $shareWithGroupOnly ? 'yes' : 'no',
448
+            'shareapi_allow_share_dialog_user_enumeration' => $shareeEnumeration? 'yes' : 'no',
449
+            'shareapi_restrict_user_enumeration_to_group' => false ? 'yes' : 'no',
450
+            'shareapi_restrict_user_enumeration_to_phone' => $shareeEnumerationPhone ? 'yes' : 'no',
451
+        ]]);
452
+
453
+        $this->instantiatePlugin();
454
+
455
+        $this->session->expects($this->any())
456
+            ->method('getUser')
457
+            ->willReturn($this->user);
458
+
459
+        if (!$shareWithGroupOnly) {
460
+            if ($shareeEnumerationPhone) {
461
+                $this->userManager->expects($this->once())
462
+                    ->method('searchKnownUsersByDisplayName')
463
+                    ->with($this->user->getUID(), $searchTerm, $this->limit, $this->offset)
464
+                    ->willReturn($userResponse);
465
+
466
+                $this->knownUserService->method('isKnownToUser')
467
+                    ->willReturnMap([
468
+                        [$this->user->getUID(), 'test0', true],
469
+                        [$this->user->getUID(), 'test1', true],
470
+                        [$this->user->getUID(), 'test2', true],
471
+                    ]);
472
+            } else {
473
+                $this->userManager->expects($this->once())
474
+                    ->method('searchDisplayName')
475
+                    ->with($searchTerm, $this->limit, $this->offset)
476
+                    ->willReturn($userResponse);
477
+            }
478
+        } else {
479
+            $this->groupManager->method('getUserGroupIds')
480
+                ->with($this->user)
481
+                ->willReturn($groupResponse);
482
+
483
+            if ($singleUser !== false) {
484
+                $this->groupManager->method('getUserGroupIds')
485
+                    ->with($singleUser)
486
+                    ->willReturn($groupResponse);
487
+            }
488
+
489
+            $this->groupManager->method('displayNamesInGroup')
490
+                ->willReturnMap($userResponse);
491
+        }
492
+
493
+        if ($singleUser !== false) {
494
+            $users[] = [$searchTerm, $singleUser];
495
+        }
496
+
497
+        if (!empty($users)) {
498
+            $this->userManager->expects($this->atLeastOnce())
499
+                ->method('get')
500
+                ->willReturnMap($users);
501
+        }
502
+
503
+        $moreResults = $this->plugin->search($searchTerm, $this->limit, $this->offset, $this->searchResult);
504
+        $result = $this->searchResult->asArray();
505
+
506
+        $this->assertEquals($exactExpected, $result['exact']['users']);
507
+        $this->assertEquals($expected, $result['users']);
508
+        $this->assertSame($reachedEnd, $moreResults);
509
+    }
510
+
511
+    public static function takeOutCurrentUserProvider(): array {
512
+        $inputUsers = [
513
+            'alice' => 'Alice',
514
+            'bob' => 'Bob',
515
+            'carol' => 'Carol',
516
+        ];
517
+        return [
518
+            [
519
+                $inputUsers,
520
+                ['alice', 'carol'],
521
+                'bob',
522
+            ],
523
+            [
524
+                $inputUsers,
525
+                ['alice', 'bob', 'carol'],
526
+                'dave',
527
+            ],
528
+            [
529
+                $inputUsers,
530
+                ['alice', 'bob', 'carol'],
531
+                null,
532
+            ],
533
+        ];
534
+    }
535
+
536
+    /**
537
+     * @dataProvider takeOutCurrentUserProvider
538
+     * @param array $users
539
+     * @param array $expectedUIDs
540
+     * @param $currentUserId
541
+     */
542
+    public function testTakeOutCurrentUser(array $users, array $expectedUIDs, $currentUserId): void {
543
+        $this->instantiatePlugin();
544
+
545
+        $this->session->expects($this->once())
546
+            ->method('getUser')
547
+            ->willReturnCallback(function () use ($currentUserId) {
548
+                if ($currentUserId !== null) {
549
+                    return $this->getUserMock($currentUserId, $currentUserId);
550
+                }
551
+                return null;
552
+            });
553
+
554
+        $this->plugin->takeOutCurrentUser($users);
555
+        $this->assertSame($expectedUIDs, array_keys($users));
556
+    }
557
+
558
+    public static function dataSearchEnumeration(): array {
559
+        return [
560
+            [
561
+                'test',
562
+                ['groupA'],
563
+                [
564
+                    ['uid' => 'test1', 'groups' => ['groupA']],
565
+                    ['uid' => 'test2', 'groups' => ['groupB']],
566
+                ],
567
+                ['exact' => [], 'wide' => ['test1']],
568
+                ['core' => ['shareapi_restrict_user_enumeration_to_group' => 'yes']],
569
+            ],
570
+            [
571
+                'test',
572
+                ['groupA'],
573
+                [
574
+                    ['uid' => 'test1', 'displayName' => 'Test user 1', 'groups' => ['groupA']],
575
+                    ['uid' => 'test2', 'displayName' => 'Test user 2', 'groups' => ['groupA']],
576
+                ],
577
+                ['exact' => [], 'wide' => []],
578
+                ['core' => ['shareapi_allow_share_dialog_user_enumeration' => 'no']],
579
+            ],
580
+            [
581
+                'test1',
582
+                ['groupA'],
583
+                [
584
+                    ['uid' => 'test1', 'displayName' => 'Test user 1', 'groups' => ['groupA']],
585
+                    ['uid' => 'test2', 'displayName' => 'Test user 2', 'groups' => ['groupA']],
586
+                ],
587
+                ['exact' => ['test1'], 'wide' => []],
588
+                ['core' => ['shareapi_allow_share_dialog_user_enumeration' => 'no']],
589
+            ],
590
+            [
591
+                'test1',
592
+                ['groupA'],
593
+                [
594
+                    ['uid' => 'test1', 'displayName' => 'Test user 1', 'groups' => ['groupA']],
595
+                    ['uid' => 'test2', 'displayName' => 'Test user 2', 'groups' => ['groupA']],
596
+                ],
597
+                ['exact' => [], 'wide' => []],
598
+                [
599
+                    'core' => [
600
+                        'shareapi_allow_share_dialog_user_enumeration' => 'no',
601
+                        'shareapi_restrict_user_enumeration_full_match_userid' => 'no',
602
+                    ],
603
+                ]
604
+            ],
605
+            [
606
+                'Test user 1',
607
+                ['groupA'],
608
+                [
609
+                    ['uid' => 'test1', 'displayName' => 'Test user 1', 'groups' => ['groupA']],
610
+                    ['uid' => 'test2', 'displayName' => 'Test user 2', 'groups' => ['groupA']],
611
+                ],
612
+                ['exact' => ['test1'], 'wide' => []],
613
+                [
614
+                    'core' => [
615
+                        'shareapi_allow_share_dialog_user_enumeration' => 'no',
616
+                        'shareapi_restrict_user_enumeration_full_match_userid' => 'no',
617
+                    ],
618
+                ]
619
+            ],
620
+            [
621
+                'Test user 1',
622
+                ['groupA'],
623
+                [
624
+                    ['uid' => 'test1', 'displayName' => 'Test user 1 (Second displayName for user 1)', 'groups' => ['groupA']],
625
+                    ['uid' => 'test2', 'displayName' => 'Test user 2 (Second displayName for user 2)', 'groups' => ['groupA']],
626
+                ],
627
+                ['exact' => [], 'wide' => []],
628
+                ['core' => ['shareapi_allow_share_dialog_user_enumeration' => 'no'],
629
+                ]
630
+            ],
631
+            [
632
+                'Test user 1',
633
+                ['groupA'],
634
+                [
635
+                    ['uid' => 'test1', 'displayName' => 'Test user 1 (Second displayName for user 1)', 'groups' => ['groupA']],
636
+                    ['uid' => 'test2', 'displayName' => 'Test user 2 (Second displayName for user 2)', 'groups' => ['groupA']],
637
+                ],
638
+                ['exact' => ['test1'], 'wide' => []],
639
+                [
640
+                    'core' => [
641
+                        'shareapi_allow_share_dialog_user_enumeration' => 'no',
642
+                        'shareapi_restrict_user_enumeration_full_match_ignore_second_dn' => 'yes',
643
+                    ],
644
+                ]
645
+            ],
646
+            [
647
+                'test1',
648
+                ['groupA'],
649
+                [
650
+                    ['uid' => 'test1', 'groups' => ['groupA']],
651
+                    ['uid' => 'test2', 'groups' => ['groupB']],
652
+                ],
653
+                ['exact' => ['test1'], 'wide' => []],
654
+                ['core' => ['shareapi_restrict_user_enumeration_to_group' => 'yes']],
655
+            ],
656
+            [
657
+                'test',
658
+                ['groupA'],
659
+                [
660
+                    ['uid' => 'test1', 'groups' => ['groupA']],
661
+                    ['uid' => 'test2', 'groups' => ['groupB', 'groupA']],
662
+                ],
663
+                ['exact' => [], 'wide' => ['test1', 'test2']],
664
+                ['core' => ['shareapi_restrict_user_enumeration_to_group' => 'yes']],
665
+            ],
666
+            [
667
+                'test',
668
+                ['groupA'],
669
+                [
670
+                    ['uid' => 'test1', 'groups' => ['groupA', 'groupC']],
671
+                    ['uid' => 'test2', 'groups' => ['groupB', 'groupA']],
672
+                ],
673
+                ['exact' => [], 'wide' => ['test1', 'test2']],
674
+                ['core' => ['shareapi_restrict_user_enumeration_to_group' => 'yes']],
675
+            ],
676
+            [
677
+                'test',
678
+                ['groupC', 'groupB'],
679
+                [
680
+                    ['uid' => 'test1', 'groups' => ['groupA', 'groupC']],
681
+                    ['uid' => 'test2', 'groups' => ['groupB', 'groupA']],
682
+                ],
683
+                ['exact' => [], 'wide' => ['test1', 'test2']],
684
+                ['core' => ['shareapi_restrict_user_enumeration_to_group' => 'yes']],
685
+            ],
686
+            [
687
+                'test',
688
+                [],
689
+                [
690
+                    ['uid' => 'test1', 'groups' => ['groupA']],
691
+                    ['uid' => 'test2', 'groups' => ['groupB', 'groupA']],
692
+                ],
693
+                ['exact' => [], 'wide' => []],
694
+                ['core' => ['shareapi_restrict_user_enumeration_to_group' => 'yes']],
695
+            ],
696
+            [
697
+                'test',
698
+                ['groupC', 'groupB'],
699
+                [
700
+                    ['uid' => 'test1', 'groups' => []],
701
+                    ['uid' => 'test2', 'groups' => []],
702
+                ],
703
+                ['exact' => [], 'wide' => []],
704
+                ['core' => ['shareapi_restrict_user_enumeration_to_group' => 'yes']],
705
+            ],
706
+            [
707
+                'test',
708
+                ['groupC', 'groupB'],
709
+                [
710
+                    ['uid' => 'test1', 'groups' => []],
711
+                    ['uid' => 'test2', 'groups' => []],
712
+                ],
713
+                ['exact' => [], 'wide' => []],
714
+                ['core' => ['shareapi_restrict_user_enumeration_to_group' => 'yes']],
715
+            ],
716
+        ];
717
+    }
718
+
719
+    /**
720
+     * @dataProvider dataSearchEnumeration
721
+     */
722
+    public function testSearchEnumerationLimit($search, $userGroups, $matchingUsers, $result, $mockedSettings): void {
723
+        $this->mockConfig($mockedSettings);
724
+
725
+        $userResults = [];
726
+        foreach ($matchingUsers as $user) {
727
+            $userResults[$user['uid']] = $user['uid'];
728
+        }
729
+
730
+        $usersById = [];
731
+        foreach ($matchingUsers as $user) {
732
+            $usersById[$user['uid']] = $user;
733
+        }
734
+
735
+        $mappedResultExact = array_map(function ($user) use ($usersById, $search) {
736
+            return [
737
+                'label' => $search === $user ? $user : $usersById[$user]['displayName'],
738
+                'value' => ['shareType' => 0, 'shareWith' => $user],
739
+                'icon' => 'icon-user',
740
+                'subline' => null,
741
+                'status' => [],
742
+                'shareWithDisplayNameUnique' => $user,
743
+            ];
744
+        }, $result['exact']);
745
+        $mappedResultWide = array_map(function ($user) {
746
+            return [
747
+                'label' => $user,
748
+                'value' => ['shareType' => 0, 'shareWith' => $user],
749
+                'icon' => 'icon-user',
750
+                'subline' => null,
751
+                'status' => [],
752
+                'shareWithDisplayNameUnique' => $user,
753
+            ];
754
+        }, $result['wide']);
755
+
756
+        $this->userManager
757
+            ->method('get')
758
+            ->willReturnCallback(function ($userId) use ($userResults) {
759
+                if (isset($userResults[$userId])) {
760
+                    return $this->getUserMock($userId, $userId);
761
+                }
762
+                return null;
763
+            });
764
+        $this->userManager
765
+            ->method('searchDisplayName')
766
+            ->willReturnCallback(function ($search) use ($matchingUsers) {
767
+                $users = array_filter(
768
+                    $matchingUsers,
769
+                    fn ($user) => str_contains(strtolower($user['displayName']), strtolower($search))
770
+                );
771
+                return array_map(
772
+                    fn ($user) => $this->getUserMock($user['uid'], $user['displayName']),
773
+                    $users);
774
+            });
775
+
776
+        $this->groupManager->method('displayNamesInGroup')
777
+            ->willReturn($userResults);
778
+
779
+
780
+        $this->session->expects($this->any())
781
+            ->method('getUser')
782
+            ->willReturn($this->getUserMock('test', 'foo'));
783
+        $this->groupManager->expects($this->any())
784
+            ->method('getUserGroupIds')
785
+            ->willReturnCallback(function ($user) use ($matchingUsers, $userGroups) {
786
+                static $firstCall = true;
787
+                if ($firstCall) {
788
+                    $firstCall = false;
789
+                    // current user
790
+                    return $userGroups;
791
+                }
792
+                $neededObject = array_filter(
793
+                    $matchingUsers,
794
+                    function ($e) use ($user) {
795
+                        return $user->getUID() === $e['uid'];
796
+                    }
797
+                );
798
+                if (count($neededObject) > 0) {
799
+                    return array_shift($neededObject)['groups'];
800
+                }
801
+                return [];
802
+            });
803
+
804
+        $this->instantiatePlugin();
805
+        $this->plugin->search($search, $this->limit, $this->offset, $this->searchResult);
806
+        $result = $this->searchResult->asArray();
807
+
808
+        $this->assertEquals($mappedResultExact, $result['exact']['users']);
809
+        $this->assertEquals($mappedResultWide, $result['users']);
810
+    }
811 811
 }
Please login to merge, or discard this patch.
tests/lib/Collaboration/Collaborators/SearchResultTest.php 2 patches
Indentation   +55 added lines, -55 removed lines patch added patch discarded remove patch
@@ -14,71 +14,71 @@
 block discarded – undo
14 14
 use Test\TestCase;
15 15
 
16 16
 class SearchResultTest extends TestCase {
17
-	/** @var IContainer|\PHPUnit\Framework\MockObject\MockObject */
18
-	protected $container;
19
-	/** @var ISearch */
20
-	protected $search;
17
+    /** @var IContainer|\PHPUnit\Framework\MockObject\MockObject */
18
+    protected $container;
19
+    /** @var ISearch */
20
+    protected $search;
21 21
 
22
-	protected function setUp(): void {
23
-		parent::setUp();
22
+    protected function setUp(): void {
23
+        parent::setUp();
24 24
 
25
-		$this->container = $this->createMock(IContainer::class);
25
+        $this->container = $this->createMock(IContainer::class);
26 26
 
27
-		$this->search = new Search($this->container);
28
-	}
27
+        $this->search = new Search($this->container);
28
+    }
29 29
 
30
-	public static function dataAddResultSet(): array {
31
-		return [
32
-			[[], ['exact' => []]],
33
-			[['users' => ['exact' => null, 'loose' => []]], ['exact' => ['users' => []], 'users' => []]],
34
-			[['groups' => ['exact' => null, 'loose' => ['l1']]], ['exact' => ['groups' => []], 'groups' => ['l1']]],
35
-			[['users' => ['exact' => ['e1'], 'loose' => []]], ['exact' => ['users' => ['e1']], 'users' => []]],
36
-		];
37
-	}
30
+    public static function dataAddResultSet(): array {
31
+        return [
32
+            [[], ['exact' => []]],
33
+            [['users' => ['exact' => null, 'loose' => []]], ['exact' => ['users' => []], 'users' => []]],
34
+            [['groups' => ['exact' => null, 'loose' => ['l1']]], ['exact' => ['groups' => []], 'groups' => ['l1']]],
35
+            [['users' => ['exact' => ['e1'], 'loose' => []]], ['exact' => ['users' => ['e1']], 'users' => []]],
36
+        ];
37
+    }
38 38
 
39
-	/**
40
-	 * @dataProvider dataAddResultSet
41
-	 * @param array $toAdd
42
-	 * @param array $expected
43
-	 */
44
-	public function testAddResultSet(array $toAdd, array $expected): void {
45
-		$result = new SearchResult();
39
+    /**
40
+     * @dataProvider dataAddResultSet
41
+     * @param array $toAdd
42
+     * @param array $expected
43
+     */
44
+    public function testAddResultSet(array $toAdd, array $expected): void {
45
+        $result = new SearchResult();
46 46
 
47
-		foreach ($toAdd as $type => $results) {
48
-			$result->addResultSet(new SearchResultType($type), $results['loose'], $results['exact']);
49
-		}
47
+        foreach ($toAdd as $type => $results) {
48
+            $result->addResultSet(new SearchResultType($type), $results['loose'], $results['exact']);
49
+        }
50 50
 
51
-		$this->assertEquals($expected, $result->asArray());
52
-	}
51
+        $this->assertEquals($expected, $result->asArray());
52
+    }
53 53
 
54
-	public static function dataHasResult(): array {
55
-		$result = ['value' => ['shareWith' => 'l1']];
56
-		return [
57
-			[[],'users', 'n1', false],
58
-			[['users' => ['exact' => null,      'loose' => [$result]]], 'users',  'l1', true],
59
-			[['users' => ['exact' => null,      'loose' => [$result]]], 'users',  'l2', false],
60
-			[['users' => ['exact' => null,      'loose' => [$result]]], 'groups', 'l1', false],
61
-			[['users' => ['exact' => [$result], 'loose' => []]],        'users',  'l1', true],
62
-			[['users' => ['exact' => [$result], 'loose' => []]],        'users',  'l2', false],
63
-			[['users' => ['exact' => [$result], 'loose' => []]],        'groups', 'l1', false],
54
+    public static function dataHasResult(): array {
55
+        $result = ['value' => ['shareWith' => 'l1']];
56
+        return [
57
+            [[],'users', 'n1', false],
58
+            [['users' => ['exact' => null,      'loose' => [$result]]], 'users',  'l1', true],
59
+            [['users' => ['exact' => null,      'loose' => [$result]]], 'users',  'l2', false],
60
+            [['users' => ['exact' => null,      'loose' => [$result]]], 'groups', 'l1', false],
61
+            [['users' => ['exact' => [$result], 'loose' => []]],        'users',  'l1', true],
62
+            [['users' => ['exact' => [$result], 'loose' => []]],        'users',  'l2', false],
63
+            [['users' => ['exact' => [$result], 'loose' => []]],        'groups', 'l1', false],
64 64
 
65
-		];
66
-	}
65
+        ];
66
+    }
67 67
 
68
-	/**
69
-	 * @dataProvider dataHasResult
70
-	 * @param array $toAdd
71
-	 * @param string $type
72
-	 * @param string $id
73
-	 * @param bool $expected
74
-	 */
75
-	public function testHasResult(array $toAdd, $type, $id, $expected): void {
76
-		$result = new SearchResult();
68
+    /**
69
+     * @dataProvider dataHasResult
70
+     * @param array $toAdd
71
+     * @param string $type
72
+     * @param string $id
73
+     * @param bool $expected
74
+     */
75
+    public function testHasResult(array $toAdd, $type, $id, $expected): void {
76
+        $result = new SearchResult();
77 77
 
78
-		foreach ($toAdd as $addType => $results) {
79
-			$result->addResultSet(new SearchResultType($addType), $results['loose'], $results['exact']);
80
-		}
78
+        foreach ($toAdd as $addType => $results) {
79
+            $result->addResultSet(new SearchResultType($addType), $results['loose'], $results['exact']);
80
+        }
81 81
 
82
-		$this->assertSame($expected, $result->hasResult(new SearchResultType($type), $id));
83
-	}
82
+        $this->assertSame($expected, $result->hasResult(new SearchResultType($type), $id));
83
+    }
84 84
 }
Please login to merge, or discard this patch.
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -54,13 +54,13 @@
 block discarded – undo
54 54
 	public static function dataHasResult(): array {
55 55
 		$result = ['value' => ['shareWith' => 'l1']];
56 56
 		return [
57
-			[[],'users', 'n1', false],
58
-			[['users' => ['exact' => null,      'loose' => [$result]]], 'users',  'l1', true],
59
-			[['users' => ['exact' => null,      'loose' => [$result]]], 'users',  'l2', false],
60
-			[['users' => ['exact' => null,      'loose' => [$result]]], 'groups', 'l1', false],
61
-			[['users' => ['exact' => [$result], 'loose' => []]],        'users',  'l1', true],
62
-			[['users' => ['exact' => [$result], 'loose' => []]],        'users',  'l2', false],
63
-			[['users' => ['exact' => [$result], 'loose' => []]],        'groups', 'l1', false],
57
+			[[], 'users', 'n1', false],
58
+			[['users' => ['exact' => null, 'loose' => [$result]]], 'users', 'l1', true],
59
+			[['users' => ['exact' => null, 'loose' => [$result]]], 'users', 'l2', false],
60
+			[['users' => ['exact' => null, 'loose' => [$result]]], 'groups', 'l1', false],
61
+			[['users' => ['exact' => [$result], 'loose' => []]], 'users', 'l1', true],
62
+			[['users' => ['exact' => [$result], 'loose' => []]], 'users', 'l2', false],
63
+			[['users' => ['exact' => [$result], 'loose' => []]], 'groups', 'l1', false],
64 64
 
65 65
 		];
66 66
 	}
Please login to merge, or discard this patch.
tests/lib/Collaboration/Collaborators/SearchTest.php 1 patch
Indentation   +235 added lines, -235 removed lines patch added patch discarded remove patch
@@ -16,239 +16,239 @@
 block discarded – undo
16 16
 use Test\TestCase;
17 17
 
18 18
 class SearchTest extends TestCase {
19
-	/** @var IContainer|\PHPUnit\Framework\MockObject\MockObject */
20
-	protected $container;
21
-	/** @var ISearch */
22
-	protected $search;
23
-
24
-	protected function setUp(): void {
25
-		parent::setUp();
26
-
27
-		$this->container = $this->createMock(IContainer::class);
28
-
29
-		$this->search = new Search($this->container);
30
-	}
31
-
32
-	/**
33
-	 * @dataProvider dataSearchSharees
34
-	 */
35
-	public function testSearch(
36
-		string $searchTerm,
37
-		array $shareTypes,
38
-		int $page,
39
-		int $perPage,
40
-		array $mockedUserResult,
41
-		array $mockedGroupsResult,
42
-		array $mockedRemotesResult,
43
-		array $mockedMailResult,
44
-		array $expected,
45
-		bool $expectedMoreResults,
46
-	): void {
47
-		$searchResult = new SearchResult();
48
-
49
-		$userPlugin = $this->createMock(ISearchPlugin::class);
50
-		$userPlugin->expects($this->any())
51
-			->method('search')
52
-			->willReturnCallback(function () use ($searchResult, $mockedUserResult, $expectedMoreResults) {
53
-				$type = new SearchResultType('users');
54
-				$searchResult->addResultSet($type, $mockedUserResult);
55
-				return $expectedMoreResults;
56
-			});
57
-
58
-		$groupPlugin = $this->createMock(ISearchPlugin::class);
59
-		$groupPlugin->expects($this->any())
60
-			->method('search')
61
-			->willReturnCallback(function () use ($searchResult, $mockedGroupsResult, $expectedMoreResults) {
62
-				$type = new SearchResultType('groups');
63
-				$searchResult->addResultSet($type, $mockedGroupsResult);
64
-				return $expectedMoreResults;
65
-			});
66
-
67
-		$remotePlugin = $this->createMock(ISearchPlugin::class);
68
-		$remotePlugin->expects($this->any())
69
-			->method('search')
70
-			->willReturnCallback(function () use ($searchResult, $mockedRemotesResult, $expectedMoreResults) {
71
-				if ($mockedRemotesResult !== null) {
72
-					$type = new SearchResultType('remotes');
73
-					$searchResult->addResultSet($type, $mockedRemotesResult['results'], $mockedRemotesResult['exact']);
74
-					if ($mockedRemotesResult['exactIdMatch'] === true) {
75
-						$searchResult->markExactIdMatch($type);
76
-					}
77
-				}
78
-				return $expectedMoreResults;
79
-			});
80
-
81
-		$mailPlugin = $this->createMock(ISearchPlugin::class);
82
-		$mailPlugin->expects($this->any())
83
-			->method('search')
84
-			->willReturnCallback(function () use ($searchResult, $mockedMailResult, $expectedMoreResults) {
85
-				$type = new SearchResultType('emails');
86
-				$searchResult->addResultSet($type, $mockedMailResult);
87
-				return $expectedMoreResults;
88
-			});
89
-
90
-		$this->container->expects($this->any())
91
-			->method('resolve')
92
-			->willReturnCallback(function ($class) use ($searchResult, $userPlugin, $groupPlugin, $remotePlugin, $mailPlugin) {
93
-				if ($class === SearchResult::class) {
94
-					return $searchResult;
95
-				} elseif ($class === $userPlugin) {
96
-					return $userPlugin;
97
-				} elseif ($class === $groupPlugin) {
98
-					return $groupPlugin;
99
-				} elseif ($class === $remotePlugin) {
100
-					return $remotePlugin;
101
-				} elseif ($class === $mailPlugin) {
102
-					return $mailPlugin;
103
-				}
104
-				return null;
105
-			});
106
-
107
-		$this->search->registerPlugin(['shareType' => 'SHARE_TYPE_USER', 'class' => $userPlugin]);
108
-		$this->search->registerPlugin(['shareType' => 'SHARE_TYPE_GROUP', 'class' => $groupPlugin]);
109
-		$this->search->registerPlugin(['shareType' => 'SHARE_TYPE_REMOTE', 'class' => $remotePlugin]);
110
-		$this->search->registerPlugin(['shareType' => 'SHARE_TYPE_EMAIL', 'class' => $mailPlugin]);
111
-
112
-		[$results, $moreResults] = $this->search->search($searchTerm, $shareTypes, false, $perPage, $perPage * ($page - 1));
113
-
114
-		$this->assertEquals($expected, $results);
115
-		$this->assertSame($expectedMoreResults, $moreResults);
116
-	}
117
-
118
-	public static function dataSearchSharees(): array {
119
-		return [
120
-			// #0
121
-			[
122
-				'test', [IShare::TYPE_USER, IShare::TYPE_GROUP, IShare::TYPE_REMOTE], 1, 2, [], [], ['results' => [], 'exact' => [], 'exactIdMatch' => false],
123
-				[],
124
-				[
125
-					'exact' => ['users' => [], 'groups' => [], 'remotes' => []],
126
-					'users' => [],
127
-					'groups' => [],
128
-					'remotes' => [],
129
-				],
130
-				false
131
-			],
132
-			// #1
133
-			[
134
-				'test', [IShare::TYPE_USER, IShare::TYPE_GROUP, IShare::TYPE_REMOTE], 1, 2, [], [], ['results' => [], 'exact' => [], 'exactIdMatch' => false],
135
-				[],
136
-				[
137
-					'exact' => ['users' => [], 'groups' => [], 'remotes' => []],
138
-					'users' => [],
139
-					'groups' => [],
140
-					'remotes' => [],
141
-				],
142
-				false
143
-			],
144
-			// #2
145
-			[
146
-				'test', [IShare::TYPE_USER, IShare::TYPE_GROUP, IShare::TYPE_REMOTE], 1, 2, [
147
-					['label' => 'test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']],
148
-				], [
149
-					['label' => 'testgroup1', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'testgroup1']],
150
-				], [
151
-					'results' => [['label' => 'testz@remote', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'testz@remote']]], 'exact' => [], 'exactIdMatch' => false,
152
-				],
153
-				[],
154
-				[
155
-					'exact' => ['users' => [], 'groups' => [], 'remotes' => []],
156
-					'users' => [
157
-						['label' => 'test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']],
158
-					],
159
-					'groups' => [
160
-						['label' => 'testgroup1', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'testgroup1']],
161
-					],
162
-					'remotes' => [
163
-						['label' => 'testz@remote', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'testz@remote']],
164
-					],
165
-				], true,
166
-			],
167
-			// #3 No groups requested
168
-			[
169
-				'test', [IShare::TYPE_USER, IShare::TYPE_REMOTE], 1, 2, [
170
-					['label' => 'test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']],
171
-				], [], [
172
-					'results' => [['label' => 'testz@remote', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'testz@remote']]], 'exact' => [], 'exactIdMatch' => false
173
-				],
174
-				[],
175
-				[
176
-					'exact' => ['users' => [], 'remotes' => []],
177
-					'users' => [
178
-						['label' => 'test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']],
179
-					],
180
-					'remotes' => [
181
-						['label' => 'testz@remote', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'testz@remote']],
182
-					],
183
-				], false,
184
-			],
185
-			// #4 Share type restricted to user - Only one user
186
-			[
187
-				'test', [IShare::TYPE_USER], 1, 2, [
188
-					['label' => 'test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']],
189
-				], [], [], [],
190
-				[
191
-					'exact' => ['users' => []],
192
-					'users' => [
193
-						['label' => 'test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']],
194
-					],
195
-				], false,
196
-			],
197
-			// #5 Share type restricted to user - Multipage result
198
-			[
199
-				'test', [IShare::TYPE_USER], 1, 2, [
200
-					['label' => 'test 1', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']],
201
-					['label' => 'test 2', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test2']],
202
-				], [], [], [],
203
-				[
204
-					'exact' => ['users' => []],
205
-					'users' => [
206
-						['label' => 'test 1', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']],
207
-						['label' => 'test 2', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test2']],
208
-					],
209
-				], true,
210
-			],
211
-			// #6 Mail shares filtered out in favor of remote shares
212
-			[
213
-				'test', // search term
214
-				[IShare::TYPE_USER, IShare::TYPE_GROUP, IShare::TYPE_REMOTE, IShare::TYPE_EMAIL], // plugins
215
-				1, // page
216
-				10, // per page
217
-				[  // user result
218
-					['label' => 'test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']],
219
-				],
220
-				[  // group result
221
-					['label' => 'testgroup1', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'testgroup1']],
222
-				],
223
-				[  // remote result
224
-					'results' => [
225
-						['label' => '[email protected]', 'uuid' => 'f3d78140-abcc-46df-b58d-c7cc1176aadf','value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => '[email protected]']]
226
-					],
227
-					'exact' => [],
228
-					'exactIdMatch' => false,
229
-				],
230
-				[  //  mail result
231
-					['label' => 'test Two', 'uuid' => 'b2321e9e-31af-43ac-a406-583fb26d1964', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => '[email protected]']],
232
-					['label' => 'test One', 'uuid' => 'f3d78140-abcc-46df-b58d-c7cc1176aadf', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => '[email protected]']],
233
-				],
234
-				[  // expected result
235
-					'exact' => ['users' => [], 'groups' => [], 'remotes' => [], 'emails' => []],
236
-					'users' => [
237
-						['label' => 'test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']],
238
-					],
239
-					'groups' => [
240
-						['label' => 'testgroup1', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'testgroup1']],
241
-					],
242
-					'remotes' => [
243
-						['label' => '[email protected]', 'uuid' => 'f3d78140-abcc-46df-b58d-c7cc1176aadf', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => '[email protected]']],
244
-					],
245
-					'emails' => [
246
-						//  one passes, another is filtered out
247
-						['label' => 'test Two', 'uuid' => 'b2321e9e-31af-43ac-a406-583fb26d1964', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => '[email protected]']]
248
-					]
249
-				],
250
-				false, // expected more results indicator
251
-			],
252
-		];
253
-	}
19
+    /** @var IContainer|\PHPUnit\Framework\MockObject\MockObject */
20
+    protected $container;
21
+    /** @var ISearch */
22
+    protected $search;
23
+
24
+    protected function setUp(): void {
25
+        parent::setUp();
26
+
27
+        $this->container = $this->createMock(IContainer::class);
28
+
29
+        $this->search = new Search($this->container);
30
+    }
31
+
32
+    /**
33
+     * @dataProvider dataSearchSharees
34
+     */
35
+    public function testSearch(
36
+        string $searchTerm,
37
+        array $shareTypes,
38
+        int $page,
39
+        int $perPage,
40
+        array $mockedUserResult,
41
+        array $mockedGroupsResult,
42
+        array $mockedRemotesResult,
43
+        array $mockedMailResult,
44
+        array $expected,
45
+        bool $expectedMoreResults,
46
+    ): void {
47
+        $searchResult = new SearchResult();
48
+
49
+        $userPlugin = $this->createMock(ISearchPlugin::class);
50
+        $userPlugin->expects($this->any())
51
+            ->method('search')
52
+            ->willReturnCallback(function () use ($searchResult, $mockedUserResult, $expectedMoreResults) {
53
+                $type = new SearchResultType('users');
54
+                $searchResult->addResultSet($type, $mockedUserResult);
55
+                return $expectedMoreResults;
56
+            });
57
+
58
+        $groupPlugin = $this->createMock(ISearchPlugin::class);
59
+        $groupPlugin->expects($this->any())
60
+            ->method('search')
61
+            ->willReturnCallback(function () use ($searchResult, $mockedGroupsResult, $expectedMoreResults) {
62
+                $type = new SearchResultType('groups');
63
+                $searchResult->addResultSet($type, $mockedGroupsResult);
64
+                return $expectedMoreResults;
65
+            });
66
+
67
+        $remotePlugin = $this->createMock(ISearchPlugin::class);
68
+        $remotePlugin->expects($this->any())
69
+            ->method('search')
70
+            ->willReturnCallback(function () use ($searchResult, $mockedRemotesResult, $expectedMoreResults) {
71
+                if ($mockedRemotesResult !== null) {
72
+                    $type = new SearchResultType('remotes');
73
+                    $searchResult->addResultSet($type, $mockedRemotesResult['results'], $mockedRemotesResult['exact']);
74
+                    if ($mockedRemotesResult['exactIdMatch'] === true) {
75
+                        $searchResult->markExactIdMatch($type);
76
+                    }
77
+                }
78
+                return $expectedMoreResults;
79
+            });
80
+
81
+        $mailPlugin = $this->createMock(ISearchPlugin::class);
82
+        $mailPlugin->expects($this->any())
83
+            ->method('search')
84
+            ->willReturnCallback(function () use ($searchResult, $mockedMailResult, $expectedMoreResults) {
85
+                $type = new SearchResultType('emails');
86
+                $searchResult->addResultSet($type, $mockedMailResult);
87
+                return $expectedMoreResults;
88
+            });
89
+
90
+        $this->container->expects($this->any())
91
+            ->method('resolve')
92
+            ->willReturnCallback(function ($class) use ($searchResult, $userPlugin, $groupPlugin, $remotePlugin, $mailPlugin) {
93
+                if ($class === SearchResult::class) {
94
+                    return $searchResult;
95
+                } elseif ($class === $userPlugin) {
96
+                    return $userPlugin;
97
+                } elseif ($class === $groupPlugin) {
98
+                    return $groupPlugin;
99
+                } elseif ($class === $remotePlugin) {
100
+                    return $remotePlugin;
101
+                } elseif ($class === $mailPlugin) {
102
+                    return $mailPlugin;
103
+                }
104
+                return null;
105
+            });
106
+
107
+        $this->search->registerPlugin(['shareType' => 'SHARE_TYPE_USER', 'class' => $userPlugin]);
108
+        $this->search->registerPlugin(['shareType' => 'SHARE_TYPE_GROUP', 'class' => $groupPlugin]);
109
+        $this->search->registerPlugin(['shareType' => 'SHARE_TYPE_REMOTE', 'class' => $remotePlugin]);
110
+        $this->search->registerPlugin(['shareType' => 'SHARE_TYPE_EMAIL', 'class' => $mailPlugin]);
111
+
112
+        [$results, $moreResults] = $this->search->search($searchTerm, $shareTypes, false, $perPage, $perPage * ($page - 1));
113
+
114
+        $this->assertEquals($expected, $results);
115
+        $this->assertSame($expectedMoreResults, $moreResults);
116
+    }
117
+
118
+    public static function dataSearchSharees(): array {
119
+        return [
120
+            // #0
121
+            [
122
+                'test', [IShare::TYPE_USER, IShare::TYPE_GROUP, IShare::TYPE_REMOTE], 1, 2, [], [], ['results' => [], 'exact' => [], 'exactIdMatch' => false],
123
+                [],
124
+                [
125
+                    'exact' => ['users' => [], 'groups' => [], 'remotes' => []],
126
+                    'users' => [],
127
+                    'groups' => [],
128
+                    'remotes' => [],
129
+                ],
130
+                false
131
+            ],
132
+            // #1
133
+            [
134
+                'test', [IShare::TYPE_USER, IShare::TYPE_GROUP, IShare::TYPE_REMOTE], 1, 2, [], [], ['results' => [], 'exact' => [], 'exactIdMatch' => false],
135
+                [],
136
+                [
137
+                    'exact' => ['users' => [], 'groups' => [], 'remotes' => []],
138
+                    'users' => [],
139
+                    'groups' => [],
140
+                    'remotes' => [],
141
+                ],
142
+                false
143
+            ],
144
+            // #2
145
+            [
146
+                'test', [IShare::TYPE_USER, IShare::TYPE_GROUP, IShare::TYPE_REMOTE], 1, 2, [
147
+                    ['label' => 'test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']],
148
+                ], [
149
+                    ['label' => 'testgroup1', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'testgroup1']],
150
+                ], [
151
+                    'results' => [['label' => 'testz@remote', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'testz@remote']]], 'exact' => [], 'exactIdMatch' => false,
152
+                ],
153
+                [],
154
+                [
155
+                    'exact' => ['users' => [], 'groups' => [], 'remotes' => []],
156
+                    'users' => [
157
+                        ['label' => 'test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']],
158
+                    ],
159
+                    'groups' => [
160
+                        ['label' => 'testgroup1', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'testgroup1']],
161
+                    ],
162
+                    'remotes' => [
163
+                        ['label' => 'testz@remote', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'testz@remote']],
164
+                    ],
165
+                ], true,
166
+            ],
167
+            // #3 No groups requested
168
+            [
169
+                'test', [IShare::TYPE_USER, IShare::TYPE_REMOTE], 1, 2, [
170
+                    ['label' => 'test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']],
171
+                ], [], [
172
+                    'results' => [['label' => 'testz@remote', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'testz@remote']]], 'exact' => [], 'exactIdMatch' => false
173
+                ],
174
+                [],
175
+                [
176
+                    'exact' => ['users' => [], 'remotes' => []],
177
+                    'users' => [
178
+                        ['label' => 'test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']],
179
+                    ],
180
+                    'remotes' => [
181
+                        ['label' => 'testz@remote', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'testz@remote']],
182
+                    ],
183
+                ], false,
184
+            ],
185
+            // #4 Share type restricted to user - Only one user
186
+            [
187
+                'test', [IShare::TYPE_USER], 1, 2, [
188
+                    ['label' => 'test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']],
189
+                ], [], [], [],
190
+                [
191
+                    'exact' => ['users' => []],
192
+                    'users' => [
193
+                        ['label' => 'test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']],
194
+                    ],
195
+                ], false,
196
+            ],
197
+            // #5 Share type restricted to user - Multipage result
198
+            [
199
+                'test', [IShare::TYPE_USER], 1, 2, [
200
+                    ['label' => 'test 1', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']],
201
+                    ['label' => 'test 2', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test2']],
202
+                ], [], [], [],
203
+                [
204
+                    'exact' => ['users' => []],
205
+                    'users' => [
206
+                        ['label' => 'test 1', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']],
207
+                        ['label' => 'test 2', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test2']],
208
+                    ],
209
+                ], true,
210
+            ],
211
+            // #6 Mail shares filtered out in favor of remote shares
212
+            [
213
+                'test', // search term
214
+                [IShare::TYPE_USER, IShare::TYPE_GROUP, IShare::TYPE_REMOTE, IShare::TYPE_EMAIL], // plugins
215
+                1, // page
216
+                10, // per page
217
+                [  // user result
218
+                    ['label' => 'test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']],
219
+                ],
220
+                [  // group result
221
+                    ['label' => 'testgroup1', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'testgroup1']],
222
+                ],
223
+                [  // remote result
224
+                    'results' => [
225
+                        ['label' => '[email protected]', 'uuid' => 'f3d78140-abcc-46df-b58d-c7cc1176aadf','value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => '[email protected]']]
226
+                    ],
227
+                    'exact' => [],
228
+                    'exactIdMatch' => false,
229
+                ],
230
+                [  //  mail result
231
+                    ['label' => 'test Two', 'uuid' => 'b2321e9e-31af-43ac-a406-583fb26d1964', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => '[email protected]']],
232
+                    ['label' => 'test One', 'uuid' => 'f3d78140-abcc-46df-b58d-c7cc1176aadf', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => '[email protected]']],
233
+                ],
234
+                [  // expected result
235
+                    'exact' => ['users' => [], 'groups' => [], 'remotes' => [], 'emails' => []],
236
+                    'users' => [
237
+                        ['label' => 'test One', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1']],
238
+                    ],
239
+                    'groups' => [
240
+                        ['label' => 'testgroup1', 'value' => ['shareType' => IShare::TYPE_GROUP, 'shareWith' => 'testgroup1']],
241
+                    ],
242
+                    'remotes' => [
243
+                        ['label' => '[email protected]', 'uuid' => 'f3d78140-abcc-46df-b58d-c7cc1176aadf', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => '[email protected]']],
244
+                    ],
245
+                    'emails' => [
246
+                        //  one passes, another is filtered out
247
+                        ['label' => 'test Two', 'uuid' => 'b2321e9e-31af-43ac-a406-583fb26d1964', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => '[email protected]']]
248
+                    ]
249
+                ],
250
+                false, // expected more results indicator
251
+            ],
252
+        ];
253
+    }
254 254
 }
Please login to merge, or discard this patch.
tests/lib/Collaboration/Collaborators/MailPluginTest.php 1 patch
Indentation   +677 added lines, -677 removed lines patch added patch discarded remove patch
@@ -26,681 +26,681 @@
 block discarded – undo
26 26
 use Test\TestCase;
27 27
 
28 28
 class MailPluginTest extends TestCase {
29
-	/** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
30
-	protected $config;
31
-
32
-	/** @var IManager|\PHPUnit\Framework\MockObject\MockObject */
33
-	protected $contactsManager;
34
-
35
-	/** @var ICloudIdManager|\PHPUnit\Framework\MockObject\MockObject */
36
-	protected $cloudIdManager;
37
-
38
-	/** @var MailPlugin */
39
-	protected $plugin;
40
-
41
-	/** @var SearchResult */
42
-	protected $searchResult;
43
-
44
-	/** @var IGroupManager|\PHPUnit\Framework\MockObject\MockObject */
45
-	protected $groupManager;
46
-
47
-	/** @var KnownUserService|\PHPUnit\Framework\MockObject\MockObject */
48
-	protected $knownUserService;
49
-
50
-	/** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */
51
-	protected $userSession;
52
-
53
-	/** @var IMailer|\PHPUnit\Framework\MockObject\MockObject */
54
-	protected $mailer;
55
-
56
-	protected function setUp(): void {
57
-		parent::setUp();
58
-
59
-		$this->config = $this->createMock(IConfig::class);
60
-		$this->contactsManager = $this->createMock(IManager::class);
61
-		$this->groupManager = $this->createMock(IGroupManager::class);
62
-		$this->knownUserService = $this->createMock(KnownUserService::class);
63
-		$this->userSession = $this->createMock(IUserSession::class);
64
-		$this->mailer = $this->createMock(IMailer::class);
65
-		$this->cloudIdManager = new CloudIdManager(
66
-			$this->contactsManager,
67
-			$this->createMock(IURLGenerator::class),
68
-			$this->createMock(IUserManager::class),
69
-			$this->createMock(ICacheFactory::class),
70
-			$this->createMock(IEventDispatcher::class)
71
-		);
72
-
73
-		$this->searchResult = new SearchResult();
74
-	}
75
-
76
-	public function instantiatePlugin() {
77
-		$this->plugin = new MailPlugin(
78
-			$this->contactsManager,
79
-			$this->cloudIdManager,
80
-			$this->config,
81
-			$this->groupManager,
82
-			$this->knownUserService,
83
-			$this->userSession,
84
-			$this->mailer
85
-		);
86
-	}
87
-
88
-	/**
89
-	 * @dataProvider dataGetEmail
90
-	 *
91
-	 * @param string $searchTerm
92
-	 * @param array $contacts
93
-	 * @param bool $shareeEnumeration
94
-	 * @param array $expected
95
-	 * @param bool $reachedEnd
96
-	 */
97
-	public function testSearch($searchTerm, $contacts, $shareeEnumeration, $expected, $exactIdMatch, $reachedEnd, $validEmail): void {
98
-		$this->config->expects($this->any())
99
-			->method('getAppValue')
100
-			->willReturnCallback(
101
-				function ($appName, $key, $default) use ($shareeEnumeration) {
102
-					if ($appName === 'core' && $key === 'shareapi_allow_share_dialog_user_enumeration') {
103
-						return $shareeEnumeration ? 'yes' : 'no';
104
-					}
105
-					return $default;
106
-				}
107
-			);
108
-
109
-		$this->instantiatePlugin();
110
-
111
-		$currentUser = $this->createMock(IUser::class);
112
-		$currentUser->method('getUID')
113
-			->willReturn('current');
114
-		$this->userSession->method('getUser')
115
-			->willReturn($currentUser);
116
-
117
-		$this->mailer->method('validateMailAddress')
118
-			->willReturn($validEmail);
119
-
120
-		$this->contactsManager->expects($this->any())
121
-			->method('search')
122
-			->willReturnCallback(function ($search, $searchAttributes) use ($searchTerm, $contacts) {
123
-				if ($search === $searchTerm) {
124
-					return $contacts;
125
-				}
126
-				return [];
127
-			});
128
-
129
-		$moreResults = $this->plugin->search($searchTerm, 2, 0, $this->searchResult);
130
-		$result = $this->searchResult->asArray();
131
-
132
-		$this->assertSame($exactIdMatch, $this->searchResult->hasExactIdMatch(new SearchResultType('emails')));
133
-		$this->assertEquals($expected, $result);
134
-		$this->assertSame($reachedEnd, $moreResults);
135
-	}
136
-
137
-	public static function dataGetEmail(): array {
138
-		return [
139
-			// data set 0
140
-			['test', [], true, ['emails' => [], 'exact' => ['emails' => []]], false, false, false],
141
-			// data set 1
142
-			['test', [], false, ['emails' => [], 'exact' => ['emails' => []]], false, false, false],
143
-			// data set 2
144
-			[
145
-				'[email protected]',
146
-				[],
147
-				true,
148
-				['emails' => [], 'exact' => ['emails' => [['uuid' => '[email protected]', 'label' => '[email protected]', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => '[email protected]']]]]],
149
-				false,
150
-				false,
151
-				true,
152
-			],
153
-			// data set 3
154
-			[ // no valid email address
155
-				'test@remote',
156
-				[],
157
-				true,
158
-				['emails' => [], 'exact' => ['emails' => []]],
159
-				false,
160
-				false,
161
-				false,
162
-			],
163
-			// data set 4
164
-			[
165
-				'[email protected]',
166
-				[],
167
-				false,
168
-				['emails' => [], 'exact' => ['emails' => [['uuid' => '[email protected]', 'label' => '[email protected]', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => '[email protected]']]]]],
169
-				false,
170
-				false,
171
-				true,
172
-			],
173
-			// data set 5
174
-			[
175
-				'test',
176
-				[
177
-					[
178
-						'UID' => 'uid3',
179
-						'FN' => 'User3 @ Localhost',
180
-					],
181
-					[
182
-						'UID' => 'uid2',
183
-						'FN' => 'User2 @ Localhost',
184
-						'EMAIL' => [
185
-						],
186
-					],
187
-					[
188
-						'UID' => 'uid1',
189
-						'FN' => 'User @ Localhost',
190
-						'EMAIL' => [
191
-							'[email protected]',
192
-						],
193
-					],
194
-				],
195
-				true,
196
-				['emails' => [['uuid' => 'uid1', 'name' => 'User @ Localhost', 'type' => '', 'label' => 'User @ Localhost ([email protected])', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => '[email protected]']]], 'exact' => ['emails' => []]],
197
-				false,
198
-				false,
199
-				false,
200
-			],
201
-			// data set 6
202
-			[
203
-				'test',
204
-				[
205
-					[
206
-						'UID' => 'uid3',
207
-						'FN' => 'User3 @ Localhost',
208
-					],
209
-					[
210
-						'UID' => 'uid2',
211
-						'FN' => 'User2 @ Localhost',
212
-						'EMAIL' => [
213
-						],
214
-					],
215
-					[
216
-						'isLocalSystemBook' => true,
217
-						'UID' => 'uid1',
218
-						'FN' => 'User @ Localhost',
219
-						'EMAIL' => [
220
-							'username@localhost',
221
-						],
222
-					],
223
-				],
224
-				false,
225
-				['emails' => [], 'exact' => ['emails' => []]],
226
-				false,
227
-				false,
228
-				false,
229
-			],
230
-			// data set 7
231
-			[
232
-				'[email protected]',
233
-				[
234
-					[
235
-						'UID' => 'uid3',
236
-						'FN' => 'User3 @ example.com',
237
-					],
238
-					[
239
-						'UID' => 'uid2',
240
-						'FN' => 'User2 @ example.com',
241
-						'EMAIL' => [
242
-						],
243
-					],
244
-					[
245
-						'UID' => 'uid1',
246
-						'FN' => 'User @ example.com',
247
-						'EMAIL' => [
248
-							'[email protected]',
249
-						],
250
-					],
251
-				],
252
-				true,
253
-				['emails' => [['uuid' => 'uid1', 'name' => 'User @ example.com', 'type' => '', 'label' => 'User @ example.com ([email protected])', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => '[email protected]']]], 'exact' => ['emails' => [['label' => '[email protected]', 'uuid' => '[email protected]', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => '[email protected]']]]]],
254
-				false,
255
-				false,
256
-				true,
257
-			],
258
-			// data set 8
259
-			[
260
-				'[email protected]',
261
-				[
262
-					[
263
-						'UID' => 'uid3',
264
-						'FN' => 'User3 @ Localhost',
265
-					],
266
-					[
267
-						'UID' => 'uid2',
268
-						'FN' => 'User2 @ Localhost',
269
-						'EMAIL' => [
270
-						],
271
-					],
272
-					[
273
-						'isLocalSystemBook' => true,
274
-						'UID' => 'uid1',
275
-						'FN' => 'User @ Localhost',
276
-						'EMAIL' => [
277
-							'username@localhost',
278
-						],
279
-					],
280
-				],
281
-				false,
282
-				['emails' => [], 'exact' => ['emails' => [['label' => '[email protected]', 'uuid' => '[email protected]', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => '[email protected]']]]]],
283
-				false,
284
-				false,
285
-				true,
286
-			],
287
-			// data set 9
288
-			[
289
-				'[email protected]',
290
-				[
291
-					[
292
-						'UID' => 'uid3',
293
-						'FN' => 'User3 @ example.com',
294
-					],
295
-					[
296
-						'UID' => 'uid2',
297
-						'FN' => 'User2 @ example.com',
298
-						'EMAIL' => [
299
-						],
300
-					],
301
-					[
302
-						'UID' => 'uid1',
303
-						'FN' => 'User @ example.com',
304
-						'EMAIL' => [
305
-							'[email protected]',
306
-						],
307
-					],
308
-				],
309
-				true,
310
-				['emails' => [], 'exact' => ['emails' => [['name' => 'User @ example.com', 'uuid' => 'uid1', 'type' => '', 'label' => 'User @ example.com ([email protected])', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => '[email protected]']]]]],
311
-				true,
312
-				false,
313
-				false,
314
-			],
315
-			// data set 10
316
-			[
317
-				'[email protected]',
318
-				[
319
-					[
320
-						'UID' => 'uid1',
321
-						'FN' => 'User3 @ example.com',
322
-					],
323
-					[
324
-						'UID' => 'uid2',
325
-						'FN' => 'User2 @ example.com',
326
-						'EMAIL' => [
327
-						],
328
-					],
329
-					[
330
-						'UID' => 'uid1',
331
-						'FN' => 'User @ example.com',
332
-						'EMAIL' => [
333
-							'[email protected]',
334
-						],
335
-					],
336
-				],
337
-				false,
338
-				['emails' => [], 'exact' => ['emails' => [['name' => 'User @ example.com', 'uuid' => 'uid1', 'type' => '', 'label' => 'User @ example.com ([email protected])', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => '[email protected]']]]]],
339
-				true,
340
-				false,
341
-				false,
342
-			],
343
-			// data set 11
344
-			// contact with space
345
-			[
346
-				'user name@localhost',
347
-				[
348
-					[
349
-						'UID' => 'uid3',
350
-						'FN' => 'User3 @ Localhost',
351
-					],
352
-					[
353
-						'UID' => 'uid2',
354
-						'FN' => 'User2 @ Localhost',
355
-						'EMAIL' => [
356
-						],
357
-					],
358
-					[
359
-						'UID' => 'uid1',
360
-						'FN' => 'User Name @ Localhost',
361
-						'EMAIL' => [
362
-							'user name@localhost',
363
-						],
364
-					],
365
-				],
366
-				false,
367
-				['emails' => [], 'exact' => ['emails' => []]],
368
-				false,
369
-				false,
370
-				false,
371
-			],
372
-			// data set 12
373
-			// remote with space, no contact
374
-			[
375
-				'user [email protected]',
376
-				[
377
-					[
378
-						'UID' => 'uid3',
379
-						'FN' => 'User3 @ Localhost',
380
-					],
381
-					[
382
-						'UID' => 'uid2',
383
-						'FN' => 'User2 @ Localhost',
384
-						'EMAIL' => [
385
-						],
386
-					],
387
-					[
388
-						'isLocalSystemBook' => true,
389
-						'UID' => 'uid1',
390
-						'FN' => 'User @ Localhost',
391
-						'EMAIL' => [
392
-							'username@localhost',
393
-						],
394
-					],
395
-				],
396
-				false,
397
-				['emails' => [], 'exact' => ['emails' => []]],
398
-				false,
399
-				false,
400
-				false,
401
-			],
402
-			// data set 13
403
-			// Local user found by email
404
-			[
405
-				'[email protected]',
406
-				[
407
-					[
408
-						'UID' => 'uid1',
409
-						'FN' => 'User',
410
-						'EMAIL' => ['[email protected]'],
411
-						'CLOUD' => ['test@localhost'],
412
-						'isLocalSystemBook' => true,
413
-					]
414
-				],
415
-				false,
416
-				['users' => [], 'exact' => ['users' => [['uuid' => 'uid1', 'name' => 'User', 'label' => 'User ([email protected])','value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test'], 'shareWithDisplayNameUnique' => '[email protected]']]]],
417
-				true,
418
-				false,
419
-				true,
420
-			],
421
-			// data set 14
422
-			// Current local user found by email => no result
423
-			[
424
-				'[email protected]',
425
-				[
426
-					[
427
-						'UID' => 'uid1',
428
-						'FN' => 'User',
429
-						'EMAIL' => ['[email protected]'],
430
-						'CLOUD' => ['current@localhost'],
431
-						'isLocalSystemBook' => true,
432
-					]
433
-				],
434
-				true,
435
-				['exact' => []],
436
-				false,
437
-				false,
438
-				true,
439
-			],
440
-			// data set 15
441
-			// Pagination and "more results" for user matches byyyyyyy emails
442
-			[
443
-				'test@example',
444
-				[
445
-					[
446
-						'UID' => 'uid1',
447
-						'FN' => 'User1',
448
-						'EMAIL' => ['[email protected]'],
449
-						'CLOUD' => ['test1@localhost'],
450
-						'isLocalSystemBook' => true,
451
-					],
452
-					[
453
-						'UID' => 'uid2',
454
-						'FN' => 'User2',
455
-						'EMAIL' => ['[email protected]'],
456
-						'CLOUD' => ['test2@localhost'],
457
-						'isLocalSystemBook' => true,
458
-					],
459
-					[
460
-						'UID' => 'uid3',
461
-						'FN' => 'User3',
462
-						'EMAIL' => ['[email protected]'],
463
-						'CLOUD' => ['test3@localhost'],
464
-						'isLocalSystemBook' => true,
465
-					],
466
-					[
467
-						'UID' => 'uid4',
468
-						'FN' => 'User4',
469
-						'EMAIL' => ['[email protected]'],
470
-						'CLOUD' => ['test4@localhost'],
471
-						'isLocalSystemBook' => true,
472
-					],
473
-				],
474
-				true,
475
-				['users' => [
476
-					['uuid' => 'uid1', 'name' => 'User1', 'label' => 'User1 ([email protected])', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1'], 'shareWithDisplayNameUnique' => '[email protected]'],
477
-					['uuid' => 'uid2', 'name' => 'User2', 'label' => 'User2 ([email protected])', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test2'], 'shareWithDisplayNameUnique' => '[email protected]'],
478
-				], 'emails' => [], 'exact' => ['users' => [], 'emails' => []]],
479
-				false,
480
-				true,
481
-				false,
482
-			],
483
-			// data set 16
484
-			// Pagination and "more results" for normal emails
485
-			[
486
-				'test@example',
487
-				[
488
-					[
489
-						'UID' => 'uid1',
490
-						'FN' => 'User1',
491
-						'EMAIL' => ['[email protected]'],
492
-						'CLOUD' => ['test1@localhost'],
493
-					],
494
-					[
495
-						'UID' => 'uid2',
496
-						'FN' => 'User2',
497
-						'EMAIL' => ['[email protected]'],
498
-						'CLOUD' => ['test2@localhost'],
499
-					],
500
-					[
501
-						'UID' => 'uid3',
502
-						'FN' => 'User3',
503
-						'EMAIL' => ['[email protected]'],
504
-						'CLOUD' => ['test3@localhost'],
505
-					],
506
-					[
507
-						'UID' => 'uid4',
508
-						'FN' => 'User4',
509
-						'EMAIL' => ['[email protected]'],
510
-						'CLOUD' => ['test4@localhost'],
511
-					],
512
-				],
513
-				true,
514
-				['emails' => [
515
-					['uuid' => 'uid1', 'name' => 'User1', 'type' => '', 'label' => 'User1 ([email protected])', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => '[email protected]']],
516
-					['uuid' => 'uid2', 'name' => 'User2', 'type' => '', 'label' => 'User2 ([email protected])', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => '[email protected]']],
517
-				], 'exact' => ['emails' => []]],
518
-				false,
519
-				true,
520
-				false,
521
-			],
522
-			// data set 17
523
-			// multiple email addresses with type
524
-			[
525
-				'User Name',
526
-				[
527
-					[
528
-						'UID' => 'uid3',
529
-						'FN' => 'User3',
530
-					],
531
-					[
532
-						'UID' => 'uid2',
533
-						'FN' => 'User2',
534
-						'EMAIL' => [
535
-						],
536
-					],
537
-					[
538
-						'UID' => 'uid1',
539
-						'FN' => 'User Name',
540
-						'EMAIL' => [
541
-							['type' => 'HOME', 'value' => '[email protected]'],
542
-							['type' => 'WORK', 'value' => '[email protected]'],
543
-						],
544
-					],
545
-				],
546
-				false,
547
-				['emails' => [
548
-				], 'exact' => ['emails' => [
549
-					['name' => 'User Name', 'uuid' => 'uid1', 'type' => 'HOME', 'label' => 'User Name ([email protected])', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => '[email protected]']],
550
-					['name' => 'User Name', 'uuid' => 'uid1', 'type' => 'WORK', 'label' => 'User Name ([email protected])', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => '[email protected]']]
551
-				]]],
552
-				false,
553
-				false,
554
-				false,
555
-			],
556
-			// data set 18
557
-			// idn email
558
-			[
559
-				'test@lölölölölölölöl.com',
560
-				[],
561
-				true,
562
-				['emails' => [], 'exact' => ['emails' => [['uuid' => 'test@lölölölölölölöl.com', 'label' => 'test@lölölölölölölöl.com', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'test@lölölölölölölöl.com']]]]],
563
-				false,
564
-				false,
565
-				true,
566
-			],
567
-		];
568
-	}
569
-
570
-	/**
571
-	 * @dataProvider dataGetEmailGroupsOnly
572
-	 *
573
-	 * @param string $searchTerm
574
-	 * @param array $contacts
575
-	 * @param array $expected
576
-	 * @param bool $exactIdMatch
577
-	 * @param bool $reachedEnd
578
-	 * @param array groups
579
-	 */
580
-	public function testSearchGroupsOnly($searchTerm, $contacts, $expected, $exactIdMatch, $reachedEnd, $userToGroupMapping, $validEmail): void {
581
-		$this->config->expects($this->any())
582
-			->method('getAppValue')
583
-			->willReturnCallback(
584
-				function ($appName, $key, $default) {
585
-					if ($appName === 'core' && $key === 'shareapi_allow_share_dialog_user_enumeration') {
586
-						return 'yes';
587
-					} elseif ($appName === 'core' && $key === 'shareapi_only_share_with_group_members') {
588
-						return 'yes';
589
-					}
590
-					return $default;
591
-				}
592
-			);
593
-
594
-		$this->instantiatePlugin();
595
-
596
-		/** @var \OCP\IUser | \PHPUnit\Framework\MockObject\MockObject */
597
-		$currentUser = $this->createMock('\OCP\IUser');
598
-
599
-		$currentUser->expects($this->any())
600
-			->method('getUID')
601
-			->willReturn('currentUser');
602
-
603
-		$this->mailer->method('validateMailAddress')
604
-			->willReturn($validEmail);
605
-
606
-		$this->contactsManager->expects($this->any())
607
-			->method('search')
608
-			->willReturnCallback(function ($search, $searchAttributes) use ($searchTerm, $contacts) {
609
-				if ($search === $searchTerm) {
610
-					return $contacts;
611
-				}
612
-				return [];
613
-			});
614
-
615
-		$this->userSession->expects($this->any())
616
-			->method('getUser')
617
-			->willReturn($currentUser);
618
-
619
-		$this->groupManager->expects($this->any())
620
-			->method('getUserGroupIds')
621
-			->willReturnCallback(function (\OCP\IUser $user) use ($userToGroupMapping) {
622
-				return $userToGroupMapping[$user->getUID()];
623
-			});
624
-
625
-		$this->groupManager->expects($this->any())
626
-			->method('isInGroup')
627
-			->willReturnCallback(function ($userId, $group) use ($userToGroupMapping) {
628
-				return in_array($group, $userToGroupMapping[$userId]);
629
-			});
630
-
631
-		$moreResults = $this->plugin->search($searchTerm, 2, 0, $this->searchResult);
632
-		$result = $this->searchResult->asArray();
633
-
634
-		$this->assertSame($exactIdMatch, $this->searchResult->hasExactIdMatch(new SearchResultType('emails')));
635
-		$this->assertEquals($expected, $result);
636
-		$this->assertSame($reachedEnd, $moreResults);
637
-	}
638
-
639
-	public static function dataGetEmailGroupsOnly(): array {
640
-		return [
641
-			// The user `User` can share with the current user
642
-			[
643
-				'test',
644
-				[
645
-					[
646
-						'FN' => 'User',
647
-						'EMAIL' => ['[email protected]'],
648
-						'CLOUD' => ['test@localhost'],
649
-						'isLocalSystemBook' => true,
650
-						'UID' => 'User'
651
-					]
652
-				],
653
-				['users' => [['label' => 'User ([email protected])', 'uuid' => 'User', 'name' => 'User', 'value' => ['shareType' => 0, 'shareWith' => 'test'],'shareWithDisplayNameUnique' => '[email protected]',]], 'emails' => [], 'exact' => ['emails' => [], 'users' => []]],
654
-				false,
655
-				false,
656
-				[
657
-					'currentUser' => ['group1'],
658
-					'User' => ['group1']
659
-				],
660
-				false,
661
-			],
662
-			// The user `User` cannot share with the current user
663
-			[
664
-				'test',
665
-				[
666
-					[
667
-						'FN' => 'User',
668
-						'EMAIL' => ['[email protected]'],
669
-						'CLOUD' => ['test@localhost'],
670
-						'isLocalSystemBook' => true,
671
-						'UID' => 'User'
672
-					]
673
-				],
674
-				['emails' => [], 'exact' => ['emails' => []]],
675
-				false,
676
-				false,
677
-				[
678
-					'currentUser' => ['group1'],
679
-					'User' => ['group2']
680
-				],
681
-				false,
682
-			],
683
-			// The user `User` cannot share with the current user, but there is an exact match on the e-mail address -> share by e-mail
684
-			[
685
-				'[email protected]',
686
-				[
687
-					[
688
-						'FN' => 'User',
689
-						'EMAIL' => ['[email protected]'],
690
-						'CLOUD' => ['test@localhost'],
691
-						'isLocalSystemBook' => true,
692
-						'UID' => 'User'
693
-					]
694
-				],
695
-				['emails' => [], 'exact' => ['emails' => [['label' => '[email protected]', 'uuid' => '[email protected]', 'value' => ['shareType' => 4,'shareWith' => '[email protected]']]]]],
696
-				false,
697
-				false,
698
-				[
699
-					'currentUser' => ['group1'],
700
-					'User' => ['group2']
701
-				],
702
-				true,
703
-			]
704
-		];
705
-	}
29
+    /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
30
+    protected $config;
31
+
32
+    /** @var IManager|\PHPUnit\Framework\MockObject\MockObject */
33
+    protected $contactsManager;
34
+
35
+    /** @var ICloudIdManager|\PHPUnit\Framework\MockObject\MockObject */
36
+    protected $cloudIdManager;
37
+
38
+    /** @var MailPlugin */
39
+    protected $plugin;
40
+
41
+    /** @var SearchResult */
42
+    protected $searchResult;
43
+
44
+    /** @var IGroupManager|\PHPUnit\Framework\MockObject\MockObject */
45
+    protected $groupManager;
46
+
47
+    /** @var KnownUserService|\PHPUnit\Framework\MockObject\MockObject */
48
+    protected $knownUserService;
49
+
50
+    /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */
51
+    protected $userSession;
52
+
53
+    /** @var IMailer|\PHPUnit\Framework\MockObject\MockObject */
54
+    protected $mailer;
55
+
56
+    protected function setUp(): void {
57
+        parent::setUp();
58
+
59
+        $this->config = $this->createMock(IConfig::class);
60
+        $this->contactsManager = $this->createMock(IManager::class);
61
+        $this->groupManager = $this->createMock(IGroupManager::class);
62
+        $this->knownUserService = $this->createMock(KnownUserService::class);
63
+        $this->userSession = $this->createMock(IUserSession::class);
64
+        $this->mailer = $this->createMock(IMailer::class);
65
+        $this->cloudIdManager = new CloudIdManager(
66
+            $this->contactsManager,
67
+            $this->createMock(IURLGenerator::class),
68
+            $this->createMock(IUserManager::class),
69
+            $this->createMock(ICacheFactory::class),
70
+            $this->createMock(IEventDispatcher::class)
71
+        );
72
+
73
+        $this->searchResult = new SearchResult();
74
+    }
75
+
76
+    public function instantiatePlugin() {
77
+        $this->plugin = new MailPlugin(
78
+            $this->contactsManager,
79
+            $this->cloudIdManager,
80
+            $this->config,
81
+            $this->groupManager,
82
+            $this->knownUserService,
83
+            $this->userSession,
84
+            $this->mailer
85
+        );
86
+    }
87
+
88
+    /**
89
+     * @dataProvider dataGetEmail
90
+     *
91
+     * @param string $searchTerm
92
+     * @param array $contacts
93
+     * @param bool $shareeEnumeration
94
+     * @param array $expected
95
+     * @param bool $reachedEnd
96
+     */
97
+    public function testSearch($searchTerm, $contacts, $shareeEnumeration, $expected, $exactIdMatch, $reachedEnd, $validEmail): void {
98
+        $this->config->expects($this->any())
99
+            ->method('getAppValue')
100
+            ->willReturnCallback(
101
+                function ($appName, $key, $default) use ($shareeEnumeration) {
102
+                    if ($appName === 'core' && $key === 'shareapi_allow_share_dialog_user_enumeration') {
103
+                        return $shareeEnumeration ? 'yes' : 'no';
104
+                    }
105
+                    return $default;
106
+                }
107
+            );
108
+
109
+        $this->instantiatePlugin();
110
+
111
+        $currentUser = $this->createMock(IUser::class);
112
+        $currentUser->method('getUID')
113
+            ->willReturn('current');
114
+        $this->userSession->method('getUser')
115
+            ->willReturn($currentUser);
116
+
117
+        $this->mailer->method('validateMailAddress')
118
+            ->willReturn($validEmail);
119
+
120
+        $this->contactsManager->expects($this->any())
121
+            ->method('search')
122
+            ->willReturnCallback(function ($search, $searchAttributes) use ($searchTerm, $contacts) {
123
+                if ($search === $searchTerm) {
124
+                    return $contacts;
125
+                }
126
+                return [];
127
+            });
128
+
129
+        $moreResults = $this->plugin->search($searchTerm, 2, 0, $this->searchResult);
130
+        $result = $this->searchResult->asArray();
131
+
132
+        $this->assertSame($exactIdMatch, $this->searchResult->hasExactIdMatch(new SearchResultType('emails')));
133
+        $this->assertEquals($expected, $result);
134
+        $this->assertSame($reachedEnd, $moreResults);
135
+    }
136
+
137
+    public static function dataGetEmail(): array {
138
+        return [
139
+            // data set 0
140
+            ['test', [], true, ['emails' => [], 'exact' => ['emails' => []]], false, false, false],
141
+            // data set 1
142
+            ['test', [], false, ['emails' => [], 'exact' => ['emails' => []]], false, false, false],
143
+            // data set 2
144
+            [
145
+                '[email protected]',
146
+                [],
147
+                true,
148
+                ['emails' => [], 'exact' => ['emails' => [['uuid' => '[email protected]', 'label' => '[email protected]', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => '[email protected]']]]]],
149
+                false,
150
+                false,
151
+                true,
152
+            ],
153
+            // data set 3
154
+            [ // no valid email address
155
+                'test@remote',
156
+                [],
157
+                true,
158
+                ['emails' => [], 'exact' => ['emails' => []]],
159
+                false,
160
+                false,
161
+                false,
162
+            ],
163
+            // data set 4
164
+            [
165
+                '[email protected]',
166
+                [],
167
+                false,
168
+                ['emails' => [], 'exact' => ['emails' => [['uuid' => '[email protected]', 'label' => '[email protected]', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => '[email protected]']]]]],
169
+                false,
170
+                false,
171
+                true,
172
+            ],
173
+            // data set 5
174
+            [
175
+                'test',
176
+                [
177
+                    [
178
+                        'UID' => 'uid3',
179
+                        'FN' => 'User3 @ Localhost',
180
+                    ],
181
+                    [
182
+                        'UID' => 'uid2',
183
+                        'FN' => 'User2 @ Localhost',
184
+                        'EMAIL' => [
185
+                        ],
186
+                    ],
187
+                    [
188
+                        'UID' => 'uid1',
189
+                        'FN' => 'User @ Localhost',
190
+                        'EMAIL' => [
191
+                            '[email protected]',
192
+                        ],
193
+                    ],
194
+                ],
195
+                true,
196
+                ['emails' => [['uuid' => 'uid1', 'name' => 'User @ Localhost', 'type' => '', 'label' => 'User @ Localhost ([email protected])', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => '[email protected]']]], 'exact' => ['emails' => []]],
197
+                false,
198
+                false,
199
+                false,
200
+            ],
201
+            // data set 6
202
+            [
203
+                'test',
204
+                [
205
+                    [
206
+                        'UID' => 'uid3',
207
+                        'FN' => 'User3 @ Localhost',
208
+                    ],
209
+                    [
210
+                        'UID' => 'uid2',
211
+                        'FN' => 'User2 @ Localhost',
212
+                        'EMAIL' => [
213
+                        ],
214
+                    ],
215
+                    [
216
+                        'isLocalSystemBook' => true,
217
+                        'UID' => 'uid1',
218
+                        'FN' => 'User @ Localhost',
219
+                        'EMAIL' => [
220
+                            'username@localhost',
221
+                        ],
222
+                    ],
223
+                ],
224
+                false,
225
+                ['emails' => [], 'exact' => ['emails' => []]],
226
+                false,
227
+                false,
228
+                false,
229
+            ],
230
+            // data set 7
231
+            [
232
+                '[email protected]',
233
+                [
234
+                    [
235
+                        'UID' => 'uid3',
236
+                        'FN' => 'User3 @ example.com',
237
+                    ],
238
+                    [
239
+                        'UID' => 'uid2',
240
+                        'FN' => 'User2 @ example.com',
241
+                        'EMAIL' => [
242
+                        ],
243
+                    ],
244
+                    [
245
+                        'UID' => 'uid1',
246
+                        'FN' => 'User @ example.com',
247
+                        'EMAIL' => [
248
+                            '[email protected]',
249
+                        ],
250
+                    ],
251
+                ],
252
+                true,
253
+                ['emails' => [['uuid' => 'uid1', 'name' => 'User @ example.com', 'type' => '', 'label' => 'User @ example.com ([email protected])', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => '[email protected]']]], 'exact' => ['emails' => [['label' => '[email protected]', 'uuid' => '[email protected]', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => '[email protected]']]]]],
254
+                false,
255
+                false,
256
+                true,
257
+            ],
258
+            // data set 8
259
+            [
260
+                '[email protected]',
261
+                [
262
+                    [
263
+                        'UID' => 'uid3',
264
+                        'FN' => 'User3 @ Localhost',
265
+                    ],
266
+                    [
267
+                        'UID' => 'uid2',
268
+                        'FN' => 'User2 @ Localhost',
269
+                        'EMAIL' => [
270
+                        ],
271
+                    ],
272
+                    [
273
+                        'isLocalSystemBook' => true,
274
+                        'UID' => 'uid1',
275
+                        'FN' => 'User @ Localhost',
276
+                        'EMAIL' => [
277
+                            'username@localhost',
278
+                        ],
279
+                    ],
280
+                ],
281
+                false,
282
+                ['emails' => [], 'exact' => ['emails' => [['label' => '[email protected]', 'uuid' => '[email protected]', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => '[email protected]']]]]],
283
+                false,
284
+                false,
285
+                true,
286
+            ],
287
+            // data set 9
288
+            [
289
+                '[email protected]',
290
+                [
291
+                    [
292
+                        'UID' => 'uid3',
293
+                        'FN' => 'User3 @ example.com',
294
+                    ],
295
+                    [
296
+                        'UID' => 'uid2',
297
+                        'FN' => 'User2 @ example.com',
298
+                        'EMAIL' => [
299
+                        ],
300
+                    ],
301
+                    [
302
+                        'UID' => 'uid1',
303
+                        'FN' => 'User @ example.com',
304
+                        'EMAIL' => [
305
+                            '[email protected]',
306
+                        ],
307
+                    ],
308
+                ],
309
+                true,
310
+                ['emails' => [], 'exact' => ['emails' => [['name' => 'User @ example.com', 'uuid' => 'uid1', 'type' => '', 'label' => 'User @ example.com ([email protected])', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => '[email protected]']]]]],
311
+                true,
312
+                false,
313
+                false,
314
+            ],
315
+            // data set 10
316
+            [
317
+                '[email protected]',
318
+                [
319
+                    [
320
+                        'UID' => 'uid1',
321
+                        'FN' => 'User3 @ example.com',
322
+                    ],
323
+                    [
324
+                        'UID' => 'uid2',
325
+                        'FN' => 'User2 @ example.com',
326
+                        'EMAIL' => [
327
+                        ],
328
+                    ],
329
+                    [
330
+                        'UID' => 'uid1',
331
+                        'FN' => 'User @ example.com',
332
+                        'EMAIL' => [
333
+                            '[email protected]',
334
+                        ],
335
+                    ],
336
+                ],
337
+                false,
338
+                ['emails' => [], 'exact' => ['emails' => [['name' => 'User @ example.com', 'uuid' => 'uid1', 'type' => '', 'label' => 'User @ example.com ([email protected])', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => '[email protected]']]]]],
339
+                true,
340
+                false,
341
+                false,
342
+            ],
343
+            // data set 11
344
+            // contact with space
345
+            [
346
+                'user name@localhost',
347
+                [
348
+                    [
349
+                        'UID' => 'uid3',
350
+                        'FN' => 'User3 @ Localhost',
351
+                    ],
352
+                    [
353
+                        'UID' => 'uid2',
354
+                        'FN' => 'User2 @ Localhost',
355
+                        'EMAIL' => [
356
+                        ],
357
+                    ],
358
+                    [
359
+                        'UID' => 'uid1',
360
+                        'FN' => 'User Name @ Localhost',
361
+                        'EMAIL' => [
362
+                            'user name@localhost',
363
+                        ],
364
+                    ],
365
+                ],
366
+                false,
367
+                ['emails' => [], 'exact' => ['emails' => []]],
368
+                false,
369
+                false,
370
+                false,
371
+            ],
372
+            // data set 12
373
+            // remote with space, no contact
374
+            [
375
+                'user [email protected]',
376
+                [
377
+                    [
378
+                        'UID' => 'uid3',
379
+                        'FN' => 'User3 @ Localhost',
380
+                    ],
381
+                    [
382
+                        'UID' => 'uid2',
383
+                        'FN' => 'User2 @ Localhost',
384
+                        'EMAIL' => [
385
+                        ],
386
+                    ],
387
+                    [
388
+                        'isLocalSystemBook' => true,
389
+                        'UID' => 'uid1',
390
+                        'FN' => 'User @ Localhost',
391
+                        'EMAIL' => [
392
+                            'username@localhost',
393
+                        ],
394
+                    ],
395
+                ],
396
+                false,
397
+                ['emails' => [], 'exact' => ['emails' => []]],
398
+                false,
399
+                false,
400
+                false,
401
+            ],
402
+            // data set 13
403
+            // Local user found by email
404
+            [
405
+                '[email protected]',
406
+                [
407
+                    [
408
+                        'UID' => 'uid1',
409
+                        'FN' => 'User',
410
+                        'EMAIL' => ['[email protected]'],
411
+                        'CLOUD' => ['test@localhost'],
412
+                        'isLocalSystemBook' => true,
413
+                    ]
414
+                ],
415
+                false,
416
+                ['users' => [], 'exact' => ['users' => [['uuid' => 'uid1', 'name' => 'User', 'label' => 'User ([email protected])','value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test'], 'shareWithDisplayNameUnique' => '[email protected]']]]],
417
+                true,
418
+                false,
419
+                true,
420
+            ],
421
+            // data set 14
422
+            // Current local user found by email => no result
423
+            [
424
+                '[email protected]',
425
+                [
426
+                    [
427
+                        'UID' => 'uid1',
428
+                        'FN' => 'User',
429
+                        'EMAIL' => ['[email protected]'],
430
+                        'CLOUD' => ['current@localhost'],
431
+                        'isLocalSystemBook' => true,
432
+                    ]
433
+                ],
434
+                true,
435
+                ['exact' => []],
436
+                false,
437
+                false,
438
+                true,
439
+            ],
440
+            // data set 15
441
+            // Pagination and "more results" for user matches byyyyyyy emails
442
+            [
443
+                'test@example',
444
+                [
445
+                    [
446
+                        'UID' => 'uid1',
447
+                        'FN' => 'User1',
448
+                        'EMAIL' => ['[email protected]'],
449
+                        'CLOUD' => ['test1@localhost'],
450
+                        'isLocalSystemBook' => true,
451
+                    ],
452
+                    [
453
+                        'UID' => 'uid2',
454
+                        'FN' => 'User2',
455
+                        'EMAIL' => ['[email protected]'],
456
+                        'CLOUD' => ['test2@localhost'],
457
+                        'isLocalSystemBook' => true,
458
+                    ],
459
+                    [
460
+                        'UID' => 'uid3',
461
+                        'FN' => 'User3',
462
+                        'EMAIL' => ['[email protected]'],
463
+                        'CLOUD' => ['test3@localhost'],
464
+                        'isLocalSystemBook' => true,
465
+                    ],
466
+                    [
467
+                        'UID' => 'uid4',
468
+                        'FN' => 'User4',
469
+                        'EMAIL' => ['[email protected]'],
470
+                        'CLOUD' => ['test4@localhost'],
471
+                        'isLocalSystemBook' => true,
472
+                    ],
473
+                ],
474
+                true,
475
+                ['users' => [
476
+                    ['uuid' => 'uid1', 'name' => 'User1', 'label' => 'User1 ([email protected])', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test1'], 'shareWithDisplayNameUnique' => '[email protected]'],
477
+                    ['uuid' => 'uid2', 'name' => 'User2', 'label' => 'User2 ([email protected])', 'value' => ['shareType' => IShare::TYPE_USER, 'shareWith' => 'test2'], 'shareWithDisplayNameUnique' => '[email protected]'],
478
+                ], 'emails' => [], 'exact' => ['users' => [], 'emails' => []]],
479
+                false,
480
+                true,
481
+                false,
482
+            ],
483
+            // data set 16
484
+            // Pagination and "more results" for normal emails
485
+            [
486
+                'test@example',
487
+                [
488
+                    [
489
+                        'UID' => 'uid1',
490
+                        'FN' => 'User1',
491
+                        'EMAIL' => ['[email protected]'],
492
+                        'CLOUD' => ['test1@localhost'],
493
+                    ],
494
+                    [
495
+                        'UID' => 'uid2',
496
+                        'FN' => 'User2',
497
+                        'EMAIL' => ['[email protected]'],
498
+                        'CLOUD' => ['test2@localhost'],
499
+                    ],
500
+                    [
501
+                        'UID' => 'uid3',
502
+                        'FN' => 'User3',
503
+                        'EMAIL' => ['[email protected]'],
504
+                        'CLOUD' => ['test3@localhost'],
505
+                    ],
506
+                    [
507
+                        'UID' => 'uid4',
508
+                        'FN' => 'User4',
509
+                        'EMAIL' => ['[email protected]'],
510
+                        'CLOUD' => ['test4@localhost'],
511
+                    ],
512
+                ],
513
+                true,
514
+                ['emails' => [
515
+                    ['uuid' => 'uid1', 'name' => 'User1', 'type' => '', 'label' => 'User1 ([email protected])', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => '[email protected]']],
516
+                    ['uuid' => 'uid2', 'name' => 'User2', 'type' => '', 'label' => 'User2 ([email protected])', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => '[email protected]']],
517
+                ], 'exact' => ['emails' => []]],
518
+                false,
519
+                true,
520
+                false,
521
+            ],
522
+            // data set 17
523
+            // multiple email addresses with type
524
+            [
525
+                'User Name',
526
+                [
527
+                    [
528
+                        'UID' => 'uid3',
529
+                        'FN' => 'User3',
530
+                    ],
531
+                    [
532
+                        'UID' => 'uid2',
533
+                        'FN' => 'User2',
534
+                        'EMAIL' => [
535
+                        ],
536
+                    ],
537
+                    [
538
+                        'UID' => 'uid1',
539
+                        'FN' => 'User Name',
540
+                        'EMAIL' => [
541
+                            ['type' => 'HOME', 'value' => '[email protected]'],
542
+                            ['type' => 'WORK', 'value' => '[email protected]'],
543
+                        ],
544
+                    ],
545
+                ],
546
+                false,
547
+                ['emails' => [
548
+                ], 'exact' => ['emails' => [
549
+                    ['name' => 'User Name', 'uuid' => 'uid1', 'type' => 'HOME', 'label' => 'User Name ([email protected])', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => '[email protected]']],
550
+                    ['name' => 'User Name', 'uuid' => 'uid1', 'type' => 'WORK', 'label' => 'User Name ([email protected])', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => '[email protected]']]
551
+                ]]],
552
+                false,
553
+                false,
554
+                false,
555
+            ],
556
+            // data set 18
557
+            // idn email
558
+            [
559
+                'test@lölölölölölölöl.com',
560
+                [],
561
+                true,
562
+                ['emails' => [], 'exact' => ['emails' => [['uuid' => 'test@lölölölölölölöl.com', 'label' => 'test@lölölölölölölöl.com', 'value' => ['shareType' => IShare::TYPE_EMAIL, 'shareWith' => 'test@lölölölölölölöl.com']]]]],
563
+                false,
564
+                false,
565
+                true,
566
+            ],
567
+        ];
568
+    }
569
+
570
+    /**
571
+     * @dataProvider dataGetEmailGroupsOnly
572
+     *
573
+     * @param string $searchTerm
574
+     * @param array $contacts
575
+     * @param array $expected
576
+     * @param bool $exactIdMatch
577
+     * @param bool $reachedEnd
578
+     * @param array groups
579
+     */
580
+    public function testSearchGroupsOnly($searchTerm, $contacts, $expected, $exactIdMatch, $reachedEnd, $userToGroupMapping, $validEmail): void {
581
+        $this->config->expects($this->any())
582
+            ->method('getAppValue')
583
+            ->willReturnCallback(
584
+                function ($appName, $key, $default) {
585
+                    if ($appName === 'core' && $key === 'shareapi_allow_share_dialog_user_enumeration') {
586
+                        return 'yes';
587
+                    } elseif ($appName === 'core' && $key === 'shareapi_only_share_with_group_members') {
588
+                        return 'yes';
589
+                    }
590
+                    return $default;
591
+                }
592
+            );
593
+
594
+        $this->instantiatePlugin();
595
+
596
+        /** @var \OCP\IUser | \PHPUnit\Framework\MockObject\MockObject */
597
+        $currentUser = $this->createMock('\OCP\IUser');
598
+
599
+        $currentUser->expects($this->any())
600
+            ->method('getUID')
601
+            ->willReturn('currentUser');
602
+
603
+        $this->mailer->method('validateMailAddress')
604
+            ->willReturn($validEmail);
605
+
606
+        $this->contactsManager->expects($this->any())
607
+            ->method('search')
608
+            ->willReturnCallback(function ($search, $searchAttributes) use ($searchTerm, $contacts) {
609
+                if ($search === $searchTerm) {
610
+                    return $contacts;
611
+                }
612
+                return [];
613
+            });
614
+
615
+        $this->userSession->expects($this->any())
616
+            ->method('getUser')
617
+            ->willReturn($currentUser);
618
+
619
+        $this->groupManager->expects($this->any())
620
+            ->method('getUserGroupIds')
621
+            ->willReturnCallback(function (\OCP\IUser $user) use ($userToGroupMapping) {
622
+                return $userToGroupMapping[$user->getUID()];
623
+            });
624
+
625
+        $this->groupManager->expects($this->any())
626
+            ->method('isInGroup')
627
+            ->willReturnCallback(function ($userId, $group) use ($userToGroupMapping) {
628
+                return in_array($group, $userToGroupMapping[$userId]);
629
+            });
630
+
631
+        $moreResults = $this->plugin->search($searchTerm, 2, 0, $this->searchResult);
632
+        $result = $this->searchResult->asArray();
633
+
634
+        $this->assertSame($exactIdMatch, $this->searchResult->hasExactIdMatch(new SearchResultType('emails')));
635
+        $this->assertEquals($expected, $result);
636
+        $this->assertSame($reachedEnd, $moreResults);
637
+    }
638
+
639
+    public static function dataGetEmailGroupsOnly(): array {
640
+        return [
641
+            // The user `User` can share with the current user
642
+            [
643
+                'test',
644
+                [
645
+                    [
646
+                        'FN' => 'User',
647
+                        'EMAIL' => ['[email protected]'],
648
+                        'CLOUD' => ['test@localhost'],
649
+                        'isLocalSystemBook' => true,
650
+                        'UID' => 'User'
651
+                    ]
652
+                ],
653
+                ['users' => [['label' => 'User ([email protected])', 'uuid' => 'User', 'name' => 'User', 'value' => ['shareType' => 0, 'shareWith' => 'test'],'shareWithDisplayNameUnique' => '[email protected]',]], 'emails' => [], 'exact' => ['emails' => [], 'users' => []]],
654
+                false,
655
+                false,
656
+                [
657
+                    'currentUser' => ['group1'],
658
+                    'User' => ['group1']
659
+                ],
660
+                false,
661
+            ],
662
+            // The user `User` cannot share with the current user
663
+            [
664
+                'test',
665
+                [
666
+                    [
667
+                        'FN' => 'User',
668
+                        'EMAIL' => ['[email protected]'],
669
+                        'CLOUD' => ['test@localhost'],
670
+                        'isLocalSystemBook' => true,
671
+                        'UID' => 'User'
672
+                    ]
673
+                ],
674
+                ['emails' => [], 'exact' => ['emails' => []]],
675
+                false,
676
+                false,
677
+                [
678
+                    'currentUser' => ['group1'],
679
+                    'User' => ['group2']
680
+                ],
681
+                false,
682
+            ],
683
+            // The user `User` cannot share with the current user, but there is an exact match on the e-mail address -> share by e-mail
684
+            [
685
+                '[email protected]',
686
+                [
687
+                    [
688
+                        'FN' => 'User',
689
+                        'EMAIL' => ['[email protected]'],
690
+                        'CLOUD' => ['test@localhost'],
691
+                        'isLocalSystemBook' => true,
692
+                        'UID' => 'User'
693
+                    ]
694
+                ],
695
+                ['emails' => [], 'exact' => ['emails' => [['label' => '[email protected]', 'uuid' => '[email protected]', 'value' => ['shareType' => 4,'shareWith' => '[email protected]']]]]],
696
+                false,
697
+                false,
698
+                [
699
+                    'currentUser' => ['group1'],
700
+                    'User' => ['group2']
701
+                ],
702
+                true,
703
+            ]
704
+        ];
705
+    }
706 706
 }
Please login to merge, or discard this patch.
tests/lib/Collaboration/Collaborators/RemotePluginTest.php 1 patch
Indentation   +378 added lines, -378 removed lines patch added patch discarded remove patch
@@ -23,408 +23,408 @@
 block discarded – undo
23 23
 use Test\TestCase;
24 24
 
25 25
 class RemotePluginTest extends TestCase {
26
-	/** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */
27
-	protected $userManager;
26
+    /** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */
27
+    protected $userManager;
28 28
 
29
-	/** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
30
-	protected $config;
29
+    /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
30
+    protected $config;
31 31
 
32
-	/** @var IManager|\PHPUnit\Framework\MockObject\MockObject */
33
-	protected $contactsManager;
32
+    /** @var IManager|\PHPUnit\Framework\MockObject\MockObject */
33
+    protected $contactsManager;
34 34
 
35
-	/** @var ICloudIdManager|\PHPUnit\Framework\MockObject\MockObject */
36
-	protected $cloudIdManager;
35
+    /** @var ICloudIdManager|\PHPUnit\Framework\MockObject\MockObject */
36
+    protected $cloudIdManager;
37 37
 
38
-	/** @var RemotePlugin */
39
-	protected $plugin;
38
+    /** @var RemotePlugin */
39
+    protected $plugin;
40 40
 
41
-	/** @var SearchResult */
42
-	protected $searchResult;
41
+    /** @var SearchResult */
42
+    protected $searchResult;
43 43
 
44
-	protected function setUp(): void {
45
-		parent::setUp();
44
+    protected function setUp(): void {
45
+        parent::setUp();
46 46
 
47
-		$this->userManager = $this->createMock(IUserManager::class);
48
-		$this->config = $this->createMock(IConfig::class);
49
-		$this->contactsManager = $this->createMock(IManager::class);
50
-		$this->cloudIdManager = new CloudIdManager(
51
-			$this->contactsManager,
52
-			$this->createMock(IURLGenerator::class),
53
-			$this->createMock(IUserManager::class),
54
-			$this->createMock(ICacheFactory::class),
55
-			$this->createMock(IEventDispatcher::class)
56
-		);
57
-		$this->searchResult = new SearchResult();
58
-	}
47
+        $this->userManager = $this->createMock(IUserManager::class);
48
+        $this->config = $this->createMock(IConfig::class);
49
+        $this->contactsManager = $this->createMock(IManager::class);
50
+        $this->cloudIdManager = new CloudIdManager(
51
+            $this->contactsManager,
52
+            $this->createMock(IURLGenerator::class),
53
+            $this->createMock(IUserManager::class),
54
+            $this->createMock(ICacheFactory::class),
55
+            $this->createMock(IEventDispatcher::class)
56
+        );
57
+        $this->searchResult = new SearchResult();
58
+    }
59 59
 
60
-	public function instantiatePlugin() {
61
-		$user = $this->createMock(IUser::class);
62
-		$user->expects($this->any())
63
-			->method('getUID')
64
-			->willReturn('admin');
65
-		$userSession = $this->createMock(IUserSession::class);
66
-		$userSession->expects($this->any())
67
-			->method('getUser')
68
-			->willReturn($user);
69
-		$this->plugin = new RemotePlugin($this->contactsManager, $this->cloudIdManager, $this->config, $this->userManager, $userSession);
70
-	}
60
+    public function instantiatePlugin() {
61
+        $user = $this->createMock(IUser::class);
62
+        $user->expects($this->any())
63
+            ->method('getUID')
64
+            ->willReturn('admin');
65
+        $userSession = $this->createMock(IUserSession::class);
66
+        $userSession->expects($this->any())
67
+            ->method('getUser')
68
+            ->willReturn($user);
69
+        $this->plugin = new RemotePlugin($this->contactsManager, $this->cloudIdManager, $this->config, $this->userManager, $userSession);
70
+    }
71 71
 
72
-	/**
73
-	 * @dataProvider dataGetRemote
74
-	 *
75
-	 * @param string $searchTerm
76
-	 * @param array $contacts
77
-	 * @param bool $shareeEnumeration
78
-	 * @param array $expected
79
-	 * @param bool $exactIdMatch
80
-	 * @param bool $reachedEnd
81
-	 */
82
-	public function testSearch($searchTerm, array $contacts, $shareeEnumeration, array $expected, $exactIdMatch, $reachedEnd): void {
83
-		$this->config->expects($this->any())
84
-			->method('getAppValue')
85
-			->willReturnCallback(
86
-				function ($appName, $key, $default) use ($shareeEnumeration) {
87
-					if ($appName === 'core' && $key === 'shareapi_allow_share_dialog_user_enumeration') {
88
-						return $shareeEnumeration ? 'yes' : 'no';
89
-					}
90
-					return $default;
91
-				}
92
-			);
72
+    /**
73
+     * @dataProvider dataGetRemote
74
+     *
75
+     * @param string $searchTerm
76
+     * @param array $contacts
77
+     * @param bool $shareeEnumeration
78
+     * @param array $expected
79
+     * @param bool $exactIdMatch
80
+     * @param bool $reachedEnd
81
+     */
82
+    public function testSearch($searchTerm, array $contacts, $shareeEnumeration, array $expected, $exactIdMatch, $reachedEnd): void {
83
+        $this->config->expects($this->any())
84
+            ->method('getAppValue')
85
+            ->willReturnCallback(
86
+                function ($appName, $key, $default) use ($shareeEnumeration) {
87
+                    if ($appName === 'core' && $key === 'shareapi_allow_share_dialog_user_enumeration') {
88
+                        return $shareeEnumeration ? 'yes' : 'no';
89
+                    }
90
+                    return $default;
91
+                }
92
+            );
93 93
 
94
-		$this->instantiatePlugin();
94
+        $this->instantiatePlugin();
95 95
 
96
-		$this->contactsManager->expects($this->any())
97
-			->method('search')
98
-			->willReturnCallback(function ($search, $searchAttributes) use ($searchTerm, $contacts) {
99
-				if ($search === $searchTerm) {
100
-					return $contacts;
101
-				}
102
-				return [];
103
-			});
96
+        $this->contactsManager->expects($this->any())
97
+            ->method('search')
98
+            ->willReturnCallback(function ($search, $searchAttributes) use ($searchTerm, $contacts) {
99
+                if ($search === $searchTerm) {
100
+                    return $contacts;
101
+                }
102
+                return [];
103
+            });
104 104
 
105
-		$moreResults = $this->plugin->search($searchTerm, 2, 0, $this->searchResult);
106
-		$result = $this->searchResult->asArray();
105
+        $moreResults = $this->plugin->search($searchTerm, 2, 0, $this->searchResult);
106
+        $result = $this->searchResult->asArray();
107 107
 
108
-		$this->assertSame($exactIdMatch, $this->searchResult->hasExactIdMatch(new SearchResultType('remotes')));
109
-		$this->assertEquals($expected, $result);
110
-		$this->assertSame($reachedEnd, $moreResults);
111
-	}
108
+        $this->assertSame($exactIdMatch, $this->searchResult->hasExactIdMatch(new SearchResultType('remotes')));
109
+        $this->assertEquals($expected, $result);
110
+        $this->assertSame($reachedEnd, $moreResults);
111
+    }
112 112
 
113
-	/**
114
-	 * @dataProvider dataTestSplitUserRemote
115
-	 *
116
-	 * @param string $remote
117
-	 * @param string $expectedUser
118
-	 * @param string $expectedUrl
119
-	 */
120
-	public function testSplitUserRemote($remote, $expectedUser, $expectedUrl): void {
121
-		$this->instantiatePlugin();
113
+    /**
114
+     * @dataProvider dataTestSplitUserRemote
115
+     *
116
+     * @param string $remote
117
+     * @param string $expectedUser
118
+     * @param string $expectedUrl
119
+     */
120
+    public function testSplitUserRemote($remote, $expectedUser, $expectedUrl): void {
121
+        $this->instantiatePlugin();
122 122
 
123
-		$this->contactsManager->expects($this->any())
124
-			->method('search')
125
-			->willReturn([]);
123
+        $this->contactsManager->expects($this->any())
124
+            ->method('search')
125
+            ->willReturn([]);
126 126
 
127
-		[$remoteUser, $remoteUrl] = $this->plugin->splitUserRemote($remote);
128
-		$this->assertSame($expectedUser, $remoteUser);
129
-		$this->assertSame($expectedUrl, $remoteUrl);
130
-	}
127
+        [$remoteUser, $remoteUrl] = $this->plugin->splitUserRemote($remote);
128
+        $this->assertSame($expectedUser, $remoteUser);
129
+        $this->assertSame($expectedUrl, $remoteUrl);
130
+    }
131 131
 
132
-	/**
133
-	 * @dataProvider dataTestSplitUserRemoteError
134
-	 *
135
-	 * @param string $id
136
-	 */
137
-	public function testSplitUserRemoteError($id): void {
138
-		$this->expectException(\Exception::class);
132
+    /**
133
+     * @dataProvider dataTestSplitUserRemoteError
134
+     *
135
+     * @param string $id
136
+     */
137
+    public function testSplitUserRemoteError($id): void {
138
+        $this->expectException(\Exception::class);
139 139
 
140
-		$this->instantiatePlugin();
141
-		$this->plugin->splitUserRemote($id);
142
-	}
140
+        $this->instantiatePlugin();
141
+        $this->plugin->splitUserRemote($id);
142
+    }
143 143
 
144
-	public static function dataGetRemote() {
145
-		return [
146
-			['test', [], true, ['remotes' => [], 'exact' => ['remotes' => []]], false, true],
147
-			['test', [], false, ['remotes' => [], 'exact' => ['remotes' => []]], false, true],
148
-			[
149
-				'test@remote',
150
-				[],
151
-				true,
152
-				['remotes' => [], 'exact' => ['remotes' => [['label' => 'test (remote)', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'test@remote', 'server' => 'remote'], 'uuid' => 'test', 'name' => 'test']]]],
153
-				false,
154
-				true,
155
-			],
156
-			[
157
-				'test@remote',
158
-				[],
159
-				false,
160
-				['remotes' => [], 'exact' => ['remotes' => [['label' => 'test (remote)', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'test@remote', 'server' => 'remote'], 'uuid' => 'test', 'name' => 'test']]]],
161
-				false,
162
-				true,
163
-			],
164
-			[
165
-				'test',
166
-				[
167
-					[
168
-						'UID' => 'uid',
169
-						'FN' => 'User3 @ Localhost',
170
-					],
171
-					[
172
-						'UID' => 'uid',
173
-						'FN' => 'User2 @ Localhost',
174
-						'CLOUD' => [
175
-						],
176
-					],
177
-					[
178
-						'UID' => 'uid1',
179
-						'FN' => 'User @ Localhost',
180
-						'CLOUD' => [
181
-							'username@localhost',
182
-						],
183
-					],
184
-				],
185
-				true,
186
-				['remotes' => [['name' => 'User @ Localhost', 'label' => 'User @ Localhost (username@localhost)', 'uuid' => 'uid1', 'type' => '', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'username@localhost', 'server' => 'localhost']]], 'exact' => ['remotes' => []]],
187
-				false,
188
-				true,
189
-			],
190
-			[
191
-				'test',
192
-				[
193
-					[
194
-						'UID' => 'uid',
195
-						'FN' => 'User3 @ Localhost',
196
-					],
197
-					[
198
-						'UID' => 'uid',
199
-						'FN' => 'User2 @ Localhost',
200
-						'CLOUD' => [
201
-						],
202
-					],
203
-					[
204
-						'UID' => 'uid',
205
-						'FN' => 'User @ Localhost',
206
-						'CLOUD' => [
207
-							'username@localhost',
208
-						],
209
-					],
210
-				],
211
-				false,
212
-				['remotes' => [], 'exact' => ['remotes' => []]],
213
-				false,
214
-				true,
215
-			],
216
-			[
217
-				'test@remote',
218
-				[
219
-					[
220
-						'UID' => 'uid',
221
-						'FN' => 'User3 @ Localhost',
222
-					],
223
-					[
224
-						'UID' => 'uid',
225
-						'FN' => 'User2 @ Localhost',
226
-						'CLOUD' => [
227
-						],
228
-					],
229
-					[
230
-						'UID' => 'uid',
231
-						'FN' => 'User @ Localhost',
232
-						'CLOUD' => [
233
-							'username@localhost',
234
-						],
235
-					],
236
-				],
237
-				true,
238
-				['remotes' => [['name' => 'User @ Localhost', 'label' => 'User @ Localhost (username@localhost)', 'uuid' => 'uid', 'type' => '', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'username@localhost', 'server' => 'localhost']]], 'exact' => ['remotes' => [['label' => 'test (remote)', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'test@remote', 'server' => 'remote'], 'uuid' => 'test', 'name' => 'test']]]],
239
-				false,
240
-				true,
241
-			],
242
-			[
243
-				'test@remote',
244
-				[
245
-					[
246
-						'UID' => 'uid',
247
-						'FN' => 'User3 @ Localhost',
248
-					],
249
-					[
250
-						'UID' => 'uid',
251
-						'FN' => 'User2 @ Localhost',
252
-						'CLOUD' => [
253
-						],
254
-					],
255
-					[
256
-						'UID' => 'uid',
257
-						'FN' => 'User @ Localhost',
258
-						'CLOUD' => [
259
-							'username@localhost',
260
-						],
261
-					],
262
-				],
263
-				false,
264
-				['remotes' => [], 'exact' => ['remotes' => [['label' => 'test (remote)', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'test@remote', 'server' => 'remote'], 'uuid' => 'test', 'name' => 'test']]]],
265
-				false,
266
-				true,
267
-			],
268
-			[
269
-				'username@localhost',
270
-				[
271
-					[
272
-						'UID' => 'uid3',
273
-						'FN' => 'User3 @ Localhost',
274
-					],
275
-					[
276
-						'UID' => '2',
277
-						'FN' => 'User2 @ Localhost',
278
-						'CLOUD' => [
279
-						],
280
-					],
281
-					[
282
-						'UID' => 'uid1',
283
-						'FN' => 'User @ Localhost',
284
-						'CLOUD' => [
285
-							'username@localhost',
286
-						],
287
-					],
288
-				],
289
-				true,
290
-				['remotes' => [], 'exact' => ['remotes' => [['name' => 'User @ Localhost', 'label' => 'User @ Localhost (username@localhost)', 'uuid' => 'uid1', 'type' => '', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'username@localhost', 'server' => 'localhost']]]]],
291
-				true,
292
-				true,
293
-			],
294
-			[
295
-				'username@localhost',
296
-				[
297
-					[
298
-						'UID' => 'uid3',
299
-						'FN' => 'User3 @ Localhost',
300
-					],
301
-					[
302
-						'UID' => 'uid2',
303
-						'FN' => 'User2 @ Localhost',
304
-						'CLOUD' => [
305
-						],
306
-					],
307
-					[
308
-						'UID' => 'uid1',
309
-						'FN' => 'User @ Localhost',
310
-						'CLOUD' => [
311
-							'username@localhost',
312
-						],
313
-					],
314
-				],
315
-				false,
316
-				['remotes' => [], 'exact' => ['remotes' => [['name' => 'User @ Localhost', 'label' => 'User @ Localhost (username@localhost)', 'uuid' => 'uid1', 'type' => '', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'username@localhost', 'server' => 'localhost']]]]],
317
-				true,
318
-				true,
319
-			],
320
-			// contact with space
321
-			[
322
-				'user name@localhost',
323
-				[
324
-					[
325
-						'UID' => 'uid1',
326
-						'FN' => 'User3 @ Localhost',
327
-					],
328
-					[
329
-						'UID' => 'uid2',
330
-						'FN' => 'User2 @ Localhost',
331
-						'CLOUD' => [
332
-						],
333
-					],
334
-					[
335
-						'UID' => 'uid3',
336
-						'FN' => 'User Name @ Localhost',
337
-						'CLOUD' => [
338
-							'user name@localhost',
339
-						],
340
-					],
341
-				],
342
-				false,
343
-				['remotes' => [], 'exact' => ['remotes' => [['name' => 'User Name @ Localhost', 'label' => 'User Name @ Localhost (user name@localhost)', 'uuid' => 'uid3', 'type' => '', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'user name@localhost', 'server' => 'localhost']]]]],
344
-				true,
345
-				true,
346
-			],
347
-			// remote with space, no contact
348
-			[
349
-				'user space@remote',
350
-				[
351
-					[
352
-						'UID' => 'uid3',
353
-						'FN' => 'User3 @ Localhost',
354
-					],
355
-					[
356
-						'UID' => 'uid2',
357
-						'FN' => 'User2 @ Localhost',
358
-						'CLOUD' => [
359
-						],
360
-					],
361
-					[
362
-						'UID' => 'uid1',
363
-						'FN' => 'User @ Localhost',
364
-						'CLOUD' => [
365
-							'username@localhost',
366
-						],
367
-					],
368
-				],
369
-				false,
370
-				['remotes' => [], 'exact' => ['remotes' => [['label' => 'user space (remote)', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'user space@remote', 'server' => 'remote'], 'uuid' => 'user space', 'name' => 'user space']]]],
371
-				false,
372
-				true,
373
-			],
374
-		];
375
-	}
144
+    public static function dataGetRemote() {
145
+        return [
146
+            ['test', [], true, ['remotes' => [], 'exact' => ['remotes' => []]], false, true],
147
+            ['test', [], false, ['remotes' => [], 'exact' => ['remotes' => []]], false, true],
148
+            [
149
+                'test@remote',
150
+                [],
151
+                true,
152
+                ['remotes' => [], 'exact' => ['remotes' => [['label' => 'test (remote)', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'test@remote', 'server' => 'remote'], 'uuid' => 'test', 'name' => 'test']]]],
153
+                false,
154
+                true,
155
+            ],
156
+            [
157
+                'test@remote',
158
+                [],
159
+                false,
160
+                ['remotes' => [], 'exact' => ['remotes' => [['label' => 'test (remote)', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'test@remote', 'server' => 'remote'], 'uuid' => 'test', 'name' => 'test']]]],
161
+                false,
162
+                true,
163
+            ],
164
+            [
165
+                'test',
166
+                [
167
+                    [
168
+                        'UID' => 'uid',
169
+                        'FN' => 'User3 @ Localhost',
170
+                    ],
171
+                    [
172
+                        'UID' => 'uid',
173
+                        'FN' => 'User2 @ Localhost',
174
+                        'CLOUD' => [
175
+                        ],
176
+                    ],
177
+                    [
178
+                        'UID' => 'uid1',
179
+                        'FN' => 'User @ Localhost',
180
+                        'CLOUD' => [
181
+                            'username@localhost',
182
+                        ],
183
+                    ],
184
+                ],
185
+                true,
186
+                ['remotes' => [['name' => 'User @ Localhost', 'label' => 'User @ Localhost (username@localhost)', 'uuid' => 'uid1', 'type' => '', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'username@localhost', 'server' => 'localhost']]], 'exact' => ['remotes' => []]],
187
+                false,
188
+                true,
189
+            ],
190
+            [
191
+                'test',
192
+                [
193
+                    [
194
+                        'UID' => 'uid',
195
+                        'FN' => 'User3 @ Localhost',
196
+                    ],
197
+                    [
198
+                        'UID' => 'uid',
199
+                        'FN' => 'User2 @ Localhost',
200
+                        'CLOUD' => [
201
+                        ],
202
+                    ],
203
+                    [
204
+                        'UID' => 'uid',
205
+                        'FN' => 'User @ Localhost',
206
+                        'CLOUD' => [
207
+                            'username@localhost',
208
+                        ],
209
+                    ],
210
+                ],
211
+                false,
212
+                ['remotes' => [], 'exact' => ['remotes' => []]],
213
+                false,
214
+                true,
215
+            ],
216
+            [
217
+                'test@remote',
218
+                [
219
+                    [
220
+                        'UID' => 'uid',
221
+                        'FN' => 'User3 @ Localhost',
222
+                    ],
223
+                    [
224
+                        'UID' => 'uid',
225
+                        'FN' => 'User2 @ Localhost',
226
+                        'CLOUD' => [
227
+                        ],
228
+                    ],
229
+                    [
230
+                        'UID' => 'uid',
231
+                        'FN' => 'User @ Localhost',
232
+                        'CLOUD' => [
233
+                            'username@localhost',
234
+                        ],
235
+                    ],
236
+                ],
237
+                true,
238
+                ['remotes' => [['name' => 'User @ Localhost', 'label' => 'User @ Localhost (username@localhost)', 'uuid' => 'uid', 'type' => '', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'username@localhost', 'server' => 'localhost']]], 'exact' => ['remotes' => [['label' => 'test (remote)', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'test@remote', 'server' => 'remote'], 'uuid' => 'test', 'name' => 'test']]]],
239
+                false,
240
+                true,
241
+            ],
242
+            [
243
+                'test@remote',
244
+                [
245
+                    [
246
+                        'UID' => 'uid',
247
+                        'FN' => 'User3 @ Localhost',
248
+                    ],
249
+                    [
250
+                        'UID' => 'uid',
251
+                        'FN' => 'User2 @ Localhost',
252
+                        'CLOUD' => [
253
+                        ],
254
+                    ],
255
+                    [
256
+                        'UID' => 'uid',
257
+                        'FN' => 'User @ Localhost',
258
+                        'CLOUD' => [
259
+                            'username@localhost',
260
+                        ],
261
+                    ],
262
+                ],
263
+                false,
264
+                ['remotes' => [], 'exact' => ['remotes' => [['label' => 'test (remote)', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'test@remote', 'server' => 'remote'], 'uuid' => 'test', 'name' => 'test']]]],
265
+                false,
266
+                true,
267
+            ],
268
+            [
269
+                'username@localhost',
270
+                [
271
+                    [
272
+                        'UID' => 'uid3',
273
+                        'FN' => 'User3 @ Localhost',
274
+                    ],
275
+                    [
276
+                        'UID' => '2',
277
+                        'FN' => 'User2 @ Localhost',
278
+                        'CLOUD' => [
279
+                        ],
280
+                    ],
281
+                    [
282
+                        'UID' => 'uid1',
283
+                        'FN' => 'User @ Localhost',
284
+                        'CLOUD' => [
285
+                            'username@localhost',
286
+                        ],
287
+                    ],
288
+                ],
289
+                true,
290
+                ['remotes' => [], 'exact' => ['remotes' => [['name' => 'User @ Localhost', 'label' => 'User @ Localhost (username@localhost)', 'uuid' => 'uid1', 'type' => '', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'username@localhost', 'server' => 'localhost']]]]],
291
+                true,
292
+                true,
293
+            ],
294
+            [
295
+                'username@localhost',
296
+                [
297
+                    [
298
+                        'UID' => 'uid3',
299
+                        'FN' => 'User3 @ Localhost',
300
+                    ],
301
+                    [
302
+                        'UID' => 'uid2',
303
+                        'FN' => 'User2 @ Localhost',
304
+                        'CLOUD' => [
305
+                        ],
306
+                    ],
307
+                    [
308
+                        'UID' => 'uid1',
309
+                        'FN' => 'User @ Localhost',
310
+                        'CLOUD' => [
311
+                            'username@localhost',
312
+                        ],
313
+                    ],
314
+                ],
315
+                false,
316
+                ['remotes' => [], 'exact' => ['remotes' => [['name' => 'User @ Localhost', 'label' => 'User @ Localhost (username@localhost)', 'uuid' => 'uid1', 'type' => '', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'username@localhost', 'server' => 'localhost']]]]],
317
+                true,
318
+                true,
319
+            ],
320
+            // contact with space
321
+            [
322
+                'user name@localhost',
323
+                [
324
+                    [
325
+                        'UID' => 'uid1',
326
+                        'FN' => 'User3 @ Localhost',
327
+                    ],
328
+                    [
329
+                        'UID' => 'uid2',
330
+                        'FN' => 'User2 @ Localhost',
331
+                        'CLOUD' => [
332
+                        ],
333
+                    ],
334
+                    [
335
+                        'UID' => 'uid3',
336
+                        'FN' => 'User Name @ Localhost',
337
+                        'CLOUD' => [
338
+                            'user name@localhost',
339
+                        ],
340
+                    ],
341
+                ],
342
+                false,
343
+                ['remotes' => [], 'exact' => ['remotes' => [['name' => 'User Name @ Localhost', 'label' => 'User Name @ Localhost (user name@localhost)', 'uuid' => 'uid3', 'type' => '', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'user name@localhost', 'server' => 'localhost']]]]],
344
+                true,
345
+                true,
346
+            ],
347
+            // remote with space, no contact
348
+            [
349
+                'user space@remote',
350
+                [
351
+                    [
352
+                        'UID' => 'uid3',
353
+                        'FN' => 'User3 @ Localhost',
354
+                    ],
355
+                    [
356
+                        'UID' => 'uid2',
357
+                        'FN' => 'User2 @ Localhost',
358
+                        'CLOUD' => [
359
+                        ],
360
+                    ],
361
+                    [
362
+                        'UID' => 'uid1',
363
+                        'FN' => 'User @ Localhost',
364
+                        'CLOUD' => [
365
+                            'username@localhost',
366
+                        ],
367
+                    ],
368
+                ],
369
+                false,
370
+                ['remotes' => [], 'exact' => ['remotes' => [['label' => 'user space (remote)', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'user space@remote', 'server' => 'remote'], 'uuid' => 'user space', 'name' => 'user space']]]],
371
+                false,
372
+                true,
373
+            ],
374
+        ];
375
+    }
376 376
 
377
-	public static function dataTestSplitUserRemote(): array {
378
-		$userPrefix = ['user@name', 'username'];
379
-		$protocols = ['', 'http://', 'https://'];
380
-		$remotes = [
381
-			'localhost',
382
-			'local.host',
383
-			'dev.local.host',
384
-			'dev.local.host/path',
385
-			'dev.local.host/at@inpath',
386
-			'127.0.0.1',
387
-			'::1',
388
-			'::192.0.2.128',
389
-			'::192.0.2.128/at@inpath',
390
-		];
377
+    public static function dataTestSplitUserRemote(): array {
378
+        $userPrefix = ['user@name', 'username'];
379
+        $protocols = ['', 'http://', 'https://'];
380
+        $remotes = [
381
+            'localhost',
382
+            'local.host',
383
+            'dev.local.host',
384
+            'dev.local.host/path',
385
+            'dev.local.host/at@inpath',
386
+            '127.0.0.1',
387
+            '::1',
388
+            '::192.0.2.128',
389
+            '::192.0.2.128/at@inpath',
390
+        ];
391 391
 
392
-		$testCases = [];
393
-		foreach ($userPrefix as $user) {
394
-			foreach ($remotes as $remote) {
395
-				foreach ($protocols as $protocol) {
396
-					$baseUrl = $user . '@' . $protocol . $remote;
392
+        $testCases = [];
393
+        foreach ($userPrefix as $user) {
394
+            foreach ($remotes as $remote) {
395
+                foreach ($protocols as $protocol) {
396
+                    $baseUrl = $user . '@' . $protocol . $remote;
397 397
 
398
-					if ($protocol === 'https://') {
399
-						// https:// protocol is not expected in the final result
400
-						$protocol = '';
401
-					}
398
+                    if ($protocol === 'https://') {
399
+                        // https:// protocol is not expected in the final result
400
+                        $protocol = '';
401
+                    }
402 402
 
403
-					$testCases[] = [$baseUrl, $user, $protocol . $remote];
404
-					$testCases[] = [$baseUrl . '/', $user, $protocol . $remote];
405
-					$testCases[] = [$baseUrl . '/index.php', $user, $protocol . $remote];
406
-					$testCases[] = [$baseUrl . '/index.php/s/token', $user, $protocol . $remote];
407
-				}
408
-			}
409
-		}
410
-		return $testCases;
411
-	}
403
+                    $testCases[] = [$baseUrl, $user, $protocol . $remote];
404
+                    $testCases[] = [$baseUrl . '/', $user, $protocol . $remote];
405
+                    $testCases[] = [$baseUrl . '/index.php', $user, $protocol . $remote];
406
+                    $testCases[] = [$baseUrl . '/index.php/s/token', $user, $protocol . $remote];
407
+                }
408
+            }
409
+        }
410
+        return $testCases;
411
+    }
412 412
 
413
-	public static function dataTestSplitUserRemoteError(): array {
414
-		return [
415
-			// Invalid path
416
-			['user@'],
413
+    public static function dataTestSplitUserRemoteError(): array {
414
+        return [
415
+            // Invalid path
416
+            ['user@'],
417 417
 
418
-			// Invalid user
419
-			['@server'],
420
-			['us/er@server'],
421
-			['us:er@server'],
418
+            // Invalid user
419
+            ['@server'],
420
+            ['us/er@server'],
421
+            ['us:er@server'],
422 422
 
423
-			// Invalid splitting
424
-			['user'],
425
-			[''],
426
-			['us/erserver'],
427
-			['us:erserver'],
428
-		];
429
-	}
423
+            // Invalid splitting
424
+            ['user'],
425
+            [''],
426
+            ['us/erserver'],
427
+            ['us:erserver'],
428
+        ];
429
+    }
430 430
 }
Please login to merge, or discard this patch.
tests/lib/Command/Integrity/SignCoreTest.php 2 patches
Indentation   +193 added lines, -193 removed lines patch added patch discarded remove patch
@@ -15,197 +15,197 @@
 block discarded – undo
15 15
 use Test\TestCase;
16 16
 
17 17
 class SignCoreTest extends TestCase {
18
-	/** @var Checker|\PHPUnit\Framework\MockObject\MockObject */
19
-	private $checker;
20
-	/** @var FileAccessHelper|\PHPUnit\Framework\MockObject\MockObject */
21
-	private $fileAccessHelper;
22
-	/** @var SignCore */
23
-	private $signCore;
24
-
25
-	protected function setUp(): void {
26
-		parent::setUp();
27
-		$this->checker = $this->createMock(Checker::class);
28
-		$this->fileAccessHelper = $this->createMock(FileAccessHelper::class);
29
-		$this->signCore = new SignCore(
30
-			$this->checker,
31
-			$this->fileAccessHelper
32
-		);
33
-	}
34
-
35
-	public function testExecuteWithMissingPrivateKey(): void {
36
-		$inputInterface = $this->createMock(InputInterface::class);
37
-		$outputInterface = $this->createMock(OutputInterface::class);
38
-
39
-		$inputInterface
40
-			->expects($this->exactly(3))
41
-			->method('getOption')
42
-			->willReturnMap([
43
-				['privateKey', null],
44
-				['certificate', 'certificate'],
45
-				['path', 'certificate'],
46
-			]);
47
-
48
-		$outputInterface
49
-			->expects($this->any())
50
-			->method('writeln')
51
-			->willReturnCallback(function (string $message) {
52
-				$this->assertEquals('--privateKey, --certificate and --path are required.', $message);
53
-			});
54
-
55
-		$this->assertSame(1, self::invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface]));
56
-	}
57
-
58
-	public function testExecuteWithMissingCertificate(): void {
59
-		$inputInterface = $this->createMock(InputInterface::class);
60
-		$outputInterface = $this->createMock(OutputInterface::class);
61
-
62
-		$inputInterface
63
-			->expects($this->exactly(3))
64
-			->method('getOption')
65
-			->willReturnMap([
66
-				['privateKey', 'privateKey'],
67
-				['certificate', null],
68
-				['path', 'certificate'],
69
-			]);
70
-
71
-		$outputInterface
72
-			->expects($this->any())
73
-			->method('writeln')
74
-			->willReturnCallback(function (string $message) {
75
-				$this->assertEquals('--privateKey, --certificate and --path are required.', $message);
76
-			});
77
-
78
-		$this->assertSame(1, self::invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface]));
79
-	}
80
-
81
-	public function testExecuteWithNotExistingPrivateKey(): void {
82
-		$inputInterface = $this->createMock(InputInterface::class);
83
-		$outputInterface = $this->createMock(OutputInterface::class);
84
-
85
-		$inputInterface
86
-			->expects($this->exactly(3))
87
-			->method('getOption')
88
-			->willReturnMap([
89
-				['privateKey', 'privateKey'],
90
-				['certificate', 'certificate'],
91
-				['path', 'certificate'],
92
-			]);
93
-
94
-		$this->fileAccessHelper
95
-			->method('file_get_contents')
96
-			->willReturnMap([
97
-				['privateKey', false],
98
-			]);
99
-
100
-		$outputInterface
101
-			->expects($this->any())
102
-			->method('writeln')
103
-			->willReturnCallback(function (string $message) {
104
-				$this->assertEquals('Private key "privateKey" does not exists.', $message);
105
-			});
106
-
107
-		$this->assertSame(1, self::invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface]));
108
-	}
109
-
110
-	public function testExecuteWithNotExistingCertificate(): void {
111
-		$inputInterface = $this->createMock(InputInterface::class);
112
-		$outputInterface = $this->createMock(OutputInterface::class);
113
-
114
-		$inputInterface
115
-			->expects($this->exactly(3))
116
-			->method('getOption')
117
-			->willReturnMap([
118
-				['privateKey', 'privateKey'],
119
-				['certificate', 'certificate'],
120
-				['path', 'certificate'],
121
-			]);
122
-
123
-		$this->fileAccessHelper
124
-			->expects($this->any())
125
-			->method('file_get_contents')
126
-			->willReturnMap([
127
-				['privateKey', file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.key')],
128
-				['certificate', false],
129
-			]);
130
-
131
-		$outputInterface
132
-			->expects($this->any())
133
-			->method('writeln')
134
-			->willReturnCallback(function (string $message) {
135
-				$this->assertEquals('Certificate "certificate" does not exists.', $message);
136
-			});
137
-
138
-		$this->assertSame(1, self::invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface]));
139
-	}
140
-
141
-	public function testExecuteWithException(): void {
142
-		$inputInterface = $this->createMock(InputInterface::class);
143
-		$outputInterface = $this->createMock(OutputInterface::class);
144
-
145
-		$inputInterface
146
-			->expects($this->exactly(3))
147
-			->method('getOption')
148
-			->willReturnMap([
149
-				['privateKey', 'privateKey'],
150
-				['certificate', 'certificate'],
151
-				['path', 'certificate'],
152
-			]);
153
-
154
-		$this->fileAccessHelper
155
-			->expects($this->any())
156
-			->method('file_get_contents')
157
-			->willReturnMap([
158
-				['privateKey', file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.key')],
159
-				['certificate', file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.crt')],
160
-			]);
161
-
162
-		$this->checker
163
-			->expects($this->once())
164
-			->method('writeCoreSignature')
165
-			->willThrowException(new \Exception('My exception message'));
166
-
167
-		$outputInterface
168
-			->expects($this->any())
169
-			->method('writeln')
170
-			->willReturnCallback(function (string $message) {
171
-				$this->assertEquals('Error: My exception message', $message);
172
-			});
173
-
174
-		$this->assertEquals(1, self::invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface]));
175
-	}
176
-
177
-	public function testExecute(): void {
178
-		$inputInterface = $this->createMock(InputInterface::class);
179
-		$outputInterface = $this->createMock(OutputInterface::class);
180
-
181
-		$inputInterface
182
-			->expects($this->exactly(3))
183
-			->method('getOption')
184
-			->willReturnMap([
185
-				['privateKey', 'privateKey'],
186
-				['certificate', 'certificate'],
187
-				['path', 'certificate'],
188
-			]);
189
-
190
-		$this->fileAccessHelper
191
-			->expects($this->any())
192
-			->method('file_get_contents')
193
-			->willReturnMap([
194
-				['privateKey', file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.key')],
195
-				['certificate', file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.crt')],
196
-			]);
197
-
198
-		$this->checker
199
-			->expects($this->once())
200
-			->method('writeCoreSignature');
201
-
202
-		$outputInterface
203
-			->expects($this->any())
204
-			->method('writeln')
205
-			->willReturnCallback(function (string $message) {
206
-				$this->assertEquals('Successfully signed "core"', $message);
207
-			});
208
-
209
-		$this->assertEquals(0, self::invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface]));
210
-	}
18
+    /** @var Checker|\PHPUnit\Framework\MockObject\MockObject */
19
+    private $checker;
20
+    /** @var FileAccessHelper|\PHPUnit\Framework\MockObject\MockObject */
21
+    private $fileAccessHelper;
22
+    /** @var SignCore */
23
+    private $signCore;
24
+
25
+    protected function setUp(): void {
26
+        parent::setUp();
27
+        $this->checker = $this->createMock(Checker::class);
28
+        $this->fileAccessHelper = $this->createMock(FileAccessHelper::class);
29
+        $this->signCore = new SignCore(
30
+            $this->checker,
31
+            $this->fileAccessHelper
32
+        );
33
+    }
34
+
35
+    public function testExecuteWithMissingPrivateKey(): void {
36
+        $inputInterface = $this->createMock(InputInterface::class);
37
+        $outputInterface = $this->createMock(OutputInterface::class);
38
+
39
+        $inputInterface
40
+            ->expects($this->exactly(3))
41
+            ->method('getOption')
42
+            ->willReturnMap([
43
+                ['privateKey', null],
44
+                ['certificate', 'certificate'],
45
+                ['path', 'certificate'],
46
+            ]);
47
+
48
+        $outputInterface
49
+            ->expects($this->any())
50
+            ->method('writeln')
51
+            ->willReturnCallback(function (string $message) {
52
+                $this->assertEquals('--privateKey, --certificate and --path are required.', $message);
53
+            });
54
+
55
+        $this->assertSame(1, self::invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface]));
56
+    }
57
+
58
+    public function testExecuteWithMissingCertificate(): void {
59
+        $inputInterface = $this->createMock(InputInterface::class);
60
+        $outputInterface = $this->createMock(OutputInterface::class);
61
+
62
+        $inputInterface
63
+            ->expects($this->exactly(3))
64
+            ->method('getOption')
65
+            ->willReturnMap([
66
+                ['privateKey', 'privateKey'],
67
+                ['certificate', null],
68
+                ['path', 'certificate'],
69
+            ]);
70
+
71
+        $outputInterface
72
+            ->expects($this->any())
73
+            ->method('writeln')
74
+            ->willReturnCallback(function (string $message) {
75
+                $this->assertEquals('--privateKey, --certificate and --path are required.', $message);
76
+            });
77
+
78
+        $this->assertSame(1, self::invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface]));
79
+    }
80
+
81
+    public function testExecuteWithNotExistingPrivateKey(): void {
82
+        $inputInterface = $this->createMock(InputInterface::class);
83
+        $outputInterface = $this->createMock(OutputInterface::class);
84
+
85
+        $inputInterface
86
+            ->expects($this->exactly(3))
87
+            ->method('getOption')
88
+            ->willReturnMap([
89
+                ['privateKey', 'privateKey'],
90
+                ['certificate', 'certificate'],
91
+                ['path', 'certificate'],
92
+            ]);
93
+
94
+        $this->fileAccessHelper
95
+            ->method('file_get_contents')
96
+            ->willReturnMap([
97
+                ['privateKey', false],
98
+            ]);
99
+
100
+        $outputInterface
101
+            ->expects($this->any())
102
+            ->method('writeln')
103
+            ->willReturnCallback(function (string $message) {
104
+                $this->assertEquals('Private key "privateKey" does not exists.', $message);
105
+            });
106
+
107
+        $this->assertSame(1, self::invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface]));
108
+    }
109
+
110
+    public function testExecuteWithNotExistingCertificate(): void {
111
+        $inputInterface = $this->createMock(InputInterface::class);
112
+        $outputInterface = $this->createMock(OutputInterface::class);
113
+
114
+        $inputInterface
115
+            ->expects($this->exactly(3))
116
+            ->method('getOption')
117
+            ->willReturnMap([
118
+                ['privateKey', 'privateKey'],
119
+                ['certificate', 'certificate'],
120
+                ['path', 'certificate'],
121
+            ]);
122
+
123
+        $this->fileAccessHelper
124
+            ->expects($this->any())
125
+            ->method('file_get_contents')
126
+            ->willReturnMap([
127
+                ['privateKey', file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.key')],
128
+                ['certificate', false],
129
+            ]);
130
+
131
+        $outputInterface
132
+            ->expects($this->any())
133
+            ->method('writeln')
134
+            ->willReturnCallback(function (string $message) {
135
+                $this->assertEquals('Certificate "certificate" does not exists.', $message);
136
+            });
137
+
138
+        $this->assertSame(1, self::invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface]));
139
+    }
140
+
141
+    public function testExecuteWithException(): void {
142
+        $inputInterface = $this->createMock(InputInterface::class);
143
+        $outputInterface = $this->createMock(OutputInterface::class);
144
+
145
+        $inputInterface
146
+            ->expects($this->exactly(3))
147
+            ->method('getOption')
148
+            ->willReturnMap([
149
+                ['privateKey', 'privateKey'],
150
+                ['certificate', 'certificate'],
151
+                ['path', 'certificate'],
152
+            ]);
153
+
154
+        $this->fileAccessHelper
155
+            ->expects($this->any())
156
+            ->method('file_get_contents')
157
+            ->willReturnMap([
158
+                ['privateKey', file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.key')],
159
+                ['certificate', file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.crt')],
160
+            ]);
161
+
162
+        $this->checker
163
+            ->expects($this->once())
164
+            ->method('writeCoreSignature')
165
+            ->willThrowException(new \Exception('My exception message'));
166
+
167
+        $outputInterface
168
+            ->expects($this->any())
169
+            ->method('writeln')
170
+            ->willReturnCallback(function (string $message) {
171
+                $this->assertEquals('Error: My exception message', $message);
172
+            });
173
+
174
+        $this->assertEquals(1, self::invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface]));
175
+    }
176
+
177
+    public function testExecute(): void {
178
+        $inputInterface = $this->createMock(InputInterface::class);
179
+        $outputInterface = $this->createMock(OutputInterface::class);
180
+
181
+        $inputInterface
182
+            ->expects($this->exactly(3))
183
+            ->method('getOption')
184
+            ->willReturnMap([
185
+                ['privateKey', 'privateKey'],
186
+                ['certificate', 'certificate'],
187
+                ['path', 'certificate'],
188
+            ]);
189
+
190
+        $this->fileAccessHelper
191
+            ->expects($this->any())
192
+            ->method('file_get_contents')
193
+            ->willReturnMap([
194
+                ['privateKey', file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.key')],
195
+                ['certificate', file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.crt')],
196
+            ]);
197
+
198
+        $this->checker
199
+            ->expects($this->once())
200
+            ->method('writeCoreSignature');
201
+
202
+        $outputInterface
203
+            ->expects($this->any())
204
+            ->method('writeln')
205
+            ->willReturnCallback(function (string $message) {
206
+                $this->assertEquals('Successfully signed "core"', $message);
207
+            });
208
+
209
+        $this->assertEquals(0, self::invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface]));
210
+    }
211 211
 }
Please login to merge, or discard this patch.
Spacing   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -48,7 +48,7 @@  discard block
 block discarded – undo
48 48
 		$outputInterface
49 49
 			->expects($this->any())
50 50
 			->method('writeln')
51
-			->willReturnCallback(function (string $message) {
51
+			->willReturnCallback(function(string $message) {
52 52
 				$this->assertEquals('--privateKey, --certificate and --path are required.', $message);
53 53
 			});
54 54
 
@@ -71,7 +71,7 @@  discard block
 block discarded – undo
71 71
 		$outputInterface
72 72
 			->expects($this->any())
73 73
 			->method('writeln')
74
-			->willReturnCallback(function (string $message) {
74
+			->willReturnCallback(function(string $message) {
75 75
 				$this->assertEquals('--privateKey, --certificate and --path are required.', $message);
76 76
 			});
77 77
 
@@ -100,7 +100,7 @@  discard block
 block discarded – undo
100 100
 		$outputInterface
101 101
 			->expects($this->any())
102 102
 			->method('writeln')
103
-			->willReturnCallback(function (string $message) {
103
+			->willReturnCallback(function(string $message) {
104 104
 				$this->assertEquals('Private key "privateKey" does not exists.', $message);
105 105
 			});
106 106
 
@@ -124,14 +124,14 @@  discard block
 block discarded – undo
124 124
 			->expects($this->any())
125 125
 			->method('file_get_contents')
126 126
 			->willReturnMap([
127
-				['privateKey', file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.key')],
127
+				['privateKey', file_get_contents(\OC::$SERVERROOT.'/tests/data/integritycheck/core.key')],
128 128
 				['certificate', false],
129 129
 			]);
130 130
 
131 131
 		$outputInterface
132 132
 			->expects($this->any())
133 133
 			->method('writeln')
134
-			->willReturnCallback(function (string $message) {
134
+			->willReturnCallback(function(string $message) {
135 135
 				$this->assertEquals('Certificate "certificate" does not exists.', $message);
136 136
 			});
137 137
 
@@ -155,8 +155,8 @@  discard block
 block discarded – undo
155 155
 			->expects($this->any())
156 156
 			->method('file_get_contents')
157 157
 			->willReturnMap([
158
-				['privateKey', file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.key')],
159
-				['certificate', file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.crt')],
158
+				['privateKey', file_get_contents(\OC::$SERVERROOT.'/tests/data/integritycheck/core.key')],
159
+				['certificate', file_get_contents(\OC::$SERVERROOT.'/tests/data/integritycheck/core.crt')],
160 160
 			]);
161 161
 
162 162
 		$this->checker
@@ -167,7 +167,7 @@  discard block
 block discarded – undo
167 167
 		$outputInterface
168 168
 			->expects($this->any())
169 169
 			->method('writeln')
170
-			->willReturnCallback(function (string $message) {
170
+			->willReturnCallback(function(string $message) {
171 171
 				$this->assertEquals('Error: My exception message', $message);
172 172
 			});
173 173
 
@@ -191,8 +191,8 @@  discard block
 block discarded – undo
191 191
 			->expects($this->any())
192 192
 			->method('file_get_contents')
193 193
 			->willReturnMap([
194
-				['privateKey', file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.key')],
195
-				['certificate', file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.crt')],
194
+				['privateKey', file_get_contents(\OC::$SERVERROOT.'/tests/data/integritycheck/core.key')],
195
+				['certificate', file_get_contents(\OC::$SERVERROOT.'/tests/data/integritycheck/core.crt')],
196 196
 			]);
197 197
 
198 198
 		$this->checker
@@ -202,7 +202,7 @@  discard block
 block discarded – undo
202 202
 		$outputInterface
203 203
 			->expects($this->any())
204 204
 			->method('writeln')
205
-			->willReturnCallback(function (string $message) {
205
+			->willReturnCallback(function(string $message) {
206 206
 				$this->assertEquals('Successfully signed "core"', $message);
207 207
 			});
208 208
 
Please login to merge, or discard this patch.