@@ -11,13 +11,16 @@ import 'package:zulip/api/route/channels.dart';
11
11
import 'package:zulip/api/route/messages.dart' ;
12
12
import 'package:zulip/model/binding.dart' ;
13
13
import 'package:zulip/model/compose.dart' ;
14
+ import 'package:zulip/model/emoji.dart' ;
14
15
import 'package:zulip/model/internal_link.dart' ;
15
16
import 'package:zulip/model/localizations.dart' ;
16
17
import 'package:zulip/model/narrow.dart' ;
17
18
import 'package:zulip/model/store.dart' ;
18
19
import 'package:zulip/model/typing_status.dart' ;
20
+ import 'package:zulip/widgets/action_sheet.dart' ;
19
21
import 'package:zulip/widgets/compose_box.dart' ;
20
22
import 'package:zulip/widgets/content.dart' ;
23
+ import 'package:zulip/widgets/emoji.dart' ;
21
24
import 'package:zulip/widgets/icons.dart' ;
22
25
import 'package:zulip/widgets/message_list.dart' ;
23
26
import 'package:share_plus_platform_interface/method_channel/method_channel_share.dart' ;
@@ -26,6 +29,7 @@ import '../api/fake_api.dart';
26
29
import '../example_data.dart' as eg;
27
30
import '../flutter_checks.dart' ;
28
31
import '../model/binding.dart' ;
32
+ import '../model/emoji_test.dart' ;
29
33
import '../model/test_store.dart' ;
30
34
import '../stdlib_checks.dart' ;
31
35
import '../test_clipboard.dart' ;
@@ -99,46 +103,107 @@ void main() {
99
103
connection.prepare (httpStatus: 400 , json: fakeResponseJson);
100
104
}
101
105
102
- group ('AddThumbsUpButton' , () {
103
- Future <void > tapButton (WidgetTester tester) async {
104
- await tester.ensureVisible (find.byIcon (ZulipIcons .smile, skipOffstage: false ));
105
- await tester.tap (find.byIcon (ZulipIcons .smile));
106
- await tester.pump (); // [MenuItemButton.onPressed] called in a post-frame callback: flutter/flutter@e4a39fa2e
107
- }
108
106
109
- testWidgets ('success' , (tester) async {
110
- final message = eg.streamMessage ();
111
- await setupToMessageActionSheet (tester, message: message, narrow: TopicNarrow .ofMessage (message));
107
+ group ('ReactionButtons' , () {
108
+ group ('popular emoji reactions;' , () {
109
+ testWidgets ('ensure all are shown' , (tester) async {
110
+ final message = eg.streamMessage ();
111
+ await setupToMessageActionSheet (tester, message: message, narrow: TopicNarrow .ofMessage (message));
112
112
113
- connection.prepare (json: {});
114
- await tapButton (tester);
115
- await tester.pump (Duration .zero);
113
+ check (popularUnicodeEmojis).length.equals (6 );
114
+
115
+ // Ensure there are only 6 buttons.
116
+ final buttons = tester.widgetList <IconButton >(find.descendant (
117
+ of: find.byType (ReactionButtons ) ,
118
+ matching: find.byType (IconButton )));
119
+ check (buttons).length.equals (6 );
120
+
121
+ // Ensure all are unicode emoji buttons.
122
+ final emojis = tester.widgetList <UnicodeEmojiWidget >(find.descendant (
123
+ of: find.ancestor (
124
+ of: find.byType (IconButton ),
125
+ matching: find.byType (ReactionButtons )),
126
+ matching: find.byType (UnicodeEmojiWidget )));
127
+ check (emojis).length.equals (6 );
128
+ check (emojis).deepEquals (popularUnicodeEmojis.map <Condition <Object ?>>((emoji) {
129
+ return (it) => it.isA <UnicodeEmojiWidget >()
130
+ ..emojiDisplay.which ((it) => it
131
+ ..emojiName.equals (emoji.emojiName)
132
+ ..emojiUnicode.equals (emoji.emojiUnicode)
133
+ ..emojiCode.equals (emoji.emojiCode));
134
+ }));
135
+ });
116
136
117
- check (connection.lastRequest).isA< http.Request > ()
118
- ..method.equals ('POST' )
119
- ..url.path.equals ('/api/v1/messages/${message .id }/reactions' )
120
- ..bodyFields.deepEquals ({
121
- 'reaction_type' : 'unicode_emoji' ,
122
- 'emoji_code' : '1f44d' ,
123
- 'emoji_name' : '+1' ,
124
- });
125
- });
137
+ for (final popularEmoji in popularUnicodeEmojis) {
138
+ Future <void > tapButton (WidgetTester tester, {required bool isSelected}) async {
139
+ final finder = find.ancestor (
140
+ of: find.text (popularEmoji.emojiUnicode),
141
+ matching: find.byType (IconButton ));
142
+
143
+ check (tester.widget <IconButton >(finder))
144
+ .isSelected.equals (isSelected);
145
+ await tester.tap (finder);
146
+ }
147
+
148
+ testWidgets ('${popularEmoji .emojiName } adding success' , (tester) async {
149
+ final message = eg.streamMessage ();
150
+ await setupToMessageActionSheet (tester, message: message, narrow: TopicNarrow .ofMessage (message));
151
+
152
+ connection.prepare (json: {});
153
+ await tapButton (tester, isSelected: false );
154
+ await tester.pump (Duration .zero);
155
+
156
+ check (connection.lastRequest).isA< http.Request > ()
157
+ ..method.equals ('POST' )
158
+ ..url.path.equals ('/api/v1/messages/${message .id }/reactions' )
159
+ ..bodyFields.deepEquals ({
160
+ 'reaction_type' : 'unicode_emoji' ,
161
+ 'emoji_code' : popularEmoji.emojiCode,
162
+ 'emoji_name' : popularEmoji.emojiName,
163
+ });
164
+ });
126
165
127
- testWidgets ('request has an error' , (tester) async {
128
- final message = eg.streamMessage ();
129
- await setupToMessageActionSheet (tester, message: message, narrow: TopicNarrow .ofMessage (message));
166
+ testWidgets ('${popularEmoji .emojiName } removing success' , (tester) async {
167
+ final message = eg.streamMessage (
168
+ reactions: [Reaction (
169
+ emojiName: popularEmoji.emojiName,
170
+ emojiCode: popularEmoji.emojiCode,
171
+ reactionType: ReactionType .unicodeEmoji,
172
+ userId: eg.selfAccount.userId)]
173
+ );
174
+ await setupToMessageActionSheet (tester, message: message, narrow: TopicNarrow .ofMessage (message));
175
+
176
+ connection.prepare (json: {});
177
+ await tapButton (tester, isSelected: true );
178
+ await tester.pump (Duration .zero);
179
+
180
+ check (connection.lastRequest).isA< http.Request > ()
181
+ ..method.equals ('DELETE' )
182
+ ..url.path.equals ('/api/v1/messages/${message .id }/reactions' )
183
+ ..bodyFields.deepEquals ({
184
+ 'reaction_type' : 'unicode_emoji' ,
185
+ 'emoji_code' : popularEmoji.emojiCode,
186
+ 'emoji_name' : popularEmoji.emojiName,
187
+ });
188
+ });
130
189
131
- connection.prepare (httpStatus: 400 , json: {
132
- 'code' : 'BAD_REQUEST' ,
133
- 'msg' : 'Invalid message(s)' ,
134
- 'result' : 'error' ,
135
- });
136
- await tapButton (tester);
137
- await tester.pump (Duration .zero); // error arrives; error dialog shows
190
+ testWidgets ('${popularEmoji .emojiName } request has an error' , (tester) async {
191
+ final message = eg.streamMessage ();
192
+ await setupToMessageActionSheet (tester, message: message, narrow: TopicNarrow .ofMessage (message));
138
193
139
- await tester.tap (find.byWidget (checkErrorDialog (tester,
140
- expectedTitle: 'Adding reaction failed' ,
141
- expectedMessage: 'Invalid message(s)' )));
194
+ connection.prepare (httpStatus: 400 , json: {
195
+ 'code' : 'BAD_REQUEST' ,
196
+ 'msg' : 'Invalid message(s)' ,
197
+ 'result' : 'error' ,
198
+ });
199
+ await tapButton (tester, isSelected: false );
200
+ await tester.pump (Duration .zero); // error arrives; error dialog shows
201
+
202
+ await tester.tap (find.byWidget (checkErrorDialog (tester,
203
+ expectedTitle: 'Adding reaction failed' ,
204
+ expectedMessage: 'Invalid message(s)' )));
205
+ });
206
+ }
142
207
});
143
208
});
144
209
@@ -700,3 +765,7 @@ void main() {
700
765
});
701
766
});
702
767
}
768
+
769
+ extension UnicodeEmojiWidgetChecks on Subject <UnicodeEmojiWidget > {
770
+ Subject <UnicodeEmojiDisplay > get emojiDisplay => has ((x) => x.emojiDisplay, 'emojiDisplay' );
771
+ }
0 commit comments