@@ -3,9 +3,11 @@ import 'package:flutter/material.dart';
3
3
import 'package:flutter_checks/flutter_checks.dart' ;
4
4
import 'package:flutter_test/flutter_test.dart' ;
5
5
import 'package:zulip/api/model/model.dart' ;
6
+ import 'package:zulip/basic.dart' ;
6
7
import 'package:zulip/widgets/app_bar.dart' ;
7
8
import 'package:zulip/widgets/compose_box.dart' ;
8
9
import 'package:zulip/widgets/content.dart' ;
10
+ import 'package:zulip/widgets/emoji.dart' ;
9
11
import 'package:zulip/widgets/home.dart' ;
10
12
import 'package:zulip/widgets/icons.dart' ;
11
13
import 'package:zulip/widgets/new_dm_sheet.dart' ;
@@ -17,11 +19,13 @@ import '../flutter_checks.dart';
17
19
import '../model/binding.dart' ;
18
20
import '../model/test_store.dart' ;
19
21
import '../test_navigation.dart' ;
22
+ import 'message_list_test.dart' ;
20
23
import 'test_app.dart' ;
21
24
22
25
Future <void > setupSheet (WidgetTester tester, {
23
26
required List <User > users,
24
27
List <int >? mutedUserIds,
28
+ List <(int userId, UserStatusChange change)>? userStatuses,
25
29
}) async {
26
30
addTearDown (testBinding.reset);
27
31
@@ -35,6 +39,7 @@ Future<void> setupSheet(WidgetTester tester, {
35
39
if (mutedUserIds != null ) {
36
40
await store.setMutedUsers (mutedUserIds);
37
41
}
42
+ await store.changeUserStatuses (userStatuses ?? []);
38
43
39
44
await tester.pumpWidget (TestZulipApp (
40
45
navigatorObservers: [testNavObserver],
@@ -65,7 +70,8 @@ void main() {
65
70
}
66
71
67
72
Finder findUserTile (User user) =>
68
- find.widgetWithText (InkWell , user.fullName).first;
73
+ find.ancestor (of: find.textContaining (user.fullName),
74
+ matching: find.byType (InkWell )).first;
69
75
70
76
Finder findUserChip (User user) {
71
77
final findAvatar = find.byWidgetPredicate ((widget) =>
@@ -120,23 +126,23 @@ void main() {
120
126
121
127
testWidgets ('shows all non-muted users initially' , (tester) async {
122
128
await setupSheet (tester, users: testUsers, mutedUserIds: [mutedUser.userId]);
123
- check (find.text ('Alice Anderson' )).findsOne ();
124
- check (find.text ('Bob Brown' )).findsOne ();
125
- check (find.text ('Charlie Carter' )).findsOne ();
129
+ check (find.textContaining ('Alice Anderson' )).findsOne ();
130
+ check (find.textContaining ('Bob Brown' )).findsOne ();
131
+ check (find.textContaining ('Charlie Carter' )).findsOne ();
126
132
127
133
check (find.byIcon (ZulipIcons .check_circle_unchecked)).findsExactly (3 );
128
134
check (find.byIcon (ZulipIcons .check_circle_checked)).findsNothing ();
129
- check (find.text ('Someone Muted' )).findsNothing ();
130
- check (find.text ('Muted user' )).findsNothing ();
135
+ check (find.textContaining ('Someone Muted' )).findsNothing ();
136
+ check (find.textContaining ('Muted user' )).findsNothing ();
131
137
});
132
138
133
139
testWidgets ('shows filtered users based on search' , (tester) async {
134
140
await setupSheet (tester, users: testUsers);
135
141
await tester.enterText (find.byType (TextField ), 'Alice' );
136
142
await tester.pump ();
137
- check (find.text ('Alice Anderson' )).findsOne ();
138
- check (find.text ('Charlie Carter' )).findsNothing ();
139
- check (find.text ('Bob Brown' )).findsNothing ();
143
+ check (find.textContaining ('Alice Anderson' )).findsOne ();
144
+ check (find.textContaining ('Charlie Carter' )).findsNothing ();
145
+ check (find.textContaining ('Bob Brown' )).findsNothing ();
140
146
});
141
147
142
148
// TODO test sorting by recent-DMs
@@ -146,43 +152,43 @@ void main() {
146
152
await setupSheet (tester, users: testUsers);
147
153
await tester.enterText (find.byType (TextField ), 'alice' );
148
154
await tester.pump ();
149
- check (find.text ('Alice Anderson' )).findsOne ();
155
+ check (find.textContaining ('Alice Anderson' )).findsOne ();
150
156
151
157
await tester.enterText (find.byType (TextField ), 'ALICE' );
152
158
await tester.pump ();
153
- check (find.text ('Alice Anderson' )).findsOne ();
159
+ check (find.textContaining ('Alice Anderson' )).findsOne ();
154
160
});
155
161
156
162
testWidgets ('partial name and last name search handling' , (tester) async {
157
163
await setupSheet (tester, users: testUsers);
158
164
159
165
await tester.enterText (find.byType (TextField ), 'Ali' );
160
166
await tester.pump ();
161
- check (find.text ('Alice Anderson' )).findsOne ();
162
- check (find.text ('Bob Brown' )).findsNothing ();
163
- check (find.text ('Charlie Carter' )).findsNothing ();
167
+ check (find.textContaining ('Alice Anderson' )).findsOne ();
168
+ check (find.textContaining ('Bob Brown' )).findsNothing ();
169
+ check (find.textContaining ('Charlie Carter' )).findsNothing ();
164
170
165
171
await tester.enterText (find.byType (TextField ), 'Anderson' );
166
172
await tester.pump ();
167
- check (find.text ('Alice Anderson' )).findsOne ();
168
- check (find.text ('Charlie Carter' )).findsNothing ();
169
- check (find.text ('Bob Brown' )).findsNothing ();
173
+ check (find.textContaining ('Alice Anderson' )).findsOne ();
174
+ check (find.textContaining ('Charlie Carter' )).findsNothing ();
175
+ check (find.textContaining ('Bob Brown' )).findsNothing ();
170
176
171
177
await tester.enterText (find.byType (TextField ), 'son' );
172
178
await tester.pump ();
173
- check (find.text ('Alice Anderson' )).findsOne ();
174
- check (find.text ('Charlie Carter' )).findsNothing ();
175
- check (find.text ('Bob Brown' )).findsNothing ();
179
+ check (find.textContaining ('Alice Anderson' )).findsOne ();
180
+ check (find.textContaining ('Charlie Carter' )).findsNothing ();
181
+ check (find.textContaining ('Bob Brown' )).findsNothing ();
176
182
});
177
183
178
184
testWidgets ('shows empty state when no users match' , (tester) async {
179
185
await setupSheet (tester, users: testUsers);
180
186
await tester.enterText (find.byType (TextField ), 'Zebra' );
181
187
await tester.pump ();
182
- check (find.text ('No users found' )).findsOne ();
183
- check (find.text ('Alice Anderson' )).findsNothing ();
184
- check (find.text ('Bob Brown' )).findsNothing ();
185
- check (find.text ('Charlie Carter' )).findsNothing ();
188
+ check (find.textContaining ('No users found' )).findsOne ();
189
+ check (find.textContaining ('Alice Anderson' )).findsNothing ();
190
+ check (find.textContaining ('Bob Brown' )).findsNothing ();
191
+ check (find.textContaining ('Charlie Carter' )).findsNothing ();
186
192
});
187
193
188
194
testWidgets ('search text clears when user is selected' , (tester) async {
@@ -252,7 +258,7 @@ void main() {
252
258
await tester.tap (findUserTile (eg.selfUser));
253
259
await tester.pump ();
254
260
checkUserSelected (tester, eg.selfUser, true );
255
- check (find.text (eg.selfUser.fullName)).findsExactly (2 );
261
+ check (find.textContaining (eg.selfUser.fullName)).findsExactly (2 );
256
262
257
263
await tester.tap (findUserTile (otherUser));
258
264
await tester.pump ();
@@ -264,7 +270,7 @@ void main() {
264
270
final otherUser = eg.user (fullName: 'Other User' );
265
271
await setupSheet (tester, users: [eg.selfUser, otherUser]);
266
272
267
- check (find.text (eg.selfUser.fullName)).findsOne ();
273
+ check (find.textContaining (eg.selfUser.fullName)).findsOne ();
268
274
269
275
await tester.tap (findUserTile (otherUser));
270
276
await tester.pump ();
@@ -285,6 +291,56 @@ void main() {
285
291
});
286
292
});
287
293
294
+ testWidgets ('status emoji is set -> emoji is displayed' , (tester) async {
295
+ void checkTileStatusEmoji (User user, {required bool isPresent}) {
296
+ final statusEmojiFinder = findStatusEmoji (UnicodeEmojiWidget );
297
+ final tileStatusFinder = find.descendant (of: findUserTile (user),
298
+ matching: statusEmojiFinder);
299
+ if (isPresent) {
300
+ checkUserStatusEmoji (tileStatusFinder, isAnimated: false );
301
+ }
302
+ check (tileStatusFinder).findsExactly (isPresent ? 1 : 0 );
303
+ }
304
+
305
+ void checkChipStatusEmoji (User user, {required bool isPresent}) {
306
+ final statusEmojiFinder = findStatusEmoji (UnicodeEmojiWidget );
307
+ final chipStatusFinder = find.descendant (of: findUserChip (user),
308
+ matching: statusEmojiFinder);
309
+ if (isPresent) {
310
+ checkUserStatusEmoji (chipStatusFinder, isAnimated: false );
311
+ }
312
+ check (chipStatusFinder).findsExactly (isPresent ? 1 : 0 );
313
+ }
314
+
315
+ final user1 = eg.user (userId: 1 , fullName: 'User 1' );
316
+ final user2 = eg.user (userId: 2 , fullName: 'User 2' );
317
+ await setupSheet (tester, users: [user1, user2], userStatuses: [
318
+ (
319
+ user1.userId,
320
+ UserStatusChange (
321
+ text: OptionSome ('Busy' ),
322
+ emoji: OptionSome (StatusEmoji (emojiName: 'working_on_it' ,
323
+ emojiCode: '1f6e0' , reactionType: ReactionType .unicodeEmoji)))
324
+ ),
325
+ ]);
326
+
327
+ checkTileStatusEmoji (user1, isPresent: true );
328
+ checkTileStatusEmoji (user2, isPresent: false );
329
+ check (findUserChip (user1)).findsNothing ();
330
+ check (findUserChip (user2)).findsNothing ();
331
+
332
+ await tester.tap (findUserTile (user1));
333
+ await tester.tap (findUserTile (user2));
334
+ await tester.pump ();
335
+
336
+ checkTileStatusEmoji (user1, isPresent: true );
337
+ checkTileStatusEmoji (user2, isPresent: false );
338
+ check (findUserChip (user1)).findsOne ();
339
+ check (findUserChip (user2)).findsOne ();
340
+ checkChipStatusEmoji (user1, isPresent: true );
341
+ checkChipStatusEmoji (user2, isPresent: false );
342
+ });
343
+
288
344
group ('navigation to DM Narrow' , () {
289
345
Future <void > runAndCheck (WidgetTester tester, {
290
346
required List <User > users,
0 commit comments