@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
33import 'package:flutter/services.dart' ;
44import 'package:flutter_gen/gen_l10n/zulip_localizations.dart' ;
55import 'package:flutter_test/flutter_test.dart' ;
6+ import 'package:http/http.dart' as http;
67import 'package:zulip/api/model/model.dart' ;
78import 'package:zulip/api/route/messages.dart' ;
89import 'package:zulip/model/compose.dart' ;
@@ -19,6 +20,7 @@ import '../example_data.dart' as eg;
1920import '../flutter_checks.dart' ;
2021import '../model/binding.dart' ;
2122import '../model/test_store.dart' ;
23+ import '../stdlib_checks.dart' ;
2224import '../test_clipboard.dart' ;
2325import '../test_share_plus.dart' ;
2426import 'compose_box_checks.dart' ;
@@ -91,6 +93,54 @@ void main() {
9193 (store.connection as FakeApiConnection ).prepare (httpStatus: 400 , json: fakeResponseJson);
9294 }
9395
96+ group ('AddThumbsUpButton' , () {
97+ Future <void > tapButton (WidgetTester tester) async {
98+ await tester.ensureVisible (find.byIcon (Icons .add_reaction_outlined, skipOffstage: false ));
99+ await tester.tap (find.byIcon (Icons .add_reaction_outlined));
100+ await tester.pump (); // [MenuItemButton.onPressed] called in a post-frame callback: flutter/flutter@e4a39fa2e
101+ }
102+
103+ testWidgets ('success' , (WidgetTester tester) async {
104+ final message = eg.streamMessage ();
105+ await setupToMessageActionSheet (tester, message: message, narrow: TopicNarrow .ofMessage (message));
106+ final store = await testBinding.globalStore.perAccount (eg.selfAccount.id);
107+
108+ final connection = store.connection as FakeApiConnection ;
109+ connection.prepare (json: {});
110+ await tapButton (tester);
111+ await tester.pump (Duration .zero);
112+
113+ check (connection.lastRequest).isA< http.Request > ()
114+ ..method.equals ('POST' )
115+ ..url.path.equals ('/api/v1/messages/${message .id }/reactions' )
116+ ..bodyFields.deepEquals ({
117+ 'reaction_type' : 'unicode_emoji' ,
118+ 'emoji_code' : '1f44d' ,
119+ 'emoji_name' : '+1' ,
120+ });
121+ });
122+
123+ testWidgets ('request has an error' , (WidgetTester tester) async {
124+ final message = eg.streamMessage ();
125+ await setupToMessageActionSheet (tester, message: message, narrow: TopicNarrow .ofMessage (message));
126+ final store = await testBinding.globalStore.perAccount (eg.selfAccount.id);
127+
128+ final connection = store.connection as FakeApiConnection ;
129+
130+ connection.prepare (httpStatus: 400 , json: {
131+ 'code' : 'BAD_REQUEST' ,
132+ 'msg' : 'Invalid message(s)' ,
133+ 'result' : 'error' ,
134+ });
135+ await tapButton (tester);
136+ await tester.pump (Duration .zero); // error arrives; error dialog shows
137+
138+ await tester.tap (find.byWidget (checkErrorDialog (tester,
139+ expectedTitle: 'Adding reaction failed' ,
140+ expectedMessage: 'Invalid message(s)' )));
141+ });
142+ });
143+
94144 group ('ShareButton' , () {
95145 // Tests should call this.
96146 MockSharePlus setupMockSharePlus () {
@@ -169,6 +219,7 @@ void main() {
169219 ///
170220 /// Checks that there is a quote-and-reply button.
171221 Future <void > tapQuoteAndReplyButton (WidgetTester tester) async {
222+ await tester.ensureVisible (find.byIcon (Icons .format_quote_outlined, skipOffstage: false ));
172223 final quoteAndReplyButton = findQuoteAndReplyButton (tester);
173224 check (quoteAndReplyButton).isNotNull ();
174225 await tester.tap (find.byWidget (quoteAndReplyButton! ));
0 commit comments