Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(chat): Adjust "author" when creating "Note to self" and "changelo… #10884

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
}
}
}