Skip to content

Commit

Permalink
fix(teams): Track team name updates
Browse files Browse the repository at this point in the history
Signed-off-by: Joas Schilling <[email protected]>
  • Loading branch information
nickvergessen committed Feb 11, 2025
1 parent f9958b2 commit 852fe60
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 11 deletions.
5 changes: 5 additions & 0 deletions lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);

Check failure on line 264 in lib/AppInfo/Application.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis

UndefinedClass

lib/AppInfo/Application.php:264:35: UndefinedClass: Class, interface or enum named OCA\Circles\Events\EditingCircleEvent does not exist (see https://psalm.dev/019)
$context->registerEventListener(CircleEditedEvent::class, CircleEditedListener::class);

Check failure on line 265 in lib/AppInfo/Application.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis

UndefinedClass

lib/AppInfo/Application.php:265:35: UndefinedClass: Class, interface or enum named OCA\Circles\Events\CircleEditedEvent does not exist (see https://psalm.dev/019)
$context->registerEventListener(AddingCircleMemberEvent::class, CircleMembershipListener::class);
$context->registerEventListener(RemovingCircleMemberEvent::class, CircleMembershipListener::class);

Expand Down
48 changes: 48 additions & 0 deletions lib/Listener/CircleEditedListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Talk\Listener;

use OCA\Circles\Events\CircleEditedEvent;
use OCA\Circles\Events\EditingCircleEvent;
use OCA\Talk\Model\Attendee;
use OCA\Talk\Service\ParticipantService;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;

/**
* @template-implements IEventListener<Event>
*/
class CircleEditedListener implements IEventListener {

public function __construct(
readonly private ParticipantService $participantService,
) {
}

public function handle(Event $event): void {
if (!$event instanceof EditingCircleEvent && !$event instanceof CircleEditedEvent) {

Check failure on line 29 in lib/Listener/CircleEditedListener.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis

UndefinedClass

lib/Listener/CircleEditedListener.php:29:26: UndefinedClass: Class, interface or enum named OCA\Circles\Events\EditingCircleEvent does not exist (see https://psalm.dev/019)
// 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,
);
}
}
52 changes: 41 additions & 11 deletions tests/integration/features/bootstrap/FeatureContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, int> */
protected static array $userToBanId;

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -220,6 +222,7 @@ public function setUp(BeforeScenarioScope $scope) {
$this->createdUsers[$server] = [];
$this->createdGroups[$server] = [];
self::$createdTeams[$server] = [];
self::$renamedTeams[$server] = [];
$this->createdGuestAccountUsers[$server] = [];
}

Expand All @@ -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);
}
Expand Down Expand Up @@ -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']);
}
Expand Down Expand Up @@ -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
Expand All @@ -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(
Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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'])) {
Expand Down Expand Up @@ -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 "([^"]*)"$/
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -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 |

0 comments on commit 852fe60

Please sign in to comment.