@@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
7
7
import 'package:flutter_gen/gen_l10n/zulip_localizations.dart' ;
8
8
import 'package:flutter_test/flutter_test.dart' ;
9
9
import 'package:image_picker/image_picker.dart' ;
10
+ import 'package:zulip/api/model/events.dart' ;
10
11
import 'package:zulip/api/model/model.dart' ;
11
12
import 'package:zulip/api/route/messages.dart' ;
12
13
import 'package:zulip/model/localizations.dart' ;
@@ -373,4 +374,112 @@ void main() {
373
374
// TODO test what happens when capturing/uploading fails
374
375
});
375
376
});
377
+
378
+ group ('compose box in DMs with deactivated users' , () {
379
+ Finder contentFieldFinder () => find.descendant (
380
+ of: find.byType (ComposeBox ),
381
+ matching: find.byType (TextField ));
382
+
383
+ Finder attachButtonFinder (IconData icon) => find.descendant (
384
+ of: find.byType (ComposeBox ),
385
+ matching: find.widgetWithIcon (IconButton , icon));
386
+
387
+ void checkComposeBoxParts ({required bool areShown}) {
388
+ check (contentFieldFinder ().evaluate ().length).equals (areShown ? 1 : 0 );
389
+ check (attachButtonFinder (Icons .attach_file).evaluate ().length).equals (areShown ? 1 : 0 );
390
+ check (attachButtonFinder (Icons .image).evaluate ().length).equals (areShown ? 1 : 0 );
391
+ check (attachButtonFinder (Icons .camera_alt).evaluate ().length).equals (areShown ? 1 : 0 );
392
+ }
393
+
394
+ void checkBanner ({required bool isShown}) {
395
+ final bannerTextFinder = find.text (GlobalLocalizations .zulipLocalizations
396
+ .errorBannerDeactivatedDmLabel);
397
+ check (bannerTextFinder.evaluate ().length).equals (isShown ? 1 : 0 );
398
+ }
399
+
400
+ void checkComposeBox ({required bool isShown}) {
401
+ checkComposeBoxParts (areShown: isShown);
402
+ checkBanner (isShown: ! isShown);
403
+ }
404
+
405
+ Future <void > changeUserStatus (WidgetTester tester,
406
+ {required User user, required bool isActive}) async {
407
+ await store.handleEvent (RealmUserUpdateEvent (id: 1 ,
408
+ userId: user.userId, isActive: isActive));
409
+ await tester.pump ();
410
+ }
411
+
412
+ final selfUser = eg.selfUser;
413
+
414
+ DmNarrow dmNarrowWith (User otherUser) => DmNarrow .withUser (otherUser.userId,
415
+ selfUserId: selfUser.userId);
416
+
417
+ DmNarrow groupDmNarrowWith (List <User > otherUsers) => DmNarrow .withOtherUsers (
418
+ otherUsers.map ((u) => u.userId), selfUserId: selfUser.userId);
419
+
420
+ group ('1:1 DMs' , () {
421
+ testWidgets ('compose box replaced with a banner' , (tester) async {
422
+ final deactivatedUser = eg.user (isActive: false );
423
+ await prepareComposeBox (tester, narrow: dmNarrowWith (deactivatedUser),
424
+ users: [deactivatedUser]);
425
+ checkComposeBox (isShown: false );
426
+ });
427
+
428
+ testWidgets ('active user becomes deactivated -> '
429
+ 'compose box is replaced with a banner' , (tester) async {
430
+ final activeUser = eg.user (isActive: true );
431
+ await prepareComposeBox (tester, narrow: dmNarrowWith (activeUser),
432
+ users: [activeUser]);
433
+ checkComposeBox (isShown: true );
434
+
435
+ await changeUserStatus (tester, user: activeUser, isActive: false );
436
+ checkComposeBox (isShown: false );
437
+ });
438
+
439
+ testWidgets ('deactivated user becomes active -> '
440
+ 'banner is replaced with the compose box' , (tester) async {
441
+ final deactivatedUser = eg.user (isActive: false );
442
+ await prepareComposeBox (tester, narrow: dmNarrowWith (deactivatedUser),
443
+ users: [deactivatedUser]);
444
+ checkComposeBox (isShown: false );
445
+
446
+ await changeUserStatus (tester, user: deactivatedUser, isActive: true );
447
+ checkComposeBox (isShown: true );
448
+ });
449
+ });
450
+
451
+ group ('group DMs' , () {
452
+ testWidgets ('compose box replaced with a banner' , (tester) async {
453
+ final deactivatedUsers = [eg.user (isActive: false ), eg.user (isActive: false )];
454
+ await prepareComposeBox (tester, narrow: groupDmNarrowWith (deactivatedUsers),
455
+ users: deactivatedUsers);
456
+ checkComposeBox (isShown: false );
457
+ });
458
+
459
+ testWidgets ('at least one user becomes deactivated -> '
460
+ 'compose box is replaced with a banner' , (tester) async {
461
+ final activeUsers = [eg.user (isActive: true ), eg.user (isActive: true )];
462
+ await prepareComposeBox (tester, narrow: groupDmNarrowWith (activeUsers),
463
+ users: activeUsers);
464
+ checkComposeBox (isShown: true );
465
+
466
+ await changeUserStatus (tester, user: activeUsers[0 ], isActive: false );
467
+ checkComposeBox (isShown: false );
468
+ });
469
+
470
+ testWidgets ('all deactivated users become active -> '
471
+ 'banner is replaced with the compose box' , (tester) async {
472
+ final deactivatedUsers = [eg.user (isActive: false ), eg.user (isActive: false )];
473
+ await prepareComposeBox (tester, narrow: groupDmNarrowWith (deactivatedUsers),
474
+ users: deactivatedUsers);
475
+ checkComposeBox (isShown: false );
476
+
477
+ await changeUserStatus (tester, user: deactivatedUsers[0 ], isActive: true );
478
+ checkComposeBox (isShown: false );
479
+
480
+ await changeUserStatus (tester, user: deactivatedUsers[1 ], isActive: true );
481
+ checkComposeBox (isShown: true );
482
+ });
483
+ });
484
+ });
376
485
}
0 commit comments