@@ -16,6 +16,7 @@ import 'package:zulip/model/localizations.dart';
16
16
import 'package:zulip/model/narrow.dart' ;
17
17
import 'package:zulip/model/store.dart' ;
18
18
import 'package:zulip/widgets/content.dart' ;
19
+ import 'package:zulip/widgets/emoji_reaction.dart' ;
19
20
import 'package:zulip/widgets/icons.dart' ;
20
21
import 'package:zulip/widgets/message_list.dart' ;
21
22
import 'package:zulip/widgets/store.dart' ;
@@ -576,6 +577,107 @@ void main() {
576
577
});
577
578
});
578
579
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 <Map <String , List <Rect >>> captureMessageRects (
613
+ WidgetTester tester,
614
+ List <Message > messages,
615
+ Message targetMessage,
616
+ ) {
617
+ assert (messages.contains (targetMessage));
618
+ final List <Map <String , List <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
+ List <Rect > getRectsMatching (Finder matching) {
625
+ final finder = find.descendant (
626
+ of: baseFinder, matching: matching)..tryEvaluate ();
627
+ check (finder.found, because: '${message .content }: $matching ' )
628
+ .isNotEmpty ();
629
+ return List .generate (
630
+ finder.found.length,
631
+ (i) => tester.getRect (finder.at (i)));
632
+ }
633
+
634
+ result.add ({
635
+ 'MessageWithPossibleSender' : [tester.getRect (baseFinder)],
636
+ 'MessageContent' : getRectsMatching (find.byType (MessageContent )),
637
+ 'Paragraph' : getRectsMatching (find.byType (Paragraph )),
638
+ if (message.id == targetMessage.id) ...{
639
+ 'Image' : getRectsMatching (find.byType (MessageImage )),
640
+ 'Star' : getRectsMatching (find.byIcon (ZulipIcons .star_filled)),
641
+ 'ReactionChip' : getRectsMatching (find.byType (ReactionChip )),
642
+ 'ReactionChipsList' : getRectsMatching (find.byType (ReactionChipsList )),
643
+ },
644
+ });
645
+ }
646
+ return result;
647
+ }
648
+
649
+ testWidgets ('edit state updates do not affect layout' , (WidgetTester tester) async {
650
+ prepareBoringImageHttpClient ();
651
+ final messages = [
652
+ eg.streamMessage (),
653
+ eg.streamMessage (
654
+ content: ContentExample .imageClusterThenContent.html,
655
+ reactions: [eg.unicodeEmojiReaction, eg.realmEmojiReaction],
656
+ flags: [MessageFlag .starred]),
657
+ eg.streamMessage (),
658
+ ];
659
+ final StreamMessage messageWithMarker = messages[1 ];
660
+ await setupMessageListPage (tester, messages: messages);
661
+ final rectsBefore = captureMessageRects (tester, messages, messageWithMarker);
662
+ checkMarkersCount (edited: 0 , moved: 0 );
663
+
664
+ await store.handleEvent (eg.updateMessageMoveEvent (
665
+ [messageWithMarker], origTopic: 'old' , newTopic: messageWithMarker.topic));
666
+ await tester.pump ();
667
+ check (captureMessageRects (tester, messages, messageWithMarker))
668
+ .deepEquals (rectsBefore);
669
+ checkMarkersCount (edited: 0 , moved: 1 );
670
+
671
+ await store.handleEvent (eg.updateMessageEditEvent (messageWithMarker));
672
+ await tester.pump ();
673
+ check (captureMessageRects (tester, messages, messageWithMarker))
674
+ .deepEquals (rectsBefore);
675
+ checkMarkersCount (edited: 1 , moved: 0 );
676
+
677
+ debugNetworkImageHttpClientProvider = null ;
678
+ });
679
+ });
680
+
579
681
group ('_UnreadMarker animations' , () {
580
682
// TODO: Improve animation state testing so it is less tied to
581
683
// implementation details and more focused on output, see:
0 commit comments