Skip to content

Commit 13a852e

Browse files
Fix notification card links to use redirect URL
- Change card notifications to use redirectToCard route instead of direct board/card URL - This ensures notifications properly open the card modal regardless of current state - Add getCardRedirectUrl method to Notifier class - Update tests to verify redirect URL functionality - Fixes issue #2469: Notifications should open card
1 parent 278b8e4 commit 13a852e

File tree

2 files changed

+52
-3
lines changed

2 files changed

+52
-3
lines changed

lib/Notification/Notifier.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ public function prepare(INotification $notification, string $languageCode): INot
125125
]
126126
]
127127
);
128-
$notification->setLink($this->getCardUrl($boardId, $cardId));
128+
$notification->setLink($this->getCardRedirectUrl($cardId));
129129
break;
130130
case 'card-overdue':
131131
$cardId = (int)$notification->getObjectId();
@@ -157,7 +157,7 @@ public function prepare(INotification $notification, string $languageCode): INot
157157
],
158158
]
159159
);
160-
$notification->setLink($this->getCardUrl($boardId, $cardId));
160+
$notification->setLink($this->getCardRedirectUrl($cardId));
161161
break;
162162
case 'card-comment-mentioned':
163163
$cardId = (int)$notification->getObjectId();
@@ -197,7 +197,7 @@ public function prepare(INotification $notification, string $languageCode): INot
197197
if ($notification->getMessage() === '{message}') {
198198
$notification->setParsedMessage($notification->getMessageParameters()['message']);
199199
}
200-
$notification->setLink($this->getCardUrl($boardId, $cardId));
200+
$notification->setLink($this->getCardRedirectUrl($cardId));
201201
break;
202202
case 'board-shared':
203203
$boardId = (int)$notification->getObjectId();
@@ -253,4 +253,8 @@ private function getBoardUrl(int $boardId): string {
253253
private function getCardUrl(int $boardId, int $cardId): string {
254254
return $this->url->linkToRouteAbsolute('deck.page.indexCard', ['boardId' => $boardId, 'cardId' => $cardId]);
255255
}
256+
257+
private function getCardRedirectUrl(int $cardId): string {
258+
return $this->url->linkToRouteAbsolute('deck.page.redirectToCard', ['cardId' => $cardId]);
259+
}
256260
}

tests/unit/Notification/NotifierTest.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ public function setUp(): void {
8383
return match ($route) {
8484
'deck.page.indexBoard' => '/board/123',
8585
'deck.page.indexCard' => '/board/123/card/234',
86+
'deck.page.redirectToCard' => '/card/234',
8687
};
8788
});
8889
}
@@ -135,6 +136,9 @@ public function testPrepareCardOverdue() {
135136
$notification->expects($this->once())
136137
->method('setIcon')
137138
->with('/absolute/deck-dark.svg');
139+
$notification->expects($this->once())
140+
->method('setLink')
141+
->with('/card/123');
138142

139143
$actualNotification = $this->notifier->prepare($notification, 'en_US');
140144

@@ -351,6 +355,47 @@ public function testPrepareBoardShared($withUserFound = true) {
351355
$this->assertEquals($notification, $actualNotification);
352356
}
353357

358+
public function testPrepareCardAssigned() {
359+
/** @var INotification|MockObject $notification */
360+
$notification = $this->createMock(INotification::class);
361+
$notification->expects($this->once())
362+
->method('getApp')
363+
->willReturn('deck');
364+
365+
$notification->expects($this->once())
366+
->method('getSubjectParameters')
367+
->willReturn(['Card title','Board title', 'admin']);
368+
369+
$notification->expects($this->once())
370+
->method('getSubject')
371+
->willReturn('card-assigned');
372+
$notification->expects($this->once())
373+
->method('getObjectId')
374+
->willReturn('123');
375+
$this->stackMapper->expects($this->once())
376+
->method('findStackFromCardId')
377+
->willReturn($this->buildMockStack());
378+
379+
$this->url->expects($this->once())
380+
->method('imagePath')
381+
->with('deck', 'deck-dark.svg')
382+
->willReturn('deck-dark.svg');
383+
$this->url->expects($this->once())
384+
->method('getAbsoluteURL')
385+
->with('deck-dark.svg')
386+
->willReturn('/absolute/deck-dark.svg');
387+
$notification->expects($this->once())
388+
->method('setIcon')
389+
->with('/absolute/deck-dark.svg');
390+
$notification->expects($this->once())
391+
->method('setLink')
392+
->with('/card/123');
393+
394+
$actualNotification = $this->notifier->prepare($notification, 'en_US');
395+
396+
$this->assertEquals($notification, $actualNotification);
397+
}
398+
354399
/**
355400
* @param int $boardId
356401
* @return Stack|MockObject

0 commit comments

Comments
 (0)