@@ -177,6 +177,36 @@ void main() {
177
177
178
178
debugNetworkImageHttpClientProvider = null ;
179
179
});
180
+
181
+ testWidgets ('options are shown in reversed order' , (tester) async {
182
+ final users = List .generate (8 , (i) => eg.user (fullName: 'A$i ' , avatarUrl: 'user$i .png' ));
183
+ final composeInputFinder = await setupToComposeInput (tester, users: users);
184
+ final store = await testBinding.globalStore.perAccount (eg.selfAccount.id);
185
+
186
+ // TODO(#226): Remove this extra edit when this bug is fixed.
187
+ await tester.enterText (composeInputFinder, 'hello @' );
188
+ await tester.enterText (composeInputFinder, 'hello @A' );
189
+ await tester.pump ();
190
+
191
+ final initialPosition = tester.getTopLeft (find.text (users.first.fullName)).dy;
192
+ // Initially, all but the last autocomplete options are visible.
193
+ checkUserShown (users.last, store, expected: false );
194
+ users.take (7 ).forEach ((user) => checkUserShown (user, store, expected: true ));
195
+
196
+ // Can't scroll down because the options grow from the bottom.
197
+ await tester.drag (find.byType (ListView ), const Offset (0 , - 50 ));
198
+ await tester.pump ();
199
+ check (tester.getTopLeft (find.text (users.first.fullName)).dy)
200
+ .equals (initialPosition);
201
+
202
+ // The last autocomplete option becomes visible after scrolling up.
203
+ await tester.drag (find.byType (ListView ), const Offset (0 , 200 ));
204
+ await tester.pump ();
205
+ users.skip (1 ).forEach ((user) => checkUserShown (user, store, expected: true ));
206
+ checkUserShown (users.first, store, expected: false );
207
+
208
+ debugNetworkImageHttpClientProvider = null ;
209
+ });
180
210
});
181
211
182
212
group ('emoji' , () {
@@ -247,6 +277,68 @@ void main() {
247
277
debugNetworkImageHttpClientProvider = null ;
248
278
});
249
279
280
+ testWidgets ('emoji options appear in the correct rendering order and do not scroll down' , (tester) async {
281
+ final composeInputFinder = await setupToComposeInput (tester);
282
+ final store = await testBinding.globalStore.perAccount (eg.selfAccount.id);
283
+
284
+ store.setServerEmojiData (
285
+ ServerEmojiData (
286
+ codeToNames: {
287
+ '1f4a4' : ['zzz' ],
288
+ '1f52a' : ['biohazard' ],
289
+ '1f92a' : ['zany_face' ],
290
+ '1f993' : ['zebra' ],
291
+ '0030-fe0f-20e3' : ['zero' ],
292
+ '1f9d0' : ['zombie' ],
293
+ }));
294
+
295
+ await store.handleEvent (
296
+ RealmEmojiUpdateEvent (
297
+ id: 1 ,
298
+ realmEmoji: {
299
+ '1' : eg.realmEmojiItem (emojiCode: '1' , emojiName: 'buzzing' )}));
300
+
301
+ final emojiSequence = ['zulip' ,'zzz' ,'💤' ,'zany_face' ,'zebra' ,'zero' ,'zombie' ,'buzzing' ,'biohazard' ];
302
+
303
+ // Enter a query; options appear, of all three emoji types.
304
+ // TODO(#226): Remove this extra edit when this bug is fixed.
305
+ await tester.enterText (composeInputFinder, 'hi :' );
306
+ await tester.enterText (composeInputFinder, 'hi :z' );
307
+ await tester.pump ();
308
+
309
+ final positions = emojiSequence.take (8 ).map ((icon) {
310
+ final finder = find.text (icon);
311
+ check (because: "Each emoji option should be rendered" , finder).findsOne ();
312
+ return tester.getTopLeft (finder).dy;
313
+ }).toList ();
314
+
315
+ await tester.drag (find.byType (ListView ), const Offset (0 , - 50 ));
316
+ await tester.pump ();
317
+ final firstEmojiPositionAfterScrollDown = tester.getTopLeft (find.text (emojiSequence[0 ])).dy;
318
+ check (
319
+ because: "ListView options should not scroll down further than initial position" ,
320
+ positions.first
321
+ ).equals (firstEmojiPositionAfterScrollDown);
322
+
323
+ check (
324
+ because: "The last emoji should not be visible before scrolling up"
325
+ ,find.text (emojiSequence.last)
326
+ ).findsNothing ();
327
+
328
+ // Scroll up
329
+ await tester.drag (find.byType (ListView ), const Offset (0 , 50 ));
330
+ await tester.pump ();
331
+
332
+ check (because: "The last emoji should be visible after scrolling up" ,
333
+ find.text (emojiSequence.last)).findsOne ();
334
+
335
+ final firstEmojiPositionAfterScrollUp = tester.getTopLeft (find.text (emojiSequence[0 ])).dy;
336
+ check (because: "Scrolling up should reveal other emoji matches" ,firstEmojiPositionAfterScrollUp)
337
+ .isGreaterOrEqual (positions.first);
338
+
339
+ debugNetworkImageHttpClientProvider = null ;
340
+ });
341
+
250
342
testWidgets ('text emoji means just show text' , (tester) async {
251
343
final composeInputFinder = await setupToComposeInput (tester);
252
344
final store = await testBinding.globalStore.perAccount (eg.selfAccount.id);
0 commit comments