Skip to content

Commit 530539d

Browse files
committed
add unit test
Signed-off-by: samin-z <samin.zavarkesh@gmail.com>
1 parent f52297e commit 530539d

3 files changed

Lines changed: 284 additions & 2 deletions

File tree

lib/Db/BoardMapper.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ public function findAllByOwner(string $userId, ?int $limit = null, ?int $offset
308308

309309
/**
310310
* Find all board with the team_id set to the given teamId
311-
*
311+
*
312312
* @return Board[]
313313
*/
314314
public function findAllAttachedToTeam(string $teamId): array {

tests/unit/Service/BoardServiceTest.php

Lines changed: 130 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@
3131
use OC\Federation\CloudIdManager;
3232
use OC\L10N\L10N;
3333
use OC\Security\SecureRandom;
34+
use OCA\Circles\Model\Circle;
3435
use OCA\Deck\Activity\ActivityManager;
36+
use OCA\Deck\BadRequestException;
3537
use OCA\Deck\Db\Acl;
3638
use OCA\Deck\Db\AclMapper;
3739
use OCA\Deck\Db\Assignment;
@@ -104,6 +106,9 @@ class BoardServiceTest extends TestCase {
104106
/** @var IUserManager */
105107
private $userManager;
106108

109+
/** @var CirclesService|MockObject */
110+
private $circlesService;
111+
107112
public function setUp(): void {
108113
parent::setUp();
109114
$this->l10n = $this->createMock(L10N::class);
@@ -125,6 +130,7 @@ public function setUp(): void {
125130
$this->boardServiceValidator = $this->createMock(BoardServiceValidator::class);
126131
$this->sessionMapper = $this->createMock(SessionMapper::class);
127132
$this->userManager = $this->createMock(IUserManager::class);
133+
$this->circlesService = $this->createMock(CirclesService::class);
128134

129135
$this->service = new BoardService(
130136
$this->boardMapper,
@@ -151,7 +157,7 @@ public function setUp(): void {
151157
$this->userManager,
152158
$this->createMock(SecureRandom::class),
153159
$this->createMock(ConfigService::class),
154-
$this->createMock(CirclesService::class),
160+
$this->circlesService,
155161
$this->userId
156162
);
157163

@@ -227,6 +233,129 @@ public function testCreateDenied() {
227233
$b = $this->service->create('MyBoard', 'admin', '00ff00');
228234
}
229235

236+
public function testCreateForTeamEmptyTeamId(): void {
237+
$this->expectException(BadRequestException::class);
238+
$this->service->createForTeam('Team board', $this->userId, '00ff00', '');
239+
}
240+
241+
public function testCreateForTeamCirclesDisabled(): void {
242+
$this->circlesService->expects($this->once())
243+
->method('isCirclesEnabled')
244+
->willReturn(false);
245+
$this->expectException(BadRequestException::class);
246+
$this->service->createForTeam('Team board', $this->userId, '00ff00', 'team-a');
247+
}
248+
249+
public function testCreateForTeamNotFound(): void {
250+
$this->circlesService->expects($this->once())
251+
->method('isCirclesEnabled')
252+
->willReturn(true);
253+
$this->circlesService->expects($this->once())
254+
->method('getCircle')
255+
->with('team-a')
256+
->willReturn(null);
257+
$this->expectException(BadRequestException::class);
258+
$this->service->createForTeam('Team board', $this->userId, '00ff00', 'team-a');
259+
}
260+
261+
public function testCreateForTeamNotMember(): void {
262+
$this->circlesService->expects($this->once())
263+
->method('isCirclesEnabled')
264+
->willReturn(true);
265+
$this->circlesService->expects($this->once())
266+
->method('getCircle')
267+
->with('team-a')
268+
->willReturn($this->createMock(Circle::class));
269+
$this->circlesService->expects($this->once())
270+
->method('isUserInCircle')
271+
->with('team-a', $this->userId)
272+
->willReturn(false);
273+
$this->expectException(NoPermissionException::class);
274+
$this->service->createForTeam('Team board', $this->userId, '00ff00', 'team-a');
275+
}
276+
277+
public function testCreateForTeamSuccess(): void {
278+
$createdBoard = new Board();
279+
$createdBoard->setId(42);
280+
$createdBoard->setTitle('Team board');
281+
$createdBoard->setOwner($this->userId);
282+
$createdBoard->setColor('00ff00');
283+
284+
$updatedBoard = new Board();
285+
$updatedBoard->setId(42);
286+
$updatedBoard->setTitle('Team board');
287+
$updatedBoard->setOwner($this->userId);
288+
$updatedBoard->setColor('00ff00');
289+
$updatedBoard->setTeamId('team-a');
290+
291+
$this->circlesService->expects($this->once())
292+
->method('isCirclesEnabled')
293+
->willReturn(true);
294+
$this->circlesService->expects($this->once())
295+
->method('getCircle')
296+
->with('team-a')
297+
->willReturn($this->createMock(Circle::class));
298+
$this->circlesService->expects($this->once())
299+
->method('isUserInCircle')
300+
->with('team-a', $this->userId)
301+
->willReturn(true);
302+
303+
/** @var BoardService|MockObject $service */
304+
$service = $this->getMockBuilder(BoardService::class)
305+
->setConstructorArgs([
306+
$this->boardMapper,
307+
$this->stackMapper,
308+
$this->cardMapper,
309+
$this->config,
310+
$this->l10n,
311+
$this->labelMapper,
312+
$this->aclMapper,
313+
$this->permissionService,
314+
$this->assignmentService,
315+
$this->notificationHelper,
316+
$this->assignedUsersMapper,
317+
$this->activityManager,
318+
$this->createMock(CloudFederationProviderManager::class),
319+
$this->createMock(CloudIdManager::class),
320+
$this->createMock(CloudFederationFactory::class),
321+
$this->eventDispatcher,
322+
$this->changeHelper,
323+
$this->urlGenerator,
324+
$this->connection,
325+
$this->boardServiceValidator,
326+
$this->sessionMapper,
327+
$this->userManager,
328+
$this->createMock(SecureRandom::class),
329+
$this->createMock(ConfigService::class),
330+
$this->circlesService,
331+
$this->userId,
332+
])
333+
->onlyMethods(['create', 'addAcl', 'find'])
334+
->getMock();
335+
336+
$service->expects($this->once())
337+
->method('create')
338+
->with('Team board', $this->userId, '00ff00')
339+
->willReturn($createdBoard);
340+
$this->boardMapper->expects($this->once())
341+
->method('update')
342+
->with($this->callback(function (Board $board) {
343+
return $board->getId() === 42 && $board->getTeamId() === 'team-a';
344+
}))
345+
->willReturn($updatedBoard);
346+
$service->expects($this->once())
347+
->method('addAcl')
348+
->with(42, Acl::PERMISSION_TYPE_CIRCLE, 'team-a', true, false, false);
349+
$service->expects($this->once())
350+
->method('find')
351+
->with(42)
352+
->willReturn($updatedBoard);
353+
354+
$result = $service->createForTeam('Team board', $this->userId, '00ff00', 'team-a');
355+
$this->assertSame($updatedBoard, $result);
356+
$this->assertEquals('team-a', $result->getTeamId());
357+
}
358+
230359
public function testUpdate() {
231360
$board = new Board();
232361
$board->setId(123);
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
/**
6+
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
7+
* SPDX-License-Identifier: AGPL-3.0-or-later
8+
*/
9+
10+
namespace OCA\Deck\Service;
11+
12+
use OCA\Deck\Db\Board;
13+
use OCA\Deck\Db\BoardMapper;
14+
use PHPUnit\Framework\MockObject\MockObject;
15+
use Test\TestCase;
16+
17+
class TeamBoardServiceTest extends TestCase {
18+
/** @var BoardMapper|MockObject */
19+
private $boardMapper;
20+
/** @var CirclesService|MockObject */
21+
private $circlesService;
22+
private TeamBoardService $service;
23+
private $userId1 = 'user1';
24+
private $userId2 = 'user2';
25+
26+
public function setUp(): void {
27+
parent::setUp();
28+
$this->boardMapper = $this->createMock(BoardMapper::class);
29+
$this->circlesService = $this->createMock(CirclesService::class);
30+
$this->service = new TeamBoardService(
31+
$this->boardMapper,
32+
$this->circlesService,
33+
);
34+
}
35+
36+
public function testTransferTeamBoardsFromDeletedUser(): void {
37+
$personalBoard = new Board();
38+
$personalBoard->setId(1);
39+
$personalBoard->setOwner($this->userId1);
40+
$personalBoard->setTeamId(null);
41+
42+
$orphanedTeamBoard = new Board();
43+
$orphanedTeamBoard->setId(2);
44+
$orphanedTeamBoard->setOwner($this->userId1);
45+
$orphanedTeamBoard->setTeamId('team-a');
46+
47+
$transferableBoard = new Board();
48+
$transferableBoard->setId(3);
49+
$transferableBoard->setOwner($this->userId1);
50+
$transferableBoard->setTeamId('team-b');
51+
52+
$this->boardMapper->expects($this->once())
53+
->method('findAllByOwner')
54+
->with($this->userId1)
55+
->willReturn([$personalBoard, $orphanedTeamBoard, $transferableBoard]);
56+
57+
$this->circlesService->expects($this->exactly(2))
58+
->method('findNextMemberUserId')
59+
->willReturnMap([
60+
['team-a', $this->userId1, null],
61+
['team-b', $this->userId1, $this->userId2],
62+
]);
63+
64+
$this->boardMapper->expects($this->once())
65+
->method('transferOwnership')
66+
->with($this->userId1, $this->userId2, 3);
67+
68+
$this->assertSame([3], $this->service->transferTeamBoardsFromDeletedUser($this->userId1));
69+
}
70+
71+
public function testHandleMemberLeftTeamTransfersOwnership(): void {
72+
$board = new Board();
73+
$board->setId(10);
74+
$board->setOwner($this->userId1);
75+
$board->setTeamId('team-a');
76+
77+
$this->boardMapper->expects($this->once())
78+
->method('findAllAttachedToTeam')
79+
->with('team-a')
80+
->willReturn([$board]);
81+
$this->circlesService->expects($this->once())
82+
->method('findNextMemberUserId')
83+
->with('team-a', $this->userId1)
84+
->willReturn($this->userId2);
85+
$this->boardMapper->expects($this->once())
86+
->method('transferOwnership')
87+
->with($this->userId1, $this->userId2, 10);
88+
$this->boardMapper->expects($this->never())
89+
->method('delete');
90+
91+
$this->service->handleMemberLeftTeam('team-a', $this->userId1);
92+
}
93+
94+
public function testHandleMemberLeftTeamDeletesWhenNoNextMember(): void {
95+
$board = new Board();
96+
$board->setId(11);
97+
$board->setOwner($this->userId1);
98+
$board->setTeamId('team-a');
99+
100+
$this->boardMapper->expects($this->once())
101+
->method('findAllAttachedToTeam')
102+
->with('team-a')
103+
->willReturn([$board]);
104+
$this->circlesService->expects($this->once())
105+
->method('findNextMemberUserId')
106+
->with('team-a', $this->userId1)
107+
->willReturn(null);
108+
$this->boardMapper->expects($this->once())
109+
->method('delete')
110+
->with($board);
111+
$this->boardMapper->expects($this->never())
112+
->method('transferOwnership');
113+
114+
$this->service->handleMemberLeftTeam('team-a', $this->userId1);
115+
}
116+
117+
public function testHandleMemberLeftTeamSkipsNonOwnerBoards(): void {
118+
$board = new Board();
119+
$board->setId(12);
120+
$board->setOwner($this->userId2);
121+
$board->setTeamId('team-a');
122+
123+
$this->boardMapper->expects($this->once())
124+
->method('findAllAttachedToTeam')
125+
->with('team-a')
126+
->willReturn([$board]);
127+
$this->circlesService->expects($this->never())
128+
->method('findNextMemberUserId');
129+
$this->boardMapper->expects($this->never())
130+
->method('transferOwnership');
131+
$this->boardMapper->expects($this->never())
132+
->method('delete');
133+
134+
$this->service->handleMemberLeftTeam('team-a', $this->userId1);
135+
}
136+
137+
public function testDeleteBoardsAttachedToTeam(): void {
138+
$boardA = new Board();
139+
$boardA->setId(20);
140+
$boardB = new Board();
141+
$boardB->setId(21);
142+
143+
$this->boardMapper->expects($this->once())
144+
->method('findAllAttachedToTeam')
145+
->with('team-a')
146+
->willReturn([$boardA, $boardB]);
147+
$this->boardMapper->expects($this->exactly(2))
148+
->method('delete')
149+
->withConsecutive([$boardA], [$boardB]);
150+
151+
$this->service->deleteBoardsAttachedToTeam('team-a');
152+
}
153+
}

0 commit comments

Comments
 (0)