@@ -16,6 +16,7 @@ import 'package:zulip/model/localizations.dart';
1616import 'package:zulip/model/narrow.dart' ;
1717import 'package:zulip/model/store.dart' ;
1818import 'package:zulip/widgets/content.dart' ;
19+ import 'package:zulip/widgets/emoji_reaction.dart' ;
1920import 'package:zulip/widgets/icons.dart' ;
2021import 'package:zulip/widgets/message_list.dart' ;
2122import 'package:zulip/widgets/store.dart' ;
@@ -576,6 +577,99 @@ void main() {
576577 });
577578 });
578579
580+ group ('EditStateMarker' , () {
581+ void checkMarkersCount ({required int edited, required int moved}) {
582+ check (find.byIcon (ZulipIcons .edited).evaluate ()).length.equals (edited);
583+ check (find.byIcon (ZulipIcons .message_moved).evaluate ()).length.equals (moved);
584+ }
585+
586+ testWidgets ('no edited or moved messages' , (WidgetTester tester) async {
587+ final message = eg.streamMessage ();
588+ await setupMessageListPage (tester, messages: [message]);
589+ checkMarkersCount (edited: 0 , moved: 0 );
590+ });
591+
592+ testWidgets ('edited and moved messages from events' , (WidgetTester tester) async {
593+ final message = eg.streamMessage ();
594+ final message2 = eg.streamMessage ();
595+ await setupMessageListPage (tester, messages: [message, message2]);
596+ checkMarkersCount (edited: 0 , moved: 0 );
597+
598+ await store.handleEvent (eg.updateMessageEditEvent (message, renderedContent: 'edited' ));
599+ await tester.pump ();
600+ checkMarkersCount (edited: 1 , moved: 0 );
601+
602+ await store.handleEvent (eg.updateMessageMoveEvent (
603+ [message, message2], origTopic: 'old' , newTopic: 'new' ));
604+ await tester.pump ();
605+ checkMarkersCount (edited: 1 , moved: 1 );
606+
607+ await store.handleEvent (eg.updateMessageEditEvent (message2, renderedContent: 'edited' ));
608+ await tester.pump ();
609+ checkMarkersCount (edited: 2 , moved: 0 );
610+ });
611+
612+ List <List <(String , Rect )>> captureMessageRects (
613+ WidgetTester tester,
614+ List <Message > messages,
615+ Message targetMessage,
616+ ) {
617+ assert (messages.contains (targetMessage));
618+ final List <List <(String , Rect )>> result = [];
619+ for (final message in messages) {
620+ final baseFinder = find.byWidgetPredicate (
621+ (widget) => widget is MessageWithPossibleSender
622+ && widget.item.message.id == message.id);
623+
624+ Rect getRectMatching (Finder matching) {
625+ final finder = find.descendant (
626+ of: baseFinder, matching: matching)..tryEvaluate ();
627+ check (finder.found, because: '${message .content }: $matching ' )
628+ .length.equals (1 );
629+ return tester.getRect (finder.first);
630+ }
631+
632+ result.add ([
633+ ('MessageWithPossibleSender' , tester.getRect (baseFinder)),
634+ ('MessageContent' , getRectMatching (find.byType (MessageContent ))),
635+ ('Paragraph' , getRectMatching (find.byType (Paragraph ))),
636+ if (message.id == targetMessage.id) ...[
637+ ('Star' , getRectMatching (find.byIcon (ZulipIcons .star_filled))),
638+ ('ReactionChipsList' , getRectMatching (find.byType (ReactionChipsList ))),
639+ ],
640+ ]);
641+ }
642+ return result;
643+ }
644+
645+ testWidgets ('edit state updates do not affect layout' , (WidgetTester tester) async {
646+ final messages = [
647+ eg.streamMessage (),
648+ eg.streamMessage (
649+ reactions: [eg.unicodeEmojiReaction, eg.realmEmojiReaction],
650+ flags: [MessageFlag .starred]),
651+ eg.streamMessage (),
652+ ];
653+ final StreamMessage messageWithMarker = messages[1 ];
654+ await setupMessageListPage (tester, messages: messages);
655+ final rectsBefore = captureMessageRects (tester, messages, messageWithMarker);
656+ checkMarkersCount (edited: 0 , moved: 0 );
657+
658+ await store.handleEvent (eg.updateMessageMoveEvent (
659+ [messageWithMarker], origTopic: 'old' , newTopic: messageWithMarker.topic));
660+ await tester.pump ();
661+ check (captureMessageRects (tester, messages, messageWithMarker))
662+ .deepEquals (rectsBefore);
663+ checkMarkersCount (edited: 0 , moved: 1 );
664+
665+ await store.handleEvent (eg.updateMessageEditEvent (messageWithMarker));
666+ await tester.pump ();
667+ check (captureMessageRects (tester, messages, messageWithMarker))
668+ .deepEquals (rectsBefore);
669+ checkMarkersCount (edited: 1 , moved: 0 );
670+ });
671+ });
672+
579673 group ('_UnreadMarker animations' , () {
580674 // TODO: Improve animation state testing so it is less tied to
581675 // implementation details and more focused on output, see:
0 commit comments