diff options
author | Joas Schilling <213943+nickvergessen@users.noreply.github.com> | 2021-06-14 16:54:05 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-14 16:54:05 +0300 |
commit | 5be186b1a4b32f888548ad16d70b1b8921da77ea (patch) | |
tree | 4054309d684f274c93050374554fbb4c00df7d5f | |
parent | bbea16e523f5d5c9a19c6aa3a2e970b33bcf1175 (diff) | |
parent | ad1de57c4cebb01268b9445fca48c8e6a4747ba7 (diff) |
Merge pull request #5749 from nextcloud/bugfix/5730/add-system-messages-for-group-attendees
Add system messages for group attendees
-rw-r--r-- | docs/chat.md | 2 | ||||
-rw-r--r-- | lib/AppInfo/Application.php | 4 | ||||
-rw-r--r-- | lib/Chat/Parser/SystemMessage.php | 44 | ||||
-rw-r--r-- | lib/Chat/SystemMessage/Listener.php | 30 | ||||
-rw-r--r-- | lib/Events/AttendeesAddedEvent.php | 27 | ||||
-rw-r--r-- | lib/Events/AttendeesEvent.php | 45 | ||||
-rw-r--r-- | lib/Events/AttendeesRemovedEvent.php | 27 | ||||
-rw-r--r-- | lib/Service/ParticipantService.php | 45 | ||||
-rw-r--r-- | tests/integration/features/chat/reply.feature | 1 | ||||
-rw-r--r-- | tests/integration/features/chat/system-messages.feature | 1 | ||||
-rw-r--r-- | tests/php/Chat/Parser/SystemMessageTest.php | 100 |
11 files changed, 322 insertions, 4 deletions
diff --git a/docs/chat.md b/docs/chat.md index d3da178b8..d102a1b18 100644 --- a/docs/chat.md +++ b/docs/chat.md @@ -261,6 +261,8 @@ See [OCP\RichObjectStrings\Definitions](https://github.com/nextcloud/server/blob * `password_removed` - {actor} removed the password for the conversation * `user_added` - {actor} added {user} to the conversation * `user_removed` - {actor} removed {user} from the conversation +* `group_added` - {actor} added group {group} to the conversation +* `group_removed` - {actor} removed group {group} from the conversation * `moderator_promoted` - {actor} promoted {user} to moderator * `moderator_demoted` - {actor} demoted {user} from moderator * `guest_moderator_promoted` - {actor} promoted {user} to moderator diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 9f624d178..f18a1c2ae 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -36,6 +36,8 @@ use OCA\Talk\Collaboration\Resources\ConversationProvider; use OCA\Talk\Collaboration\Resources\Listener as ResourceListener; use OCA\Talk\Config; use OCA\Talk\Dashboard\TalkWidget; +use OCA\Talk\Events\AttendeesAddedEvent; +use OCA\Talk\Events\AttendeesRemovedEvent; use OCA\Talk\Events\ChatEvent; use OCA\Talk\Events\RoomEvent; use OCA\Talk\Deck\DeckPluginLoader; @@ -111,6 +113,8 @@ class Application extends App implements IBootstrap { $context->registerEventListener(UserChangedEvent::class, UserDisplayNameListener::class); $context->registerEventListener(\OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent::class, DeckPluginLoader::class); $context->registerEventListener(RegisterOperationsEvent::class, RegisterOperationsListener::class); + $context->registerEventListener(AttendeesAddedEvent::class, SystemMessageListener::class); + $context->registerEventListener(AttendeesRemovedEvent::class, SystemMessageListener::class); $context->registerSearchProvider(ConversationSearch::class); $context->registerSearchProvider(CurrentMessageSearch::class); diff --git a/lib/Chat/Parser/SystemMessage.php b/lib/Chat/Parser/SystemMessage.php index 669ac3f8a..ce71303c0 100644 --- a/lib/Chat/Parser/SystemMessage.php +++ b/lib/Chat/Parser/SystemMessage.php @@ -35,6 +35,8 @@ use OCP\Files\InvalidPathException; use OCP\Files\IRootFolder; use OCP\Files\Node; use OCP\Files\NotFoundException; +use OCP\IGroup; +use OCP\IGroupManager; use OCP\IL10N; use OCP\IPreview as IPreviewManager; use OCP\IURLGenerator; @@ -46,6 +48,8 @@ class SystemMessage { /** @var IUserManager */ protected $userManager; + /** @var IGroupManager */ + protected $groupManager; /** @var GuestManager */ protected $guestManager; /** @var IPreviewManager */ @@ -62,15 +66,19 @@ class SystemMessage { /** @var string[] */ protected $displayNames = []; /** @var string[] */ + protected $groupNames = []; + /** @var string[] */ protected $guestNames = []; public function __construct(IUserManager $userManager, + IGroupManager $groupManager, GuestManager $guestManager, IPreviewManager $previewManager, RoomShareProvider $shareProvider, IRootFolder $rootFolder, IURLGenerator $url) { $this->userManager = $userManager; + $this->groupManager = $groupManager; $this->guestManager = $guestManager; $this->previewManager = $previewManager; $this->shareProvider = $shareProvider; @@ -270,6 +278,22 @@ class SystemMessage { $parsedMessage = $this->l->t('An administrator removed {user}'); } } + } elseif ($message === 'group_added') { + $parsedParameters['group'] = $this->getGroup($parameters['group']); + $parsedMessage = $this->l->t('{actor} added group {group}'); + if ($currentUserIsActor) { + $parsedMessage = $this->l->t('You added group {group}'); + } elseif ($cliIsActor) { + $parsedMessage = $this->l->t('An administrator added group {group}'); + } + } elseif ($message === 'group_removed') { + $parsedParameters['group'] = $this->getGroup($parameters['group']); + $parsedMessage = $this->l->t('{actor} removed group {group}'); + if ($currentUserIsActor) { + $parsedMessage = $this->l->t('You removed group {group}'); + } elseif ($cliIsActor) { + $parsedMessage = $this->l->t('An administrator removed group {group}'); + } } elseif ($message === 'moderator_promoted') { $parsedParameters['user'] = $this->getUser($parameters['user']); $parsedMessage = $this->l->t('{actor} promoted {user} to moderator'); @@ -519,6 +543,18 @@ class SystemMessage { ]; } + protected function getGroup(string $gid): array { + if (!isset($this->groupNames[$gid])) { + $this->groupNames[$gid] = $this->getDisplayNameGroup($gid); + } + + return [ + 'type' => 'group', + 'id' => $gid, + 'name' => $this->groupNames[$gid], + ]; + } + protected function getDisplayName(string $uid): string { $user = $this->userManager->get($uid); if ($user instanceof IUser) { @@ -527,6 +563,14 @@ class SystemMessage { return $uid; } + protected function getDisplayNameGroup(string $gid): string { + $group = $this->groupManager->get($gid); + if ($group instanceof IGroup) { + return $group->getDisplayName(); + } + return $gid; + } + protected function getGuest(Room $room, string $actorId): array { if (!isset($this->guestNames[$actorId])) { $this->guestNames[$actorId] = $this->getGuestName($room, $actorId); diff --git a/lib/Chat/SystemMessage/Listener.php b/lib/Chat/SystemMessage/Listener.php index c36af4980..4b1facb3e 100644 --- a/lib/Chat/SystemMessage/Listener.php +++ b/lib/Chat/SystemMessage/Listener.php @@ -25,6 +25,8 @@ namespace OCA\Talk\Chat\SystemMessage; use OCA\Talk\Chat\ChatManager; use OCA\Talk\Events\AddParticipantsEvent; +use OCA\Talk\Events\AttendeesAddedEvent; +use OCA\Talk\Events\AttendeesRemovedEvent; use OCA\Talk\Events\ModifyLobbyEvent; use OCA\Talk\Events\ModifyParticipantEvent; use OCA\Talk\Events\ModifyRoomEvent; @@ -40,14 +42,16 @@ use OCA\Talk\Share\RoomShareProvider; use OCA\Talk\TalkSession; use OCA\Talk\Webinary; use OCP\AppFramework\Utility\ITimeFactory; +use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventDispatcher; +use OCP\EventDispatcher\IEventListener; use OCP\IRequest; use OCP\IUser; use OCP\IUserSession; use OCP\Share\IShare; use Symfony\Component\EventDispatcher\GenericEvent; -class Listener { +class Listener implements IEventListener { /** @var IRequest */ protected $request; @@ -331,6 +335,30 @@ class Listener { $dispatcher->addListener(RoomShareProvider::class . '::' . 'share_file_again', $listener); } + public function handle(Event $event): void { + if ($event instanceof AttendeesAddedEvent) { + $this->attendeesAddedEvent($event); + } elseif ($event instanceof AttendeesRemovedEvent) { + $this->attendeesRemovedEvent($event); + } + } + + protected function attendeesAddedEvent(AttendeesAddedEvent $event): void { + foreach ($event->getAttendees() as $attendee) { + if ($attendee->getActorType() === Attendee::ACTOR_GROUPS) { + $this->sendSystemMessage($event->getRoom(), 'group_added', ['group' => $attendee->getActorId()]); + } + } + } + + protected function attendeesRemovedEvent(AttendeesRemovedEvent $event): void { + foreach ($event->getAttendees() as $attendee) { + if ($attendee->getActorType() === Attendee::ACTOR_GROUPS) { + $this->sendSystemMessage($event->getRoom(), 'group_removed', ['group' => $attendee->getActorId()]); + } + } + } + protected function sendSystemMessage(Room $room, string $message, array $parameters = [], Participant $participant = null): void { if ($participant instanceof Participant) { $actorType = $participant->getAttendee()->getActorType(); diff --git a/lib/Events/AttendeesAddedEvent.php b/lib/Events/AttendeesAddedEvent.php new file mode 100644 index 000000000..c7b684b26 --- /dev/null +++ b/lib/Events/AttendeesAddedEvent.php @@ -0,0 +1,27 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2021 Joas Schilling <coding@schilljs.com> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCA\Talk\Events; + +class AttendeesAddedEvent extends AttendeesEvent { +} diff --git a/lib/Events/AttendeesEvent.php b/lib/Events/AttendeesEvent.php new file mode 100644 index 000000000..c78998b6b --- /dev/null +++ b/lib/Events/AttendeesEvent.php @@ -0,0 +1,45 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2021 Joas Schilling <coding@schilljs.com> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCA\Talk\Events; + +use OCA\Talk\Model\Attendee; +use OCA\Talk\Room; + +class AttendeesEvent extends RoomEvent { + /** @var Attendee[] */ + protected $attendees; + + public function __construct(Room $room, + array $attendees) { + parent::__construct($room); + $this->attendees = $attendees; + } + + /** + * @return Attendee[] + */ + public function getAttendees(): array { + return $this->attendees; + } +} diff --git a/lib/Events/AttendeesRemovedEvent.php b/lib/Events/AttendeesRemovedEvent.php new file mode 100644 index 000000000..fe93b19bb --- /dev/null +++ b/lib/Events/AttendeesRemovedEvent.php @@ -0,0 +1,27 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2021 Joas Schilling <coding@schilljs.com> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCA\Talk\Events; + +class AttendeesRemovedEvent extends AttendeesEvent { +} diff --git a/lib/Service/ParticipantService.php b/lib/Service/ParticipantService.php index 2d1762dcc..b5c18054d 100644 --- a/lib/Service/ParticipantService.php +++ b/lib/Service/ParticipantService.php @@ -27,6 +27,8 @@ use OCA\Circles\Model\Circle; use OCA\Circles\Model\Member; use OCA\Talk\Config; use OCA\Talk\Events\AddParticipantsEvent; +use OCA\Talk\Events\AttendeesAddedEvent; +use OCA\Talk\Events\AttendeesRemovedEvent; use OCA\Talk\Events\JoinRoomGuestEvent; use OCA\Talk\Events\JoinRoomUserEvent; use OCA\Talk\Events\ModifyParticipantEvent; @@ -275,6 +277,9 @@ class ParticipantService { $attendee->setParticipantType(Participant::GUEST); $attendee->setLastReadMessage($lastMessage); $this->attendeeMapper->insert($attendee); + + $attendeeEvent = new AttendeesAddedEvent($room, [$attendee]); + $this->dispatcher->dispatchTyped($attendeeEvent); } $session = $this->sessionService->createSessionForAttendee($attendee); @@ -306,6 +311,7 @@ class ParticipantService { $lastMessage = (int) $room->getLastMessage()->getId(); } + $attendees = []; foreach ($participants as $participant) { $readPrivacy = Participant::PRIVACY_PUBLIC; if ($participant['actorType'] === Attendee::ACTOR_USERS) { @@ -323,8 +329,13 @@ class ParticipantService { $attendee->setLastReadMessage($lastMessage); $attendee->setReadPrivacy($readPrivacy); $this->attendeeMapper->insert($attendee); + + $attendees[] = $attendee; } + $attendeeEvent = new AttendeesAddedEvent($room, $attendees); + $this->dispatcher->dispatchTyped($attendeeEvent); + $this->dispatcher->dispatch(Room::EVENT_AFTER_USERS_ADD, $event); } @@ -377,6 +388,9 @@ class ParticipantService { $attendee->setParticipantType(Participant::USER); $attendee->setReadPrivacy(Participant::PRIVACY_PRIVATE); $this->attendeeMapper->insert($attendee); + + $attendeeEvent = new AttendeesAddedEvent($room, [$attendee]); + $this->dispatcher->dispatchTyped($attendeeEvent); } $this->addUsers($room, $newParticipants); @@ -448,6 +462,9 @@ class ParticipantService { // $attendee->setParticipantType(Participant::USER); // $attendee->setReadPrivacy(Participant::PRIVACY_PRIVATE); // $this->attendeeMapper->insert($attendee); +// +// $attendeeEvent = new AttendeesAddedEvent($room, [$attendee]); +// $this->dispatcher->dispatchTyped($attendeeEvent); // } $this->addUsers($room, $newParticipants); @@ -479,6 +496,9 @@ class ParticipantService { $this->attendeeMapper->insert($attendee); // FIXME handle duplicate invites gracefully + $attendeeEvent = new AttendeesAddedEvent($room, [$attendee]); + $this->dispatcher->dispatchTyped($attendeeEvent); + return new Participant($room, $attendee, null); } @@ -538,12 +558,15 @@ class ParticipantService { if ($participant->getAttendee()->getParticipantType() === Participant::USER_SELF_JOINED) { $this->attendeeMapper->delete($participant->getAttendee()); + + $attendeeEvent = new AttendeesRemovedEvent($room, [$participant->getAttendee()]); + $this->dispatcher->dispatchTyped($attendeeEvent); } $this->dispatcher->dispatch(Room::EVENT_AFTER_ROOM_DISCONNECT, $event); } - public function removeAttendee(Room $room, Participant $participant, string $reason): void { + public function removeAttendee(Room $room, Participant $participant, string $reason, bool $attendeeEventIsTriggeredAlready = false): void { $isUser = $participant->getAttendee()->getActorType() === Attendee::ACTOR_USERS; $sessions = $this->sessionService->getAllSessionsForAttendee($participant->getAttendee()); @@ -560,6 +583,11 @@ class ParticipantService { $this->sessionMapper->deleteByAttendeeId($participant->getAttendee()->getId()); $this->attendeeMapper->delete($participant->getAttendee()); + if (!$attendeeEventIsTriggeredAlready) { + $attendeeEvent = new AttendeesRemovedEvent($room, [$participant->getAttendee()]); + $this->dispatcher->dispatchTyped($attendeeEvent); + } + if ($isUser) { $this->dispatcher->dispatch(Room::EVENT_AFTER_USER_REMOVE, $event); } else { @@ -584,6 +612,7 @@ class ParticipantService { $groupsInRoom[] = $attendee->getActorId(); } + $attendees = []; foreach ($removedGroup->getUsers() as $user) { try { $participant = $room->getParticipant($user->getUID()); @@ -597,11 +626,15 @@ class ParticipantService { continue; } + $attendees[] = $participant->getAttendee(); if ($participant->getAttendee()->getParticipantType() === Participant::USER) { // Only remove normal users, not moderators/admins - $this->removeAttendee($room, $participant, $reason); + $this->removeAttendee($room, $participant, $reason, true); } } + + $attendeeEvent = new AttendeesRemovedEvent($room, $attendees); + $this->dispatcher->dispatchTyped($attendeeEvent); } public function removeUser(Room $room, IUser $user, string $reason): void { @@ -623,6 +656,9 @@ class ParticipantService { $this->attendeeMapper->delete($attendee); + $attendeeEvent = new AttendeesRemovedEvent($room, [$attendee]); + $this->dispatcher->dispatchTyped($attendeeEvent); + $this->dispatcher->dispatch(Room::EVENT_AFTER_USER_REMOVE, $event); } @@ -657,14 +693,19 @@ class ParticipantService { ->andWhere($query->expr()->isNull('s.id')); $attendeeIds = []; + $attendees = []; $result = $query->execute(); while ($row = $result->fetch()) { $attendeeIds[] = (int) $row['a_id']; + $attendees[] = $this->attendeeMapper->createAttendeeFromRow($row); } $result->closeCursor(); $this->attendeeMapper->deleteByIds($attendeeIds); + $attendeeEvent = new AttendeesRemovedEvent($room, $attendees); + $this->dispatcher->dispatchTyped($attendeeEvent); + $this->dispatcher->dispatch(Room::EVENT_AFTER_GUESTS_CLEAN, $event); } diff --git a/tests/integration/features/chat/reply.feature b/tests/integration/features/chat/reply.feature index cc1fff0fb..276f4a591 100644 --- a/tests/integration/features/chat/reply.feature +++ b/tests/integration/features/chat/reply.feature @@ -112,6 +112,7 @@ Feature: chat/reply And user "participant1" sees the following system messages in room "group room" with 200 | room | actorType | actorId | actorDisplayName | systemMessage | | group room | users | participant1 | participant1-displayname | user_added | + | group room | users | participant1 | participant1-displayname | group_added | | group room | users | participant1 | participant1-displayname | conversation_created | When user "participant1" sends reply "Message X-1" on message "conversation_created" to room "group room" with 400 Then user "participant1" sees the following messages in room "group room" with 200 diff --git a/tests/integration/features/chat/system-messages.feature b/tests/integration/features/chat/system-messages.feature index b2ea311d2..2bcff686a 100644 --- a/tests/integration/features/chat/system-messages.feature +++ b/tests/integration/features/chat/system-messages.feature @@ -87,6 +87,7 @@ Feature: System messages | room | actorType | actorId | actorDisplayName | systemMessage | | room | users | participant1 | participant1-displayname | user_added | | room | users | participant1 | participant1-displayname | user_added | + | room | users | participant1 | participant1-displayname | group_added | | room | users | participant1 | participant1-displayname | conversation_created | Scenario: Creating a one2one room diff --git a/tests/php/Chat/Parser/SystemMessageTest.php b/tests/php/Chat/Parser/SystemMessageTest.php index 2bf100973..5f140fb23 100644 --- a/tests/php/Chat/Parser/SystemMessageTest.php +++ b/tests/php/Chat/Parser/SystemMessageTest.php @@ -36,6 +36,8 @@ use OCP\Files\InvalidPathException; use OCP\Files\IRootFolder; use OCP\Files\Node; use OCP\Files\NotFoundException; +use OCP\IGroup; +use OCP\IGroupManager; use OCP\IL10N; use OCP\IPreview as IPreviewManager; use OCP\IURLGenerator; @@ -53,6 +55,8 @@ class SystemMessageTest extends TestCase { /** @var IUserManager|MockObject */ protected $userManager; + /** @var IGroupManager|MockObject */ + protected $groupManager; /** @var GuestManager|MockObject */ protected $guestManager; /** @var IPreviewManager|MockObject */ @@ -70,6 +74,7 @@ class SystemMessageTest extends TestCase { parent::setUp(); $this->userManager = $this->createMock(IUserManager::class); + $this->groupManager = $this->createMock(IGroupManager::class); $this->guestManager = $this->createMock(GuestManager::class); $this->previewManager = $this->createMock(IPreviewManager::class); $this->shareProvider = $this->createMock(RoomShareProvider::class); @@ -98,6 +103,7 @@ class SystemMessageTest extends TestCase { $mock = $this->getMockBuilder(SystemMessage::class) ->setConstructorArgs([ $this->userManager, + $this->groupManager, $this->guestManager, $this->previewManager, $this->shareProvider, @@ -111,6 +117,7 @@ class SystemMessageTest extends TestCase { } return new SystemMessage( $this->userManager, + $this->groupManager, $this->guestManager, $this->previewManager, $this->shareProvider, @@ -243,6 +250,22 @@ class SystemMessageTest extends TestCase { 'You removed {user}', ['actor' => ['id' => 'actor', 'type' => 'user'], 'user' => ['id' => 'user', 'type' => 'user']], ], + ['group_added', ['group' => 'g1'], 'recipient', + '{actor} added group {group}', + ['actor' => ['id' => 'actor', 'type' => 'user'], 'group' => ['id' => 'g1', 'type' => 'group']], + ], + ['group_added', ['group' => 'g1'], 'actor', + 'You added group {group}', + ['actor' => ['id' => 'actor', 'type' => 'user'], 'group' => ['id' => 'g1', 'type' => 'group']], + ], + ['group_removed', ['group' => 'g1'], 'recipient', + '{actor} removed group {group}', + ['actor' => ['id' => 'actor', 'type' => 'user'], 'group' => ['id' => 'g1', 'type' => 'group']], + ], + ['group_removed', ['group' => 'g1'], 'actor', + 'You removed group {group}', + ['actor' => ['id' => 'actor', 'type' => 'user'], 'group' => ['id' => 'g1', 'type' => 'group']], + ], ['moderator_promoted', ['user' => 'user'], 'recipient', '{actor} promoted {user} to moderator', ['actor' => ['id' => 'actor', 'type' => 'user'], 'user' => ['id' => 'user', 'type' => 'user']], @@ -414,7 +437,7 @@ class SystemMessageTest extends TestCase { /** @var Room|MockObject $room */ $room = $this->createMock(Room::class); - $parser = $this->getParser(['getActorFromComment', 'getUser', 'getGuest', 'parseCall', 'getFileFromShare']); + $parser = $this->getParser(['getActorFromComment', 'getUser', 'getGroup', 'getGuest', 'parseCall', 'getFileFromShare']); $parser->expects($this->once()) ->method('getActorFromComment') ->with($room, $comment) @@ -424,6 +447,10 @@ class SystemMessageTest extends TestCase { ->with($parameters['user'] ?? 'user') ->willReturn(['id' => $parameters['user'] ?? 'user', 'type' => 'user']); $parser->expects($this->any()) + ->method('getGroup') + ->with($parameters['group'] ?? 'group') + ->willReturn(['id' => $parameters['group'] ?? 'group', 'type' => 'group']); + $parser->expects($this->any()) ->method('getGuest') ->with($room, $parameters['session'] ?? 'guest') ->willReturn(['id' => $parameters['session'] ?? 'guest', 'type' => 'guest']); @@ -898,6 +925,77 @@ class SystemMessageTest extends TestCase { $this->assertSame($name, self::invokePrivate($parser, 'getDisplayName', [$uid])); } + public function dataGetGroup(): array { + return [ + ['test', [], false, 'Test'], + ['foo', ['admin' => 'Admin'], false, 'Bar'], + ['admin', ['admin' => 'Administrator'], true, 'Administrator'], + ]; + } + + /** + * @dataProvider dataGetGroup + * @param string $gid + * @param array $cache + * @param bool $cacheHit + * @param string $name + */ + public function testGetGroup(string $gid, array $cache, bool $cacheHit, string $name): void { + $parser = $this->getParser(['getDisplayNameGroup']); + + self::invokePrivate($parser, 'groupNames', [$cache]); + + if (!$cacheHit) { + $parser->expects(self::once()) + ->method('getDisplayNameGroup') + ->with($gid) + ->willReturn($name); + } else { + $parser->expects(self::never()) + ->method('getDisplayNameGroup'); + } + + $result = self::invokePrivate($parser, 'getGroup', [$gid]); + self::assertSame('group', $result['type']); + self::assertSame($gid, $result['id']); + self::assertSame($name, $result['name']); + } + + public function dataGetDisplayNameGroup(): array { + return [ + ['test', true, 'Test'], + ['foo', false, 'foo'], + ]; + } + + /** + * @dataProvider dataGetDisplayNameGroup + * @param string $gid + * @param bool $validGroup + * @param string $name + */ + public function testGetDisplayNameGroup(string $gid, bool $validGroup, string $name): void { + $parser = $this->getParser(); + + if ($validGroup) { + $group = $this->createMock(IGroup::class); + $group->expects(self::once()) + ->method('getDisplayName') + ->willReturn($name); + $this->groupManager->expects(self::once()) + ->method('get') + ->with($gid) + ->willReturn($group); + } else { + $this->groupManager->expects(self::once()) + ->method('get') + ->with($gid) + ->willReturn(null); + } + + self::assertSame($name, self::invokePrivate($parser, 'getDisplayNameGroup', [$gid])); + } + public function testGetGuest() { $actorId = sha1('name'); |