Skip to content

Commit bec4321

Browse files
fix(sharereview): skip context navigation cleanup for non-context shares
Calling contextNavigationMapper::deleteByShareId() for every share deletion would be misleading since context navigation entries only exist for context-type shares. Fetching the share entity first lets us guard the cleanup call behind a node-type check, so it only runs when the deleted share actually belongs to a context. This removes the confusing and potentially spammy error log path that could appear for ordinary table and view share deletions. Assisted-by: ClaudeCode:claude-sonnet-4-6 Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
1 parent 525ca5e commit bec4321

2 files changed

Lines changed: 50 additions & 14 deletions

File tree

lib/ShareReview/ShareReviewSource.php

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
use OCA\Tables\Db\ShareMapper;
1616
use OCA\Tables\Db\TableMapper;
1717
use OCA\Tables\Db\ViewMapper;
18+
use OCP\AppFramework\Db\DoesNotExistException;
19+
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
1820
use OCP\Constants;
1921
use OCP\DB\Exception;
2022
use OCP\IL10N;
@@ -87,22 +89,30 @@ public function getShares(): array {
8789

8890
public function deleteShare(string $shareId): bool {
8991
$this->logger->info('Tables ShareReview: deleting share {id}', ['id' => $shareId]);
90-
try {
91-
$deleted = $this->shareMapper->deleteById((int)$shareId);
92-
} catch (Exception $e) {
93-
$this->logger->error('Tables ShareReview: failed to delete share {id}: {message}', ['id' => $shareId, 'message' => $e->getMessage()]);
94-
return false;
95-
}
9692

97-
if (!$deleted) {
93+
try {
94+
$share = $this->shareMapper->find((int)$shareId);
95+
} catch (DoesNotExistException) {
9896
$this->logger->warning('Tables ShareReview: share {id} not found', ['id' => $shareId]);
9997
return false;
98+
} catch (MultipleObjectsReturnedException|Exception $e) {
99+
$this->logger->error('Tables ShareReview: failed to find share {id}: {message}', ['id' => $shareId, 'message' => $e->getMessage()]);
100+
return false;
100101
}
101102

102103
try {
103-
$this->contextNavigationMapper->deleteByShareId((int)$shareId);
104+
$this->shareMapper->delete($share);
104105
} catch (Exception $e) {
105-
$this->logger->error('Tables ShareReview: failed to clean up context navigation for share {id}: {message}', ['id' => $shareId, 'message' => $e->getMessage()]);
106+
$this->logger->error('Tables ShareReview: failed to delete share {id}: {message}', ['id' => $shareId, 'message' => $e->getMessage()]);
107+
return false;
108+
}
109+
110+
if ($share->getNodeType() === self::NODE_TYPE_CONTEXT) {
111+
try {
112+
$this->contextNavigationMapper->deleteByShareId((int)$shareId);
113+
} catch (Exception $e) {
114+
$this->logger->error('Tables ShareReview: failed to clean up context navigation for share {id}: {message}', ['id' => $shareId, 'message' => $e->getMessage()]);
115+
}
106116
}
107117
return true;
108118
}

tests/unit/ShareReview/ShareReviewSourceTest.php

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@
1111

1212
use OCA\Tables\Db\ContextMapper;
1313
use OCA\Tables\Db\ContextNavigationMapper;
14+
use OCA\Tables\Db\Share;
1415
use OCA\Tables\Db\ShareMapper;
1516
use OCA\Tables\Db\TableMapper;
1617
use OCA\Tables\Db\ViewMapper;
1718
use OCA\Tables\ShareReview\ShareReviewSource;
19+
use OCP\AppFramework\Db\DoesNotExistException;
1820
use OCP\Constants;
1921
use OCP\DB\Exception;
2022
use OCP\IL10N;
@@ -225,16 +227,36 @@ public function testGetSharesReturnsEmptyOnDbException(): void {
225227
$this->assertSame([], $this->source->getShares());
226228
}
227229

228-
public function testDeleteShareSuccess(): void {
229-
$this->shareMapper->expects($this->once())->method('deleteById')->with(7)->willReturn(true);
230+
private function makeShare(int $id, string $nodeType): Share {
231+
$share = new Share();
232+
$share->setId($id);
233+
$share->setNodeType($nodeType);
234+
return $share;
235+
}
236+
237+
public function testDeleteShareTableSuccessSkipsContextNavCleanup(): void {
238+
$share = $this->makeShare(7, 'table');
239+
$this->shareMapper->expects($this->once())->method('find')->with(7)->willReturn($share);
240+
$this->shareMapper->expects($this->once())->method('delete')->with($share);
241+
$this->contextNavigationMapper->expects($this->never())->method('deleteByShareId');
242+
$this->logger->expects($this->once())->method('info');
243+
244+
$this->assertTrue($this->source->deleteShare('7'));
245+
}
246+
247+
public function testDeleteShareContextSuccessCleansUpContextNav(): void {
248+
$share = $this->makeShare(7, 'context');
249+
$this->shareMapper->expects($this->once())->method('find')->with(7)->willReturn($share);
250+
$this->shareMapper->expects($this->once())->method('delete')->with($share);
230251
$this->contextNavigationMapper->expects($this->once())->method('deleteByShareId')->with(7);
231252
$this->logger->expects($this->once())->method('info');
232253

233254
$this->assertTrue($this->source->deleteShare('7'));
234255
}
235256

236257
public function testDeleteShareNotFoundReturnsFalse(): void {
237-
$this->shareMapper->method('deleteById')->willReturn(false);
258+
$this->shareMapper->method('find')->willThrowException(new DoesNotExistException('not found'));
259+
$this->shareMapper->expects($this->never())->method('delete');
238260
$this->contextNavigationMapper->expects($this->never())->method('deleteByShareId');
239261
$this->logger->expects($this->once())->method('info');
240262
$this->logger->expects($this->once())->method('warning');
@@ -243,7 +265,9 @@ public function testDeleteShareNotFoundReturnsFalse(): void {
243265
}
244266

245267
public function testDeleteShareReturnsFalseOnDeleteException(): void {
246-
$this->shareMapper->method('deleteById')->willThrowException($this->createMock(Exception::class));
268+
$share = $this->makeShare(7, 'table');
269+
$this->shareMapper->method('find')->willReturn($share);
270+
$this->shareMapper->method('delete')->willThrowException($this->createMock(Exception::class));
247271
$this->contextNavigationMapper->expects($this->never())->method('deleteByShareId');
248272
$this->logger->expects($this->once())->method('info');
249273
$this->logger->expects($this->once())->method('error');
@@ -252,7 +276,9 @@ public function testDeleteShareReturnsFalseOnDeleteException(): void {
252276
}
253277

254278
public function testDeleteShareReturnsTrueOnContextNavigationException(): void {
255-
$this->shareMapper->method('deleteById')->willReturn(true);
279+
$share = $this->makeShare(42, 'context');
280+
$this->shareMapper->method('find')->willReturn($share);
281+
$this->shareMapper->method('delete');
256282
$this->contextNavigationMapper->method('deleteByShareId')->willThrowException($this->createMock(Exception::class));
257283
$this->logger->expects($this->once())->method('info');
258284
$this->logger->expects($this->once())->method('error');

0 commit comments

Comments
 (0)