From 852fe606bdf8c9b9ab172083634b8aed131b362d Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 11 Feb 2025 15:55:47 +0100 Subject: [PATCH] fix(teams): Track team name updates Signed-off-by: Joas Schilling --- lib/AppInfo/Application.php | 5 ++ lib/Listener/CircleEditedListener.php | 48 +++++++++++++++++ .../features/bootstrap/FeatureContext.php | 52 +++++++++++++++---- .../conversation-5/team-participants.feature | 26 ++++++++++ 4 files changed, 120 insertions(+), 11 deletions(-) create mode 100644 lib/Listener/CircleEditedListener.php create mode 100644 tests/integration/features/conversation-5/team-participants.feature diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index ff1eebbbc6a..938c08b371f 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -10,6 +10,8 @@ use OCA\Circles\Events\AddingCircleMemberEvent; use OCA\Circles\Events\CircleDestroyedEvent; +use OCA\Circles\Events\CircleEditedEvent; +use OCA\Circles\Events\EditingCircleEvent; use OCA\Circles\Events\RemovingCircleMemberEvent; use OCA\Files\Event\LoadSidebar; use OCA\Files_Sharing\Event\BeforeTemplateRenderedEvent; @@ -82,6 +84,7 @@ use OCA\Talk\Listener\BeforeUserLoggedOutListener; use OCA\Talk\Listener\BotListener; use OCA\Talk\Listener\CircleDeletedListener; +use OCA\Talk\Listener\CircleEditedListener; use OCA\Talk\Listener\CircleMembershipListener; use OCA\Talk\Listener\CSPListener; use OCA\Talk\Listener\DisplayNameListener; @@ -258,6 +261,8 @@ public function register(IRegistrationContext $context): void { $context->registerEventListener(UserAddedEvent::class, GroupMembershipListener::class); $context->registerEventListener(UserRemovedEvent::class, GroupMembershipListener::class); $context->registerEventListener(CircleDestroyedEvent::class, CircleDeletedListener::class); + $context->registerEventListener(EditingCircleEvent::class, CircleEditedListener::class); + $context->registerEventListener(CircleEditedEvent::class, CircleEditedListener::class); $context->registerEventListener(AddingCircleMemberEvent::class, CircleMembershipListener::class); $context->registerEventListener(RemovingCircleMemberEvent::class, CircleMembershipListener::class); diff --git a/lib/Listener/CircleEditedListener.php b/lib/Listener/CircleEditedListener.php new file mode 100644 index 00000000000..390454a77f7 --- /dev/null +++ b/lib/Listener/CircleEditedListener.php @@ -0,0 +1,48 @@ + + */ +class CircleEditedListener implements IEventListener { + + public function __construct( + readonly private ParticipantService $participantService, + ) { + } + + public function handle(Event $event): void { + if (!$event instanceof EditingCircleEvent && !$event instanceof CircleEditedEvent) { + // Unrelated + return; + } + + $displayName = $event->getCircle()->getDisplayName(); + if ($event instanceof EditingCircleEvent) { + // In the before event we need to cheat to get the name + if ($event->getFederatedEvent()?->getData()?->hasKey('name')) { + $displayName = $event->getFederatedEvent()->getData()->g('name'); + } + } + + $this->participantService->updateDisplayNameForActor( + Attendee::ACTOR_CIRCLES, + $event->getCircle()->getSingleId(), + $displayName, + ); + } +} diff --git a/tests/integration/features/bootstrap/FeatureContext.php b/tests/integration/features/bootstrap/FeatureContext.php index 5685bdcc5e9..80dc9c615e8 100644 --- a/tests/integration/features/bootstrap/FeatureContext.php +++ b/tests/integration/features/bootstrap/FeatureContext.php @@ -65,6 +65,8 @@ class FeatureContext implements Context, SnippetAcceptingContext { protected static array $modifiedSince; /** @var array */ protected static array $createdTeams = []; + /** @var array */ + protected static array $renamedTeams = []; /** @var array */ protected static array $userToBanId; @@ -128,7 +130,7 @@ public static function getTokenForIdentifier(string $identifier) { } public static function getTeamIdForLabel(string $server, string $label): string { - return self::$createdTeams[$server][$label] ?? throw new \RuntimeException('Unknown team: ' . $label); + return self::$createdTeams[$server][$label] ?? self::$renamedTeams[$server][$label] ?? throw new \RuntimeException('Unknown team: ' . $label); } public static function getMessageIdForText(string $text): int { @@ -220,6 +222,7 @@ public function setUp(BeforeScenarioScope $scope) { $this->createdUsers[$server] = []; $this->createdGroups[$server] = []; self::$createdTeams[$server] = []; + self::$renamedTeams[$server] = []; $this->createdGuestAccountUsers[$server] = []; } @@ -246,15 +249,15 @@ public function tearDown() { foreach (['LOCAL', 'REMOTE'] as $server) { $this->usingServer($server); + foreach (self::$createdTeams[$server] as $team => $id) { + $this->deleteTeam($team); + } foreach ($this->createdUsers[$server] as $user) { $this->deleteUser($user); } foreach ($this->createdGroups[$server] as $group) { $this->deleteGroup($group); } - foreach (self::$createdTeams[$server] as $team => $id) { - $this->deleteTeam($team); - } foreach ($this->createdGuestAccountUsers[$server] as $user) { $this->deleteGuestUser($user); } @@ -914,6 +917,10 @@ protected function assertAttendeeList(string $identifier, ?TableNode $formData, $attendee['actorId'] .= '@' . rtrim($this->localRemoteServerUrl, '/'); } + if (isset($attendee['actorId']) && preg_match('/TEAM_ID\(([^)]+)\)/', $attendee['actorId'], $matches)) { + $attendee['actorId'] = self::getTeamIdForLabel($this->currentServer, $matches[1]); + } + if (isset($attendee['sessionIds']) && str_contains($attendee['sessionIds'], '@{$LOCAL_URL}')) { $attendee['sessionIds'] = str_replace('{$LOCAL_URL}', rtrim($this->localServerUrl, '/'), $attendee['sessionIds']); } @@ -1973,7 +1980,7 @@ public function userChangesListableScopeOfTheRoom(string $user, string $identifi } /** - * @Then /^user "([^"]*)" adds (user|group|email|circle|federated_user|phone|team) "([^"]*)" to room "([^"]*)" with (\d+) \((v4)\)$/ + * @Then /^user "([^"]*)" adds (user|group|email|federated_user|phone|team) "([^"]*)" to room "([^"]*)" with (\d+) \((v4)\)$/ * * @param string $user * @param string $newType @@ -1993,8 +2000,8 @@ public function userAddAttendeeToRoom(string $user, string $newType, string $new } } - if ($newType === 'circle' || $newType === 'team') { - $newId = self::$createdTeams[$this->currentServer][$newId]; + if ($newType === 'team') { + $newId = self::getTeamIdForLabel($this->currentServer, $newId); } $this->sendRequest( @@ -2319,7 +2326,7 @@ public function userSendsMessageToRoom(string $user, string $sendingMode, string if (str_contains($message, '@"TEAM_ID(')) { $result = preg_match('/TEAM_ID\(([^)]+)\)/', $message, $matches); if ($result) { - $message = str_replace($matches[0], 'team/' . self::$createdTeams[$this->currentServer][$matches[1]], $message); + $message = str_replace($matches[0], 'team/' . self::getTeamIdForLabel($this->currentServer, $matches[1]), $message); } } @@ -3570,7 +3577,7 @@ public function userGetsTheFollowingCollaboratorSuggestions($user, $identifier, $expected = array_map(function (array $mention): array { $result = preg_match('/TEAM_ID\(([^)]+)\)/', $mention['id'], $matches); if ($result) { - $mention['id'] = self::$createdTeams[$this->currentServer][$matches[1]]; + $mention['id'] = self::getTeamIdForLabel($this->currentServer, $matches[1]); } return $mention; }, $formData->getHash()); @@ -3978,7 +3985,7 @@ private function assertNotifications($notifications, TableNode $formData) { [$roomToken, $message] = explode('/', $expectedNotification['object_id'], 2); $result = preg_match('/TEAM_ID\(([^)]+)\)/', $message, $matches); if ($result) { - $message = str_replace($matches[0], 'team/' . self::$createdTeams[$this->currentServer][$matches[1]], $message); + $message = str_replace($matches[0], 'team/' . self::getTeamIdForLabel($this->currentServer, $matches[1]), $message); } $expectedNotification['object_id'] = $roomToken . '/' . $message; } @@ -4015,7 +4022,7 @@ private function assertNotifications($notifications, TableNode $formData) { } $result = preg_match('/TEAM_ID\(([^)]+)\)/', $expectedNotification['message'], $matches); if ($result) { - $data['message'] = str_replace($matches[0], self::$createdTeams[$this->currentServer][$matches[1]], $data['message']); + $data['message'] = str_replace($matches[0], self::getTeamIdForLabel($this->currentServer, $matches[1]), $data['message']); } } if (isset($expectedNotification['object_type'])) { @@ -4289,6 +4296,29 @@ public function assureTeamExists(string $team): void { self::$createdTeams[$this->currentServer][$team] = $data['id']; } + /** + * @Given /^User "([^"]*)" creates team "([^"]*)"$/ + */ + public function createTeamAsUser(string $owner, string $team): void { + $this->runOcc(['circles:manage:create', '--type', '1', '--output', 'json', $owner, $team]); + $this->theCommandWasSuccessful(); + + $output = $this->getLastStdOut(); + $data = json_decode($output, true); + + self::$createdTeams[$this->currentServer][$team] = $data['id']; + } + + /** + * @Given /^team "([^"]*)" is renamed to "([^"]*)"$/ + */ + public function assureTeamRenamed(string $team, string $newName): void { + $id = self::$createdTeams[$this->currentServer][$team]; + $this->runOcc(['circles:manage:edit', $id, 'displayName', $newName]); + $this->theCommandWasSuccessful(); + self::$renamedTeams[$this->currentServer][$newName] = $id; + } + /** * @Given /^add user "([^"]*)" to team "([^"]*)"$/ */ diff --git a/tests/integration/features/conversation-5/team-participants.feature b/tests/integration/features/conversation-5/team-participants.feature new file mode 100644 index 00000000000..fab3d34fc89 --- /dev/null +++ b/tests/integration/features/conversation-5/team-participants.feature @@ -0,0 +1,26 @@ +Feature: conversation-5/team-participants + Background: + Given user "participant1" exists + Given user "participant2" exists + And User "participant1" creates team "Team A" + And add user "participant2" to team "Team A" + + Scenario: Owner invites a team + Given user "participant1" creates room "room" (v4) + | roomType | 3 | + | roomName | room | + And user "participant1" sees the following attendees in room "room" with 200 (v4) + | actorType | actorId | participantType | + | users | participant1 | 1 | + And user "participant1" adds team "Team A" to room "room" with 200 (v4) + And user "participant1" sees the following attendees in room "room" with 200 (v4) + | actorType | actorId | participantType | displayName | + | users | participant1 | 1 | participant1-displayname | + | circles | TEAM_ID(Team A) | 3 | Team A | + | users | participant2 | 3 | participant2-displayname | + And team "Team A" is renamed to "Team Alpha" + And user "participant1" sees the following attendees in room "room" with 200 (v4) + | actorType | actorId | participantType | displayName | + | users | participant1 | 1 | participant1-displayname | + | circles | TEAM_ID(Team A) | 3 | Team Alpha | + | users | participant2 | 3 | participant2-displayname |