Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/Activity/DeckProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ public function parse($language, IEvent $event, ?IEvent $previousEvent = null):

$subjectIdentifier = $event->getSubject();
$subjectParams = $event->getSubjectParameters();
$ownActivity = ($event->getAuthor() === $this->userId);

/**
* Map stored parameter objects to rich string types
Expand All @@ -85,6 +84,7 @@ public function parse($language, IEvent $event, ?IEvent $previousEvent = null):
$author = $subjectParams['author'];
unset($subjectParams['author']);
}
$ownActivity = ($author === $this->userId);
$user = $this->userManager->get($author);
$params = [];
if ($user !== null) {
Expand Down
5 changes: 4 additions & 1 deletion lib/Notification/NotificationHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ public function sendBoardShared(int $boardId, Acl $acl, bool $markAsRead = false
$notification = $this->generateBoardShared($board, $acl->getParticipant());
if ($markAsRead) {
$this->notificationManager->markProcessed($notification);
} else {
} elseif ($acl->getParticipant() !== $this->currentUser) {
$notification->setDateTime(new DateTime());
$this->notificationManager->notify($notification);
}
Expand All @@ -201,6 +201,9 @@ public function sendBoardShared(int $boardId, Acl $acl, bool $markAsRead = false

public function sendMention(IComment $comment): void {
foreach ($comment->getMentions() as $mention) {
if ((string)$mention['id'] === $this->currentUser) {
continue;
}
$card = $this->cardMapper->find($comment->getObjectId());
$boardId = $this->cardMapper->findBoardId($card->getId());
$notification = $this->notificationManager->createNotification();
Expand Down
116 changes: 116 additions & 0 deletions tests/unit/Notification/NotificationHelperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -527,4 +527,120 @@ public function testSendMention() {

$this->notificationHelper->sendMention($comment);
}

/**
* When a comment mentions the current user ('admin'), that mention must
* be silently skipped while other mentioned users still get notified.
*/
public function testSendMentionSkipsSelf() {
$comment = $this->createMock(IComment::class);
$comment->expects($this->any())
->method('getObjectId')
->willReturn(123);
$comment->expects($this->any())
->method('getMessage')
->willReturn('@admin @user1 This is a message.');
$comment->expects($this->once())
->method('getMentions')
->willReturn([
['id' => 'admin'],
['id' => 'user1']
]);
$card = new Card();
$card->setId(123);
$card->setTitle('MyCard');
$this->cardMapper->expects($this->any())
->method('find')
->with(123)
->willReturn($card);
$this->cardMapper->expects($this->any())
->method('findBoardId')
->with(123)
->willReturn(1);

// Only one notification should be created — for user1, not for admin
$notification = $this->createMock(INotification::class);
$notification->expects($this->once())->method('setApp')->with('deck')->willReturn($notification);
$notification->expects($this->once())->method('setUser')->with('user1')->willReturn($notification);
$notification->expects($this->once())->method('setObject')->with('card', 123)->willReturn($notification);
$notification->expects($this->once())->method('setSubject')->with('card-comment-mentioned', ['MyCard', 1, 'admin'])->willReturn($notification);
$notification->expects($this->once())->method('setDateTime')->willReturn($notification);

$this->notificationManager->expects($this->once())
->method('createNotification')
->willReturn($notification);
$this->notificationManager->expects($this->once())
->method('notify')
->with($notification);

$this->notificationHelper->sendMention($comment);
}

/**
* Sharing a board with yourself must not trigger a notification.
*/
public function testSendBoardSharedUserSkipsSelf() {
$board = new Board();
$board->setId(123);
$board->setTitle('MyBoardTitle');
$acl = new Acl();
$acl->setParticipant('admin');
$acl->setType(Acl::PERMISSION_TYPE_USER);
$this->boardMapper->expects($this->once())
->method('find')
->with(123)
->willReturn($board);

// generateBoardShared still creates the notification object,
// but notify() must never be called for the acting user
$notification = $this->createMock(INotification::class);
$notification->expects($this->once())->method('setApp')->with('deck')->willReturn($notification);
$notification->expects($this->once())->method('setUser')->with('admin')->willReturn($notification);
$notification->expects($this->once())->method('setObject')->with('board', 123)->willReturn($notification);
$notification->expects($this->once())->method('setSubject')->with('board-shared', ['MyBoardTitle', 'admin'])->willReturn($notification);

$this->notificationManager->expects($this->once())
->method('createNotification')
->willReturn($notification);
$this->notificationManager->expects($this->never())
->method('notify');

$this->notificationHelper->sendBoardShared(123, $acl);
}

/**
* Unsharing a board (markAsRead=true) must still clean up stale
* notifications via markProcessed, even when the participant is the
* acting user. This ensures pre-existing self-notifications get removed.
*/
public function testSendBoardSharedSelfMarkAsReadStillCleansUp() {
$board = new Board();
$board->setId(123);
$board->setTitle('MyBoardTitle');
$acl = new Acl();
$acl->setParticipant('admin');
$acl->setType(Acl::PERMISSION_TYPE_USER);
$this->boardMapper->expects($this->once())
->method('find')
->with(123)
->willReturn($board);

$notification = $this->createMock(INotification::class);
$notification->expects($this->once())->method('setApp')->with('deck')->willReturn($notification);
$notification->expects($this->once())->method('setUser')->with('admin')->willReturn($notification);
$notification->expects($this->once())->method('setObject')->with('board', 123)->willReturn($notification);
$notification->expects($this->once())->method('setSubject')->with('board-shared', ['MyBoardTitle', 'admin'])->willReturn($notification);

$this->notificationManager->expects($this->once())
->method('createNotification')
->willReturn($notification);
// markProcessed must be called to clean up any stale notification
$this->notificationManager->expects($this->once())
->method('markProcessed')
->with($notification);
$this->notificationManager->expects($this->never())
->method('notify');

$this->notificationHelper->sendBoardShared(123, $acl, true);
}
}