@@ -5,9 +5,11 @@ import 'package:checks/checks.dart';
5
5
import 'package:fake_async/fake_async.dart' ;
6
6
import 'package:flutter/cupertino.dart' ;
7
7
import 'package:test/scaffolding.dart' ;
8
+ import 'package:zulip/api/model/initial_snapshot.dart' ;
8
9
import 'package:zulip/api/model/model.dart' ;
9
10
import 'package:zulip/model/autocomplete.dart' ;
10
11
import 'package:zulip/model/narrow.dart' ;
12
+ import 'package:zulip/model/store.dart' ;
11
13
import 'package:zulip/widgets/compose_box.dart' ;
12
14
13
15
import '../example_data.dart' as eg;
@@ -318,4 +320,131 @@ void main() {
318
320
doCheck ('Four F' , eg.user (fullName: 'Full Name Four Words' ), false );
319
321
});
320
322
});
323
+
324
+ group ('MentionAutocompleteView sorting users results' , () {
325
+ late PerAccountStore store;
326
+
327
+ Future <void > prepare ({
328
+ List <User > users = const [],
329
+ List <RecentDmConversation > dmConversations = const [],
330
+ }) async {
331
+ store = eg.store (initialSnapshot: eg.initialSnapshot (
332
+ recentPrivateConversations: dmConversations));
333
+ await store.addUsers (users);
334
+ }
335
+
336
+ group ('MentionAutocompleteView.compareByDms' , () {
337
+ test ('has DMs with userA and userB, latest with userA, prioritizes userA' , () async {
338
+ await prepare (dmConversations: [
339
+ RecentDmConversation (userIds: [1 ], maxMessageId: 200 ),
340
+ RecentDmConversation (userIds: [1 , 2 ], maxMessageId: 100 ),
341
+ ]);
342
+
343
+ final userA = eg.user (userId: 1 );
344
+ final userB = eg.user (userId: 2 );
345
+ final compareAB = MentionAutocompleteView .compareByDms (userA, userB, store: store);
346
+ check (compareAB).isNegative ();
347
+ });
348
+
349
+ test ('has DMs with userA and userB, latest with userB, prioritizes userB' , () async {
350
+ await prepare (dmConversations: [
351
+ RecentDmConversation (userIds: [2 ], maxMessageId: 200 ),
352
+ RecentDmConversation (userIds: [1 , 2 ], maxMessageId: 100 ),
353
+ ]);
354
+
355
+ final userA = eg.user (userId: 1 );
356
+ final userB = eg.user (userId: 2 );
357
+ final compareAB = MentionAutocompleteView .compareByDms (userA, userB, store: store);
358
+ check (compareAB).isGreaterThan (0 );
359
+ });
360
+
361
+ test ('has DMs with userA and userB, equally recent, prioritizes neither' , () async {
362
+ await prepare (dmConversations: [
363
+ RecentDmConversation (userIds: [1 , 2 ], maxMessageId: 100 ),
364
+ ]);
365
+
366
+ final userA = eg.user (userId: 1 );
367
+ final userB = eg.user (userId: 2 );
368
+ final compareAB = MentionAutocompleteView .compareByDms (userA, userB, store: store);
369
+ check (compareAB).equals (0 );
370
+ });
371
+
372
+ test ('has DMs with userA but not userB, prioritizes userA' , () async {
373
+ await prepare (dmConversations: [
374
+ RecentDmConversation (userIds: [1 ], maxMessageId: 100 ),
375
+ ]);
376
+
377
+ final userA = eg.user (userId: 1 );
378
+ final userB = eg.user (userId: 2 );
379
+ final compareAB = MentionAutocompleteView .compareByDms (userA, userB, store: store);
380
+ check (compareAB).isNegative ();
381
+ });
382
+
383
+ test ('has DMs with userB but not userA, prioritizes userB' , () async {
384
+ await prepare (dmConversations: [
385
+ RecentDmConversation (userIds: [2 ], maxMessageId: 100 ),
386
+ ]);
387
+
388
+ final userA = eg.user (userId: 1 );
389
+ final userB = eg.user (userId: 2 );
390
+ final compareAB = MentionAutocompleteView .compareByDms (userA, userB, store: store);
391
+ check (compareAB).isGreaterThan (0 );
392
+ });
393
+
394
+ test ('doesn\' t have DMs with userA or userB, prioritizes neither' , () async {
395
+ await prepare (dmConversations: []);
396
+
397
+ final userA = eg.user (userId: 1 );
398
+ final userB = eg.user (userId: 2 );
399
+ final compareAB = MentionAutocompleteView .compareByDms (userA, userB, store: store);
400
+ check (compareAB).equals (0 );
401
+ });
402
+ });
403
+
404
+ test ('autocomplete suggests relevant users in the following order: '
405
+ '1. Users most recent in the DM conversations' , () async {
406
+ final users = [
407
+ eg.user (userId: 0 ),
408
+ eg.user (userId: 1 ),
409
+ eg.user (userId: 2 ),
410
+ eg.user (userId: 3 ),
411
+ eg.user (userId: 4 ),
412
+ ];
413
+
414
+ final dmConversations = [
415
+ RecentDmConversation (userIds: [3 ], maxMessageId: 300 ),
416
+ RecentDmConversation (userIds: [0 ], maxMessageId: 200 ),
417
+ RecentDmConversation (userIds: [0 , 1 ], maxMessageId: 100 ),
418
+ ];
419
+
420
+ Future <void > checkResultsIn (Narrow narrow, {required List <int > expected}) async {
421
+ await prepare (users: users, dmConversations: dmConversations);
422
+ final view = MentionAutocompleteView .init (store: store, narrow: narrow);
423
+
424
+ bool done = false ;
425
+ view.addListener (() { done = true ; });
426
+ view.query = MentionAutocompleteQuery ('' );
427
+ await Future (() {});
428
+ check (done).isTrue ();
429
+ final results = view.results
430
+ .map ((e) => (e as UserMentionAutocompleteResult ).userId)
431
+ .toList ();
432
+ check (results).deepEquals (expected);
433
+ }
434
+
435
+ const streamNarrow = StreamNarrow (1 );
436
+ await checkResultsIn (streamNarrow, expected: [3 , 0 , 1 , 2 , 4 ]);
437
+
438
+ const topicNarrow = TopicNarrow (1 , 'topic' );
439
+ await checkResultsIn (topicNarrow, expected: [3 , 0 , 1 , 2 , 4 ]);
440
+
441
+ final dmNarrow = DmNarrow (allRecipientIds: [eg.selfUser.userId], selfUserId: eg.selfUser.userId);
442
+ await checkResultsIn (dmNarrow, expected: [3 , 0 , 1 , 2 , 4 ]);
443
+
444
+ const allMessagesNarrow = CombinedFeedNarrow ();
445
+ // Results are in the original order as we do not sort them for
446
+ // [CombinedFeedNarrow] because we can not access autocomplete for now.
447
+ await checkResultsIn (allMessagesNarrow, expected: [0 , 1 , 2 , 3 , 4 ]);
448
+ });
449
+ });
321
450
}
0 commit comments