diff --git a/lib/Notification/NotificationHelper.php b/lib/Notification/NotificationHelper.php index b2d0a9aa9..e4a6f21ee 100644 --- a/lib/Notification/NotificationHelper.php +++ b/lib/Notification/NotificationHelper.php @@ -94,6 +94,24 @@ public function sendCardDuedate($card) { $this->cardMapper->markNotified($card); } + public function sendCardAssigned($card, $userId) { + $boardId = $this->cardMapper->findBoardId($card->getId()); + $board = $this->getBoard($boardId); + + $notification = $this->notificationManager->createNotification(); + $notification + ->setApp('deck') + ->setUser((string) $userId) + ->setDateTime(new DateTime()) + ->setObject('card', $card->getId()) + ->setSubject('card-assigned', [ + $card->getTitle(), + $board->getTitle(), + $this->currentUser + ]); + $this->notificationManager->notify($notification); + } + /** * Send notifications that a board was shared with a user/group * diff --git a/lib/Notification/Notifier.php b/lib/Notification/Notifier.php index 1049a8201..fd54fe88b 100644 --- a/lib/Notification/Notifier.php +++ b/lib/Notification/Notifier.php @@ -73,6 +73,30 @@ public function prepare(INotification $notification, $languageCode) { $params = $notification->getSubjectParameters(); switch ($notification->getSubject()) { + case 'card-assigned': + $cardId = $notification->getObjectId(); + $boardId = $this->cardMapper->findBoardId($cardId); + $initiator = $this->userManager->get($params[2]); + if ($initiator !== null) { + $dn = $initiator->getDisplayName(); + } else { + $dn = $params[2]; + } + $notification->setParsedSubject( + (string) $l->t('The card "%s" on "%s" has been assigned to you by %s.', [$params[0], $params[1], $dn]) + ); + $notification->setRichSubject( + (string) $l->t('{user} has assigned the card "%s" on "%s" to you.', [$params[0], $params[1]]), + [ + 'user' => [ + 'type' => 'user', + 'id' => $params[2], + 'name' => $dn, + ] + ] + ); + $notification->setLink($this->url->linkToRouteAbsolute('deck.page.index') . '#!/board/' . $boardId . '//card/' . $cardId . ''); + break; case 'card-overdue': $cardId = $notification->getObjectId(); $boardId = $this->cardMapper->findBoardId($cardId); diff --git a/lib/Service/CardService.php b/lib/Service/CardService.php index 26fa3753c..a9b7ae7a2 100644 --- a/lib/Service/CardService.php +++ b/lib/Service/CardService.php @@ -29,6 +29,7 @@ use OCA\Deck\Db\CardMapper; use OCA\Deck\Db\Acl; use OCA\Deck\Db\StackMapper; +use OCA\Deck\Notification\NotificationHelper; use OCA\Deck\NotFoundException; use OCA\Deck\StatusException; @@ -39,16 +40,20 @@ class CardService { private $stackMapper; private $permissionService; private $boardService; + private $notificationHelper; private $assignedUsersMapper; private $attachmentService; + private $currentUser; - public function __construct(CardMapper $cardMapper, StackMapper $stackMapper, PermissionService $permissionService, BoardService $boardService, AssignedUsersMapper $assignedUsersMapper, AttachmentService $attachmentService) { + public function __construct(CardMapper $cardMapper, StackMapper $stackMapper, PermissionService $permissionService, BoardService $boardService, NotificationHelper $notificationHelper, AssignedUsersMapper $assignedUsersMapper, AttachmentService $attachmentService, $userId) { $this->cardMapper = $cardMapper; $this->stackMapper = $stackMapper; $this->permissionService = $permissionService; $this->boardService = $boardService; + $this->notificationHelper = $notificationHelper; $this->assignedUsersMapper = $assignedUsersMapper; $this->attachmentService = $attachmentService; + $this->currentUser = $userId; } public function find($cardId) { @@ -202,6 +207,13 @@ public function assignUser($cardId, $userId) { return false; } } + + if ($userId !== $this->currentUser) { + /* Notifyuser about the card assignment */ + $card = $this->cardMapper->find($cardId); + $this->notificationHelper->sendCardAssigned($card, $userId); + } + $assignment = new AssignedUsers(); $assignment->setCardId($cardId); $assignment->setParticipant($userId); diff --git a/tests/unit/Notification/NotificationHelperTest.php b/tests/unit/Notification/NotificationHelperTest.php index c6625777a..c9c11bc70 100644 --- a/tests/unit/Notification/NotificationHelperTest.php +++ b/tests/unit/Notification/NotificationHelperTest.php @@ -184,6 +184,49 @@ public function testSendCardDuedate() { $this->notificationHelper->sendCardDuedate($card); } + public function testSendCardAssignedUser() { + $board = new Board(); + $board->setId(123); + $board->setTitle('MyBoardTitle'); + $this->boardMapper->expects($this->once()) + ->method('find') + ->with(123) + ->willReturn($board); + + $acl = new Acl(); + $acl->setParticipant('admin'); + $acl->setType(Acl::PERMISSION_TYPE_USER); + + $card = new Card(); + $card->setTitle('MyCardTitle'); + $card->setOwner('admin'); + $card->setStackId(123); + $card->setOrder(999); + $card->setType('text'); + $card->setId(1337); + $card->setAssignedUsers(['userA']); + $this->cardMapper->expects($this->once()) + ->method('findBoardId') + ->with(1337) + ->willReturn(123); + + $notification = $this->createMock(INotification::class); + $notification->expects($this->once())->method('setApp')->with('deck')->willReturn($notification); + $notification->expects($this->once())->method('setUser')->with('userA')->willReturn($notification); + $notification->expects($this->once())->method('setObject')->with('card', 1337)->willReturn($notification); + $notification->expects($this->once())->method('setSubject')->with('card-assigned', ['MyCardTitle', 'MyBoardTitle', 'admin'])->willReturn($notification); + $notification->expects($this->once())->method('setDateTime')->willReturn($notification); + + $this->notificationManager->expects($this->at(0)) + ->method('createNotification') + ->willReturn($notification); + $this->notificationManager->expects($this->at(1)) + ->method('notify') + ->with($notification); + + $this->notificationHelper->sendCardAssigned($card, 'userA'); + } + public function testSendBoardSharedUser() { $board = new Board(); $board->setId(123); diff --git a/tests/unit/Notification/NotifierTest.php b/tests/unit/Notification/NotifierTest.php index 406196221..3d8992cdd 100644 --- a/tests/unit/Notification/NotifierTest.php +++ b/tests/unit/Notification/NotifierTest.php @@ -129,11 +129,82 @@ public function testPrepareCardOverdue() { } + public function dataPrepareCardAssigned() { + return [ + [true], [false] + ]; + } + + /** @dataProvider dataPrepareCardAssigned */ + public function testPrepareCardAssigned($withUserFound = true) { + /** @var INotification $notification */ + $notification = $this->createMock(INotification::class); + $notification->expects($this->once()) + ->method('getApp') + ->willReturn('deck'); + + $notification->expects($this->once()) + ->method('getSubjectParameters') + ->willReturn(['Card title','Board title', 'otheruser']); + + $notification->expects($this->once()) + ->method('getSubject') + ->willReturn('card-assigned'); + $notification->expects($this->once()) + ->method('getObjectId') + ->willReturn('123'); + if ($withUserFound) { + $user = $this->createMock(IUser::class); + $user->expects($this->any()) + ->method('getDisplayName') + ->willReturn('Other User'); + $dn = 'Other User'; + } else { + $user = null; + $dn = 'otheruser'; + } + $this->userManager->expects($this->once()) + ->method('get') + ->with('otheruser') + ->willReturn($user); + + $expectedMessage = 'The card "Card title" on "Board title" has been assigned to you by '.$dn.'.'; + $notification->expects($this->once()) + ->method('setParsedSubject') + ->with($expectedMessage); + $notification->expects($this->once()) + ->method('setRichSubject') + ->with('{user} has assigned the card "Card title" on "Board title" to you.', [ + 'user' => [ + 'type' => 'user', + 'id' => 'otheruser', + 'name' => $dn, + ] + ]); + + $this->url->expects($this->once()) + ->method('imagePath') + ->with('deck', 'deck-dark.svg') + ->willReturn('deck-dark.svg'); + $this->url->expects($this->once()) + ->method('getAbsoluteURL') + ->with('deck-dark.svg') + ->willReturn('/absolute/deck-dark.svg'); + $notification->expects($this->once()) + ->method('setIcon') + ->with('/absolute/deck-dark.svg'); + + $actualNotification = $this->notifier->prepare($notification, 'en_US'); + + $this->assertEquals($notification, $actualNotification); + } + public function dataPrepareBoardShared() { return [ [true], [false] ]; } + /** @dataProvider dataPrepareBoardShared */ public function testPrepareBoardShared($withUserFound = true) { /** @var INotification $notification */ diff --git a/tests/unit/Service/CardServiceTest.php b/tests/unit/Service/CardServiceTest.php index 0822bab3d..0f850c006 100644 --- a/tests/unit/Service/CardServiceTest.php +++ b/tests/unit/Service/CardServiceTest.php @@ -30,6 +30,7 @@ use OCA\Deck\Db\CardMapper; use OCA\Deck\Db\StackMapper; use OCA\Deck\NotFoundException; +use OCA\Deck\Notification\NotificationHelper; use OCA\Deck\StatusException; use Test\TestCase; @@ -43,6 +44,8 @@ class CardServiceTest extends TestCase { private $stackMapper; /** @var PermissionService|\PHPUnit\Framework\MockObject\MockObject */ private $permissionService; + /** @var NotificationHelper */ + private $notificationHelper; /** @var AssignedUsersMapper|\PHPUnit\Framework\MockObject\MockObject */ private $assignedUsersMapper; /** @var BoardService|\PHPUnit\Framework\MockObject\MockObject */ @@ -54,9 +57,10 @@ public function setUp() { $this->stackMapper = $this->createMock(StackMapper::class); $this->permissionService = $this->createMock(PermissionService::class); $this->boardService = $this->createMock(BoardService::class); + $this->notificationHelper = $this->createMock(NotificationHelper::class); $this->assignedUsersMapper = $this->createMock(AssignedUsersMapper::class); $this->attachmentService = $this->createMock(AttachmentService::class); - $this->cardService = new CardService($this->cardMapper, $this->stackMapper, $this->permissionService, $this->boardService, $this->assignedUsersMapper, $this->attachmentService); + $this->cardService = new CardService($this->cardMapper, $this->stackMapper, $this->permissionService, $this->boardService, $this->notificationHelper, $this->assignedUsersMapper, $this->attachmentService, 'userXY'); } public function testFind() {