@@ -545,4 +545,78 @@ void main() {
545
545
check (mockSharePlus.sharedString).isNull ();
546
546
});
547
547
});
548
+
549
+ group ('MarkAsUnread' , () {
550
+ Future <void > tapButton (WidgetTester tester) async {
551
+ await tester.ensureVisible (find.byIcon (Icons .mark_chat_unread_outlined, skipOffstage: false ));
552
+ await tester.tap (find.byIcon (Icons .mark_chat_unread_outlined));
553
+ await tester.pump (); // [MenuItemButton.onPressed] called in a post-frame callback: flutter/flutter@e4a39fa2e
554
+ }
555
+
556
+ testWidgets ('not visible if message is not read' , (WidgetTester tester) async {
557
+ final unreadMessage = eg.streamMessage (flags: []);
558
+ await setupToMessageActionSheet (tester, message: unreadMessage, narrow: TopicNarrow .ofMessage (unreadMessage));
559
+
560
+ check (find.byIcon (Icons .mark_chat_unread_outlined).evaluate ().length).equals (0 );
561
+ });
562
+
563
+ testWidgets ('visible if message is read' , (WidgetTester tester) async {
564
+ final message = eg.streamMessage (flags: [MessageFlag .read]);
565
+ await setupToMessageActionSheet (tester, message: message, narrow: TopicNarrow .ofMessage (message));
566
+
567
+ check (find.byIcon (Icons .mark_chat_unread_outlined).evaluate ().length).equals (1 );
568
+ });
569
+
570
+ testWidgets ('success' , (WidgetTester tester) async {
571
+ final message = eg.streamMessage (flags: [MessageFlag .read]);
572
+ await setupToMessageActionSheet (tester, message: message, narrow: TopicNarrow .ofMessage (message));
573
+ final store = await testBinding.globalStore.perAccount (eg.selfAccount.id);
574
+
575
+ final connection = store.connection as FakeApiConnection ;
576
+ connection.prepare (json: UpdateMessageFlagsForNarrowResult (
577
+ processedCount: 11 ,
578
+ updatedCount: 3 ,
579
+ firstProcessedId: null ,
580
+ lastProcessedId: null ,
581
+ foundOldest: false ,
582
+ foundNewest: true ).toJson ());
583
+
584
+ await tapButton (tester);
585
+ await tester.pump (Duration .zero);
586
+
587
+ check (connection.lastRequest).isA< http.Request > ()
588
+ ..method.equals ('POST' )
589
+ ..url.path.equals ('/api/v1/messages/flags/narrow' )
590
+ ..bodyFields.deepEquals ({
591
+ 'num_before' : '0' ,
592
+ 'num_after' : '1000' ,
593
+ 'op' : 'remove' ,
594
+ 'flag' : 'read' ,
595
+ 'include_anchor' : 'true' ,
596
+ 'anchor' : '${message .id }' ,
597
+ 'narrow' : '[{"operator":"stream","operand":${message .streamId }},{"operator":"topic","operand":"${message .topic }"}]' ,
598
+ });
599
+ });
600
+
601
+ testWidgets ('request has an error' , (WidgetTester tester) async {
602
+ final message = eg.streamMessage (flags: [MessageFlag .read]);
603
+ await setupToMessageActionSheet (tester, message: message, narrow: TopicNarrow .ofMessage (message));
604
+ final store = await testBinding.globalStore.perAccount (eg.selfAccount.id);
605
+ final zulipLocalizations = GlobalLocalizations .zulipLocalizations;
606
+
607
+ final connection = store.connection as FakeApiConnection ;
608
+
609
+ connection.prepare (httpStatus: 400 , json: {
610
+ 'code' : 'BAD_REQUEST' ,
611
+ 'msg' : 'Invalid message(s)' ,
612
+ 'result' : 'error' ,
613
+ });
614
+ await tapButton (tester);
615
+ await tester.pump (Duration .zero); // error arrives; error dialog shows
616
+
617
+ await tester.tap (find.byWidget (checkErrorDialog (tester,
618
+ expectedTitle: zulipLocalizations.errorMarkAsUnreadFailedTitle,
619
+ expectedMessage: 'Invalid message(s)' )));
620
+ });
621
+ });
548
622
}
0 commit comments