Skip to content

Commit 756bdef

Browse files
committed
fixup! fix: use stable route for comment search results
1 parent a5fee4a commit 756bdef

File tree

1 file changed

+164
-0
lines changed

1 file changed

+164
-0
lines changed
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
7+
* SPDX-License-Identifier: AGPL-3.0-or-later
8+
*/
9+
10+
namespace OCA\Comments\Tests\Unit\Search;
11+
12+
use OC\Comments\Comment;
13+
use OCA\Comments\Search\CommentsSearchProvider;
14+
use OCP\Comments\IComment;
15+
use OCP\Comments\ICommentsManager;
16+
use OCP\Files\File;
17+
use OCP\Files\Folder;
18+
use OCP\Files\IRootFolder;
19+
use OCP\IL10N;
20+
use OCP\IURLGenerator;
21+
use OCP\IUser;
22+
use OCP\IUserManager;
23+
use OCP\Search\IFilter;
24+
use OCP\Search\ISearchQuery;
25+
use PHPUnit\Framework\MockObject\MockObject;
26+
use Psr\Log\NullLogger;
27+
use Test\TestCase;
28+
29+
class CommentsSearchProviderTest extends TestCase {
30+
31+
private IUserManager&MockObject $userManager;
32+
private IL10N&MockObject $l10n;
33+
private IURLGenerator&MockObject $urlGenerator;
34+
private ICommentsManager&MockObject $commentsManager;
35+
private IRootFolder&MockObject $rootFolder;
36+
private CommentsSearchProvider $provider;
37+
38+
39+
protected function setUp(): void {
40+
parent::setUp();
41+
42+
$this->userManager = $this->createMock(IUserManager::class);
43+
$this->l10n = $this->createMock(IL10N::class);
44+
$this->urlGenerator = $this->createMock(IURLGenerator::class);
45+
$this->commentsManager = $this->createMock(ICommentsManager::class);
46+
$this->rootFolder = $this->createMock(IRootFolder::class);
47+
48+
$userFolder = $this->createMock(Folder::class);
49+
$userFolder->method('getFirstNodeById')->willReturnCallback(function (int $id) {
50+
if ($id % 4 === 0) {
51+
// Returning null for every fourth file to simulate a file not found case.
52+
return null;
53+
}
54+
$node = $this->createMock(File::class);
55+
$node->method('getId')->willReturn($id);
56+
$node->method('getPath')->willReturn('/' . $id . '.txt');
57+
return $node;
58+
});
59+
$userFolder->method('getRelativePath')->willReturnArgument(0);
60+
$this->rootFolder->method('getUserFolder')->willReturn($userFolder);
61+
62+
$this->userManager->method('userExists')->willReturn(true);
63+
64+
$this->l10n->method('t')->willReturnArgument(0);
65+
66+
$this->provider = new CommentsSearchProvider(
67+
$this->userManager,
68+
$this->l10n,
69+
$this->urlGenerator,
70+
$this->commentsManager,
71+
$this->rootFolder,
72+
new NullLogger(),
73+
);
74+
}
75+
76+
public function testGetId(): void {
77+
$this->assertEquals('comments', $this->provider->getId());
78+
}
79+
80+
public function testGetName(): void {
81+
$this->l10n->expects($this->once())
82+
->method('t')
83+
->with('Comments')
84+
->willReturnArgument(0);
85+
86+
$this->assertEquals('Comments', $this->provider->getName());
87+
}
88+
89+
public function testSearch(): void {
90+
$this->commentsManager->method('search')->willReturnCallback(function (string $search, string $objectType, string $objectId, string $verb, int $offset, int $limit = 50) {
91+
// The search method is call until 50 comments are found or there are no more comments to search.
92+
$comments = [];
93+
for ($i = 1; $i <= $limit; $i++) {
94+
$comments[] = $this->mockComment(($offset + $i));
95+
}
96+
return $comments;
97+
});
98+
$user = $this->createMock(IUser::class);
99+
$user->method('getUID')->willReturn('alice');
100+
$searchTermFilter = $this->createMock(IFilter::class);
101+
$searchTermFilter->method('get')->willReturn('search term');
102+
$searchQuery = $this->createMock(ISearchQuery::class);
103+
$searchQuery->method('getFilter')->willReturnCallback(function ($name) use ($searchTermFilter) {
104+
return match ($name) {
105+
'term' => $searchTermFilter,
106+
default => null,
107+
};
108+
});
109+
110+
$result = $this->provider->search($user, $searchQuery);
111+
$data = $result->jsonSerialize();
112+
113+
$this->assertCount(50, $data['entries']);
114+
}
115+
116+
public function testSearchNoMoreComments(): void {
117+
$this->commentsManager->method('search')->willReturnCallback(function (string $search, string $objectType, string $objectId, string $verb, int $offset, int $limit = 50) {
118+
// Decrease the limit to simulate no more comments to search -> the break case.
119+
if ($offset > 0) {
120+
$limit--;
121+
}
122+
$comments = [];
123+
for ($i = 1; $i <= $limit; $i++) {
124+
$comments[] = $this->mockComment(($offset + $i));
125+
}
126+
return $comments;
127+
});
128+
$user = $this->createMock(IUser::class);
129+
$user->method('getUID')->willReturn('alice');
130+
$searchTermFilter = $this->createMock(IFilter::class);
131+
$searchTermFilter->method('get')->willReturn('search term');
132+
$searchQuery = $this->createMock(ISearchQuery::class);
133+
$searchQuery->method('getFilter')->willReturnCallback(function ($name) use ($searchTermFilter) {
134+
return match ($name) {
135+
'term' => $searchTermFilter,
136+
default => null,
137+
};
138+
});
139+
140+
141+
$result = $this->provider->search($user, $searchQuery);
142+
$data = $result->jsonSerialize();
143+
144+
$this->assertCount(46, $data['entries']);
145+
}
146+
147+
private function mockComment(int $id): IComment {
148+
return new Comment([
149+
'id' => (string)$id,
150+
'parent_id' => '0',
151+
'topmost_parent_id' => '0',
152+
'children_count' => 0,
153+
'actor_type' => 'users',
154+
'actor_id' => 'user' . $id,
155+
'message' => 'Comment ' . $id,
156+
'verb' => 'comment',
157+
'creation_timestamp' => new \DateTime(),
158+
'latest_child_timestamp' => null,
159+
'object_type' => 'files',
160+
'object_id' => (string)$id
161+
]);
162+
}
163+
164+
}

0 commit comments

Comments
 (0)