1
+
2
+
1
3
import 'package:checks/checks.dart' ;
2
4
import 'package:flutter/material.dart' ;
3
5
import 'package:flutter/services.dart' ;
4
6
import 'package:flutter_gen/gen_l10n/zulip_localizations.dart' ;
5
7
import 'package:flutter_test/flutter_test.dart' ;
8
+ import 'package:http/http.dart' as http;
6
9
import 'package:zulip/api/model/model.dart' ;
7
10
import 'package:zulip/api/route/messages.dart' ;
8
11
import 'package:zulip/model/compose.dart' ;
@@ -19,6 +22,7 @@ import '../example_data.dart' as eg;
19
22
import '../flutter_checks.dart' ;
20
23
import '../model/binding.dart' ;
21
24
import '../model/test_store.dart' ;
25
+ import '../stdlib_checks.dart' ;
22
26
import '../test_clipboard.dart' ;
23
27
import '../test_share_plus.dart' ;
24
28
import 'compose_box_checks.dart' ;
@@ -90,6 +94,63 @@ void main() {
90
94
(store.connection as FakeApiConnection ).prepare (httpStatus: 400 , json: fakeResponseJson);
91
95
}
92
96
97
+ group ('AddThumbsUpButton' , () {
98
+ setUp (() async {
99
+ TestZulipBinding .ensureInitialized ();
100
+ TestWidgetsFlutterBinding .ensureInitialized ();
101
+ });
102
+
103
+ tearDown (() async {
104
+ testBinding.reset ();
105
+ });
106
+
107
+ Future <void > tapButton (WidgetTester tester) async {
108
+ await tester.ensureVisible (find.byIcon (Icons .add_reaction_outlined, skipOffstage: false ));
109
+ await tester.tap (find.byIcon (Icons .add_reaction_outlined));
110
+ await tester.pump (); // [MenuItemButton.onPressed] called in a post-frame callback: flutter/flutter@e4a39fa2e
111
+ }
112
+
113
+ testWidgets ('success' , (WidgetTester tester) async {
114
+ final message = eg.streamMessage ();
115
+ await setupToMessageActionSheet (tester, message: message, narrow: TopicNarrow .ofMessage (message));
116
+ final store = await testBinding.globalStore.perAccount (eg.selfAccount.id);
117
+
118
+ final connection = store.connection as FakeApiConnection ;
119
+ connection.prepare (json: {});
120
+ await tapButton (tester);
121
+ await tester.pump (Duration .zero);
122
+
123
+ check (connection.lastRequest).isA< http.Request > ()
124
+ ..method.equals ('POST' )
125
+ ..url.path.equals ('/api/v1/messages/${message .id }/reactions' )
126
+ ..bodyFields.deepEquals ({
127
+ 'reaction_type' : 'unicode_emoji' ,
128
+ 'emoji_code' : '1f44d' ,
129
+ 'emoji_name' : '+1' ,
130
+ });
131
+ });
132
+
133
+ testWidgets ('request has an error' , (WidgetTester tester) async {
134
+ final message = eg.streamMessage ();
135
+ await setupToMessageActionSheet (tester, message: message, narrow: TopicNarrow .ofMessage (message));
136
+ final store = await testBinding.globalStore.perAccount (eg.selfAccount.id);
137
+
138
+ final connection = store.connection as FakeApiConnection ;
139
+
140
+ connection.prepare (httpStatus: 400 , json: {
141
+ 'code' : 'BAD_REQUEST' ,
142
+ 'msg' : 'Invalid message(s)' ,
143
+ 'result' : 'error' ,
144
+ });
145
+ await tapButton (tester);
146
+ await tester.pump (Duration .zero); // error arrives; error dialog shows
147
+
148
+ await tester.tap (find.byWidget (checkErrorDialog (tester,
149
+ expectedTitle: 'Adding reaction failed' ,
150
+ expectedMessage: 'Invalid message(s)' )));
151
+ });
152
+ });
153
+
93
154
group ('ShareButton' , () {
94
155
// Tests should call setupMockSharePlus.
95
156
setUp (() async {
@@ -177,6 +238,7 @@ void main() {
177
238
///
178
239
/// Checks that there is a quote-and-reply button.
179
240
Future <void > tapQuoteAndReplyButton (WidgetTester tester) async {
241
+ await tester.ensureVisible (find.byIcon (Icons .format_quote_outlined, skipOffstage: false ));
180
242
final quoteAndReplyButton = findQuoteAndReplyButton (tester);
181
243
check (quoteAndReplyButton).isNotNull ();
182
244
await tester.tap (find.byWidget (quoteAndReplyButton! ));
0 commit comments