Skip to content

Commit 9f7c7c4

Browse files
test(listener): add unit tests for UserDeletedListener functionality
Added comprehensive unit tests for the UserDeletedListener to ensure proper handling of user deletion events, including scenarios with no accounts, single and multiple accounts, client exceptions, and partial failures. This enhances test coverage and reliability of the mail account deletion process. Signed-off-by: Misha M.-Kupriyanov <[email protected]>
1 parent 26f2e99 commit 9f7c7c4

File tree

1 file changed

+190
-0
lines changed

1 file changed

+190
-0
lines changed
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
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\Listener;
11+
12+
use ChristophWurst\Nextcloud\Testing\TestCase;
13+
use OCA\Mail\Account;
14+
use OCA\Mail\Db\MailAccount;
15+
use OCA\Mail\Exception\ClientException;
16+
use OCA\Mail\Listener\UserDeletedListener;
17+
use OCA\Mail\Service\AccountService;
18+
use OCP\EventDispatcher\Event;
19+
use OCP\IUser;
20+
use OCP\User\Events\UserDeletedEvent;
21+
use PHPUnit\Framework\MockObject\MockObject;
22+
use Psr\Log\LoggerInterface;
23+
24+
class UserDeletedListenerTest extends TestCase {
25+
private AccountService&MockObject $accountService;
26+
private LoggerInterface&MockObject $logger;
27+
private UserDeletedListener $listener;
28+
29+
protected function setUp(): void {
30+
parent::setUp();
31+
32+
$this->accountService = $this->createMock(AccountService::class);
33+
$this->logger = $this->createMock(LoggerInterface::class);
34+
35+
$this->listener = new UserDeletedListener(
36+
$this->accountService,
37+
$this->logger
38+
);
39+
}
40+
41+
private function createUserMock(string $userId): IUser&MockObject {
42+
$user = $this->createMock(IUser::class);
43+
$user->method('getUID')->willReturn($userId);
44+
return $user;
45+
}
46+
47+
private function createAccountMock(int $id): Account {
48+
$mailAccount = new MailAccount();
49+
$mailAccount->setId($id);
50+
return new Account($mailAccount);
51+
}
52+
53+
public function testImplementsIEventListener(): void {
54+
$this->assertInstanceOf(\OCP\EventDispatcher\IEventListener::class, $this->listener);
55+
}
56+
57+
public function testHandleUnrelated(): void {
58+
$event = new Event();
59+
60+
$this->accountService->expects($this->never())
61+
->method('findByUserId');
62+
63+
$this->listener->handle($event);
64+
65+
$this->addToAssertionCount(1);
66+
}
67+
68+
public function testHandleUserDeletedWithNoAccounts(): void {
69+
$user = $this->createUserMock('test-user');
70+
$event = new UserDeletedEvent($user);
71+
72+
$this->accountService->expects($this->once())
73+
->method('findByUserId')
74+
->with('test-user')
75+
->willReturn([]);
76+
77+
$this->accountService->expects($this->never())
78+
->method('delete');
79+
80+
$this->logger->expects($this->never())
81+
->method('error');
82+
83+
$this->listener->handle($event);
84+
}
85+
86+
public function testHandleUserDeletedWithSingleAccount(): void {
87+
$user = $this->createUserMock('test-user');
88+
$account = $this->createAccountMock(42);
89+
$event = new UserDeletedEvent($user);
90+
91+
$this->accountService->expects($this->once())
92+
->method('findByUserId')
93+
->with('test-user')
94+
->willReturn([$account]);
95+
96+
$this->accountService->expects($this->once())
97+
->method('delete')
98+
->with('test-user', 42);
99+
100+
$this->logger->expects($this->never())
101+
->method('error');
102+
103+
$this->listener->handle($event);
104+
}
105+
106+
public function testHandleUserDeletedWithMultipleAccounts(): void {
107+
$user = $this->createUserMock('test-user');
108+
$account1 = $this->createAccountMock(1);
109+
$account2 = $this->createAccountMock(2);
110+
$account3 = $this->createAccountMock(3);
111+
$event = new UserDeletedEvent($user);
112+
113+
$this->accountService->expects($this->once())
114+
->method('findByUserId')
115+
->with('test-user')
116+
->willReturn([$account1, $account2, $account3]);
117+
118+
$this->accountService->expects($this->exactly(3))
119+
->method('delete')
120+
->willReturnCallback(function ($userId, $accountId) {
121+
$this->assertSame('test-user', $userId);
122+
$this->assertContains($accountId, [1, 2, 3]);
123+
});
124+
125+
$this->logger->expects($this->never())
126+
->method('error');
127+
128+
$this->listener->handle($event);
129+
}
130+
131+
public function testHandleUserDeletedWithClientException(): void {
132+
$user = $this->createUserMock('test-user');
133+
$account = $this->createAccountMock(42);
134+
$event = new UserDeletedEvent($user);
135+
136+
$exception = new ClientException('Test exception');
137+
138+
$this->accountService->expects($this->once())
139+
->method('findByUserId')
140+
->with('test-user')
141+
->willReturn([$account]);
142+
143+
$this->accountService->expects($this->once())
144+
->method('delete')
145+
->with('test-user', 42)
146+
->willThrowException($exception);
147+
148+
$this->logger->expects($this->once())
149+
->method('error')
150+
->with(
151+
'Could not delete user\'s Mail account: Test exception',
152+
['exception' => $exception]
153+
);
154+
155+
$this->listener->handle($event);
156+
}
157+
158+
public function testHandleUserDeletedWithPartialFailure(): void {
159+
$user = $this->createUserMock('test-user');
160+
$account1 = $this->createAccountMock(1);
161+
$account2 = $this->createAccountMock(2);
162+
$account3 = $this->createAccountMock(3);
163+
$event = new UserDeletedEvent($user);
164+
165+
$exception = new ClientException('Failed to delete account 2');
166+
167+
$this->accountService->expects($this->once())
168+
->method('findByUserId')
169+
->with('test-user')
170+
->willReturn([$account1, $account2, $account3]);
171+
172+
$this->accountService->expects($this->exactly(3))
173+
->method('delete')
174+
->willReturnCallback(function ($userId, $accountId) use ($exception) {
175+
$this->assertSame('test-user', $userId);
176+
if ($accountId === 2) {
177+
throw $exception;
178+
}
179+
});
180+
181+
$this->logger->expects($this->once())
182+
->method('error')
183+
->with(
184+
'Could not delete user\'s Mail account: Failed to delete account 2',
185+
['exception' => $exception]
186+
);
187+
188+
$this->listener->handle($event);
189+
}
190+
}

0 commit comments

Comments
 (0)