@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
3
3
import 'package:flutter/services.dart' ;
4
4
import 'package:flutter_gen/gen_l10n/zulip_localizations.dart' ;
5
5
import 'package:flutter_test/flutter_test.dart' ;
6
+ import 'package:http/http.dart' as http;
6
7
import 'package:zulip/api/model/model.dart' ;
7
8
import 'package:zulip/api/route/messages.dart' ;
8
9
import 'package:zulip/model/compose.dart' ;
@@ -19,6 +20,7 @@ import '../example_data.dart' as eg;
19
20
import '../flutter_checks.dart' ;
20
21
import '../model/binding.dart' ;
21
22
import '../model/test_store.dart' ;
23
+ import '../stdlib_checks.dart' ;
22
24
import '../test_clipboard.dart' ;
23
25
import '../test_share_plus.dart' ;
24
26
import 'compose_box_checks.dart' ;
@@ -91,6 +93,54 @@ void main() {
91
93
(store.connection as FakeApiConnection ).prepare (httpStatus: 400 , json: fakeResponseJson);
92
94
}
93
95
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
+
94
144
group ('ShareButton' , () {
95
145
// Tests should call this.
96
146
MockSharePlus setupMockSharePlus () {
@@ -169,6 +219,7 @@ void main() {
169
219
///
170
220
/// Checks that there is a quote-and-reply button.
171
221
Future <void > tapQuoteAndReplyButton (WidgetTester tester) async {
222
+ await tester.ensureVisible (find.byIcon (Icons .format_quote_outlined, skipOffstage: false ));
172
223
final quoteAndReplyButton = findQuoteAndReplyButton (tester);
173
224
check (quoteAndReplyButton).isNotNull ();
174
225
await tester.tap (find.byWidget (quoteAndReplyButton! ));
0 commit comments