Skip to content

Commit 52dcdfc

Browse files
committed
test: add partial unit tests for context chat
Signed-off-by: Edward Ly <contact@edward.ly>
1 parent c3282c7 commit 52dcdfc

2 files changed

Lines changed: 314 additions & 0 deletions

File tree

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
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\Mail\Tests\Unit\BackgroundJob;
11+
12+
use ChristophWurst\Nextcloud\Testing\ServiceMockObject;
13+
use ChristophWurst\Nextcloud\Testing\TestCase;
14+
use Horde_Imap_Client_DateTime;
15+
use Horde_Imap_Client_Socket;
16+
use OC\BackgroundJob\JobList;
17+
use OCA\Mail\Account;
18+
use OCA\Mail\AddressList;
19+
use OCA\Mail\AppInfo\Application;
20+
use OCA\Mail\BackgroundJob\ContextChat\SubmitContentJob;
21+
use OCA\Mail\Db\Mailbox;
22+
// use OCA\Mail\Db\Message;
23+
use OCA\Mail\Model\IMAPMessage;
24+
use OCA\Mail\Service\Html;
25+
26+
class SubmitContentJobTest extends TestCase {
27+
/** @var ServiceMockObject */
28+
private $serviceMock;
29+
30+
/** @var SubmitContentJob */
31+
private $job;
32+
33+
/** @var Account|MockObject */
34+
private $account;
35+
36+
/** @var Mailbox|MockObject */
37+
private $mailbox;
38+
39+
protected function setUp(): void {
40+
parent::setUp();
41+
42+
if (!class_exists(\OCP\ContextChat\IContentProvider::class)) {
43+
$this->markTestSkipped();
44+
}
45+
46+
$this->serviceMock = $this->createServiceMock(SubmitContentJob::class);
47+
$this->job = $this->serviceMock->getService();
48+
49+
// Make sure the job is actually run
50+
$this->serviceMock->getParameter('time')
51+
->method('getTime')
52+
->willReturn(500000);
53+
// Set our common argument
54+
$this->job->setArgument([
55+
'userId' => 'user123',
56+
'accountId' => 1,
57+
'mailboxId' => 1,
58+
'nextMessageId' => 1,
59+
'startTime' => time() - Application::CONTEXT_CHAT_MESSAGE_MAX_AGE,
60+
]);
61+
// Set a fake ID
62+
$this->job->setId(99);
63+
}
64+
65+
public function testRun(): void {
66+
// TODO: add tests for various number of messages per mailbox and starting IDs
67+
$this->markTestIncomplete();
68+
69+
$client = $this->createMock(Horde_Imap_Client_Socket::class);
70+
$this->serviceMock->getParameter('clientFactory')
71+
->expects(self::once())
72+
->method('getClient')
73+
->with($this->account)
74+
->willReturn($client);
75+
$imapMessage = new IMAPMessage(
76+
123,
77+
'',
78+
[],
79+
new AddressList([]),
80+
new AddressList([]),
81+
new AddressList([]),
82+
new AddressList([]),
83+
new AddressList([]),
84+
'',
85+
'',
86+
'',
87+
false,
88+
[],
89+
[],
90+
false,
91+
[],
92+
new Horde_Imap_Client_DateTime(),
93+
'',
94+
'',
95+
false,
96+
[],
97+
null,
98+
false,
99+
'',
100+
'',
101+
false,
102+
false,
103+
false,
104+
$this->createMock(Html::class),
105+
false,
106+
);
107+
$this->serviceMock->getParameter('mailManager')
108+
->expects(self::once())
109+
->method('getImapMessage')
110+
->with($client, $this->account, $this->mailbox, 123, true)
111+
->willReturn($imapMessage);
112+
$this->serviceMock->getParameter('contextChatProvider')
113+
->expects(self::once())
114+
->method('getId')
115+
->willReturn('mail');
116+
$this->serviceMock->getParameter('contentManager')
117+
->expects(self::once())
118+
->method('submitContent');
119+
$this->serviceMock->getParameter('jobList')
120+
->expects(self::never())
121+
->method('add');
122+
123+
$this->job->setArgument([
124+
'userId' => 'user123',
125+
'accountId' => 1,
126+
'mailboxId' => 1,
127+
'nextMessageId' => 1,
128+
'startTime' => time() - Application::CONTEXT_CHAT_MESSAGE_MAX_AGE,
129+
]);
130+
$this->job->start($this->createMock(JobList::class));
131+
}
132+
}
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
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\Mail\Tests\Unit\ContextChat;
11+
12+
use ChristophWurst\Nextcloud\Testing\TestCase;
13+
use OCA\Mail\Account;
14+
use OCA\Mail\ContextChat\ContextChatProvider;
15+
use OCA\Mail\Db\MailAccount;
16+
use OCA\Mail\Db\Mailbox;
17+
use OCA\Mail\Db\Message;
18+
use OCA\Mail\Db\MessageMapper;
19+
use OCA\Mail\Events\MessageDeletedEvent;
20+
use OCA\Mail\Events\NewMessagesSynchronized;
21+
use OCA\Mail\Service\AccountService;
22+
use OCA\Mail\Service\MailManager;
23+
use OCP\BackgroundJob\IJobList;
24+
use OCP\ContextChat\Events\ContentProviderRegisterEvent;
25+
use OCP\ContextChat\IContentManager;
26+
use OCP\IURLGenerator;
27+
use OCP\IUserManager;
28+
use PHPUnit\Framework\Attributes\DataProvider;
29+
use PHPUnit\Framework\MockObject\MockObject;
30+
31+
class ContextChatProviderTest extends TestCase {
32+
/** @var AccountService|MockObject */
33+
private $accountService;
34+
35+
/** @var MailManager|MockObject */
36+
private $mailManager;
37+
38+
/** @var MessageMapper|MockObject */
39+
private $messageMapper;
40+
41+
/** @var IURLGenerator|MockObject */
42+
private $urlGenerator;
43+
44+
/** @var IUserManager|MockObject */
45+
private $userManager;
46+
47+
/** @var IContentManager|MockObject */
48+
private $contentManager;
49+
50+
/** @var IJobList|MockObject */
51+
private $jobList;
52+
53+
/** @var ContextChatProvider */
54+
private $contextChatProvider;
55+
56+
protected function setUp(): void {
57+
parent::setUp();
58+
59+
if (!class_exists(\OCP\ContextChat\IContentManager::class)) {
60+
$this->markTestSkipped();
61+
}
62+
63+
$this->accountService = $this->createMock(AccountService::class);
64+
$this->mailManager = $this->createMock(MailManager::class);
65+
$this->messageMapper = $this->createMock(MessageMapper::class);
66+
$this->urlGenerator = $this->createMock(IURLGenerator::class);
67+
$this->userManager = $this->createMock(IUserManager::class);
68+
$this->contentManager = $this->createMock(IContentManager::class);
69+
$this->jobList = $this->createMock(IJobList::class);
70+
71+
$this->contextChatProvider = new ContextChatProvider(
72+
$this->accountService,
73+
$this->mailManager,
74+
$this->messageMapper,
75+
$this->urlGenerator,
76+
$this->userManager,
77+
$this->contentManager,
78+
$this->jobList,
79+
);
80+
}
81+
82+
public function provideEvents(): array {
83+
$account = new Account(new MailAccount());
84+
$mailbox = new Mailbox();
85+
$messages = [];
86+
$messages[] = new Message();
87+
$messages[] = new Message();
88+
89+
return [
90+
// TODO: fix the following constructor
91+
// 'handle ContentProviderRegisterEvent' => [new ContentProviderRegisterEvent($this->contentManager)],
92+
'handle NewMessagesSynchronized' => [new NewMessagesSynchronized($account, $mailbox, $messages)],
93+
'handle MessageDeletedEvent' => [new MessageDeletedEvent($account, $mailbox, 1)],
94+
];
95+
}
96+
97+
/**
98+
* @dataProvider provideEvents
99+
*/
100+
public function testHandleWithoutContextChat($event) {
101+
// TODO: confirm test works after OCP\ContextChat classes are found
102+
$this->markTestIncomplete();
103+
104+
$this->contentManager->expects($this->once())
105+
->method('isContextChatAvailable')
106+
->willReturn(false);
107+
$this->assertNull($this->contextChatProvider->handle($event));
108+
}
109+
110+
/**
111+
* @dataProvider provideEvents
112+
*/
113+
public function testHandleWithContextChat($event) {
114+
// TODO: confirm test works after OCP\ContextChat classes are found
115+
$this->markTestIncomplete();
116+
117+
$this->contentManager->expects($this->once())
118+
->method('isContextChatAvailable')
119+
->willReturn(true);
120+
121+
if ($event instanceof ContentProviderRegisterEvent) {
122+
$this->contentManager->expects($this->once())
123+
->method('registerContentProvider');
124+
}
125+
126+
if ($event instanceof NewMessagesSynchronized) {
127+
$this->jobList->expects($this->once())
128+
->method('add');
129+
}
130+
131+
if ($event instanceof MessageDeletedEvent) {
132+
$this->contentManager->expects($this->once())
133+
->method('deleteContent');
134+
}
135+
136+
$this->assertNull($this->contextChatProvider->handle($event));
137+
}
138+
139+
public function testGetId() {
140+
// TODO: confirm test works after OCP\ContextChat classes are found
141+
$this->markTestIncomplete();
142+
143+
$this->assertEquals($this->contextChatProvider->getId(), 'mail');
144+
}
145+
146+
public function testGetAppId() {
147+
// TODO: confirm test works after OCP\ContextChat classes are found
148+
$this->markTestIncomplete();
149+
150+
$this->assertEquals($this->contextChatProvider->getAppId(), 'mail');
151+
}
152+
153+
public function testGetItemUrl() {
154+
// TODO: confirm test works after OCP\ContextChat classes are found
155+
$this->markTestIncomplete();
156+
157+
$message = new Message();
158+
$message->setUid(2);
159+
$message->setMailboxId(1);
160+
$this->messageMapper->expects($this->once())
161+
->method('findByIds')
162+
->with('', [2], '')
163+
->willReturn([$message]);
164+
$this->urlGenerator->expects($this->once())
165+
->method('linkToRouteAbsolute')
166+
->with('mail.page.thread', ['mailboxId' => 1, 'id' => '2'])
167+
->willReturn('http://localhost/apps/mail/box/1/thread/2');
168+
$itemUrl = $this->contextChatProvider->getItemUrl('2');
169+
$this->assertEquals($itemUrl, 'http://localhost/apps/mail/box/1/thread/2');
170+
}
171+
172+
public function testTriggerInitialImport() {
173+
// TODO: finish test
174+
$this->markTestIncomplete();
175+
176+
// $account = new Account(new MailAccount());
177+
// $this->accountService->expects($this->once())
178+
// ->method('findByUserId')
179+
// ->willReturn([$account]);
180+
$this->assertNull($this->contextChatProvider->triggerInitialImport());
181+
}
182+
}

0 commit comments

Comments
 (0)