diff --git a/lib/widgets/autocomplete.dart b/lib/widgets/autocomplete.dart index a1e5289b01..39dc67b8d3 100644 --- a/lib/widgets/autocomplete.dart +++ b/lib/widgets/autocomplete.dart @@ -134,6 +134,7 @@ class _AutocompleteFieldState positions[i + 1], isTrue, + reason: '${expectedUserSequence[i + 1]} should appear above ${expectedUserSequence[i]} because of reverse order'); + } + + await tester.drag(listViewFinder, const Offset(0, 200)); //should be capped at prev position + await tester.pumpAndSettle(); + + checkUserShown(user8, store, expected: true); + checkUserShown(user1, store, expected: false); + + //8th user should be above 7th user + expect(tester.getTopLeft(find.text(user8.fullName)).dy < tester.getTopLeft(find.text(user7.fullName)).dy, + isTrue, reason:"8th user should be above 7th user"); + + debugNetworkImageHttpClientProvider = null; + }); }); group('emoji', () { @@ -247,6 +318,101 @@ void main() { debugNetworkImageHttpClientProvider = null; }); + testWidgets('emoji options appear in the correct rendering order and do not scroll down', (tester) async { + final composeInputFinder = await setupToComposeInput(tester); + final store = await testBinding.globalStore.perAccount(eg.selfAccount.id); + + store.setServerEmojiData( + ServerEmojiData( + codeToNames: { + '1f4a4': ['zzz', 'sleepy'], // Unicode emoji for "zzz" + '1f52a': ['biohazard'], + '1f92a': ['zany_face'], + '1f993': ['zebra'], + '0030-fe0f-20e3': ['zero'], + '1f9d0': ['zombie'], + }, + ), + ); + await store.handleEvent( + RealmEmojiUpdateEvent( + id: 1, + realmEmoji: { + '1': eg.realmEmojiItem(emojiCode: '1', emojiName: 'buzzing'), + }, + ), + ); + + const zulipOptionLabel = 'zulip'; + const zanyFaceOptionLabel = 'zany_face'; + const zebraOptionLabel = 'zebra'; + const zzzOptionLabel = 'zzz, sleepy'; + const unicodeGlyph = '💤'; + const zombieOptionLabel = 'zombie'; + const zeroOptionLabel = 'zero'; + const buzzingOptionLabel = 'buzzing'; + const biohazardOptionLabel = 'biohazard'; + + // Adjust the order so the best match appears last + final emojiSequence = [ + zulipOptionLabel, + zzzOptionLabel, + unicodeGlyph, + zanyFaceOptionLabel, + zebraOptionLabel, + zeroOptionLabel, + zombieOptionLabel, + buzzingOptionLabel, + // biohazardOptionLabel, this won't be rendered in the list initally since it is the 7th option. + ]; + + await tester.enterText(composeInputFinder, 'hi :'); + await tester.enterText(composeInputFinder, 'hi :z'); + await tester.pumpAndSettle(); + + final listViewFinder = find.byType(ListView); + expect(listViewFinder, findsOneWidget, reason: 'ListView should be rendered'); + + final positions = emojiSequence.map((icon) { + final finder = find.text(icon); + expect(finder, findsOneWidget, reason: 'Each emoji option should be rendered'); + return tester.getTopLeft(finder).dy; + }).toList(); + + for (int i = 0; i < positions.length - 1; i++) { + expect(positions[i] > positions[i + 1], isTrue, + reason: '${emojiSequence[i + 1]} should appear above ${emojiSequence[i]} because of reverse order'); + } + + final initialScrollOffset = tester.getTopLeft(listViewFinder).dy; + await tester.drag(listViewFinder, const Offset(0, -50)); + await tester.pumpAndSettle(); + final scrollOffsetAfterDragDown = tester.getTopLeft(listViewFinder).dy; + + expect(scrollOffsetAfterDragDown, initialScrollOffset, + reason: 'ListView should not scroll down because it is already at the bottom'); + + final biohazardFinder = find.text(biohazardOptionLabel); + expect(biohazardFinder, findsNothing, reason: 'The biohazard emoji should not be visible before scrolling up'); + + // Scroll up + await tester.drag(listViewFinder, const Offset(0, 50)); + await tester.pumpAndSettle(); + + expect(biohazardFinder, findsOneWidget, reason: 'The biohazard emoji should be visible after scrolling up'); + + final firstEmojiPositionAfterScrollUp = tester.getTopLeft(find.text(emojiSequence[0])).dy; + // print(firstEmojiPositionAfterScrollUp); + // print(positions[0]); + expect(firstEmojiPositionAfterScrollUp >= positions[0], isTrue, + reason: 'Scrolling up should reveal other emoji matches'); + + expect(tester.getTopLeft(find.text(biohazardOptionLabel)).runtimeType,const Offset(1,2).runtimeType, reason:"7th best result should only be visible on scrolling up"); + + debugNetworkImageHttpClientProvider = null; + + }); + testWidgets('text emoji means just show text', (tester) async { final composeInputFinder = await setupToComposeInput(tester); final store = await testBinding.globalStore.perAccount(eg.selfAccount.id);