Completed
Push — master ( ed485a...e6bcc4 )
by Joas
31:47 queued 16s
created
tests/lib/Comments/ManagerTest.php 2 patches
Indentation   +2521 added lines, -2521 removed lines patch added patch discarded remove patch
@@ -35,2542 +35,2542 @@
 block discarded – undo
35 35
  * @group DB
36 36
  */
37 37
 class ManagerTest extends TestCase {
38
-	/** @var IDBConnection */
39
-	private $connection;
40
-	/** @var \PHPUnit\Framework\MockObject\MockObject|IRootFolder */
41
-	private $rootFolder;
42
-
43
-	protected function setUp(): void {
44
-		parent::setUp();
45
-
46
-		$this->connection = \OC::$server->getDatabaseConnection();
47
-		$this->rootFolder = $this->createMock(IRootFolder::class);
48
-
49
-		$sql = $this->connection->getDatabasePlatform()->getTruncateTableSQL('`*PREFIX*comments`');
50
-		$this->connection->prepare($sql)->execute();
51
-		$sql = $this->connection->getDatabasePlatform()->getTruncateTableSQL('`*PREFIX*reactions`');
52
-		$this->connection->prepare($sql)->execute();
53
-	}
54
-
55
-	protected function addDatabaseEntry($parentId, $topmostParentId, $creationDT = null, $latestChildDT = null, $objectId = null, $expireDate = null) {
56
-		$creationDT ??= new \DateTime();
57
-		$latestChildDT ??= new \DateTime('yesterday');
58
-		$objectId ??= 'file64';
59
-
60
-		$qb = $this->connection->getQueryBuilder();
61
-		$qb
62
-			->insert('comments')
63
-			->values([
64
-				'parent_id' => $qb->createNamedParameter($parentId),
65
-				'topmost_parent_id' => $qb->createNamedParameter($topmostParentId),
66
-				'children_count' => $qb->createNamedParameter(2),
67
-				'actor_type' => $qb->createNamedParameter('users'),
68
-				'actor_id' => $qb->createNamedParameter('alice'),
69
-				'message' => $qb->createNamedParameter('nice one'),
70
-				'verb' => $qb->createNamedParameter('comment'),
71
-				'creation_timestamp' => $qb->createNamedParameter($creationDT, IQueryBuilder::PARAM_DATETIME_MUTABLE),
72
-				'latest_child_timestamp' => $qb->createNamedParameter($latestChildDT, IQueryBuilder::PARAM_DATETIME_MUTABLE),
73
-				'object_type' => $qb->createNamedParameter('files'),
74
-				'object_id' => $qb->createNamedParameter($objectId),
75
-				'expire_date' => $qb->createNamedParameter($expireDate, IQueryBuilder::PARAM_DATETIME_MUTABLE),
76
-				'reference_id' => $qb->createNamedParameter('referenceId'),
77
-				'meta_data' => $qb->createNamedParameter(json_encode(['last_edit_actor_id' => 'admin'])),
78
-			])
79
-			->executeStatement();
80
-
81
-		return $qb->getLastInsertId();
82
-	}
83
-
84
-	protected function getManager() {
85
-		return new Manager(
86
-			$this->connection,
87
-			$this->createMock(LoggerInterface::class),
88
-			$this->createMock(IConfig::class),
89
-			$this->createMock(ITimeFactory::class),
90
-			new EmojiHelper($this->connection),
91
-			$this->createMock(IInitialStateService::class),
92
-			$this->rootFolder,
93
-			$this->createMock(IEventDispatcher::class),
94
-		);
95
-	}
96
-
97
-
98
-	public function testGetCommentNotFound(): void {
99
-		$this->expectException(\OCP\Comments\NotFoundException::class);
100
-
101
-		$manager = $this->getManager();
102
-		$manager->get('22');
103
-	}
104
-
105
-
106
-	public function testGetCommentNotFoundInvalidInput(): void {
107
-		$this->expectException(\InvalidArgumentException::class);
108
-
109
-		$manager = $this->getManager();
110
-		$manager->get('unexisting22');
111
-	}
112
-
113
-	public function testGetComment(): void {
114
-		$manager = $this->getManager();
115
-
116
-		$creationDT = new \DateTime('yesterday');
117
-		$latestChildDT = new \DateTime();
118
-
119
-		$qb = \OCP\Server::get(IDBConnection::class)->getQueryBuilder();
120
-		$qb
121
-			->insert('comments')
122
-			->values([
123
-				'parent_id' => $qb->createNamedParameter('2'),
124
-				'topmost_parent_id' => $qb->createNamedParameter('1'),
125
-				'children_count' => $qb->createNamedParameter(2),
126
-				'actor_type' => $qb->createNamedParameter('users'),
127
-				'actor_id' => $qb->createNamedParameter('alice'),
128
-				'message' => $qb->createNamedParameter('nice one'),
129
-				'verb' => $qb->createNamedParameter('comment'),
130
-				'creation_timestamp' => $qb->createNamedParameter($creationDT, 'datetime'),
131
-				'latest_child_timestamp' => $qb->createNamedParameter($latestChildDT, 'datetime'),
132
-				'object_type' => $qb->createNamedParameter('files'),
133
-				'object_id' => $qb->createNamedParameter('file64'),
134
-				'reference_id' => $qb->createNamedParameter('referenceId'),
135
-				'meta_data' => $qb->createNamedParameter(json_encode(['last_edit_actor_id' => 'admin'])),
136
-			])
137
-			->executeStatement();
138
-
139
-		$id = (string)$qb->getLastInsertId();
140
-
141
-		$comment = $manager->get($id);
142
-		$this->assertInstanceOf(IComment::class, $comment);
143
-		$this->assertSame($id, $comment->getId());
144
-		$this->assertSame('2', $comment->getParentId());
145
-		$this->assertSame('1', $comment->getTopmostParentId());
146
-		$this->assertSame(2, $comment->getChildrenCount());
147
-		$this->assertSame('users', $comment->getActorType());
148
-		$this->assertSame('alice', $comment->getActorId());
149
-		$this->assertSame('nice one', $comment->getMessage());
150
-		$this->assertSame('comment', $comment->getVerb());
151
-		$this->assertSame('files', $comment->getObjectType());
152
-		$this->assertSame('file64', $comment->getObjectId());
153
-		$this->assertEquals($creationDT->getTimestamp(), $comment->getCreationDateTime()->getTimestamp());
154
-		$this->assertEquals($latestChildDT->getTimestamp(), $comment->getLatestChildDateTime()->getTimestamp());
155
-		$this->assertEquals('referenceId', $comment->getReferenceId());
156
-		$this->assertEquals(['last_edit_actor_id' => 'admin'], $comment->getMetaData());
157
-	}
158
-
159
-
160
-	public function testGetTreeNotFound(): void {
161
-		$this->expectException(\OCP\Comments\NotFoundException::class);
162
-
163
-		$manager = $this->getManager();
164
-		$manager->getTree('22');
165
-	}
166
-
167
-
168
-	public function testGetTreeNotFoundInvalidIpnut(): void {
169
-		$this->expectException(\InvalidArgumentException::class);
170
-
171
-		$manager = $this->getManager();
172
-		$manager->getTree('unexisting22');
173
-	}
174
-
175
-	public function testGetTree(): void {
176
-		$headId = $this->addDatabaseEntry(0, 0);
177
-
178
-		$this->addDatabaseEntry($headId, $headId, new \DateTime('-3 hours'));
179
-		$this->addDatabaseEntry($headId, $headId, new \DateTime('-2 hours'));
180
-		$id = $this->addDatabaseEntry($headId, $headId, new \DateTime('-1 hour'));
181
-
182
-		$manager = $this->getManager();
183
-		$tree = $manager->getTree($headId);
184
-
185
-		// Verifying the root comment
186
-		$this->assertArrayHasKey('comment', $tree);
187
-		$this->assertInstanceOf(IComment::class, $tree['comment']);
188
-		$this->assertSame((string)$headId, $tree['comment']->getId());
189
-		$this->assertArrayHasKey('replies', $tree);
190
-		$this->assertCount(3, $tree['replies']);
191
-
192
-		// one level deep
193
-		foreach ($tree['replies'] as $reply) {
194
-			$this->assertInstanceOf(IComment::class, $reply['comment']);
195
-			$this->assertSame((string)$id, $reply['comment']->getId());
196
-			$this->assertCount(0, $reply['replies']);
197
-			$id--;
198
-		}
199
-	}
200
-
201
-	public function testGetTreeNoReplies(): void {
202
-		$id = $this->addDatabaseEntry(0, 0);
203
-
204
-		$manager = $this->getManager();
205
-		$tree = $manager->getTree($id);
206
-
207
-		// Verifying the root comment
208
-		$this->assertArrayHasKey('comment', $tree);
209
-		$this->assertInstanceOf(IComment::class, $tree['comment']);
210
-		$this->assertSame((string)$id, $tree['comment']->getId());
211
-		$this->assertArrayHasKey('replies', $tree);
212
-		$this->assertCount(0, $tree['replies']);
213
-	}
214
-
215
-	public function testGetTreeWithLimitAndOffset(): void {
216
-		$headId = $this->addDatabaseEntry(0, 0);
217
-
218
-		$this->addDatabaseEntry($headId, $headId, new \DateTime('-3 hours'));
219
-		$this->addDatabaseEntry($headId, $headId, new \DateTime('-2 hours'));
220
-		$this->addDatabaseEntry($headId, $headId, new \DateTime('-1 hour'));
221
-		$idToVerify = $this->addDatabaseEntry($headId, $headId, new \DateTime());
222
-
223
-		$manager = $this->getManager();
224
-
225
-		for ($offset = 0; $offset < 3; $offset += 2) {
226
-			$tree = $manager->getTree((string)$headId, 2, $offset);
227
-
228
-			// Verifying the root comment
229
-			$this->assertArrayHasKey('comment', $tree);
230
-			$this->assertInstanceOf(IComment::class, $tree['comment']);
231
-			$this->assertSame((string)$headId, $tree['comment']->getId());
232
-			$this->assertArrayHasKey('replies', $tree);
233
-			$this->assertCount(2, $tree['replies']);
234
-
235
-			// one level deep
236
-			foreach ($tree['replies'] as $reply) {
237
-				$this->assertInstanceOf(IComment::class, $reply['comment']);
238
-				$this->assertSame((string)$idToVerify, $reply['comment']->getId());
239
-				$this->assertCount(0, $reply['replies']);
240
-				$idToVerify--;
241
-			}
242
-		}
243
-	}
244
-
245
-	public function testGetForObject(): void {
246
-		$this->addDatabaseEntry(0, 0);
247
-
248
-		$manager = $this->getManager();
249
-		$comments = $manager->getForObject('files', 'file64');
250
-
251
-		$this->assertIsArray($comments);
252
-		$this->assertCount(1, $comments);
253
-		$this->assertInstanceOf(IComment::class, $comments[0]);
254
-		$this->assertSame('nice one', $comments[0]->getMessage());
255
-	}
256
-
257
-	public function testGetForObjectWithLimitAndOffset(): void {
258
-		$this->addDatabaseEntry(0, 0, new \DateTime('-6 hours'));
259
-		$this->addDatabaseEntry(0, 0, new \DateTime('-5 hours'));
260
-		$this->addDatabaseEntry(1, 1, new \DateTime('-4 hours'));
261
-		$this->addDatabaseEntry(0, 0, new \DateTime('-3 hours'));
262
-		$this->addDatabaseEntry(2, 2, new \DateTime('-2 hours'));
263
-		$this->addDatabaseEntry(2, 2, new \DateTime('-1 hours'));
264
-		$idToVerify = $this->addDatabaseEntry(3, 1, new \DateTime());
265
-
266
-		$manager = $this->getManager();
267
-		$offset = 0;
268
-		do {
269
-			$comments = $manager->getForObject('files', 'file64', 3, $offset);
270
-
271
-			$this->assertIsArray($comments);
272
-			foreach ($comments as $key => $comment) {
273
-				$this->assertInstanceOf(IComment::class, $comment);
274
-				$this->assertSame('nice one', $comment->getMessage());
275
-				$this->assertSame((string)$idToVerify, $comment->getId(), 'ID wrong for comment ' . $key . ' on offset: ' . $offset);
276
-				$idToVerify--;
277
-			}
278
-			$offset += 3;
279
-		} while (count($comments) > 0);
280
-	}
281
-
282
-	public function testGetForObjectWithDateTimeConstraint(): void {
283
-		$this->addDatabaseEntry(0, 0, new \DateTime('-6 hours'));
284
-		$this->addDatabaseEntry(0, 0, new \DateTime('-5 hours'));
285
-		$id1 = $this->addDatabaseEntry(0, 0, new \DateTime('-3 hours'));
286
-		$id2 = $this->addDatabaseEntry(2, 2, new \DateTime('-2 hours'));
287
-
288
-		$manager = $this->getManager();
289
-		$comments = $manager->getForObject('files', 'file64', 0, 0, new \DateTime('-4 hours'));
290
-
291
-		$this->assertCount(2, $comments);
292
-		$this->assertSame((string)$id2, $comments[0]->getId());
293
-		$this->assertSame((string)$id1, $comments[1]->getId());
294
-	}
295
-
296
-	public function testGetForObjectWithLimitAndOffsetAndDateTimeConstraint(): void {
297
-		$this->addDatabaseEntry(0, 0, new \DateTime('-7 hours'));
298
-		$this->addDatabaseEntry(0, 0, new \DateTime('-6 hours'));
299
-		$this->addDatabaseEntry(1, 1, new \DateTime('-5 hours'));
300
-		$this->addDatabaseEntry(0, 0, new \DateTime('-3 hours'));
301
-		$this->addDatabaseEntry(2, 2, new \DateTime('-2 hours'));
302
-		$this->addDatabaseEntry(2, 2, new \DateTime('-1 hours'));
303
-		$idToVerify = $this->addDatabaseEntry(3, 1, new \DateTime());
304
-
305
-		$manager = $this->getManager();
306
-		$offset = 0;
307
-		do {
308
-			$comments = $manager->getForObject('files', 'file64', 3, $offset, new \DateTime('-4 hours'));
309
-
310
-			$this->assertIsArray($comments);
311
-			foreach ($comments as $comment) {
312
-				$this->assertInstanceOf(IComment::class, $comment);
313
-				$this->assertSame('nice one', $comment->getMessage());
314
-				$this->assertSame((string)$idToVerify, $comment->getId());
315
-				$this->assertGreaterThanOrEqual(4, $comment->getId());
316
-				$idToVerify--;
317
-			}
318
-			$offset += 3;
319
-		} while (count($comments) > 0);
320
-	}
321
-
322
-	public function testGetNumberOfCommentsForObject(): void {
323
-		for ($i = 1; $i < 5; $i++) {
324
-			$this->addDatabaseEntry(0, 0);
325
-		}
326
-
327
-		$manager = $this->getManager();
328
-
329
-		$amount = $manager->getNumberOfCommentsForObject('untype', '00');
330
-		$this->assertSame(0, $amount);
331
-
332
-		$amount = $manager->getNumberOfCommentsForObject('files', 'file64');
333
-		$this->assertSame(4, $amount);
334
-	}
335
-
336
-	public function testGetNumberOfUnreadCommentsForFolder(): void {
337
-		$folder = $this->createMock(Folder::class);
338
-		$fileIds = range(1111, 1114);
339
-		$children = array_map(function (int $id) {
340
-			$file = $this->createMock(Folder::class);
341
-			$file->method('getId')
342
-				->willReturn($id);
343
-			return $file;
344
-		}, $fileIds);
345
-		$folder->method('getId')->willReturn(1000);
346
-		$folder->method('getDirectoryListing')->willReturn($children);
347
-		$this->rootFolder->method('getFirstNodeById')
348
-			->with($folder->getId())
349
-			->willReturn($folder);
350
-
351
-		// 2 comment for 1111 with 1 before read marker
352
-		// 2 comments for 1112 with no read marker
353
-		// 1 comment for 1113 before read marker
354
-		// 1 comment for 1114 with no read marker
355
-		$this->addDatabaseEntry(0, 0, null, null, $fileIds[1]);
356
-		for ($i = 0; $i < 4; $i++) {
357
-			$this->addDatabaseEntry(0, 0, null, null, $fileIds[$i]);
358
-		}
359
-		$this->addDatabaseEntry(0, 0, (new \DateTime())->modify('-2 days'), null, $fileIds[0]);
360
-		/** @var IUser|\PHPUnit\Framework\MockObject\MockObject $user */
361
-		$user = $this->createMock(IUser::class);
362
-		$user->expects($this->any())
363
-			->method('getUID')
364
-			->willReturn('comment_test');
365
-
366
-		$manager = $this->getManager();
367
-
368
-		$manager->setReadMark('files', (string)$fileIds[0], (new \DateTime())->modify('-1 days'), $user);
369
-		$manager->setReadMark('files', (string)$fileIds[2], (new \DateTime()), $user);
370
-
371
-		$amount = $manager->getNumberOfUnreadCommentsForFolder($folder->getId(), $user);
372
-		$this->assertEquals([
373
-			$fileIds[0] => 1,
374
-			$fileIds[1] => 2,
375
-			$fileIds[3] => 1,
376
-		], $amount);
377
-	}
378
-
379
-	/**
380
-	 * @dataProvider dataGetForObjectSince
381
-	 */
382
-	public function testGetForObjectSince(?int $lastKnown, string $order, int $limit, int $resultFrom, int $resultTo): void {
383
-		$ids = [];
384
-		$ids[] = $this->addDatabaseEntry(0, 0);
385
-		$ids[] = $this->addDatabaseEntry(0, 0);
386
-		$ids[] = $this->addDatabaseEntry(0, 0);
387
-		$ids[] = $this->addDatabaseEntry(0, 0);
388
-		$ids[] = $this->addDatabaseEntry(0, 0);
389
-
390
-		$manager = $this->getManager();
391
-		$comments = $manager->getForObjectSince('files', 'file64', ($lastKnown === null ? 0 : $ids[$lastKnown]), $order, $limit);
392
-
393
-		$expected = array_slice($ids, $resultFrom, $resultTo - $resultFrom + 1);
394
-		if ($order === 'desc') {
395
-			$expected = array_reverse($expected);
396
-		}
397
-
398
-		$this->assertSame($expected, array_map(static fn (IComment $c): int => (int)$c->getId(), $comments));
399
-	}
400
-
401
-	public static function dataGetForObjectSince(): array {
402
-		return [
403
-			[null, 'asc', 20, 0, 4],
404
-			[null, 'asc', 2, 0, 1],
405
-			[null, 'desc', 20, 0, 4],
406
-			[null, 'desc', 2, 3, 4],
407
-			[1, 'asc', 20, 2, 4],
408
-			[1, 'asc', 2, 2, 3],
409
-			[3, 'desc', 20, 0, 2],
410
-			[3, 'desc', 2, 1, 2],
411
-		];
412
-	}
413
-
414
-	public static function invalidCreateArgsProvider(): array {
415
-		return [
416
-			['', 'aId-1', 'oType-1', 'oId-1'],
417
-			['aType-1', '', 'oType-1', 'oId-1'],
418
-			['aType-1', 'aId-1', '', 'oId-1'],
419
-			['aType-1', 'aId-1', 'oType-1', ''],
420
-			[1, 'aId-1', 'oType-1', 'oId-1'],
421
-			['aType-1', 1, 'oType-1', 'oId-1'],
422
-			['aType-1', 'aId-1', 1, 'oId-1'],
423
-			['aType-1', 'aId-1', 'oType-1', 1],
424
-		];
425
-	}
426
-
427
-	/**
428
-	 * @dataProvider invalidCreateArgsProvider
429
-	 */
430
-	public function testCreateCommentInvalidArguments(string|int $aType, string|int $aId, string|int $oType, string|int $oId): void {
431
-		$this->expectException(\InvalidArgumentException::class);
432
-
433
-		$manager = $this->getManager();
434
-		$manager->create($aType, $aId, $oType, $oId);
435
-	}
436
-
437
-	public function testCreateComment(): void {
438
-		$actorType = 'bot';
439
-		$actorId = 'bob';
440
-		$objectType = 'weather';
441
-		$objectId = 'bielefeld';
442
-
443
-		$comment = $this->getManager()->create($actorType, $actorId, $objectType, $objectId);
444
-		$this->assertInstanceOf(IComment::class, $comment);
445
-		$this->assertSame($actorType, $comment->getActorType());
446
-		$this->assertSame($actorId, $comment->getActorId());
447
-		$this->assertSame($objectType, $comment->getObjectType());
448
-		$this->assertSame($objectId, $comment->getObjectId());
449
-	}
450
-
451
-
452
-	public function testDelete(): void {
453
-		$this->expectException(\OCP\Comments\NotFoundException::class);
454
-
455
-		$manager = $this->getManager();
456
-
457
-		$done = $manager->delete('404');
458
-		$this->assertFalse($done);
459
-
460
-		$done = $manager->delete('%');
461
-		$this->assertFalse($done);
462
-
463
-		$done = $manager->delete('');
464
-		$this->assertFalse($done);
465
-
466
-		$id = (string)$this->addDatabaseEntry(0, 0);
467
-		$comment = $manager->get($id);
468
-		$this->assertInstanceOf(IComment::class, $comment);
469
-		$done = $manager->delete($id);
470
-		$this->assertTrue($done);
471
-		$manager->get($id);
472
-	}
473
-
474
-	/**
475
-	 * @dataProvider providerTestSave
476
-	 */
477
-	public function testSave(string $message, string $actorId, string $verb, ?string $parentId, ?string $id = ''): IComment {
478
-		$manager = $this->getManager();
479
-		$comment = new Comment();
480
-		$comment
481
-			->setId($id)
482
-			->setActor('users', $actorId)
483
-			->setObject('files', 'file64')
484
-			->setMessage($message)
485
-			->setVerb($verb);
486
-		if ($parentId) {
487
-			$comment->setParentId($parentId);
488
-		}
489
-
490
-		$saveSuccessful = $manager->save($comment);
491
-		$this->assertTrue($saveSuccessful, 'Comment saving was not successful');
492
-		$this->assertNotEquals('', $comment->getId(), 'Comment ID should not be empty');
493
-		$this->assertNotEquals('0', $comment->getId(), 'Comment ID should not be string \'0\'');
494
-		$this->assertNotNull($comment->getCreationDateTime(), 'Comment creation date should not be null');
495
-
496
-		$loadedComment = $manager->get($comment->getId());
497
-		$this->assertSame($comment->getMessage(), $loadedComment->getMessage(), 'Comment message should match');
498
-		$this->assertEquals($comment->getCreationDateTime()->getTimestamp(), $loadedComment->getCreationDateTime()->getTimestamp(), 'Comment creation date should match');
499
-		return $comment;
500
-	}
501
-
502
-	public static function providerTestSave(): array {
503
-		return [
504
-			['very beautiful, I am impressed!', 'alice', 'comment', null],
505
-		];
506
-	}
507
-
508
-	public function testSaveUpdate(): void {
509
-		$manager = $this->getManager();
510
-		$comment = new Comment();
511
-		$comment
512
-			->setActor('users', 'alice')
513
-			->setObject('files', 'file64')
514
-			->setMessage('very beautiful, I am impressed!')
515
-			->setVerb('comment')
516
-			->setExpireDate(new \DateTime('+2 hours'));
517
-
518
-		$manager->save($comment);
519
-
520
-		$loadedComment = $manager->get($comment->getId());
521
-		// Compare current object with database values
522
-		$this->assertSame($comment->getMessage(), $loadedComment->getMessage());
523
-		$this->assertSame(
524
-			$comment->getExpireDate()->format('Y-m-d H:i:s'),
525
-			$loadedComment->getExpireDate()->format('Y-m-d H:i:s')
526
-		);
527
-
528
-		// Preserve the original comment to compare after update
529
-		$original = clone $comment;
530
-
531
-		// Update values
532
-		$comment->setMessage('very beautiful, I am really so much impressed!')
533
-			->setExpireDate(new \DateTime('+1 hours'));
534
-		$manager->save($comment);
535
-
536
-		$loadedComment = $manager->get($comment->getId());
537
-		// Compare current object with database values
538
-		$this->assertSame($comment->getMessage(), $loadedComment->getMessage());
539
-		$this->assertSame(
540
-			$comment->getExpireDate()->format('Y-m-d H:i:s'),
541
-			$loadedComment->getExpireDate()->format('Y-m-d H:i:s')
542
-		);
543
-
544
-		// Compare original object with database values
545
-		$this->assertNotSame($original->getMessage(), $loadedComment->getMessage());
546
-		$this->assertNotSame(
547
-			$original->getExpireDate()->format('Y-m-d H:i:s'),
548
-			$loadedComment->getExpireDate()->format('Y-m-d H:i:s')
549
-		);
550
-	}
551
-
552
-
553
-	public function testSaveUpdateException(): void {
554
-		$manager = $this->getManager();
555
-		$comment = new Comment();
556
-		$comment
557
-			->setActor('users', 'alice')
558
-			->setObject('files', 'file64')
559
-			->setMessage('very beautiful, I am impressed!')
560
-			->setVerb('comment');
561
-
562
-		$manager->save($comment);
563
-
564
-		$manager->delete($comment->getId());
565
-
566
-		$comment->setMessage('very beautiful, I am really so much impressed!');
567
-		$this->expectException(\OCP\Comments\NotFoundException::class);
568
-		$manager->save($comment);
569
-	}
570
-
571
-
572
-	public function testSaveIncomplete(): void {
573
-
574
-		$manager = $this->getManager();
575
-		$comment = new Comment();
576
-		$comment->setMessage('from no one to nothing');
577
-
578
-		$this->expectException(\UnexpectedValueException::class);
579
-		$manager->save($comment);
580
-	}
581
-
582
-	public function testSaveAsChild(): void {
583
-		$id = (string)$this->addDatabaseEntry(0, 0);
584
-
585
-		$manager = $this->getManager();
586
-
587
-		for ($i = 0; $i < 3; $i++) {
588
-			$comment = new Comment();
589
-			$comment
590
-				->setActor('users', 'alice')
591
-				->setObject('files', 'file64')
592
-				->setParentId($id)
593
-				->setMessage('full ack')
594
-				->setVerb('comment')
595
-				// setting the creation time avoids using sleep() while making sure to test with different timestamps
596
-				->setCreationDateTime(new \DateTime('+' . $i . ' minutes'));
597
-
598
-			$manager->save($comment);
599
-
600
-			$this->assertSame($id, $comment->getTopmostParentId());
601
-			$parentComment = $manager->get($id);
602
-			$this->assertSame($i + 1, $parentComment->getChildrenCount());
603
-			$this->assertEquals($comment->getCreationDateTime()->getTimestamp(), $parentComment->getLatestChildDateTime()->getTimestamp());
604
-		}
605
-	}
606
-
607
-	public static function invalidActorArgsProvider(): array {
608
-		return
609
-			[
610
-				['', ''],
611
-				[1, 'alice'],
612
-				['users', 1],
613
-			];
614
-	}
615
-
616
-	/**
617
-	 * @dataProvider invalidActorArgsProvider
618
-	 */
619
-	public function testDeleteReferencesOfActorInvalidInput(string|int $type, string|int $id): void {
620
-		$this->expectException(\InvalidArgumentException::class);
621
-
622
-		$manager = $this->getManager();
623
-		$manager->deleteReferencesOfActor($type, $id);
624
-	}
625
-
626
-	public function testDeleteReferencesOfActor(): void {
627
-		$ids = [];
628
-		$ids[] = $this->addDatabaseEntry(0, 0);
629
-		$ids[] = $this->addDatabaseEntry(0, 0);
630
-		$ids[] = $this->addDatabaseEntry(0, 0);
631
-
632
-		$manager = $this->getManager();
633
-
634
-		// just to make sure they are really set, with correct actor data
635
-		$comment = $manager->get((string)$ids[1]);
636
-		$this->assertSame('users', $comment->getActorType());
637
-		$this->assertSame('alice', $comment->getActorId());
638
-
639
-		$wasSuccessful = $manager->deleteReferencesOfActor('users', 'alice');
640
-		$this->assertTrue($wasSuccessful);
641
-
642
-		foreach ($ids as $id) {
643
-			$comment = $manager->get((string)$id);
644
-			$this->assertSame(ICommentsManager::DELETED_USER, $comment->getActorType());
645
-			$this->assertSame(ICommentsManager::DELETED_USER, $comment->getActorId());
646
-		}
647
-
648
-		// actor info is gone from DB, but when database interaction is alright,
649
-		// we still expect to get true back
650
-		$wasSuccessful = $manager->deleteReferencesOfActor('users', 'alice');
651
-		$this->assertTrue($wasSuccessful);
652
-	}
653
-
654
-	public function testDeleteReferencesOfActorWithUserManagement(): void {
655
-		$user = \OCP\Server::get(IUserManager::class)->createUser('xenia', 'NotAnEasyPassword123456+');
656
-		$this->assertInstanceOf(IUser::class, $user);
657
-
658
-		$manager = \OCP\Server::get(ICommentsManager::class);
659
-		$comment = $manager->create('users', $user->getUID(), 'files', 'file64');
660
-		$comment
661
-			->setMessage('Most important comment I ever left on the Internet.')
662
-			->setVerb('comment');
663
-		$status = $manager->save($comment);
664
-		$this->assertTrue($status);
665
-
666
-		$commentID = $comment->getId();
667
-		$user->delete();
668
-
669
-		$comment = $manager->get($commentID);
670
-		$this->assertSame(ICommentsManager::DELETED_USER, $comment->getActorType());
671
-		$this->assertSame(ICommentsManager::DELETED_USER, $comment->getActorId());
672
-	}
673
-
674
-	public static function invalidObjectArgsProvider(): array {
675
-		return
676
-			[
677
-				['', ''],
678
-				[1, 'file64'],
679
-				['files', 1],
680
-			];
681
-	}
682
-
683
-	/**
684
-	 * @dataProvider invalidObjectArgsProvider
685
-	 */
686
-	public function testDeleteCommentsAtObjectInvalidInput(string|int $type, string|int $id): void {
687
-		$this->expectException(\InvalidArgumentException::class);
688
-
689
-		$manager = $this->getManager();
690
-		$manager->deleteCommentsAtObject($type, $id);
691
-	}
692
-
693
-	public function testDeleteCommentsAtObject(): void {
694
-		$ids = [];
695
-		$ids[] = $this->addDatabaseEntry(0, 0);
696
-		$ids[] = $this->addDatabaseEntry(0, 0);
697
-		$ids[] = $this->addDatabaseEntry(0, 0);
698
-
699
-		$manager = $this->getManager();
700
-
701
-		// just to make sure they are really set, with correct actor data
702
-		$comment = $manager->get((string)$ids[1]);
703
-		$this->assertSame('files', $comment->getObjectType());
704
-		$this->assertSame('file64', $comment->getObjectId());
705
-
706
-		$wasSuccessful = $manager->deleteCommentsAtObject('files', 'file64');
707
-		$this->assertTrue($wasSuccessful);
708
-
709
-		$verified = 0;
710
-		foreach ($ids as $id) {
711
-			try {
712
-				$manager->get((string)$id);
713
-			} catch (NotFoundException) {
714
-				$verified++;
715
-			}
716
-		}
717
-		$this->assertSame(3, $verified);
718
-
719
-		// actor info is gone from DB, but when database interaction is alright,
720
-		// we still expect to get true back
721
-		$wasSuccessful = $manager->deleteCommentsAtObject('files', 'file64');
722
-		$this->assertTrue($wasSuccessful);
723
-	}
724
-
725
-	public function testDeleteCommentsExpiredAtObjectTypeAndId(): void {
726
-		$ids = [];
727
-		$ids[] = $this->addDatabaseEntry(0, 0, null, null, null, new \DateTime('+2 hours'));
728
-		$ids[] = $this->addDatabaseEntry(0, 0, null, null, null, new \DateTime('+2 hours'));
729
-		$ids[] = $this->addDatabaseEntry(0, 0, null, null, null, new \DateTime('+2 hours'));
730
-		$ids[] = $this->addDatabaseEntry(0, 0, null, null, null, new \DateTime('-2 hours'));
731
-		$ids[] = $this->addDatabaseEntry(0, 0, null, null, null, new \DateTime('-2 hours'));
732
-		$ids[] = $this->addDatabaseEntry(0, 0, null, null, null, new \DateTime('-2 hours'));
733
-
734
-		$manager = new Manager(
735
-			$this->connection,
736
-			$this->createMock(LoggerInterface::class),
737
-			$this->createMock(IConfig::class),
738
-			Server::get(ITimeFactory::class),
739
-			new EmojiHelper($this->connection),
740
-			$this->createMock(IInitialStateService::class),
741
-			$this->rootFolder,
742
-			$this->createMock(IEventDispatcher::class)
743
-		);
744
-
745
-		// just to make sure they are really set, with correct actor data
746
-		$comment = $manager->get((string)$ids[1]);
747
-		$this->assertSame('files', $comment->getObjectType());
748
-		$this->assertSame('file64', $comment->getObjectId());
749
-
750
-		$deleted = $manager->deleteCommentsExpiredAtObject('files', 'file64');
751
-		$this->assertTrue($deleted);
752
-
753
-		$deleted = 0;
754
-		$exists = 0;
755
-		foreach ($ids as $id) {
756
-			try {
757
-				$manager->get((string)$id);
758
-				$exists++;
759
-			} catch (NotFoundException) {
760
-				$deleted++;
761
-			}
762
-		}
763
-		$this->assertSame(3, $exists);
764
-		$this->assertSame(3, $deleted);
765
-
766
-		// actor info is gone from DB, but when database interaction is alright,
767
-		// we still expect to get true back
768
-		$deleted = $manager->deleteCommentsExpiredAtObject('files', 'file64');
769
-		$this->assertFalse($deleted);
770
-	}
771
-
772
-	public function testDeleteCommentsExpiredAtObjectType(): void {
773
-		$ids = [];
774
-		$ids[] = $this->addDatabaseEntry(0, 0, null, null, 'file1', new \DateTime('-2 hours'));
775
-		$ids[] = $this->addDatabaseEntry(0, 0, null, null, 'file2', new \DateTime('-2 hours'));
776
-		$ids[] = $this->addDatabaseEntry(0, 0, null, null, 'file3', new \DateTime('-2 hours'));
777
-		$ids[] = $this->addDatabaseEntry(0, 0, null, null, 'file3', new \DateTime());
778
-		$ids[] = $this->addDatabaseEntry(0, 0, null, null, 'file3', new \DateTime());
779
-		$ids[] = $this->addDatabaseEntry(0, 0, null, null, 'file3', new \DateTime());
780
-
781
-		$manager = new Manager(
782
-			$this->connection,
783
-			$this->createMock(LoggerInterface::class),
784
-			$this->createMock(IConfig::class),
785
-			Server::get(ITimeFactory::class),
786
-			new EmojiHelper($this->connection),
787
-			$this->createMock(IInitialStateService::class),
788
-			$this->rootFolder,
789
-			$this->createMock(IEventDispatcher::class)
790
-		);
791
-
792
-		$deleted = $manager->deleteCommentsExpiredAtObject('files');
793
-		$this->assertTrue($deleted);
794
-
795
-		$deleted = 0;
796
-		$exists = 0;
797
-		foreach ($ids as $id) {
798
-			try {
799
-				$manager->get((string)$id);
800
-				$exists++;
801
-			} catch (NotFoundException) {
802
-				$deleted++;
803
-			}
804
-		}
805
-		$this->assertSame(0, $exists);
806
-		$this->assertSame(6, $deleted);
807
-
808
-		// actor info is gone from DB, but when database interaction is alright,
809
-		// we still expect to get true back
810
-		$deleted = $manager->deleteCommentsExpiredAtObject('files');
811
-		$this->assertFalse($deleted);
812
-	}
813
-
814
-	public function testSetMarkRead(): void {
815
-		/** @var IUser|\PHPUnit\Framework\MockObject\MockObject $user */
816
-		$user = $this->createMock(IUser::class);
817
-		$user->expects($this->any())
818
-			->method('getUID')
819
-			->willReturn('alice');
820
-
821
-		$dateTimeSet = new \DateTime();
822
-
823
-		$manager = $this->getManager();
824
-		$manager->setReadMark('robot', '36', $dateTimeSet, $user);
825
-
826
-		$dateTimeGet = $manager->getReadMark('robot', '36', $user);
827
-
828
-		$this->assertEquals($dateTimeSet->getTimestamp(), $dateTimeGet->getTimestamp());
829
-	}
830
-
831
-	public function testSetMarkReadUpdate(): void {
832
-		/** @var IUser|\PHPUnit\Framework\MockObject\MockObject $user */
833
-		$user = $this->createMock(IUser::class);
834
-		$user->expects($this->any())
835
-			->method('getUID')
836
-			->willReturn('alice');
837
-
838
-		$dateTimeSet = new \DateTime('yesterday');
839
-
840
-		$manager = $this->getManager();
841
-		$manager->setReadMark('robot', '36', $dateTimeSet, $user);
842
-
843
-		$dateTimeSet = new \DateTime('today');
844
-		$manager->setReadMark('robot', '36', $dateTimeSet, $user);
845
-
846
-		$dateTimeGet = $manager->getReadMark('robot', '36', $user);
847
-
848
-		$this->assertEquals($dateTimeSet, $dateTimeGet);
849
-	}
850
-
851
-	public function testReadMarkDeleteUser(): void {
852
-		/** @var IUser|\PHPUnit\Framework\MockObject\MockObject $user */
853
-		$user = $this->createMock(IUser::class);
854
-		$user->expects($this->any())
855
-			->method('getUID')
856
-			->willReturn('alice');
857
-
858
-		$dateTimeSet = new \DateTime();
859
-
860
-		$manager = $this->getManager();
861
-		$manager->setReadMark('robot', '36', $dateTimeSet, $user);
862
-
863
-		$manager->deleteReadMarksFromUser($user);
864
-		$dateTimeGet = $manager->getReadMark('robot', '36', $user);
865
-
866
-		$this->assertNull($dateTimeGet);
867
-	}
868
-
869
-	public function testReadMarkDeleteObject(): void {
870
-		/** @var IUser|\PHPUnit\Framework\MockObject\MockObject $user */
871
-		$user = $this->createMock(IUser::class);
872
-		$user->expects($this->any())
873
-			->method('getUID')
874
-			->willReturn('alice');
38
+    /** @var IDBConnection */
39
+    private $connection;
40
+    /** @var \PHPUnit\Framework\MockObject\MockObject|IRootFolder */
41
+    private $rootFolder;
42
+
43
+    protected function setUp(): void {
44
+        parent::setUp();
45
+
46
+        $this->connection = \OC::$server->getDatabaseConnection();
47
+        $this->rootFolder = $this->createMock(IRootFolder::class);
48
+
49
+        $sql = $this->connection->getDatabasePlatform()->getTruncateTableSQL('`*PREFIX*comments`');
50
+        $this->connection->prepare($sql)->execute();
51
+        $sql = $this->connection->getDatabasePlatform()->getTruncateTableSQL('`*PREFIX*reactions`');
52
+        $this->connection->prepare($sql)->execute();
53
+    }
54
+
55
+    protected function addDatabaseEntry($parentId, $topmostParentId, $creationDT = null, $latestChildDT = null, $objectId = null, $expireDate = null) {
56
+        $creationDT ??= new \DateTime();
57
+        $latestChildDT ??= new \DateTime('yesterday');
58
+        $objectId ??= 'file64';
59
+
60
+        $qb = $this->connection->getQueryBuilder();
61
+        $qb
62
+            ->insert('comments')
63
+            ->values([
64
+                'parent_id' => $qb->createNamedParameter($parentId),
65
+                'topmost_parent_id' => $qb->createNamedParameter($topmostParentId),
66
+                'children_count' => $qb->createNamedParameter(2),
67
+                'actor_type' => $qb->createNamedParameter('users'),
68
+                'actor_id' => $qb->createNamedParameter('alice'),
69
+                'message' => $qb->createNamedParameter('nice one'),
70
+                'verb' => $qb->createNamedParameter('comment'),
71
+                'creation_timestamp' => $qb->createNamedParameter($creationDT, IQueryBuilder::PARAM_DATETIME_MUTABLE),
72
+                'latest_child_timestamp' => $qb->createNamedParameter($latestChildDT, IQueryBuilder::PARAM_DATETIME_MUTABLE),
73
+                'object_type' => $qb->createNamedParameter('files'),
74
+                'object_id' => $qb->createNamedParameter($objectId),
75
+                'expire_date' => $qb->createNamedParameter($expireDate, IQueryBuilder::PARAM_DATETIME_MUTABLE),
76
+                'reference_id' => $qb->createNamedParameter('referenceId'),
77
+                'meta_data' => $qb->createNamedParameter(json_encode(['last_edit_actor_id' => 'admin'])),
78
+            ])
79
+            ->executeStatement();
80
+
81
+        return $qb->getLastInsertId();
82
+    }
83
+
84
+    protected function getManager() {
85
+        return new Manager(
86
+            $this->connection,
87
+            $this->createMock(LoggerInterface::class),
88
+            $this->createMock(IConfig::class),
89
+            $this->createMock(ITimeFactory::class),
90
+            new EmojiHelper($this->connection),
91
+            $this->createMock(IInitialStateService::class),
92
+            $this->rootFolder,
93
+            $this->createMock(IEventDispatcher::class),
94
+        );
95
+    }
96
+
97
+
98
+    public function testGetCommentNotFound(): void {
99
+        $this->expectException(\OCP\Comments\NotFoundException::class);
100
+
101
+        $manager = $this->getManager();
102
+        $manager->get('22');
103
+    }
104
+
105
+
106
+    public function testGetCommentNotFoundInvalidInput(): void {
107
+        $this->expectException(\InvalidArgumentException::class);
108
+
109
+        $manager = $this->getManager();
110
+        $manager->get('unexisting22');
111
+    }
112
+
113
+    public function testGetComment(): void {
114
+        $manager = $this->getManager();
115
+
116
+        $creationDT = new \DateTime('yesterday');
117
+        $latestChildDT = new \DateTime();
118
+
119
+        $qb = \OCP\Server::get(IDBConnection::class)->getQueryBuilder();
120
+        $qb
121
+            ->insert('comments')
122
+            ->values([
123
+                'parent_id' => $qb->createNamedParameter('2'),
124
+                'topmost_parent_id' => $qb->createNamedParameter('1'),
125
+                'children_count' => $qb->createNamedParameter(2),
126
+                'actor_type' => $qb->createNamedParameter('users'),
127
+                'actor_id' => $qb->createNamedParameter('alice'),
128
+                'message' => $qb->createNamedParameter('nice one'),
129
+                'verb' => $qb->createNamedParameter('comment'),
130
+                'creation_timestamp' => $qb->createNamedParameter($creationDT, 'datetime'),
131
+                'latest_child_timestamp' => $qb->createNamedParameter($latestChildDT, 'datetime'),
132
+                'object_type' => $qb->createNamedParameter('files'),
133
+                'object_id' => $qb->createNamedParameter('file64'),
134
+                'reference_id' => $qb->createNamedParameter('referenceId'),
135
+                'meta_data' => $qb->createNamedParameter(json_encode(['last_edit_actor_id' => 'admin'])),
136
+            ])
137
+            ->executeStatement();
138
+
139
+        $id = (string)$qb->getLastInsertId();
140
+
141
+        $comment = $manager->get($id);
142
+        $this->assertInstanceOf(IComment::class, $comment);
143
+        $this->assertSame($id, $comment->getId());
144
+        $this->assertSame('2', $comment->getParentId());
145
+        $this->assertSame('1', $comment->getTopmostParentId());
146
+        $this->assertSame(2, $comment->getChildrenCount());
147
+        $this->assertSame('users', $comment->getActorType());
148
+        $this->assertSame('alice', $comment->getActorId());
149
+        $this->assertSame('nice one', $comment->getMessage());
150
+        $this->assertSame('comment', $comment->getVerb());
151
+        $this->assertSame('files', $comment->getObjectType());
152
+        $this->assertSame('file64', $comment->getObjectId());
153
+        $this->assertEquals($creationDT->getTimestamp(), $comment->getCreationDateTime()->getTimestamp());
154
+        $this->assertEquals($latestChildDT->getTimestamp(), $comment->getLatestChildDateTime()->getTimestamp());
155
+        $this->assertEquals('referenceId', $comment->getReferenceId());
156
+        $this->assertEquals(['last_edit_actor_id' => 'admin'], $comment->getMetaData());
157
+    }
158
+
159
+
160
+    public function testGetTreeNotFound(): void {
161
+        $this->expectException(\OCP\Comments\NotFoundException::class);
162
+
163
+        $manager = $this->getManager();
164
+        $manager->getTree('22');
165
+    }
166
+
167
+
168
+    public function testGetTreeNotFoundInvalidIpnut(): void {
169
+        $this->expectException(\InvalidArgumentException::class);
170
+
171
+        $manager = $this->getManager();
172
+        $manager->getTree('unexisting22');
173
+    }
174
+
175
+    public function testGetTree(): void {
176
+        $headId = $this->addDatabaseEntry(0, 0);
177
+
178
+        $this->addDatabaseEntry($headId, $headId, new \DateTime('-3 hours'));
179
+        $this->addDatabaseEntry($headId, $headId, new \DateTime('-2 hours'));
180
+        $id = $this->addDatabaseEntry($headId, $headId, new \DateTime('-1 hour'));
181
+
182
+        $manager = $this->getManager();
183
+        $tree = $manager->getTree($headId);
184
+
185
+        // Verifying the root comment
186
+        $this->assertArrayHasKey('comment', $tree);
187
+        $this->assertInstanceOf(IComment::class, $tree['comment']);
188
+        $this->assertSame((string)$headId, $tree['comment']->getId());
189
+        $this->assertArrayHasKey('replies', $tree);
190
+        $this->assertCount(3, $tree['replies']);
191
+
192
+        // one level deep
193
+        foreach ($tree['replies'] as $reply) {
194
+            $this->assertInstanceOf(IComment::class, $reply['comment']);
195
+            $this->assertSame((string)$id, $reply['comment']->getId());
196
+            $this->assertCount(0, $reply['replies']);
197
+            $id--;
198
+        }
199
+    }
200
+
201
+    public function testGetTreeNoReplies(): void {
202
+        $id = $this->addDatabaseEntry(0, 0);
203
+
204
+        $manager = $this->getManager();
205
+        $tree = $manager->getTree($id);
206
+
207
+        // Verifying the root comment
208
+        $this->assertArrayHasKey('comment', $tree);
209
+        $this->assertInstanceOf(IComment::class, $tree['comment']);
210
+        $this->assertSame((string)$id, $tree['comment']->getId());
211
+        $this->assertArrayHasKey('replies', $tree);
212
+        $this->assertCount(0, $tree['replies']);
213
+    }
214
+
215
+    public function testGetTreeWithLimitAndOffset(): void {
216
+        $headId = $this->addDatabaseEntry(0, 0);
217
+
218
+        $this->addDatabaseEntry($headId, $headId, new \DateTime('-3 hours'));
219
+        $this->addDatabaseEntry($headId, $headId, new \DateTime('-2 hours'));
220
+        $this->addDatabaseEntry($headId, $headId, new \DateTime('-1 hour'));
221
+        $idToVerify = $this->addDatabaseEntry($headId, $headId, new \DateTime());
222
+
223
+        $manager = $this->getManager();
224
+
225
+        for ($offset = 0; $offset < 3; $offset += 2) {
226
+            $tree = $manager->getTree((string)$headId, 2, $offset);
227
+
228
+            // Verifying the root comment
229
+            $this->assertArrayHasKey('comment', $tree);
230
+            $this->assertInstanceOf(IComment::class, $tree['comment']);
231
+            $this->assertSame((string)$headId, $tree['comment']->getId());
232
+            $this->assertArrayHasKey('replies', $tree);
233
+            $this->assertCount(2, $tree['replies']);
234
+
235
+            // one level deep
236
+            foreach ($tree['replies'] as $reply) {
237
+                $this->assertInstanceOf(IComment::class, $reply['comment']);
238
+                $this->assertSame((string)$idToVerify, $reply['comment']->getId());
239
+                $this->assertCount(0, $reply['replies']);
240
+                $idToVerify--;
241
+            }
242
+        }
243
+    }
244
+
245
+    public function testGetForObject(): void {
246
+        $this->addDatabaseEntry(0, 0);
247
+
248
+        $manager = $this->getManager();
249
+        $comments = $manager->getForObject('files', 'file64');
250
+
251
+        $this->assertIsArray($comments);
252
+        $this->assertCount(1, $comments);
253
+        $this->assertInstanceOf(IComment::class, $comments[0]);
254
+        $this->assertSame('nice one', $comments[0]->getMessage());
255
+    }
256
+
257
+    public function testGetForObjectWithLimitAndOffset(): void {
258
+        $this->addDatabaseEntry(0, 0, new \DateTime('-6 hours'));
259
+        $this->addDatabaseEntry(0, 0, new \DateTime('-5 hours'));
260
+        $this->addDatabaseEntry(1, 1, new \DateTime('-4 hours'));
261
+        $this->addDatabaseEntry(0, 0, new \DateTime('-3 hours'));
262
+        $this->addDatabaseEntry(2, 2, new \DateTime('-2 hours'));
263
+        $this->addDatabaseEntry(2, 2, new \DateTime('-1 hours'));
264
+        $idToVerify = $this->addDatabaseEntry(3, 1, new \DateTime());
265
+
266
+        $manager = $this->getManager();
267
+        $offset = 0;
268
+        do {
269
+            $comments = $manager->getForObject('files', 'file64', 3, $offset);
270
+
271
+            $this->assertIsArray($comments);
272
+            foreach ($comments as $key => $comment) {
273
+                $this->assertInstanceOf(IComment::class, $comment);
274
+                $this->assertSame('nice one', $comment->getMessage());
275
+                $this->assertSame((string)$idToVerify, $comment->getId(), 'ID wrong for comment ' . $key . ' on offset: ' . $offset);
276
+                $idToVerify--;
277
+            }
278
+            $offset += 3;
279
+        } while (count($comments) > 0);
280
+    }
281
+
282
+    public function testGetForObjectWithDateTimeConstraint(): void {
283
+        $this->addDatabaseEntry(0, 0, new \DateTime('-6 hours'));
284
+        $this->addDatabaseEntry(0, 0, new \DateTime('-5 hours'));
285
+        $id1 = $this->addDatabaseEntry(0, 0, new \DateTime('-3 hours'));
286
+        $id2 = $this->addDatabaseEntry(2, 2, new \DateTime('-2 hours'));
287
+
288
+        $manager = $this->getManager();
289
+        $comments = $manager->getForObject('files', 'file64', 0, 0, new \DateTime('-4 hours'));
290
+
291
+        $this->assertCount(2, $comments);
292
+        $this->assertSame((string)$id2, $comments[0]->getId());
293
+        $this->assertSame((string)$id1, $comments[1]->getId());
294
+    }
295
+
296
+    public function testGetForObjectWithLimitAndOffsetAndDateTimeConstraint(): void {
297
+        $this->addDatabaseEntry(0, 0, new \DateTime('-7 hours'));
298
+        $this->addDatabaseEntry(0, 0, new \DateTime('-6 hours'));
299
+        $this->addDatabaseEntry(1, 1, new \DateTime('-5 hours'));
300
+        $this->addDatabaseEntry(0, 0, new \DateTime('-3 hours'));
301
+        $this->addDatabaseEntry(2, 2, new \DateTime('-2 hours'));
302
+        $this->addDatabaseEntry(2, 2, new \DateTime('-1 hours'));
303
+        $idToVerify = $this->addDatabaseEntry(3, 1, new \DateTime());
304
+
305
+        $manager = $this->getManager();
306
+        $offset = 0;
307
+        do {
308
+            $comments = $manager->getForObject('files', 'file64', 3, $offset, new \DateTime('-4 hours'));
309
+
310
+            $this->assertIsArray($comments);
311
+            foreach ($comments as $comment) {
312
+                $this->assertInstanceOf(IComment::class, $comment);
313
+                $this->assertSame('nice one', $comment->getMessage());
314
+                $this->assertSame((string)$idToVerify, $comment->getId());
315
+                $this->assertGreaterThanOrEqual(4, $comment->getId());
316
+                $idToVerify--;
317
+            }
318
+            $offset += 3;
319
+        } while (count($comments) > 0);
320
+    }
321
+
322
+    public function testGetNumberOfCommentsForObject(): void {
323
+        for ($i = 1; $i < 5; $i++) {
324
+            $this->addDatabaseEntry(0, 0);
325
+        }
326
+
327
+        $manager = $this->getManager();
328
+
329
+        $amount = $manager->getNumberOfCommentsForObject('untype', '00');
330
+        $this->assertSame(0, $amount);
331
+
332
+        $amount = $manager->getNumberOfCommentsForObject('files', 'file64');
333
+        $this->assertSame(4, $amount);
334
+    }
335
+
336
+    public function testGetNumberOfUnreadCommentsForFolder(): void {
337
+        $folder = $this->createMock(Folder::class);
338
+        $fileIds = range(1111, 1114);
339
+        $children = array_map(function (int $id) {
340
+            $file = $this->createMock(Folder::class);
341
+            $file->method('getId')
342
+                ->willReturn($id);
343
+            return $file;
344
+        }, $fileIds);
345
+        $folder->method('getId')->willReturn(1000);
346
+        $folder->method('getDirectoryListing')->willReturn($children);
347
+        $this->rootFolder->method('getFirstNodeById')
348
+            ->with($folder->getId())
349
+            ->willReturn($folder);
350
+
351
+        // 2 comment for 1111 with 1 before read marker
352
+        // 2 comments for 1112 with no read marker
353
+        // 1 comment for 1113 before read marker
354
+        // 1 comment for 1114 with no read marker
355
+        $this->addDatabaseEntry(0, 0, null, null, $fileIds[1]);
356
+        for ($i = 0; $i < 4; $i++) {
357
+            $this->addDatabaseEntry(0, 0, null, null, $fileIds[$i]);
358
+        }
359
+        $this->addDatabaseEntry(0, 0, (new \DateTime())->modify('-2 days'), null, $fileIds[0]);
360
+        /** @var IUser|\PHPUnit\Framework\MockObject\MockObject $user */
361
+        $user = $this->createMock(IUser::class);
362
+        $user->expects($this->any())
363
+            ->method('getUID')
364
+            ->willReturn('comment_test');
365
+
366
+        $manager = $this->getManager();
367
+
368
+        $manager->setReadMark('files', (string)$fileIds[0], (new \DateTime())->modify('-1 days'), $user);
369
+        $manager->setReadMark('files', (string)$fileIds[2], (new \DateTime()), $user);
370
+
371
+        $amount = $manager->getNumberOfUnreadCommentsForFolder($folder->getId(), $user);
372
+        $this->assertEquals([
373
+            $fileIds[0] => 1,
374
+            $fileIds[1] => 2,
375
+            $fileIds[3] => 1,
376
+        ], $amount);
377
+    }
378
+
379
+    /**
380
+     * @dataProvider dataGetForObjectSince
381
+     */
382
+    public function testGetForObjectSince(?int $lastKnown, string $order, int $limit, int $resultFrom, int $resultTo): void {
383
+        $ids = [];
384
+        $ids[] = $this->addDatabaseEntry(0, 0);
385
+        $ids[] = $this->addDatabaseEntry(0, 0);
386
+        $ids[] = $this->addDatabaseEntry(0, 0);
387
+        $ids[] = $this->addDatabaseEntry(0, 0);
388
+        $ids[] = $this->addDatabaseEntry(0, 0);
389
+
390
+        $manager = $this->getManager();
391
+        $comments = $manager->getForObjectSince('files', 'file64', ($lastKnown === null ? 0 : $ids[$lastKnown]), $order, $limit);
392
+
393
+        $expected = array_slice($ids, $resultFrom, $resultTo - $resultFrom + 1);
394
+        if ($order === 'desc') {
395
+            $expected = array_reverse($expected);
396
+        }
397
+
398
+        $this->assertSame($expected, array_map(static fn (IComment $c): int => (int)$c->getId(), $comments));
399
+    }
400
+
401
+    public static function dataGetForObjectSince(): array {
402
+        return [
403
+            [null, 'asc', 20, 0, 4],
404
+            [null, 'asc', 2, 0, 1],
405
+            [null, 'desc', 20, 0, 4],
406
+            [null, 'desc', 2, 3, 4],
407
+            [1, 'asc', 20, 2, 4],
408
+            [1, 'asc', 2, 2, 3],
409
+            [3, 'desc', 20, 0, 2],
410
+            [3, 'desc', 2, 1, 2],
411
+        ];
412
+    }
413
+
414
+    public static function invalidCreateArgsProvider(): array {
415
+        return [
416
+            ['', 'aId-1', 'oType-1', 'oId-1'],
417
+            ['aType-1', '', 'oType-1', 'oId-1'],
418
+            ['aType-1', 'aId-1', '', 'oId-1'],
419
+            ['aType-1', 'aId-1', 'oType-1', ''],
420
+            [1, 'aId-1', 'oType-1', 'oId-1'],
421
+            ['aType-1', 1, 'oType-1', 'oId-1'],
422
+            ['aType-1', 'aId-1', 1, 'oId-1'],
423
+            ['aType-1', 'aId-1', 'oType-1', 1],
424
+        ];
425
+    }
426
+
427
+    /**
428
+     * @dataProvider invalidCreateArgsProvider
429
+     */
430
+    public function testCreateCommentInvalidArguments(string|int $aType, string|int $aId, string|int $oType, string|int $oId): void {
431
+        $this->expectException(\InvalidArgumentException::class);
432
+
433
+        $manager = $this->getManager();
434
+        $manager->create($aType, $aId, $oType, $oId);
435
+    }
436
+
437
+    public function testCreateComment(): void {
438
+        $actorType = 'bot';
439
+        $actorId = 'bob';
440
+        $objectType = 'weather';
441
+        $objectId = 'bielefeld';
442
+
443
+        $comment = $this->getManager()->create($actorType, $actorId, $objectType, $objectId);
444
+        $this->assertInstanceOf(IComment::class, $comment);
445
+        $this->assertSame($actorType, $comment->getActorType());
446
+        $this->assertSame($actorId, $comment->getActorId());
447
+        $this->assertSame($objectType, $comment->getObjectType());
448
+        $this->assertSame($objectId, $comment->getObjectId());
449
+    }
450
+
451
+
452
+    public function testDelete(): void {
453
+        $this->expectException(\OCP\Comments\NotFoundException::class);
454
+
455
+        $manager = $this->getManager();
456
+
457
+        $done = $manager->delete('404');
458
+        $this->assertFalse($done);
459
+
460
+        $done = $manager->delete('%');
461
+        $this->assertFalse($done);
462
+
463
+        $done = $manager->delete('');
464
+        $this->assertFalse($done);
465
+
466
+        $id = (string)$this->addDatabaseEntry(0, 0);
467
+        $comment = $manager->get($id);
468
+        $this->assertInstanceOf(IComment::class, $comment);
469
+        $done = $manager->delete($id);
470
+        $this->assertTrue($done);
471
+        $manager->get($id);
472
+    }
473
+
474
+    /**
475
+     * @dataProvider providerTestSave
476
+     */
477
+    public function testSave(string $message, string $actorId, string $verb, ?string $parentId, ?string $id = ''): IComment {
478
+        $manager = $this->getManager();
479
+        $comment = new Comment();
480
+        $comment
481
+            ->setId($id)
482
+            ->setActor('users', $actorId)
483
+            ->setObject('files', 'file64')
484
+            ->setMessage($message)
485
+            ->setVerb($verb);
486
+        if ($parentId) {
487
+            $comment->setParentId($parentId);
488
+        }
489
+
490
+        $saveSuccessful = $manager->save($comment);
491
+        $this->assertTrue($saveSuccessful, 'Comment saving was not successful');
492
+        $this->assertNotEquals('', $comment->getId(), 'Comment ID should not be empty');
493
+        $this->assertNotEquals('0', $comment->getId(), 'Comment ID should not be string \'0\'');
494
+        $this->assertNotNull($comment->getCreationDateTime(), 'Comment creation date should not be null');
495
+
496
+        $loadedComment = $manager->get($comment->getId());
497
+        $this->assertSame($comment->getMessage(), $loadedComment->getMessage(), 'Comment message should match');
498
+        $this->assertEquals($comment->getCreationDateTime()->getTimestamp(), $loadedComment->getCreationDateTime()->getTimestamp(), 'Comment creation date should match');
499
+        return $comment;
500
+    }
501
+
502
+    public static function providerTestSave(): array {
503
+        return [
504
+            ['very beautiful, I am impressed!', 'alice', 'comment', null],
505
+        ];
506
+    }
507
+
508
+    public function testSaveUpdate(): void {
509
+        $manager = $this->getManager();
510
+        $comment = new Comment();
511
+        $comment
512
+            ->setActor('users', 'alice')
513
+            ->setObject('files', 'file64')
514
+            ->setMessage('very beautiful, I am impressed!')
515
+            ->setVerb('comment')
516
+            ->setExpireDate(new \DateTime('+2 hours'));
517
+
518
+        $manager->save($comment);
519
+
520
+        $loadedComment = $manager->get($comment->getId());
521
+        // Compare current object with database values
522
+        $this->assertSame($comment->getMessage(), $loadedComment->getMessage());
523
+        $this->assertSame(
524
+            $comment->getExpireDate()->format('Y-m-d H:i:s'),
525
+            $loadedComment->getExpireDate()->format('Y-m-d H:i:s')
526
+        );
527
+
528
+        // Preserve the original comment to compare after update
529
+        $original = clone $comment;
530
+
531
+        // Update values
532
+        $comment->setMessage('very beautiful, I am really so much impressed!')
533
+            ->setExpireDate(new \DateTime('+1 hours'));
534
+        $manager->save($comment);
535
+
536
+        $loadedComment = $manager->get($comment->getId());
537
+        // Compare current object with database values
538
+        $this->assertSame($comment->getMessage(), $loadedComment->getMessage());
539
+        $this->assertSame(
540
+            $comment->getExpireDate()->format('Y-m-d H:i:s'),
541
+            $loadedComment->getExpireDate()->format('Y-m-d H:i:s')
542
+        );
543
+
544
+        // Compare original object with database values
545
+        $this->assertNotSame($original->getMessage(), $loadedComment->getMessage());
546
+        $this->assertNotSame(
547
+            $original->getExpireDate()->format('Y-m-d H:i:s'),
548
+            $loadedComment->getExpireDate()->format('Y-m-d H:i:s')
549
+        );
550
+    }
551
+
552
+
553
+    public function testSaveUpdateException(): void {
554
+        $manager = $this->getManager();
555
+        $comment = new Comment();
556
+        $comment
557
+            ->setActor('users', 'alice')
558
+            ->setObject('files', 'file64')
559
+            ->setMessage('very beautiful, I am impressed!')
560
+            ->setVerb('comment');
561
+
562
+        $manager->save($comment);
563
+
564
+        $manager->delete($comment->getId());
565
+
566
+        $comment->setMessage('very beautiful, I am really so much impressed!');
567
+        $this->expectException(\OCP\Comments\NotFoundException::class);
568
+        $manager->save($comment);
569
+    }
570
+
571
+
572
+    public function testSaveIncomplete(): void {
573
+
574
+        $manager = $this->getManager();
575
+        $comment = new Comment();
576
+        $comment->setMessage('from no one to nothing');
577
+
578
+        $this->expectException(\UnexpectedValueException::class);
579
+        $manager->save($comment);
580
+    }
581
+
582
+    public function testSaveAsChild(): void {
583
+        $id = (string)$this->addDatabaseEntry(0, 0);
584
+
585
+        $manager = $this->getManager();
586
+
587
+        for ($i = 0; $i < 3; $i++) {
588
+            $comment = new Comment();
589
+            $comment
590
+                ->setActor('users', 'alice')
591
+                ->setObject('files', 'file64')
592
+                ->setParentId($id)
593
+                ->setMessage('full ack')
594
+                ->setVerb('comment')
595
+                // setting the creation time avoids using sleep() while making sure to test with different timestamps
596
+                ->setCreationDateTime(new \DateTime('+' . $i . ' minutes'));
597
+
598
+            $manager->save($comment);
599
+
600
+            $this->assertSame($id, $comment->getTopmostParentId());
601
+            $parentComment = $manager->get($id);
602
+            $this->assertSame($i + 1, $parentComment->getChildrenCount());
603
+            $this->assertEquals($comment->getCreationDateTime()->getTimestamp(), $parentComment->getLatestChildDateTime()->getTimestamp());
604
+        }
605
+    }
606
+
607
+    public static function invalidActorArgsProvider(): array {
608
+        return
609
+            [
610
+                ['', ''],
611
+                [1, 'alice'],
612
+                ['users', 1],
613
+            ];
614
+    }
615
+
616
+    /**
617
+     * @dataProvider invalidActorArgsProvider
618
+     */
619
+    public function testDeleteReferencesOfActorInvalidInput(string|int $type, string|int $id): void {
620
+        $this->expectException(\InvalidArgumentException::class);
621
+
622
+        $manager = $this->getManager();
623
+        $manager->deleteReferencesOfActor($type, $id);
624
+    }
625
+
626
+    public function testDeleteReferencesOfActor(): void {
627
+        $ids = [];
628
+        $ids[] = $this->addDatabaseEntry(0, 0);
629
+        $ids[] = $this->addDatabaseEntry(0, 0);
630
+        $ids[] = $this->addDatabaseEntry(0, 0);
631
+
632
+        $manager = $this->getManager();
633
+
634
+        // just to make sure they are really set, with correct actor data
635
+        $comment = $manager->get((string)$ids[1]);
636
+        $this->assertSame('users', $comment->getActorType());
637
+        $this->assertSame('alice', $comment->getActorId());
638
+
639
+        $wasSuccessful = $manager->deleteReferencesOfActor('users', 'alice');
640
+        $this->assertTrue($wasSuccessful);
641
+
642
+        foreach ($ids as $id) {
643
+            $comment = $manager->get((string)$id);
644
+            $this->assertSame(ICommentsManager::DELETED_USER, $comment->getActorType());
645
+            $this->assertSame(ICommentsManager::DELETED_USER, $comment->getActorId());
646
+        }
647
+
648
+        // actor info is gone from DB, but when database interaction is alright,
649
+        // we still expect to get true back
650
+        $wasSuccessful = $manager->deleteReferencesOfActor('users', 'alice');
651
+        $this->assertTrue($wasSuccessful);
652
+    }
653
+
654
+    public function testDeleteReferencesOfActorWithUserManagement(): void {
655
+        $user = \OCP\Server::get(IUserManager::class)->createUser('xenia', 'NotAnEasyPassword123456+');
656
+        $this->assertInstanceOf(IUser::class, $user);
657
+
658
+        $manager = \OCP\Server::get(ICommentsManager::class);
659
+        $comment = $manager->create('users', $user->getUID(), 'files', 'file64');
660
+        $comment
661
+            ->setMessage('Most important comment I ever left on the Internet.')
662
+            ->setVerb('comment');
663
+        $status = $manager->save($comment);
664
+        $this->assertTrue($status);
665
+
666
+        $commentID = $comment->getId();
667
+        $user->delete();
668
+
669
+        $comment = $manager->get($commentID);
670
+        $this->assertSame(ICommentsManager::DELETED_USER, $comment->getActorType());
671
+        $this->assertSame(ICommentsManager::DELETED_USER, $comment->getActorId());
672
+    }
673
+
674
+    public static function invalidObjectArgsProvider(): array {
675
+        return
676
+            [
677
+                ['', ''],
678
+                [1, 'file64'],
679
+                ['files', 1],
680
+            ];
681
+    }
682
+
683
+    /**
684
+     * @dataProvider invalidObjectArgsProvider
685
+     */
686
+    public function testDeleteCommentsAtObjectInvalidInput(string|int $type, string|int $id): void {
687
+        $this->expectException(\InvalidArgumentException::class);
688
+
689
+        $manager = $this->getManager();
690
+        $manager->deleteCommentsAtObject($type, $id);
691
+    }
692
+
693
+    public function testDeleteCommentsAtObject(): void {
694
+        $ids = [];
695
+        $ids[] = $this->addDatabaseEntry(0, 0);
696
+        $ids[] = $this->addDatabaseEntry(0, 0);
697
+        $ids[] = $this->addDatabaseEntry(0, 0);
698
+
699
+        $manager = $this->getManager();
700
+
701
+        // just to make sure they are really set, with correct actor data
702
+        $comment = $manager->get((string)$ids[1]);
703
+        $this->assertSame('files', $comment->getObjectType());
704
+        $this->assertSame('file64', $comment->getObjectId());
705
+
706
+        $wasSuccessful = $manager->deleteCommentsAtObject('files', 'file64');
707
+        $this->assertTrue($wasSuccessful);
708
+
709
+        $verified = 0;
710
+        foreach ($ids as $id) {
711
+            try {
712
+                $manager->get((string)$id);
713
+            } catch (NotFoundException) {
714
+                $verified++;
715
+            }
716
+        }
717
+        $this->assertSame(3, $verified);
718
+
719
+        // actor info is gone from DB, but when database interaction is alright,
720
+        // we still expect to get true back
721
+        $wasSuccessful = $manager->deleteCommentsAtObject('files', 'file64');
722
+        $this->assertTrue($wasSuccessful);
723
+    }
724
+
725
+    public function testDeleteCommentsExpiredAtObjectTypeAndId(): void {
726
+        $ids = [];
727
+        $ids[] = $this->addDatabaseEntry(0, 0, null, null, null, new \DateTime('+2 hours'));
728
+        $ids[] = $this->addDatabaseEntry(0, 0, null, null, null, new \DateTime('+2 hours'));
729
+        $ids[] = $this->addDatabaseEntry(0, 0, null, null, null, new \DateTime('+2 hours'));
730
+        $ids[] = $this->addDatabaseEntry(0, 0, null, null, null, new \DateTime('-2 hours'));
731
+        $ids[] = $this->addDatabaseEntry(0, 0, null, null, null, new \DateTime('-2 hours'));
732
+        $ids[] = $this->addDatabaseEntry(0, 0, null, null, null, new \DateTime('-2 hours'));
733
+
734
+        $manager = new Manager(
735
+            $this->connection,
736
+            $this->createMock(LoggerInterface::class),
737
+            $this->createMock(IConfig::class),
738
+            Server::get(ITimeFactory::class),
739
+            new EmojiHelper($this->connection),
740
+            $this->createMock(IInitialStateService::class),
741
+            $this->rootFolder,
742
+            $this->createMock(IEventDispatcher::class)
743
+        );
744
+
745
+        // just to make sure they are really set, with correct actor data
746
+        $comment = $manager->get((string)$ids[1]);
747
+        $this->assertSame('files', $comment->getObjectType());
748
+        $this->assertSame('file64', $comment->getObjectId());
749
+
750
+        $deleted = $manager->deleteCommentsExpiredAtObject('files', 'file64');
751
+        $this->assertTrue($deleted);
752
+
753
+        $deleted = 0;
754
+        $exists = 0;
755
+        foreach ($ids as $id) {
756
+            try {
757
+                $manager->get((string)$id);
758
+                $exists++;
759
+            } catch (NotFoundException) {
760
+                $deleted++;
761
+            }
762
+        }
763
+        $this->assertSame(3, $exists);
764
+        $this->assertSame(3, $deleted);
765
+
766
+        // actor info is gone from DB, but when database interaction is alright,
767
+        // we still expect to get true back
768
+        $deleted = $manager->deleteCommentsExpiredAtObject('files', 'file64');
769
+        $this->assertFalse($deleted);
770
+    }
771
+
772
+    public function testDeleteCommentsExpiredAtObjectType(): void {
773
+        $ids = [];
774
+        $ids[] = $this->addDatabaseEntry(0, 0, null, null, 'file1', new \DateTime('-2 hours'));
775
+        $ids[] = $this->addDatabaseEntry(0, 0, null, null, 'file2', new \DateTime('-2 hours'));
776
+        $ids[] = $this->addDatabaseEntry(0, 0, null, null, 'file3', new \DateTime('-2 hours'));
777
+        $ids[] = $this->addDatabaseEntry(0, 0, null, null, 'file3', new \DateTime());
778
+        $ids[] = $this->addDatabaseEntry(0, 0, null, null, 'file3', new \DateTime());
779
+        $ids[] = $this->addDatabaseEntry(0, 0, null, null, 'file3', new \DateTime());
780
+
781
+        $manager = new Manager(
782
+            $this->connection,
783
+            $this->createMock(LoggerInterface::class),
784
+            $this->createMock(IConfig::class),
785
+            Server::get(ITimeFactory::class),
786
+            new EmojiHelper($this->connection),
787
+            $this->createMock(IInitialStateService::class),
788
+            $this->rootFolder,
789
+            $this->createMock(IEventDispatcher::class)
790
+        );
791
+
792
+        $deleted = $manager->deleteCommentsExpiredAtObject('files');
793
+        $this->assertTrue($deleted);
794
+
795
+        $deleted = 0;
796
+        $exists = 0;
797
+        foreach ($ids as $id) {
798
+            try {
799
+                $manager->get((string)$id);
800
+                $exists++;
801
+            } catch (NotFoundException) {
802
+                $deleted++;
803
+            }
804
+        }
805
+        $this->assertSame(0, $exists);
806
+        $this->assertSame(6, $deleted);
807
+
808
+        // actor info is gone from DB, but when database interaction is alright,
809
+        // we still expect to get true back
810
+        $deleted = $manager->deleteCommentsExpiredAtObject('files');
811
+        $this->assertFalse($deleted);
812
+    }
813
+
814
+    public function testSetMarkRead(): void {
815
+        /** @var IUser|\PHPUnit\Framework\MockObject\MockObject $user */
816
+        $user = $this->createMock(IUser::class);
817
+        $user->expects($this->any())
818
+            ->method('getUID')
819
+            ->willReturn('alice');
820
+
821
+        $dateTimeSet = new \DateTime();
822
+
823
+        $manager = $this->getManager();
824
+        $manager->setReadMark('robot', '36', $dateTimeSet, $user);
825
+
826
+        $dateTimeGet = $manager->getReadMark('robot', '36', $user);
827
+
828
+        $this->assertEquals($dateTimeSet->getTimestamp(), $dateTimeGet->getTimestamp());
829
+    }
830
+
831
+    public function testSetMarkReadUpdate(): void {
832
+        /** @var IUser|\PHPUnit\Framework\MockObject\MockObject $user */
833
+        $user = $this->createMock(IUser::class);
834
+        $user->expects($this->any())
835
+            ->method('getUID')
836
+            ->willReturn('alice');
837
+
838
+        $dateTimeSet = new \DateTime('yesterday');
839
+
840
+        $manager = $this->getManager();
841
+        $manager->setReadMark('robot', '36', $dateTimeSet, $user);
842
+
843
+        $dateTimeSet = new \DateTime('today');
844
+        $manager->setReadMark('robot', '36', $dateTimeSet, $user);
845
+
846
+        $dateTimeGet = $manager->getReadMark('robot', '36', $user);
847
+
848
+        $this->assertEquals($dateTimeSet, $dateTimeGet);
849
+    }
850
+
851
+    public function testReadMarkDeleteUser(): void {
852
+        /** @var IUser|\PHPUnit\Framework\MockObject\MockObject $user */
853
+        $user = $this->createMock(IUser::class);
854
+        $user->expects($this->any())
855
+            ->method('getUID')
856
+            ->willReturn('alice');
857
+
858
+        $dateTimeSet = new \DateTime();
859
+
860
+        $manager = $this->getManager();
861
+        $manager->setReadMark('robot', '36', $dateTimeSet, $user);
862
+
863
+        $manager->deleteReadMarksFromUser($user);
864
+        $dateTimeGet = $manager->getReadMark('robot', '36', $user);
865
+
866
+        $this->assertNull($dateTimeGet);
867
+    }
868
+
869
+    public function testReadMarkDeleteObject(): void {
870
+        /** @var IUser|\PHPUnit\Framework\MockObject\MockObject $user */
871
+        $user = $this->createMock(IUser::class);
872
+        $user->expects($this->any())
873
+            ->method('getUID')
874
+            ->willReturn('alice');
875 875
 
876
-		$dateTimeSet = new \DateTime();
876
+        $dateTimeSet = new \DateTime();
877 877
 
878
-		$manager = $this->getManager();
879
-		$manager->setReadMark('robot', '36', $dateTimeSet, $user);
878
+        $manager = $this->getManager();
879
+        $manager->setReadMark('robot', '36', $dateTimeSet, $user);
880 880
 
881
-		$manager->deleteReadMarksOnObject('robot', '36');
882
-		$dateTimeGet = $manager->getReadMark('robot', '36', $user);
881
+        $manager->deleteReadMarksOnObject('robot', '36');
882
+        $dateTimeGet = $manager->getReadMark('robot', '36', $user);
883 883
 
884
-		$this->assertNull($dateTimeGet);
885
-	}
884
+        $this->assertNull($dateTimeGet);
885
+    }
886 886
 
887
-	public function testSendEvent(): void {
888
-		$handler1 = $this->createMock(ICommentsEventHandler::class);
889
-		$handler1->expects($this->exactly(4))
890
-			->method('handle');
887
+    public function testSendEvent(): void {
888
+        $handler1 = $this->createMock(ICommentsEventHandler::class);
889
+        $handler1->expects($this->exactly(4))
890
+            ->method('handle');
891 891
 
892
-		$handler2 = $this->createMock(ICommentsEventHandler::class);
893
-		$handler1->expects($this->exactly(4))
894
-			->method('handle');
892
+        $handler2 = $this->createMock(ICommentsEventHandler::class);
893
+        $handler1->expects($this->exactly(4))
894
+            ->method('handle');
895 895
 
896
-		$manager = $this->getManager();
897
-		$manager->registerEventHandler(function () use ($handler1) {
898
-			return $handler1;
899
-		});
900
-		$manager->registerEventHandler(function () use ($handler2) {
901
-			return $handler2;
902
-		});
896
+        $manager = $this->getManager();
897
+        $manager->registerEventHandler(function () use ($handler1) {
898
+            return $handler1;
899
+        });
900
+        $manager->registerEventHandler(function () use ($handler2) {
901
+            return $handler2;
902
+        });
903 903
 
904
-		$comment = new Comment();
905
-		$comment
906
-			->setActor('users', 'alice')
907
-			->setObject('files', 'file64')
908
-			->setMessage('very beautiful, I am impressed!')
909
-			->setVerb('comment');
904
+        $comment = new Comment();
905
+        $comment
906
+            ->setActor('users', 'alice')
907
+            ->setObject('files', 'file64')
908
+            ->setMessage('very beautiful, I am impressed!')
909
+            ->setVerb('comment');
910 910
 
911
-		// Add event
912
-		$manager->save($comment);
911
+        // Add event
912
+        $manager->save($comment);
913 913
 
914
-		// Update event
915
-		$comment->setMessage('Different topic');
916
-		$manager->save($comment);
914
+        // Update event
915
+        $comment->setMessage('Different topic');
916
+        $manager->save($comment);
917 917
 
918
-		// Delete event
919
-		$manager->delete($comment->getId());
920
-	}
918
+        // Delete event
919
+        $manager->delete($comment->getId());
920
+    }
921 921
 
922
-	public function testResolveDisplayName(): void {
923
-		$manager = $this->getManager();
922
+    public function testResolveDisplayName(): void {
923
+        $manager = $this->getManager();
924 924
 
925
-		$planetClosure = function ($name) {
926
-			return ucfirst($name);
927
-		};
925
+        $planetClosure = function ($name) {
926
+            return ucfirst($name);
927
+        };
928 928
 
929
-		$galaxyClosure = function ($name) {
930
-			return strtoupper($name);
931
-		};
929
+        $galaxyClosure = function ($name) {
930
+            return strtoupper($name);
931
+        };
932 932
 
933
-		$manager->registerDisplayNameResolver('planet', $planetClosure);
934
-		$manager->registerDisplayNameResolver('galaxy', $galaxyClosure);
933
+        $manager->registerDisplayNameResolver('planet', $planetClosure);
934
+        $manager->registerDisplayNameResolver('galaxy', $galaxyClosure);
935 935
 
936
-		$this->assertSame('Neptune', $manager->resolveDisplayName('planet', 'neptune'));
937
-		$this->assertSame('SOMBRERO', $manager->resolveDisplayName('galaxy', 'sombrero'));
938
-	}
936
+        $this->assertSame('Neptune', $manager->resolveDisplayName('planet', 'neptune'));
937
+        $this->assertSame('SOMBRERO', $manager->resolveDisplayName('galaxy', 'sombrero'));
938
+    }
939 939
 
940
-
941
-	public function testRegisterResolverDuplicate(): void {
942
-		$this->expectException(\OutOfBoundsException::class);
943
-
944
-		$manager = $this->getManager();
945
-
946
-		$planetClosure = function ($name) {
947
-			return ucfirst($name);
948
-		};
949
-		$manager->registerDisplayNameResolver('planet', $planetClosure);
950
-		$manager->registerDisplayNameResolver('planet', $planetClosure);
951
-	}
952
-
953
-
954
-	public function testRegisterResolverInvalidType(): void {
955
-		$this->expectException(\InvalidArgumentException::class);
956
-
957
-		$manager = $this->getManager();
958
-
959
-		$planetClosure = function ($name) {
960
-			return ucfirst($name);
961
-		};
962
-		$manager->registerDisplayNameResolver(1337, $planetClosure);
963
-	}
964
-
965
-
966
-	public function testResolveDisplayNameUnregisteredType(): void {
967
-		$this->expectException(\OutOfBoundsException::class);
968
-
969
-		$manager = $this->getManager();
970
-
971
-		$planetClosure = function ($name) {
972
-			return ucfirst($name);
973
-		};
974
-
975
-		$manager->registerDisplayNameResolver('planet', $planetClosure);
976
-		$manager->resolveDisplayName('galaxy', 'sombrero');
977
-	}
978
-
979
-	public function testResolveDisplayNameDirtyResolver(): void {
980
-		$manager = $this->getManager();
981
-
982
-		$planetClosure = function () {
983
-			return null;
984
-		};
985
-
986
-		$manager->registerDisplayNameResolver('planet', $planetClosure);
987
-		$this->assertIsString($manager->resolveDisplayName('planet', 'neptune'));
988
-	}
989
-
990
-	public function testResolveDisplayNameInvalidType(): void {
991
-
992
-		$manager = $this->getManager();
993
-
994
-		$planetClosure = function () {
995
-			return null;
996
-		};
997
-
998
-		$manager->registerDisplayNameResolver('planet', $planetClosure);
999
-		$this->expectException(\InvalidArgumentException::class);
1000
-		$this->assertIsString($manager->resolveDisplayName(1337, 'neptune'));
1001
-	}
1002
-
1003
-	private function skipIfNotSupport4ByteUTF(): void {
1004
-		if (!$this->getManager()->supportReactions()) {
1005
-			$this->markTestSkipped('MySQL doesn\'t support 4 byte UTF-8');
1006
-		}
1007
-	}
1008
-
1009
-	/**
1010
-	 * @dataProvider providerTestReactionAddAndDelete
1011
-	 */
1012
-	public function testReactionAddAndDelete(array $comments, array $reactionsExpected): void {
1013
-		$this->skipIfNotSupport4ByteUTF();
1014
-		$manager = $this->getManager();
1015
-
1016
-		$processedComments = $this->proccessComments($comments);
1017
-		$comment = end($processedComments);
1018
-		if ($comment->getParentId()) {
1019
-			$parent = $manager->get($comment->getParentId());
1020
-			$this->assertEqualsCanonicalizing($reactionsExpected, $parent->getReactions());
1021
-		}
1022
-	}
1023
-
1024
-	public static function providerTestReactionAddAndDelete(): array {
1025
-		return[
1026
-			[
1027
-				[
1028
-					['message', 'alice', 'comment', null],
1029
-				], [],
1030
-			],
1031
-			[
1032
-				[
1033
-					['message', 'alice', 'comment', null],
1034
-					['
Please login to merge, or discard this patch.
Spacing   +46 added lines, -46 removed lines patch added patch discarded remove patch
@@ -136,7 +136,7 @@  discard block
 block discarded – undo
136 136
 			])
137 137
 			->executeStatement();
138 138
 
139
-		$id = (string)$qb->getLastInsertId();
139
+		$id = (string) $qb->getLastInsertId();
140 140
 
141 141
 		$comment = $manager->get($id);
142 142
 		$this->assertInstanceOf(IComment::class, $comment);
@@ -185,14 +185,14 @@  discard block
 block discarded – undo
185 185
 		// Verifying the root comment
186 186
 		$this->assertArrayHasKey('comment', $tree);
187 187
 		$this->assertInstanceOf(IComment::class, $tree['comment']);
188
-		$this->assertSame((string)$headId, $tree['comment']->getId());
188
+		$this->assertSame((string) $headId, $tree['comment']->getId());
189 189
 		$this->assertArrayHasKey('replies', $tree);
190 190
 		$this->assertCount(3, $tree['replies']);
191 191
 
192 192
 		// one level deep
193 193
 		foreach ($tree['replies'] as $reply) {
194 194
 			$this->assertInstanceOf(IComment::class, $reply['comment']);
195
-			$this->assertSame((string)$id, $reply['comment']->getId());
195
+			$this->assertSame((string) $id, $reply['comment']->getId());
196 196
 			$this->assertCount(0, $reply['replies']);
197 197
 			$id--;
198 198
 		}
@@ -207,7 +207,7 @@  discard block
 block discarded – undo
207 207
 		// Verifying the root comment
208 208
 		$this->assertArrayHasKey('comment', $tree);
209 209
 		$this->assertInstanceOf(IComment::class, $tree['comment']);
210
-		$this->assertSame((string)$id, $tree['comment']->getId());
210
+		$this->assertSame((string) $id, $tree['comment']->getId());
211 211
 		$this->assertArrayHasKey('replies', $tree);
212 212
 		$this->assertCount(0, $tree['replies']);
213 213
 	}
@@ -223,19 +223,19 @@  discard block
 block discarded – undo
223 223
 		$manager = $this->getManager();
224 224
 
225 225
 		for ($offset = 0; $offset < 3; $offset += 2) {
226
-			$tree = $manager->getTree((string)$headId, 2, $offset);
226
+			$tree = $manager->getTree((string) $headId, 2, $offset);
227 227
 
228 228
 			// Verifying the root comment
229 229
 			$this->assertArrayHasKey('comment', $tree);
230 230
 			$this->assertInstanceOf(IComment::class, $tree['comment']);
231
-			$this->assertSame((string)$headId, $tree['comment']->getId());
231
+			$this->assertSame((string) $headId, $tree['comment']->getId());
232 232
 			$this->assertArrayHasKey('replies', $tree);
233 233
 			$this->assertCount(2, $tree['replies']);
234 234
 
235 235
 			// one level deep
236 236
 			foreach ($tree['replies'] as $reply) {
237 237
 				$this->assertInstanceOf(IComment::class, $reply['comment']);
238
-				$this->assertSame((string)$idToVerify, $reply['comment']->getId());
238
+				$this->assertSame((string) $idToVerify, $reply['comment']->getId());
239 239
 				$this->assertCount(0, $reply['replies']);
240 240
 				$idToVerify--;
241 241
 			}
@@ -272,7 +272,7 @@  discard block
 block discarded – undo
272 272
 			foreach ($comments as $key => $comment) {
273 273
 				$this->assertInstanceOf(IComment::class, $comment);
274 274
 				$this->assertSame('nice one', $comment->getMessage());
275
-				$this->assertSame((string)$idToVerify, $comment->getId(), 'ID wrong for comment ' . $key . ' on offset: ' . $offset);
275
+				$this->assertSame((string) $idToVerify, $comment->getId(), 'ID wrong for comment '.$key.' on offset: '.$offset);
276 276
 				$idToVerify--;
277 277
 			}
278 278
 			$offset += 3;
@@ -289,8 +289,8 @@  discard block
 block discarded – undo
289 289
 		$comments = $manager->getForObject('files', 'file64', 0, 0, new \DateTime('-4 hours'));
290 290
 
291 291
 		$this->assertCount(2, $comments);
292
-		$this->assertSame((string)$id2, $comments[0]->getId());
293
-		$this->assertSame((string)$id1, $comments[1]->getId());
292
+		$this->assertSame((string) $id2, $comments[0]->getId());
293
+		$this->assertSame((string) $id1, $comments[1]->getId());
294 294
 	}
295 295
 
296 296
 	public function testGetForObjectWithLimitAndOffsetAndDateTimeConstraint(): void {
@@ -311,7 +311,7 @@  discard block
 block discarded – undo
311 311
 			foreach ($comments as $comment) {
312 312
 				$this->assertInstanceOf(IComment::class, $comment);
313 313
 				$this->assertSame('nice one', $comment->getMessage());
314
-				$this->assertSame((string)$idToVerify, $comment->getId());
314
+				$this->assertSame((string) $idToVerify, $comment->getId());
315 315
 				$this->assertGreaterThanOrEqual(4, $comment->getId());
316 316
 				$idToVerify--;
317 317
 			}
@@ -336,7 +336,7 @@  discard block
 block discarded – undo
336 336
 	public function testGetNumberOfUnreadCommentsForFolder(): void {
337 337
 		$folder = $this->createMock(Folder::class);
338 338
 		$fileIds = range(1111, 1114);
339
-		$children = array_map(function (int $id) {
339
+		$children = array_map(function(int $id) {
340 340
 			$file = $this->createMock(Folder::class);
341 341
 			$file->method('getId')
342 342
 				->willReturn($id);
@@ -365,8 +365,8 @@  discard block
 block discarded – undo
365 365
 
366 366
 		$manager = $this->getManager();
367 367
 
368
-		$manager->setReadMark('files', (string)$fileIds[0], (new \DateTime())->modify('-1 days'), $user);
369
-		$manager->setReadMark('files', (string)$fileIds[2], (new \DateTime()), $user);
368
+		$manager->setReadMark('files', (string) $fileIds[0], (new \DateTime())->modify('-1 days'), $user);
369
+		$manager->setReadMark('files', (string) $fileIds[2], (new \DateTime()), $user);
370 370
 
371 371
 		$amount = $manager->getNumberOfUnreadCommentsForFolder($folder->getId(), $user);
372 372
 		$this->assertEquals([
@@ -395,7 +395,7 @@  discard block
 block discarded – undo
395 395
 			$expected = array_reverse($expected);
396 396
 		}
397 397
 
398
-		$this->assertSame($expected, array_map(static fn (IComment $c): int => (int)$c->getId(), $comments));
398
+		$this->assertSame($expected, array_map(static fn (IComment $c): int => (int) $c->getId(), $comments));
399 399
 	}
400 400
 
401 401
 	public static function dataGetForObjectSince(): array {
@@ -427,7 +427,7 @@  discard block
 block discarded – undo
427 427
 	/**
428 428
 	 * @dataProvider invalidCreateArgsProvider
429 429
 	 */
430
-	public function testCreateCommentInvalidArguments(string|int $aType, string|int $aId, string|int $oType, string|int $oId): void {
430
+	public function testCreateCommentInvalidArguments(string | int $aType, string | int $aId, string | int $oType, string | int $oId): void {
431 431
 		$this->expectException(\InvalidArgumentException::class);
432 432
 
433 433
 		$manager = $this->getManager();
@@ -463,7 +463,7 @@  discard block
 block discarded – undo
463 463
 		$done = $manager->delete('');
464 464
 		$this->assertFalse($done);
465 465
 
466
-		$id = (string)$this->addDatabaseEntry(0, 0);
466
+		$id = (string) $this->addDatabaseEntry(0, 0);
467 467
 		$comment = $manager->get($id);
468 468
 		$this->assertInstanceOf(IComment::class, $comment);
469 469
 		$done = $manager->delete($id);
@@ -580,7 +580,7 @@  discard block
 block discarded – undo
580 580
 	}
581 581
 
582 582
 	public function testSaveAsChild(): void {
583
-		$id = (string)$this->addDatabaseEntry(0, 0);
583
+		$id = (string) $this->addDatabaseEntry(0, 0);
584 584
 
585 585
 		$manager = $this->getManager();
586 586
 
@@ -593,7 +593,7 @@  discard block
 block discarded – undo
593 593
 				->setMessage('full ack')
594 594
 				->setVerb('comment')
595 595
 				// setting the creation time avoids using sleep() while making sure to test with different timestamps
596
-				->setCreationDateTime(new \DateTime('+' . $i . ' minutes'));
596
+				->setCreationDateTime(new \DateTime('+'.$i.' minutes'));
597 597
 
598 598
 			$manager->save($comment);
599 599
 
@@ -616,7 +616,7 @@  discard block
 block discarded – undo
616 616
 	/**
617 617
 	 * @dataProvider invalidActorArgsProvider
618 618
 	 */
619
-	public function testDeleteReferencesOfActorInvalidInput(string|int $type, string|int $id): void {
619
+	public function testDeleteReferencesOfActorInvalidInput(string | int $type, string | int $id): void {
620 620
 		$this->expectException(\InvalidArgumentException::class);
621 621
 
622 622
 		$manager = $this->getManager();
@@ -632,7 +632,7 @@  discard block
 block discarded – undo
632 632
 		$manager = $this->getManager();
633 633
 
634 634
 		// just to make sure they are really set, with correct actor data
635
-		$comment = $manager->get((string)$ids[1]);
635
+		$comment = $manager->get((string) $ids[1]);
636 636
 		$this->assertSame('users', $comment->getActorType());
637 637
 		$this->assertSame('alice', $comment->getActorId());
638 638
 
@@ -640,7 +640,7 @@  discard block
 block discarded – undo
640 640
 		$this->assertTrue($wasSuccessful);
641 641
 
642 642
 		foreach ($ids as $id) {
643
-			$comment = $manager->get((string)$id);
643
+			$comment = $manager->get((string) $id);
644 644
 			$this->assertSame(ICommentsManager::DELETED_USER, $comment->getActorType());
645 645
 			$this->assertSame(ICommentsManager::DELETED_USER, $comment->getActorId());
646 646
 		}
@@ -683,7 +683,7 @@  discard block
 block discarded – undo
683 683
 	/**
684 684
 	 * @dataProvider invalidObjectArgsProvider
685 685
 	 */
686
-	public function testDeleteCommentsAtObjectInvalidInput(string|int $type, string|int $id): void {
686
+	public function testDeleteCommentsAtObjectInvalidInput(string | int $type, string | int $id): void {
687 687
 		$this->expectException(\InvalidArgumentException::class);
688 688
 
689 689
 		$manager = $this->getManager();
@@ -699,7 +699,7 @@  discard block
 block discarded – undo
699 699
 		$manager = $this->getManager();
700 700
 
701 701
 		// just to make sure they are really set, with correct actor data
702
-		$comment = $manager->get((string)$ids[1]);
702
+		$comment = $manager->get((string) $ids[1]);
703 703
 		$this->assertSame('files', $comment->getObjectType());
704 704
 		$this->assertSame('file64', $comment->getObjectId());
705 705
 
@@ -709,7 +709,7 @@  discard block
 block discarded – undo
709 709
 		$verified = 0;
710 710
 		foreach ($ids as $id) {
711 711
 			try {
712
-				$manager->get((string)$id);
712
+				$manager->get((string) $id);
713 713
 			} catch (NotFoundException) {
714 714
 				$verified++;
715 715
 			}
@@ -743,7 +743,7 @@  discard block
 block discarded – undo
743 743
 		);
744 744
 
745 745
 		// just to make sure they are really set, with correct actor data
746
-		$comment = $manager->get((string)$ids[1]);
746
+		$comment = $manager->get((string) $ids[1]);
747 747
 		$this->assertSame('files', $comment->getObjectType());
748 748
 		$this->assertSame('file64', $comment->getObjectId());
749 749
 
@@ -754,7 +754,7 @@  discard block
 block discarded – undo
754 754
 		$exists = 0;
755 755
 		foreach ($ids as $id) {
756 756
 			try {
757
-				$manager->get((string)$id);
757
+				$manager->get((string) $id);
758 758
 				$exists++;
759 759
 			} catch (NotFoundException) {
760 760
 				$deleted++;
@@ -796,7 +796,7 @@  discard block
 block discarded – undo
796 796
 		$exists = 0;
797 797
 		foreach ($ids as $id) {
798 798
 			try {
799
-				$manager->get((string)$id);
799
+				$manager->get((string) $id);
800 800
 				$exists++;
801 801
 			} catch (NotFoundException) {
802 802
 				$deleted++;
@@ -894,10 +894,10 @@  discard block
 block discarded – undo
894 894
 			->method('handle');
895 895
 
896 896
 		$manager = $this->getManager();
897
-		$manager->registerEventHandler(function () use ($handler1) {
897
+		$manager->registerEventHandler(function() use ($handler1) {
898 898
 			return $handler1;
899 899
 		});
900
-		$manager->registerEventHandler(function () use ($handler2) {
900
+		$manager->registerEventHandler(function() use ($handler2) {
901 901
 			return $handler2;
902 902
 		});
903 903
 
@@ -922,11 +922,11 @@  discard block
 block discarded – undo
922 922
 	public function testResolveDisplayName(): void {
923 923
 		$manager = $this->getManager();
924 924
 
925
-		$planetClosure = function ($name) {
925
+		$planetClosure = function($name) {
926 926
 			return ucfirst($name);
927 927
 		};
928 928
 
929
-		$galaxyClosure = function ($name) {
929
+		$galaxyClosure = function($name) {
930 930
 			return strtoupper($name);
931 931
 		};
932 932
 
@@ -943,7 +943,7 @@  discard block
 block discarded – undo
943 943
 
944 944
 		$manager = $this->getManager();
945 945
 
946
-		$planetClosure = function ($name) {
946
+		$planetClosure = function($name) {
947 947
 			return ucfirst($name);
948 948
 		};
949 949
 		$manager->registerDisplayNameResolver('planet', $planetClosure);
@@ -956,7 +956,7 @@  discard block
 block discarded – undo
956 956
 
957 957
 		$manager = $this->getManager();
958 958
 
959
-		$planetClosure = function ($name) {
959
+		$planetClosure = function($name) {
960 960
 			return ucfirst($name);
961 961
 		};
962 962
 		$manager->registerDisplayNameResolver(1337, $planetClosure);
@@ -968,7 +968,7 @@  discard block
 block discarded – undo
968 968
 
969 969
 		$manager = $this->getManager();
970 970
 
971
-		$planetClosure = function ($name) {
971
+		$planetClosure = function($name) {
972 972
 			return ucfirst($name);
973 973
 		};
974 974
 
@@ -979,7 +979,7 @@  discard block
 block discarded – undo
979 979
 	public function testResolveDisplayNameDirtyResolver(): void {
980 980
 		$manager = $this->getManager();
981 981
 
982
-		$planetClosure = function () {
982
+		$planetClosure = function() {
983 983
 			return null;
984 984
 		};
985 985
 
@@ -991,7 +991,7 @@  discard block
 block discarded – undo
991 991
 
992 992
 		$manager = $this->getManager();
993 993
 
994
-		$planetClosure = function () {
994
+		$planetClosure = function() {
995 995
 			return null;
996 996
 		};
997 997
 
@@ -1079,14 +1079,14 @@  discard block
 block discarded – undo
1079 1079
 			[$message, $actorId, $verb, $parentText] = $comment;
1080 1080
 			$parentId = null;
1081 1081
 			if ($parentText) {
1082
-				$parentId = (string)$comments[$parentText]->getId();
1082
+				$parentId = (string) $comments[$parentText]->getId();
1083 1083
 			}
1084 1084
 			$id = '';
1085 1085
 			if ($verb === 'reaction_deleted') {
1086
-				$id = $comments[$message . '#' . $actorId]->getId();
1086
+				$id = $comments[$message.'#'.$actorId]->getId();
1087 1087
 			}
1088 1088
 			$comment = $this->testSave($message, $actorId, $verb, $parentId, $id);
1089
-			$comments[$comment->getMessage() . '#' . $comment->getActorId()] = $comment;
1089
+			$comments[$comment->getMessage().'#'.$comment->getActorId()] = $comment;
1090 1090
 		}
1091 1091
 		return $comments;
1092 1092
 	}
@@ -1100,8 +1100,8 @@  discard block
 block discarded – undo
1100 1100
 
1101 1101
 		$processedComments = $this->proccessComments($comments);
1102 1102
 		$comment = reset($processedComments);
1103
-		$all = $manager->retrieveAllReactions((int)$comment->getId());
1104
-		$actual = array_map(static function (IComment $row): array {
1103
+		$all = $manager->retrieveAllReactions((int) $comment->getId());
1104
+		$actual = array_map(static function(IComment $row): array {
1105 1105
 			return [
1106 1106
 				$row->getActorId(),
1107 1107
 				$row->getMessage(),
@@ -2360,8 +2360,8 @@  discard block
 block discarded – undo
2360 2360
 
2361 2361
 		$processedComments = $this->proccessComments($comments);
2362 2362
 		$comment = reset($processedComments);
2363
-		$all = $manager->retrieveAllReactionsWithSpecificReaction((int)$comment->getId(), $reaction);
2364
-		$actual = array_map(static function (IComment $row): array {
2363
+		$all = $manager->retrieveAllReactionsWithSpecificReaction((int) $comment->getId(), $reaction);
2364
+		$actual = array_map(static function(IComment $row): array {
2365 2365
 			return [
2366 2366
 				$row->getActorId(),
2367 2367
 				$row->getMessage(),
@@ -2421,8 +2421,8 @@  discard block
 block discarded – undo
2421 2421
 		if ($notFound) {
2422 2422
 			$this->expectException(\OCP\Comments\NotFoundException::class);
2423 2423
 		}
2424
-		$comment = $processedComments[$expected['message'] . '#' . $expected['actorId']];
2425
-		$actual = $manager->getReactionComment((int)$comment->getParentId(), $comment->getActorType(), $comment->getActorId(), $comment->getMessage());
2424
+		$comment = $processedComments[$expected['message'].'#'.$expected['actorId']];
2425
+		$actual = $manager->getReactionComment((int) $comment->getParentId(), $comment->getActorType(), $comment->getActorId(), $comment->getMessage());
2426 2426
 		if (!$notFound) {
2427 2427
 			$this->assertEquals($expected['message'], $actual->getMessage());
2428 2428
 			$this->assertEquals($expected['actorId'], $actual->getActorId());
Please login to merge, or discard this patch.