feat: Add command parser
This commit is contained in:
parent
5200764604
commit
fcb8d48bd7
|
|
@ -31,6 +31,7 @@ export 'src/utils/states_map.dart';
|
||||||
export 'src/utils/sync_update_extension.dart';
|
export 'src/utils/sync_update_extension.dart';
|
||||||
export 'src/utils/to_device_event.dart';
|
export 'src/utils/to_device_event.dart';
|
||||||
export 'src/utils/uia_request.dart';
|
export 'src/utils/uia_request.dart';
|
||||||
|
export 'src/utils/commands_extension.dart';
|
||||||
export 'src/client.dart';
|
export 'src/client.dart';
|
||||||
export 'src/event.dart';
|
export 'src/event.dart';
|
||||||
export 'src/room.dart';
|
export 'src/room.dart';
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ import 'database/database.dart' show Database;
|
||||||
import 'event.dart';
|
import 'event.dart';
|
||||||
import 'room.dart';
|
import 'room.dart';
|
||||||
import 'user.dart';
|
import 'user.dart';
|
||||||
|
import 'utils/commands_extension.dart';
|
||||||
import 'utils/device_keys_list.dart';
|
import 'utils/device_keys_list.dart';
|
||||||
import 'utils/event_update.dart';
|
import 'utils/event_update.dart';
|
||||||
import 'utils/matrix_file.dart';
|
import 'utils/matrix_file.dart';
|
||||||
|
|
@ -83,6 +84,9 @@ class Client extends MatrixApi {
|
||||||
|
|
||||||
bool mxidLocalPartFallback = true;
|
bool mxidLocalPartFallback = true;
|
||||||
|
|
||||||
|
// For CommandsClientExtension
|
||||||
|
final Map<String, FutureOr<String> Function(CommandArgs)> commands = {};
|
||||||
|
|
||||||
/// Create a client
|
/// Create a client
|
||||||
/// [clientName] = unique identifier of this client
|
/// [clientName] = unique identifier of this client
|
||||||
/// [database]: The database instance to use
|
/// [database]: The database instance to use
|
||||||
|
|
@ -147,6 +151,9 @@ class Client extends MatrixApi {
|
||||||
EventTypes.Sticker,
|
EventTypes.Sticker,
|
||||||
]);
|
]);
|
||||||
this.httpClient = httpClient ?? http.Client();
|
this.httpClient = httpClient ?? http.Client();
|
||||||
|
|
||||||
|
// register all the default commands
|
||||||
|
registerDefaultCommands();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The required name for this client.
|
/// The required name for this client.
|
||||||
|
|
|
||||||
|
|
@ -578,15 +578,17 @@ class Room {
|
||||||
Event inReplyTo,
|
Event inReplyTo,
|
||||||
String editEventId,
|
String editEventId,
|
||||||
bool parseMarkdown = true,
|
bool parseMarkdown = true,
|
||||||
Map<String, Map<String, String>> emotePacks}) {
|
Map<String, Map<String, String>> emotePacks,
|
||||||
|
bool parseCommands = true,
|
||||||
|
String msgtype = MessageTypes.Text}) {
|
||||||
|
if (parseCommands) {
|
||||||
|
return client.parseAndRunCommand(this, message,
|
||||||
|
inReplyTo: inReplyTo, editEventId: editEventId, txid: txid);
|
||||||
|
}
|
||||||
final event = <String, dynamic>{
|
final event = <String, dynamic>{
|
||||||
'msgtype': 'm.text',
|
'msgtype': msgtype,
|
||||||
'body': message,
|
'body': message,
|
||||||
};
|
};
|
||||||
if (message.startsWith('/me ')) {
|
|
||||||
event['msgtype'] = 'm.emote';
|
|
||||||
event['body'] = message.substring(4);
|
|
||||||
}
|
|
||||||
if (parseMarkdown) {
|
if (parseMarkdown) {
|
||||||
final html = markdown(event['body'], emotePacks ?? this.emotePacks);
|
final html = markdown(event['body'], emotePacks ?? this.emotePacks);
|
||||||
// if the decoded html is the same as the body, there is no need in sending a formatted message
|
// if the decoded html is the same as the body, there is no need in sending a formatted message
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,203 @@
|
||||||
|
/*
|
||||||
|
* Famedly Matrix SDK
|
||||||
|
* Copyright (C) 2021 Famedly GmbH
|
||||||
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import '../../famedlysdk.dart';
|
||||||
|
|
||||||
|
extension CommandsClientExtension on Client {
|
||||||
|
/// Add a command to the command handler. [command] is its name, and [callback] is the
|
||||||
|
/// callback to invoke
|
||||||
|
void addCommand(
|
||||||
|
String command, FutureOr<String> Function(CommandArgs) callback) {
|
||||||
|
commands[command.toLowerCase()] = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parse and execute a string, [msg] is the input. Optionally [inReplyTo] is the event being
|
||||||
|
/// replied to and [editEventId] is the eventId of the event being replied to
|
||||||
|
Future<String> parseAndRunCommand(Room room, String msg,
|
||||||
|
{Event inReplyTo, String editEventId, String txid}) async {
|
||||||
|
final args = CommandArgs(
|
||||||
|
inReplyTo: inReplyTo,
|
||||||
|
editEventId: editEventId,
|
||||||
|
msg: '',
|
||||||
|
room: room,
|
||||||
|
txid: txid,
|
||||||
|
);
|
||||||
|
if (!msg.startsWith('/')) {
|
||||||
|
if (commands.containsKey('send')) {
|
||||||
|
args.msg = msg;
|
||||||
|
return await commands['send'](args);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// remove the /
|
||||||
|
msg = msg.substring(1);
|
||||||
|
var command = msg;
|
||||||
|
if (msg.contains(' ')) {
|
||||||
|
final idx = msg.indexOf(' ');
|
||||||
|
command = msg.substring(0, idx).toLowerCase();
|
||||||
|
args.msg = msg.substring(idx + 1);
|
||||||
|
} else {
|
||||||
|
command = msg.toLowerCase();
|
||||||
|
}
|
||||||
|
if (commands.containsKey(command)) {
|
||||||
|
return await commands[command](args);
|
||||||
|
}
|
||||||
|
if (msg.startsWith('/') && commands.containsKey('send')) {
|
||||||
|
// re-set to include the "command"
|
||||||
|
args.msg = msg;
|
||||||
|
return await commands['send'](args);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Unregister all commands
|
||||||
|
void unregisterAllCommands() {
|
||||||
|
commands.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Register all default commands
|
||||||
|
void registerDefaultCommands() {
|
||||||
|
addCommand('send', (CommandArgs args) async {
|
||||||
|
return await args.room.sendTextEvent(
|
||||||
|
args.msg,
|
||||||
|
inReplyTo: args.inReplyTo,
|
||||||
|
editEventId: args.editEventId,
|
||||||
|
parseCommands: false,
|
||||||
|
txid: args.txid,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
addCommand('me', (CommandArgs args) async {
|
||||||
|
return await args.room.sendTextEvent(
|
||||||
|
args.msg,
|
||||||
|
inReplyTo: args.inReplyTo,
|
||||||
|
editEventId: args.editEventId,
|
||||||
|
msgtype: MessageTypes.Emote,
|
||||||
|
parseCommands: false,
|
||||||
|
txid: args.txid,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
addCommand('plain', (CommandArgs args) async {
|
||||||
|
return await args.room.sendTextEvent(
|
||||||
|
args.msg,
|
||||||
|
inReplyTo: args.inReplyTo,
|
||||||
|
editEventId: args.editEventId,
|
||||||
|
parseMarkdown: false,
|
||||||
|
parseCommands: false,
|
||||||
|
txid: args.txid,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
addCommand('html', (CommandArgs args) async {
|
||||||
|
final event = <String, dynamic>{
|
||||||
|
'msgtype': 'm.text',
|
||||||
|
'body': args.msg,
|
||||||
|
'format': 'org.matrix.custom.html',
|
||||||
|
'formatted_body': args.msg,
|
||||||
|
};
|
||||||
|
return await args.room.sendEvent(
|
||||||
|
event,
|
||||||
|
inReplyTo: args.inReplyTo,
|
||||||
|
editEventId: args.editEventId,
|
||||||
|
txid: args.txid,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
addCommand('react', (CommandArgs args) async {
|
||||||
|
if (args.inReplyTo == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return await args.room.sendReaction(args.inReplyTo.eventId, args.msg);
|
||||||
|
});
|
||||||
|
addCommand('join', (CommandArgs args) async {
|
||||||
|
await args.room.client.joinRoomOrAlias(args.msg);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
addCommand('leave', (CommandArgs args) async {
|
||||||
|
await args.room.leave();
|
||||||
|
return '';
|
||||||
|
});
|
||||||
|
addCommand('op', (CommandArgs args) async {
|
||||||
|
final parts = args.msg.split(' ');
|
||||||
|
if (parts.isEmpty) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
var pl = 50;
|
||||||
|
if (parts.length >= 2) {
|
||||||
|
pl = int.tryParse(parts[1]);
|
||||||
|
}
|
||||||
|
final mxid = parts.first;
|
||||||
|
return await args.room.setPower(mxid, pl);
|
||||||
|
});
|
||||||
|
addCommand('kick', (CommandArgs args) async {
|
||||||
|
final parts = args.msg.split(' ');
|
||||||
|
await args.room.kick(parts.first);
|
||||||
|
return '';
|
||||||
|
});
|
||||||
|
addCommand('ban', (CommandArgs args) async {
|
||||||
|
final parts = args.msg.split(' ');
|
||||||
|
await args.room.ban(parts.first);
|
||||||
|
return '';
|
||||||
|
});
|
||||||
|
addCommand('unban', (CommandArgs args) async {
|
||||||
|
final parts = args.msg.split(' ');
|
||||||
|
await args.room.unban(parts.first);
|
||||||
|
return '';
|
||||||
|
});
|
||||||
|
addCommand('invite', (CommandArgs args) async {
|
||||||
|
final parts = args.msg.split(' ');
|
||||||
|
await args.room.invite(parts.first);
|
||||||
|
return '';
|
||||||
|
});
|
||||||
|
addCommand('myroomnick', (CommandArgs args) async {
|
||||||
|
final currentEventJson = args.room
|
||||||
|
.getState(EventTypes.RoomMember, args.room.client.userID)
|
||||||
|
.content
|
||||||
|
.copy();
|
||||||
|
currentEventJson['displayname'] = args.msg;
|
||||||
|
return await args.room.client.sendState(
|
||||||
|
args.room.id,
|
||||||
|
EventTypes.RoomMember,
|
||||||
|
currentEventJson,
|
||||||
|
args.room.client.userID,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
addCommand('myroomavatar', (CommandArgs args) async {
|
||||||
|
final currentEventJson = args.room
|
||||||
|
.getState(EventTypes.RoomMember, args.room.client.userID)
|
||||||
|
.content
|
||||||
|
.copy();
|
||||||
|
currentEventJson['avatar_url'] = args.msg;
|
||||||
|
return await args.room.client.sendState(
|
||||||
|
args.room.id,
|
||||||
|
EventTypes.RoomMember,
|
||||||
|
currentEventJson,
|
||||||
|
args.room.client.userID,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CommandArgs {
|
||||||
|
String msg;
|
||||||
|
String editEventId;
|
||||||
|
Event inReplyTo;
|
||||||
|
Room room;
|
||||||
|
String txid;
|
||||||
|
CommandArgs(
|
||||||
|
{this.msg, this.editEventId, this.inReplyTo, this.room, this.txid});
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,255 @@
|
||||||
|
/*
|
||||||
|
* Famedly Matrix SDK
|
||||||
|
* Copyright (C) 2021 Famedly GmbH
|
||||||
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
|
import 'fake_client.dart';
|
||||||
|
import 'fake_matrix_api.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
group('Commands', () {
|
||||||
|
Client client;
|
||||||
|
Room room;
|
||||||
|
|
||||||
|
final getLastMessagePayload =
|
||||||
|
([String type = 'm.room.message', String stateKey]) {
|
||||||
|
final state = stateKey != null;
|
||||||
|
return json.decode(FakeMatrixApi.calledEndpoints.entries
|
||||||
|
.firstWhere((e) => e.key.startsWith(
|
||||||
|
'/client/r0/rooms/${Uri.encodeComponent(room.id)}/${state ? 'state' : 'send'}/${Uri.encodeComponent(type)}${state && stateKey.isNotEmpty ? '/' + Uri.encodeComponent(stateKey) : ''}'))
|
||||||
|
.value
|
||||||
|
.first);
|
||||||
|
};
|
||||||
|
|
||||||
|
test('setupClient', () async {
|
||||||
|
client = await getClient();
|
||||||
|
room = Room(id: '!1234:fakeServer.notExisting', client: client);
|
||||||
|
room.setState(Event(
|
||||||
|
type: 'm.room.power_levels',
|
||||||
|
content: {},
|
||||||
|
room: room,
|
||||||
|
stateKey: '',
|
||||||
|
));
|
||||||
|
room.setState(Event(
|
||||||
|
type: 'm.room.member',
|
||||||
|
content: {'membership': 'join'},
|
||||||
|
room: room,
|
||||||
|
stateKey: client.userID,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('send', () async {
|
||||||
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
|
await room.sendTextEvent('/send Hello World');
|
||||||
|
var sent = getLastMessagePayload();
|
||||||
|
expect(sent, {
|
||||||
|
'msgtype': 'm.text',
|
||||||
|
'body': 'Hello World',
|
||||||
|
});
|
||||||
|
|
||||||
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
|
await room.sendTextEvent('Beep Boop');
|
||||||
|
sent = getLastMessagePayload();
|
||||||
|
expect(sent, {
|
||||||
|
'msgtype': 'm.text',
|
||||||
|
'body': 'Beep Boop',
|
||||||
|
});
|
||||||
|
|
||||||
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
|
await room.sendTextEvent('Beep *Boop*');
|
||||||
|
sent = getLastMessagePayload();
|
||||||
|
expect(sent, {
|
||||||
|
'msgtype': 'm.text',
|
||||||
|
'body': 'Beep *Boop*',
|
||||||
|
'format': 'org.matrix.custom.html',
|
||||||
|
'formatted_body': 'Beep <em>Boop</em>',
|
||||||
|
});
|
||||||
|
|
||||||
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
|
await room.sendTextEvent('//send Hello World');
|
||||||
|
sent = getLastMessagePayload();
|
||||||
|
expect(sent, {
|
||||||
|
'msgtype': 'm.text',
|
||||||
|
'body': '/send Hello World',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('me', () async {
|
||||||
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
|
await room.sendTextEvent('/me heya');
|
||||||
|
var sent = getLastMessagePayload();
|
||||||
|
expect(sent, {
|
||||||
|
'msgtype': 'm.emote',
|
||||||
|
'body': 'heya',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('plain', () async {
|
||||||
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
|
await room.sendTextEvent('/plain *floof*');
|
||||||
|
var sent = getLastMessagePayload();
|
||||||
|
expect(sent, {
|
||||||
|
'msgtype': 'm.text',
|
||||||
|
'body': '*floof*',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('html', () async {
|
||||||
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
|
await room.sendTextEvent('/html <b>yay</b>');
|
||||||
|
var sent = getLastMessagePayload();
|
||||||
|
expect(sent, {
|
||||||
|
'msgtype': 'm.text',
|
||||||
|
'body': '<b>yay</b>',
|
||||||
|
'format': 'org.matrix.custom.html',
|
||||||
|
'formatted_body': '<b>yay</b>',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('react', () async {
|
||||||
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
|
await room.sendTextEvent('/react 🦊',
|
||||||
|
inReplyTo: Event(eventId: '\$event'));
|
||||||
|
var sent = getLastMessagePayload('m.reaction');
|
||||||
|
expect(sent, {
|
||||||
|
'm.relates_to': {
|
||||||
|
'rel_type': 'm.annotation',
|
||||||
|
'event_id': '\$event',
|
||||||
|
'key': '🦊',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('join', () async {
|
||||||
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
|
await room.sendTextEvent('/join !newroom:example.com');
|
||||||
|
expect(
|
||||||
|
FakeMatrixApi
|
||||||
|
.calledEndpoints['/client/r0/join/!newroom%3Aexample.com']
|
||||||
|
.first !=
|
||||||
|
null,
|
||||||
|
true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('leave', () async {
|
||||||
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
|
await room.sendTextEvent('/leave');
|
||||||
|
expect(
|
||||||
|
FakeMatrixApi
|
||||||
|
.calledEndpoints[
|
||||||
|
'/client/r0/rooms/!1234%3AfakeServer.notExisting/leave']
|
||||||
|
.first !=
|
||||||
|
null,
|
||||||
|
true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('op', () async {
|
||||||
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
|
await room.sendTextEvent('/op @user:example.org');
|
||||||
|
var sent = getLastMessagePayload('m.room.power_levels', '');
|
||||||
|
expect(sent, {
|
||||||
|
'users': {'@user:example.org': 50}
|
||||||
|
});
|
||||||
|
|
||||||
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
|
await room.sendTextEvent('/op @user:example.org 100');
|
||||||
|
sent = getLastMessagePayload('m.room.power_levels', '');
|
||||||
|
expect(sent, {
|
||||||
|
'users': {'@user:example.org': 100}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('kick', () async {
|
||||||
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
|
await room.sendTextEvent('/kick @baduser:example.org');
|
||||||
|
expect(
|
||||||
|
json.decode(FakeMatrixApi
|
||||||
|
.calledEndpoints[
|
||||||
|
'/client/r0/rooms/!1234%3AfakeServer.notExisting/kick']
|
||||||
|
.first),
|
||||||
|
{
|
||||||
|
'user_id': '@baduser:example.org',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('ban', () async {
|
||||||
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
|
await room.sendTextEvent('/ban @baduser:example.org');
|
||||||
|
expect(
|
||||||
|
json.decode(FakeMatrixApi
|
||||||
|
.calledEndpoints[
|
||||||
|
'/client/r0/rooms/!1234%3AfakeServer.notExisting/ban']
|
||||||
|
.first),
|
||||||
|
{
|
||||||
|
'user_id': '@baduser:example.org',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('unban', () async {
|
||||||
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
|
await room.sendTextEvent('/unban @baduser:example.org');
|
||||||
|
expect(
|
||||||
|
json.decode(FakeMatrixApi
|
||||||
|
.calledEndpoints[
|
||||||
|
'/client/r0/rooms/!1234%3AfakeServer.notExisting/unban']
|
||||||
|
.first),
|
||||||
|
{
|
||||||
|
'user_id': '@baduser:example.org',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('invite', () async {
|
||||||
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
|
await room.sendTextEvent('/invite @baduser:example.org');
|
||||||
|
expect(
|
||||||
|
json.decode(FakeMatrixApi
|
||||||
|
.calledEndpoints[
|
||||||
|
'/client/r0/rooms/!1234%3AfakeServer.notExisting/invite']
|
||||||
|
.first),
|
||||||
|
{
|
||||||
|
'user_id': '@baduser:example.org',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('myroomnick', () async {
|
||||||
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
|
await room.sendTextEvent('/myroomnick Foxies~');
|
||||||
|
var sent = getLastMessagePayload('m.room.member', client.userID);
|
||||||
|
expect(sent, {
|
||||||
|
'displayname': 'Foxies~',
|
||||||
|
'membership': 'join',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('myroomavatar', () async {
|
||||||
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
|
await room.sendTextEvent('/myroomavatar mxc://beep/boop');
|
||||||
|
var sent = getLastMessagePayload('m.room.member', client.userID);
|
||||||
|
expect(sent, {
|
||||||
|
'avatar_url': 'mxc://beep/boop',
|
||||||
|
'membership': 'join',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('dispose client', () async {
|
||||||
|
await client.dispose(closeDatabase: true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -104,6 +104,10 @@ class FakeMatrixApi extends MockClient {
|
||||||
action.contains(
|
action.contains(
|
||||||
'/client/r0/rooms/!1234%3AfakeServer.notExisting/send/')) {
|
'/client/r0/rooms/!1234%3AfakeServer.notExisting/send/')) {
|
||||||
res = {'event_id': '\$event${FakeMatrixApi.eventCounter++}'};
|
res = {'event_id': '\$event${FakeMatrixApi.eventCounter++}'};
|
||||||
|
} else if (method == 'PUT' &&
|
||||||
|
action.contains(
|
||||||
|
'/client/r0/rooms/!1234%3AfakeServer.notExisting/state/')) {
|
||||||
|
res = {'event_id': '\$event${FakeMatrixApi.eventCounter++}'};
|
||||||
} else if (action.contains('/client/r0/sync')) {
|
} else if (action.contains('/client/r0/sync')) {
|
||||||
res = {
|
res = {
|
||||||
'next_batch': DateTime.now().millisecondsSinceEpoch.toString
|
'next_batch': DateTime.now().millisecondsSinceEpoch.toString
|
||||||
|
|
@ -1830,16 +1834,23 @@ class FakeMatrixApi extends MockClient {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'/client/r0/rooms/!localpart%3Aexample.com/invite': (var req) => {},
|
'/client/r0/rooms/!localpart%3Aexample.com/invite': (var req) => {},
|
||||||
|
'/client/r0/rooms/!1234%3AfakeServer.notExisting/invite': (var req) => {},
|
||||||
'/client/r0/rooms/!localpart%3Aexample.com/leave': (var req) => {},
|
'/client/r0/rooms/!localpart%3Aexample.com/leave': (var req) => {},
|
||||||
|
'/client/r0/rooms/!1234%3AfakeServer.notExisting/leave': (var req) => {},
|
||||||
'/client/r0/rooms/!localpart%3Aexample.com/forget': (var req) => {},
|
'/client/r0/rooms/!localpart%3Aexample.com/forget': (var req) => {},
|
||||||
'/client/r0/rooms/!localpart%3Aserver.abc/kick': (var req) => {},
|
'/client/r0/rooms/!localpart%3Aserver.abc/kick': (var req) => {},
|
||||||
|
'/client/r0/rooms/!1234%3AfakeServer.notExisting/kick': (var req) => {},
|
||||||
'/client/r0/rooms/!localpart%3Aexample.com/kick': (var req) => {},
|
'/client/r0/rooms/!localpart%3Aexample.com/kick': (var req) => {},
|
||||||
'/client/r0/rooms/!localpart%3Aexample.com/ban': (var req) => {},
|
'/client/r0/rooms/!localpart%3Aexample.com/ban': (var req) => {},
|
||||||
|
'/client/r0/rooms/!1234%3AfakeServer.notExisting/ban': (var req) => {},
|
||||||
'/client/r0/rooms/!localpart%3Aexample.com/unban': (var req) => {},
|
'/client/r0/rooms/!localpart%3Aexample.com/unban': (var req) => {},
|
||||||
|
'/client/r0/rooms/!1234%3AfakeServer.notExisting/unban': (var req) => {},
|
||||||
'/client/r0/rooms/!localpart%3Aexample.com/join': (var req) =>
|
'/client/r0/rooms/!localpart%3Aexample.com/join': (var req) =>
|
||||||
{'room_id': '!localpart:example.com'},
|
{'room_id': '!localpart:example.com'},
|
||||||
'/client/r0/join/!localpart%3Aexample.com?server_name=example.com&server_name=example.abc':
|
'/client/r0/join/!localpart%3Aexample.com?server_name=example.com&server_name=example.abc':
|
||||||
(var req) => {'room_id': '!localpart:example.com'},
|
(var req) => {'room_id': '!localpart:example.com'},
|
||||||
|
'/client/r0/join/!newroom%3Aexample.com': (var req) =>
|
||||||
|
{'room_id': '!newroom%3A:example.com'},
|
||||||
'/client/r0/keys/upload': (var req) => {
|
'/client/r0/keys/upload': (var req) => {
|
||||||
'one_time_key_counts': {
|
'one_time_key_counts': {
|
||||||
'curve25519': 10,
|
'curve25519': 10,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue