Skip to content

Commit ad8efb3

Browse files
committed
api [nfc]: Extract and parse UpdateMessageMoveData from UpdateMessageEvent
While this says [nfc], there is actually a change: `toJson` no longer includes these message move related fields. However, this seems to have nearly no impact on the tests, and clearly does not affect the app. Signed-off-by: Zixuan James Li <[email protected]>
1 parent f294005 commit ad8efb3

File tree

6 files changed

+118
-58
lines changed

6 files changed

+118
-58
lines changed

lib/api/model/events.dart

+54-15
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,52 @@ class MessageEvent extends Event {
701701
}
702702
}
703703

704+
/// Data structure representing a message move.
705+
class UpdateMessageMoveData {
706+
final int? origStreamId;
707+
final int? newStreamId;
708+
709+
final PropagateMode? propagateMode;
710+
711+
final TopicName? origTopic;
712+
final TopicName? newTopic;
713+
714+
UpdateMessageMoveData({
715+
required this.origStreamId,
716+
required this.newStreamId,
717+
required this.propagateMode,
718+
required this.origTopic,
719+
required this.newTopic,
720+
});
721+
722+
/// Extract [UpdateMessageMoveData] from the JSON object for an
723+
/// [UpdateMessageEvent].
724+
///
725+
/// Throws an error if the data is malformed.
726+
factory UpdateMessageMoveData.fromJson(Object? json) {
727+
json as Map<String, Object?>;
728+
final origStreamId = (json['stream_id'] as num?)?.toInt();
729+
final newStreamId = (json['new_stream_id'] as num?)?.toInt();
730+
final propagateModeString = json['propagate_mode'] as String?;
731+
final propagateMode = propagateModeString == null ? null
732+
: PropagateMode.fromRawString(propagateModeString);
733+
final origTopic = json['orig_subject'] == null ? null
734+
: TopicName.fromJson(json['orig_subject'] as String);
735+
final newTopic = json['subject'] == null ? null
736+
: TopicName.fromJson(json['subject'] as String);
737+
738+
return UpdateMessageMoveData(
739+
origStreamId: origStreamId,
740+
newStreamId: newStreamId,
741+
propagateMode: propagateMode,
742+
origTopic: origTopic,
743+
newTopic: newTopic,
744+
);
745+
}
746+
747+
Object? toJson() => null;
748+
}
749+
704750
/// A Zulip event of type `update_message`: https://zulip.com/api/get-events#update_message
705751
@JsonSerializable(fieldRename: FieldRename.snake)
706752
class UpdateMessageEvent extends Event {
@@ -718,16 +764,8 @@ class UpdateMessageEvent extends Event {
718764

719765
// final String? streamName; // ignore
720766

721-
@JsonKey(name: 'stream_id')
722-
final int? origStreamId;
723-
final int? newStreamId;
724-
725-
final PropagateMode? propagateMode;
726-
727-
@JsonKey(name: 'orig_subject')
728-
final TopicName? origTopic;
729-
@JsonKey(name: 'subject')
730-
final TopicName? newTopic;
767+
@JsonKey(readValue: _readMoveData)
768+
final UpdateMessageMoveData moveData;
731769

732770
// final List<TopicLink> topicLinks; // TODO handle
733771

@@ -747,18 +785,19 @@ class UpdateMessageEvent extends Event {
747785
required this.messageIds,
748786
required this.flags,
749787
required this.editTimestamp,
750-
required this.origStreamId,
751-
required this.newStreamId,
752-
required this.propagateMode,
753-
required this.origTopic,
754-
required this.newTopic,
788+
required this.moveData,
755789
required this.origContent,
756790
required this.origRenderedContent,
757791
required this.content,
758792
required this.renderedContent,
759793
required this.isMeMessage,
760794
});
761795

796+
static Object? _readMoveData(Map<Object?, Object?> json, String key) {
797+
// Parsing [UpdateMessageMoveData] requires `json`, not the default `json[key]`.
798+
return json as Object?;
799+
}
800+
762801
factory UpdateMessageEvent.fromJson(Map<String, dynamic> json) =>
763802
_$UpdateMessageEventFromJson(json);
764803

lib/api/model/events.g.dart

+3-21
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/model/message.dart

+6-5
Original file line numberDiff line numberDiff line change
@@ -172,11 +172,12 @@ class MessageStoreImpl with MessageStore {
172172
// The interaction between the fields of these events are a bit tricky.
173173
// For reference, see: https://zulip.com/api/get-events#update_message
174174

175-
final origStreamId = event.origStreamId;
176-
final newStreamId = event.newStreamId; // null if topic-only move
177-
final origTopic = event.origTopic;
178-
final newTopic = event.newTopic;
179-
final propagateMode = event.propagateMode;
175+
final moveData = event.moveData;
176+
final origStreamId = moveData.origStreamId;
177+
final newStreamId = moveData.newStreamId; // null if topic-only move
178+
final origTopic = moveData.origTopic;
179+
final newTopic = moveData.newTopic;
180+
final propagateMode = moveData.propagateMode;
180181

181182
if (origTopic == null) {
182183
// There was no move.

test/api/model/events_checks.dart

+10-5
Original file line numberDiff line numberDiff line change
@@ -48,18 +48,23 @@ extension UpdateMessageEventChecks on Subject<UpdateMessageEvent> {
4848
Subject<List<int>> get messageIds => has((e) => e.messageIds, 'messageIds');
4949
Subject<List<MessageFlag>> get flags => has((e) => e.flags, 'flags');
5050
Subject<int?> get editTimestamp => has((e) => e.editTimestamp, 'editTimestamp');
51-
Subject<int?> get origStreamId => has((e) => e.origStreamId, 'origStreamId');
52-
Subject<int?> get newStreamId => has((e) => e.newStreamId, 'newStreamId');
53-
Subject<PropagateMode?> get propagateMode => has((e) => e.propagateMode, 'propagateMode');
54-
Subject<TopicName?> get origTopic => has((e) => e.origTopic, 'origTopic');
55-
Subject<TopicName?> get newTopic => has((e) => e.newTopic, 'newTopic');
51+
Subject<UpdateMessageMoveData?> get moveData => has((e) => e.moveData, 'moveData');
5652
Subject<String?> get origContent => has((e) => e.origContent, 'origContent');
5753
Subject<String?> get origRenderedContent => has((e) => e.origRenderedContent, 'origRenderedContent');
5854
Subject<String?> get content => has((e) => e.content, 'content');
5955
Subject<String?> get renderedContent => has((e) => e.renderedContent, 'renderedContent');
6056
Subject<bool?> get isMeMessage => has((e) => e.isMeMessage, 'isMeMessage');
6157
}
6258

59+
60+
extension UpdateMessageMoveDataChecks on Subject<UpdateMessageMoveData> {
61+
Subject<int?> get origStreamId => has((e) => e.origStreamId, 'origStreamId');
62+
Subject<int?> get newStreamId => has((e) => e.newStreamId, 'newStreamId');
63+
Subject<PropagateMode?> get propagateMode => has((e) => e.propagateMode, 'propagateMode');
64+
Subject<TopicName?> get origTopic => has((e) => e.origTopic, 'origTopic');
65+
Subject<TopicName?> get newTopic => has((e) => e.newTopic, 'newTopic');
66+
}
67+
6368
extension DeleteMessageEventChecks on Subject<DeleteMessageEvent> {
6469
Subject<MessageType?> get messageType => has((e) => e.messageType, 'messageType');
6570
}

test/api/model/events_test.dart

+31-2
Original file line numberDiff line numberDiff line change
@@ -101,14 +101,29 @@ void main() {
101101
'edit_timestamp': 1718741351,
102102
};
103103

104+
test('smoke moveData', () {
105+
check(Event.fromJson({ ...baseJson,
106+
'stream_id': 1,
107+
'new_stream_id': 2,
108+
'orig_subject': 'foo',
109+
'subject': 'bar',
110+
'propagate_mode': 'change_all',
111+
})).isA<UpdateMessageEvent>().moveData.isNotNull()
112+
..origStreamId.equals(1)
113+
..newStreamId.equals(2)
114+
..origTopic.equals(TopicName('foo'))
115+
..newTopic.equals(TopicName('bar'))
116+
..propagateMode.equals(PropagateMode.changeAll);
117+
});
118+
104119
test('stream_id -> origStreamId, subject = orig_subject', () {
105120
check(Event.fromJson({ ...baseJson,
106121
'stream_id': 1,
107122
'new_stream_id': 2,
108123
'orig_subject': 'foo',
109124
'subject': null,
110125
'propagate_mode': 'change_all',
111-
})).isA<UpdateMessageEvent>()
126+
})).isA<UpdateMessageEvent>().moveData.isNotNull()
112127
..origStreamId.equals(1)
113128
..newStreamId.equals(2)
114129
..origTopic.equals(TopicName('foo'))
@@ -122,12 +137,26 @@ void main() {
122137
'orig_subject': 'foo',
123138
'subject': 'bar',
124139
'propagate_mode': 'change_all',
125-
})).isA<UpdateMessageEvent>()
140+
})).isA<UpdateMessageEvent>().moveData.isNotNull()
126141
..origStreamId.equals(1)
127142
..newStreamId.isNull()
128143
..origTopic.equals(const TopicName('foo'))
129144
..newTopic.equals(const TopicName('bar'));
130145
});
146+
147+
test('no message move', () {
148+
check(Event.fromJson({...baseJson,
149+
'stream_id': 1,
150+
'orig_content': 'foo',
151+
'orig_rendered_content': 'foo',
152+
'content': 'bar',
153+
'rendered_content': 'bar',
154+
})).isA<UpdateMessageEvent>().moveData.isNotNull()
155+
..origStreamId.equals(1)
156+
..newStreamId.isNull()
157+
..origTopic.isNull()
158+
..newTopic.isNull();
159+
});
131160
});
132161

133162
test('delete_message: require streamId and topic for stream messages', () {

test/example_data.dart

+14-10
Original file line numberDiff line numberDiff line change
@@ -653,11 +653,13 @@ UpdateMessageEvent updateMessageEditEvent(
653653
messageIds: [messageId],
654654
flags: flags ?? origMessage.flags,
655655
editTimestamp: editTimestamp ?? 1234567890, // TODO generate timestamp
656-
origStreamId: origMessage is StreamMessage ? origMessage.streamId : null,
657-
newStreamId: null,
658-
propagateMode: null,
659-
origTopic: null,
660-
newTopic: null,
656+
moveData: UpdateMessageMoveData(
657+
origStreamId: origMessage is StreamMessage ? origMessage.streamId : null,
658+
newStreamId: null,
659+
propagateMode: null,
660+
origTopic: null,
661+
newTopic: null,
662+
),
661663
origContent: 'some probably-mismatched old Markdown',
662664
origRenderedContent: origMessage.content,
663665
content: 'some probably-mismatched new Markdown',
@@ -690,11 +692,13 @@ UpdateMessageEvent _updateMessageMoveEvent(
690692
messageIds: messageIds,
691693
flags: flags,
692694
editTimestamp: 1234567890, // TODO generate timestamp
693-
origStreamId: origStreamId,
694-
newStreamId: newStreamId,
695-
propagateMode: propagateMode,
696-
origTopic: origTopic,
697-
newTopic: newTopic,
695+
moveData: UpdateMessageMoveData(
696+
origStreamId: origStreamId,
697+
newStreamId: newStreamId,
698+
propagateMode: propagateMode,
699+
origTopic: origTopic,
700+
newTopic: newTopic,
701+
),
698702
origContent: origContent,
699703
origRenderedContent: origContent,
700704
content: newContent,

0 commit comments

Comments
 (0)