Skip to content

Commit

Permalink
Merge pull request #10884 from nextcloud/bugfix/10875/adjust-author-o…
Browse files Browse the repository at this point in the history
…f-notetoself-and-changelog-creation

fix(chat): Adjust "author" when creating "Note to self" and "changelo…
  • Loading branch information
nickvergessen authored Nov 14, 2023
2 parents bc94370 + 9b09df6 commit f4d3343
Show file tree
Hide file tree
Showing 8 changed files with 168 additions and 13 deletions.
9 changes: 7 additions & 2 deletions lib/Chat/Parser/SystemMessage.php
Original file line number Diff line number Diff line change
Expand Up @@ -143,13 +143,18 @@ protected function parseMessage(Message $chatMessage): void {
$participant->getAttendee()->getActorId() === $parsedParameters['actor']['id'];
}
$cliIsActor = $parsedParameters['actor']['type'] === 'guest' &&
'guest/cli' === $parsedParameters['actor']['id'];
'guest/' . Attendee::ACTOR_ID_CLI === $parsedParameters['actor']['id'];

if ($message === 'conversation_created') {
$systemIsActor = $parsedParameters['actor']['type'] === 'guest' &&
'guest/' . Attendee::ACTOR_ID_SYSTEM === $parsedParameters['actor']['id'];

$parsedMessage = $this->l->t('{actor} created the conversation');
if ($currentUserIsActor) {
$parsedMessage = $this->l->t('You created the conversation');
} elseif ($cliIsActor) {
} elseif ($systemIsActor) {
$parsedMessage = $this->l->t('System created the conversation');
}if ($cliIsActor) {
$parsedMessage = $this->l->t('An administrator created the conversation');
}
} elseif ($message === 'conversation_renamed') {
Expand Down
64 changes: 62 additions & 2 deletions lib/Chat/SystemMessage/Listener.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
use OCA\Talk\Model\Session;
use OCA\Talk\Participant;
use OCA\Talk\Room;
use OCA\Talk\Service\NoteToSelfService;
use OCA\Talk\Service\ParticipantService;
use OCA\Talk\TalkSession;
use OCA\Talk\Webinary;
Expand Down Expand Up @@ -157,7 +158,11 @@ protected function sendSystemMessageAboutCallLeft(ParticipantModifiedEvent $even
}

protected function sendSystemMessageAboutConversationCreated(RoomCreatedEvent $event): void {
$this->sendSystemMessage($event->getRoom(), 'conversation_created');
if ($event->getRoom()->getType() === Room::TYPE_CHANGELOG || $this->isCreatingNoteToSelfAutomatically($event)) {
$this->sendSystemMessage($event->getRoom(), 'conversation_created', forceSystemAsActor: true);
} else {
$this->sendSystemMessage($event->getRoom(), 'conversation_created');
}
}

protected function sendSystemMessageAboutConversationRenamed(RoomModifiedEvent $event): void {
Expand All @@ -174,6 +179,10 @@ protected function sendSystemMessageAboutConversationRenamed(RoomModifiedEvent $

protected function sendSystemMessageAboutRoomDescriptionChanges(RoomModifiedEvent $event): void {
if ($event->getNewValue() !== '') {
if ($this->isCreatingNoteToSelf($event)) {
return;
}

$this->sendSystemMessage($event->getRoom(), 'description_set', [
'newDescription' => $event->getNewValue(),
]);
Expand Down Expand Up @@ -253,6 +262,10 @@ protected function addSystemMessageUserAdded(AttendeesAddedEvent $event, Attende
return;
}

if ($room->getType() === Room::TYPE_CHANGELOG) {
return;
}

$userJoinedFileRoom = $room->getObjectType() === Room::OBJECT_TYPE_FILE && $attendee->getParticipantType() !== Participant::USER_SELF_JOINED;

// add a message "X joined the conversation", whenever user $userId:
Expand Down Expand Up @@ -407,10 +420,13 @@ protected function attendeesRemovedEvent(AttendeesRemovedEvent $event): void {
}
}

protected function sendSystemMessage(Room $room, string $message, array $parameters = [], Participant $participant = null, bool $shouldSkipLastMessageUpdate = false, bool $silent = false): IComment {
protected function sendSystemMessage(Room $room, string $message, array $parameters = [], Participant $participant = null, bool $shouldSkipLastMessageUpdate = false, bool $silent = false, bool $forceSystemAsActor = false): IComment {
if ($participant instanceof Participant) {
$actorType = $participant->getAttendee()->getActorType();
$actorId = $participant->getAttendee()->getActorId();
} elseif ($forceSystemAsActor) {
$actorType = Attendee::ACTOR_GUESTS;
$actorId = Attendee::ACTOR_ID_SYSTEM;
} else {
$user = $this->userSession->getUser();
if ($user instanceof IUser) {
Expand Down Expand Up @@ -524,11 +540,55 @@ protected function getCallRecordingPrefix(RoomModifiedEvent $event): string {

protected function avatarChanged(RoomModifiedEvent $event): void {
if ($event->getNewValue()) {
if ($this->isCreatingNoteToSelf($event)) {
return;
}

$message = 'avatar_set';
} else {
$message = 'avatar_removed';
}

$this->sendSystemMessage($event->getRoom(), $message);
}

protected function isCreatingNoteToSelf(RoomModifiedEvent $event): bool {
if ($event->getRoom()->getType() !== Room::TYPE_NOTE_TO_SELF) {
return false;
}

$exception = new \Exception();
$trace = $exception->getTrace();

foreach ($trace as $step) {
if (isset($step['class']) && $step['class'] === NoteToSelfService::class &&
isset($step['function']) && $step['function'] === 'initialCreateNoteToSelfForUser') {
return true;
}
if (isset($step['class']) && $step['class'] === NoteToSelfService::class &&
isset($step['function']) && $step['function'] === 'ensureNoteToSelfExistsForUser') {
return true;
}
}

return false;
}

protected function isCreatingNoteToSelfAutomatically(RoomCreatedEvent $event): bool {
if ($event->getRoom()->getType() !== Room::TYPE_NOTE_TO_SELF) {
return false;
}

$exception = new \Exception();
$trace = $exception->getTrace();

foreach ($trace as $step) {
if (isset($step['class']) && $step['class'] === NoteToSelfService::class &&
isset($step['function']) && $step['function'] === 'initialCreateNoteToSelfForUser') {
return true;
}
}

return false;
}
}
1 change: 1 addition & 0 deletions lib/Model/Attendee.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ class Attendee extends Entity {
// Special actor IDs
public const ACTOR_BOT_PREFIX = 'bot-';
public const ACTOR_ID_CLI = 'cli';
public const ACTOR_ID_SYSTEM = 'system';
public const ACTOR_ID_CHANGELOG = 'changelog';

public const PERMISSIONS_DEFAULT = 0;
Expand Down
31 changes: 25 additions & 6 deletions tests/integration/features/bootstrap/FeatureContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ public function setUp() {
self::$tokenToIdentifier = [];
self::$sessionIdToUser = [
'cli' => 'cli',
'system' => 'system',
'failed-to-get-session' => 'failed-to-get-session',
];
self::$userToSessionId = [];
Expand Down Expand Up @@ -283,24 +284,31 @@ public function userCanFindListedRoomsWithTerm(string $user, string $term, strin
}

/**
* @Then /^user "([^"]*)" is participant of the following (unordered )?rooms \((v4)\)$/
* @Then /^user "([^"]*)" is participant of the following (unordered )?(note-to-self )?rooms \((v4)\)$/
*
* @param string $user
* @param string $shouldOrder
* @param string $apiVersion
* @param TableNode|null $formData
*/
public function userIsParticipantOfRooms(string $user, string $shouldOrder, string $apiVersion, TableNode $formData = null): void {
public function userIsParticipantOfRooms(string $user, string $shouldOrder, string $shouldFilter, string $apiVersion, TableNode $formData = null): void {
$this->setCurrentUser($user);
$this->sendRequest('GET', '/apps/spreed/api/' . $apiVersion . '/room');
$this->assertStatusCode($this->response, 200);

$rooms = $this->getDataFromResponse($this->response);

$rooms = array_filter($rooms, function ($room) {
// Filter out "Talk updates" and "Note to self" conversations
return $room['type'] !== 4 && $room['type'] !== 6;
});
if ($shouldFilter === '') {
$rooms = array_filter($rooms, function ($room) {
// Filter out "Talk updates" and "Note to self" conversations
return $room['type'] !== 4 && $room['type'] !== 6;
});
} elseif ($shouldFilter === 'note-to-self ') {
$rooms = array_filter($rooms, function ($room) {
// Filter out "Talk updates" conversations
return $room['type'] !== 4;
});
}

if ($formData === null) {
Assert::assertEmpty($rooms);
Expand Down Expand Up @@ -912,6 +920,17 @@ public function userCreatesNoteToSelf(string $user, string $apiVersion): void {
self::$tokenToIdentifier[$response['token']] = $user . '-note-to-self';
}

/**
* @Then /^user "([^"]*)" reset note-to-self preference$/
*
* @param string $user
*/
public function userResetNoteToSelfPreference(string $user): void {
$this->setCurrentUser($user);
$this->sendRequest('DELETE', '/apps/provisioning_api/api/v1/config/users/spreed/note_to_self');
$this->assertStatusCode($this->response, 200);
}

/**
* @Then /^user "([^"]*)" creates room "([^"]*)" with (\d+) \((v4)\)$/
*
Expand Down
6 changes: 3 additions & 3 deletions tests/integration/features/chat/mentions.feature
Original file line number Diff line number Diff line change
Expand Up @@ -627,9 +627,9 @@ Feature: chat/mentions
Scenario: At-all in note-to-self broke the mention parsing
And user "participant1" creates note-to-self (v4)
And user "participant1" sends message "Test @all" to room "participant1-note-to-self" with 201
And user "participant1" is participant of the following rooms (v4)
# | id | type | name |
# | participant1-note-to-self | 6 | Note to self |
And user "participant1" is participant of the following note-to-self rooms (v4)
| id | type | name |
| participant1-note-to-self | 6 | Note to self |
Then user "participant1" sees the following messages in room "participant1-note-to-self" with 200
| room | actorType | actorId | actorDisplayName | message | messageParameters |
| participant1-note-to-self | users | participant1 | participant1-displayname | Test {mention-call1} | "IGNORE" |
24 changes: 24 additions & 0 deletions tests/integration/features/chat/note-to-self.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Feature: chat/note-to-self

Background:
Given user "participant1" exists

Scenario: Created manually via the endpoint
When user "participant1" reset note-to-self preference
When user "participant1" creates note-to-self (v4)
And user "participant1" is participant of the following note-to-self rooms (v4)
| id | type | name |
| participant1-note-to-self | 6 | Note to self |
Then user "participant1" sees the following system messages in room "participant1-note-to-self" with 200
| room | actorType | actorId | actorDisplayName | message | messageParameters | systemMessage |
| participant1-note-to-self | users | participant1 | participant1-displayname | You created the conversation | {"actor":{"type":"user","id":"participant1","name":"participant1-displayname"}} | conversation_created |


Scenario: Created automatically when fetching the room list
When user "participant1" reset note-to-self preference
And user "participant1" is participant of the following note-to-self rooms (v4)
| id | type | name |
| Note to self | 6 | Note to self |
Then user "participant1" sees the following system messages in room "Note to self" with 200
| room | actorType | actorId | actorDisplayName | message | messageParameters | systemMessage |
| Note to self | guests | system | | System created the conversation | {"actor":{"type":"guest","id":"guest\/system","name":"Guest"}} | conversation_created |
3 changes: 3 additions & 0 deletions tests/integration/spreedcheats/lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@

namespace OCA\SpreedCheats\AppInfo;

use OCA\SpreedCheats\PreferenceListener;
use OCA\SpreedCheats\SpeechToText\LoremIpsumSpeechToTextProvider;
use OCA\SpreedCheats\Translation\LoremIpsumTranslationProvider;
use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\Config\BeforePreferenceDeletedEvent;

class Application extends App implements IBootstrap {
public const APP_ID = 'spreedcheats';
Expand All @@ -40,6 +42,7 @@ public function __construct() {
public function register(IRegistrationContext $context): void {
$context->registerSpeechToTextProvider(LoremIpsumSpeechToTextProvider::class);
$context->registerTranslationProvider(LoremIpsumTranslationProvider::class);
$context->registerEventListener(BeforePreferenceDeletedEvent::class, PreferenceListener::class);
}

public function boot(IBootContext $context): void {
Expand Down
43 changes: 43 additions & 0 deletions tests/integration/spreedcheats/lib/PreferenceListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 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\SpreedCheats;

use OCP\Config\BeforePreferenceDeletedEvent;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;

/**
* @template-implements IEventListener<Event>
*/
class PreferenceListener implements IEventListener {
public function handle(Event $event): void {
if (!$event instanceof BeforePreferenceDeletedEvent) {
return;
}

if ($event->getAppId() === 'spreed') {
$event->setValid(true);
}
}
}

0 comments on commit f4d3343

Please sign in to comment.