Skip to content

Commit fe11d69

Browse files
committed
api: Add updateMessage route
Since it has a `propagate_mode` param that means the same as PropagateMode in an update-message event -- this is after all the update-message request binding -- move that enum's definition here, from lib/api/model, and adjust imports.
1 parent 8ee140d commit fe11d69

File tree

7 files changed

+121
-9
lines changed

7 files changed

+121
-9
lines changed

lib/api/model/events.dart

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'package:json_annotation/json_annotation.dart';
22

33
import '../../model/algorithms.dart';
4+
import '../route/messages.dart';
45
import 'json.dart';
56
import 'model.dart';
67
import 'submessage.dart';
@@ -766,14 +767,6 @@ class UpdateMessageEvent extends Event {
766767
Map<String, dynamic> toJson() => _$UpdateMessageEventToJson(this);
767768
}
768769

769-
/// As in [UpdateMessageEvent.propagateMode].
770-
@JsonEnum(fieldRename: FieldRename.snake)
771-
enum PropagateMode {
772-
changeOne,
773-
changeLater,
774-
changeAll;
775-
}
776-
777770
/// A Zulip event of type `delete_message`: https://zulip.com/api/get-events#delete_message
778771
@JsonSerializable(fieldRename: FieldRename.snake)
779772
class DeleteMessageEvent extends Event {

lib/api/model/events.g.dart

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/api/route/messages.dart

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,49 @@ class SendMessageResult {
271271
Map<String, dynamic> toJson() => _$SendMessageResultToJson(this);
272272
}
273273

274+
/// https://zulip.com/api/update-message
275+
Future<UpdateMessageResult> updateMessage(
276+
ApiConnection connection, {
277+
required int messageId,
278+
String? topic,
279+
PropagateMode? propagateMode,
280+
bool? sendNotificationToOldThread,
281+
bool? sendNotificationToNewThread,
282+
String? content,
283+
int? streamId,
284+
}) {
285+
return connection.patch('updateMessage', UpdateMessageResult.fromJson, 'messages/$messageId', {
286+
if (topic != null) 'topic': RawParameter(topic),
287+
if (propagateMode != null) 'propagate_mode': RawParameter(propagateMode.toJson()),
288+
if (sendNotificationToOldThread != null) 'send_notification_to_old_thread': sendNotificationToOldThread,
289+
if (sendNotificationToNewThread != null) 'send_notification_to_new_thread': sendNotificationToNewThread,
290+
if (content != null) 'content': RawParameter(content),
291+
if (streamId != null) 'stream_id': streamId,
292+
});
293+
}
294+
295+
/// As in [updateMessage] or [UpdateMessageEvent.propagateMode].
296+
@JsonEnum(fieldRename: FieldRename.snake, alwaysCreate: true)
297+
enum PropagateMode {
298+
changeOne,
299+
changeLater,
300+
changeAll;
301+
302+
String toJson() =>_$PropagateModeEnumMap[this]!;
303+
}
304+
305+
@JsonSerializable(fieldRename: FieldRename.snake)
306+
class UpdateMessageResult {
307+
// final List<DetachedUpload> detachedUploads; // TODO handle
308+
309+
UpdateMessageResult();
310+
311+
factory UpdateMessageResult.fromJson(Map<String, dynamic> json) =>
312+
_$UpdateMessageResultFromJson(json);
313+
314+
Map<String, dynamic> toJson() => _$UpdateMessageResultToJson(this);
315+
}
316+
274317
/// https://zulip.com/api/upload-file
275318
Future<UploadFileResult> uploadFile(
276319
ApiConnection connection, {

lib/api/route/messages.g.dart

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/api/model/events_checks.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'package:checks/checks.dart';
22
import 'package:zulip/api/model/events.dart';
33
import 'package:zulip/api/model/model.dart';
4+
import 'package:zulip/api/route/messages.dart';
45

56
extension EventChecks on Subject<Event> {
67
Subject<int> get id => has((e) => e.id, 'id');

test/api/route/messages_test.dart

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,67 @@ void main() {
456456
});
457457
});
458458

459+
group('updateMessage', () {
460+
Future<UpdateMessageResult> checkUpdateMessage(
461+
FakeApiConnection connection, {
462+
required int messageId,
463+
String? topic,
464+
PropagateMode? propagateMode,
465+
bool? sendNotificationToOldThread,
466+
bool? sendNotificationToNewThread,
467+
String? content,
468+
int? streamId,
469+
required Map<String, String> expected,
470+
}) async {
471+
final result = await updateMessage(connection,
472+
messageId: messageId,
473+
topic: topic,
474+
propagateMode: propagateMode,
475+
sendNotificationToOldThread: sendNotificationToOldThread,
476+
sendNotificationToNewThread: sendNotificationToNewThread,
477+
content: content,
478+
streamId: streamId,
479+
);
480+
check(connection.lastRequest).isA<http.Request>()
481+
..method.equals('PATCH')
482+
..url.path.equals('/api/v1/messages/$messageId')
483+
..bodyFields.deepEquals(expected);
484+
return result;
485+
}
486+
487+
test('topic/content change', () {
488+
// A separate test exercises `streamId`;
489+
// the API doesn't allow changing channel and content at the same time.
490+
return FakeApiConnection.with_((connection) async {
491+
connection.prepare(json: UpdateMessageResult().toJson());
492+
await checkUpdateMessage(connection,
493+
messageId: eg.streamMessage().id,
494+
topic: 'new topic',
495+
propagateMode: PropagateMode.changeAll,
496+
sendNotificationToOldThread: true,
497+
sendNotificationToNewThread: true,
498+
content: 'asdf',
499+
expected: {
500+
'topic': 'new topic',
501+
'propagate_mode': 'change_all',
502+
'send_notification_to_old_thread': 'true',
503+
'send_notification_to_new_thread': 'true',
504+
'content': 'asdf',
505+
});
506+
});
507+
});
508+
509+
test('channel change', () {
510+
return FakeApiConnection.with_((connection) async {
511+
connection.prepare(json: UpdateMessageResult().toJson());
512+
await checkUpdateMessage(connection,
513+
messageId: eg.streamMessage().id,
514+
streamId: 1,
515+
expected: {'stream_id': '1'});
516+
});
517+
});
518+
});
519+
459520
group('uploadFile', () {
460521
Future<void> checkUploadFile(FakeApiConnection connection, {
461522
required List<List<int>> content,

test/model/message_list_test.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import 'package:zulip/api/exception.dart';
88
import 'package:zulip/api/model/events.dart';
99
import 'package:zulip/api/model/model.dart';
1010
import 'package:zulip/api/model/narrow.dart';
11+
import 'package:zulip/api/route/messages.dart';
1112
import 'package:zulip/model/algorithms.dart';
1213
import 'package:zulip/model/content.dart';
1314
import 'package:zulip/model/message_list.dart';

0 commit comments

Comments
 (0)