@@ -41,6 +41,8 @@ void main() {
41
41
42
42
Future <GlobalKey <ComposeBoxController >> prepareComposeBox (WidgetTester tester, {
43
43
required Narrow narrow,
44
+ User ? selfUser,
45
+ int ? realmWaitingPeriodThreshold,
44
46
List <User > users = const [],
45
47
List <ZulipStream > streams = const [],
46
48
}) async {
@@ -49,16 +51,19 @@ void main() {
49
51
'Add a channel with "streamId" the same as of $narrow .streamId to the store.' );
50
52
}
51
53
addTearDown (testBinding.reset);
52
- await testBinding.globalStore.add (eg.selfAccount, eg.initialSnapshot ());
54
+ selfUser ?? = eg.selfUser;
55
+ final account = eg.account (user: selfUser);
56
+ await testBinding.globalStore.add (account, eg.initialSnapshot (
57
+ realmWaitingPeriodThreshold: realmWaitingPeriodThreshold));
53
58
54
- store = await testBinding.globalStore.perAccount (eg.selfAccount .id);
59
+ store = await testBinding.globalStore.perAccount (account .id);
55
60
56
- await store.addUsers ([eg. selfUser, ...users]);
61
+ await store.addUsers ([selfUser, ...users]);
57
62
await store.addStreams (streams);
58
63
connection = store.connection as FakeApiConnection ;
59
64
60
65
final controllerKey = GlobalKey <ComposeBoxController >();
61
- await tester.pumpWidget (TestZulipApp (accountId: eg.selfAccount .id,
66
+ await tester.pumpWidget (TestZulipApp (accountId: account .id,
62
67
child: Column (
63
68
// This positions the compose box at the bottom of the screen,
64
69
// simulating the layout of the message list page.
@@ -579,7 +584,9 @@ void main() {
579
584
});
580
585
581
586
group ('error banner' , () {
582
- Finder contentFieldFinder () => find.descendant (
587
+ final zulipLocalizations = GlobalLocalizations .zulipLocalizations;
588
+
589
+ Finder inputFieldFinder () => find.descendant (
583
590
of: find.byType (ComposeBox ),
584
591
matching: find.byType (TextField ));
585
592
@@ -588,24 +595,26 @@ void main() {
588
595
matching: find.widgetWithIcon (IconButton , icon));
589
596
590
597
void checkComposeBoxParts ({required bool areShown}) {
591
- check (contentFieldFinder ().evaluate ().length).equals (areShown ? 1 : 0 );
598
+ final inputFieldCount = inputFieldFinder ().evaluate ().length;
599
+ areShown ? check (inputFieldCount).isGreaterThan (0 ) : check (inputFieldCount).equals (0 );
592
600
check (attachButtonFinder (Icons .attach_file).evaluate ().length).equals (areShown ? 1 : 0 );
593
601
check (attachButtonFinder (Icons .image).evaluate ().length).equals (areShown ? 1 : 0 );
594
602
check (attachButtonFinder (Icons .camera_alt).evaluate ().length).equals (areShown ? 1 : 0 );
595
603
}
596
604
597
- void checkBanner ({required bool isShown}) {
598
- final bannerTextFinder = find.text (GlobalLocalizations .zulipLocalizations
599
- .errorBannerDeactivatedDmLabel);
600
- check (bannerTextFinder.evaluate ().length).equals (isShown ? 1 : 0 );
605
+ void checkBannerWithLabel (String label, {required bool isShown}) {
606
+ check (find.text (label).evaluate ().length).equals (isShown ? 1 : 0 );
601
607
}
602
608
603
- void checkComposeBox ( {required bool isShown }) {
609
+ void checkComposeBoxIsShown ( bool isShown, {required String bannerLabel }) {
604
610
checkComposeBoxParts (areShown: isShown);
605
- checkBanner ( isShown: ! isShown);
611
+ checkBannerWithLabel (bannerLabel, isShown: ! isShown);
606
612
}
607
613
608
614
group ('in DMs with deactivated users' , () {
615
+ void checkComposeBox ({required bool isShown}) => checkComposeBoxIsShown (isShown,
616
+ bannerLabel: zulipLocalizations.errorBannerDeactivatedDmLabel);
617
+
609
618
Future <void > changeUserStatus (WidgetTester tester,
610
619
{required User user, required bool isActive}) async {
611
620
await store.handleEvent (RealmUserUpdateEvent (id: 1 ,
@@ -684,5 +693,103 @@ void main() {
684
693
});
685
694
});
686
695
});
696
+
697
+ group ('in channel/topic narrow according to channel post policy' , () {
698
+ void checkComposeBox ({required bool isShown}) => checkComposeBoxIsShown (isShown,
699
+ bannerLabel: zulipLocalizations.errorBannerCannotPostInChannelLabel);
700
+
701
+ final narrowTestCases = [
702
+ ('channel' , const ChannelNarrow (1 )),
703
+ ('topic' , const TopicNarrow (1 , 'topic' )),
704
+ ];
705
+
706
+ for (final (String narrowType, Narrow narrow) in narrowTestCases) {
707
+ testWidgets ('compose box is shown in $narrowType narrow' , (tester) async {
708
+ await prepareComposeBox (tester,
709
+ narrow: narrow,
710
+ selfUser: eg.user (role: UserRole .administrator),
711
+ streams: [eg.stream (streamId: 1 ,
712
+ channelPostPolicy: ChannelPostPolicy .moderators)]);
713
+ checkComposeBox (isShown: true );
714
+ });
715
+
716
+ testWidgets ('error banner is shown in $narrowType narrow' , (tester) async {
717
+ await prepareComposeBox (tester,
718
+ narrow: narrow,
719
+ selfUser: eg.user (role: UserRole .moderator),
720
+ streams: [eg.stream (streamId: 1 ,
721
+ channelPostPolicy: ChannelPostPolicy .administrators)]);
722
+ checkComposeBox (isShown: false );
723
+ });
724
+ }
725
+
726
+ Future <void > changeUserRole (WidgetTester tester, {
727
+ required User user,
728
+ required UserRole role,
729
+ }) async {
730
+ await store.handleEvent (RealmUserUpdateEvent (id: 1 ,
731
+ userId: user.userId, role: role));
732
+ await tester.pump ();
733
+ }
734
+
735
+ Future <void > changeChannelPolicy (WidgetTester tester, {
736
+ required ZulipStream channel,
737
+ required ChannelPostPolicy policy,
738
+ }) async {
739
+ await store.handleEvent (eg.channelUpdateEvent (channel,
740
+ property: ChannelPropertyName .channelPostPolicy, value: policy));
741
+ await tester.pump ();
742
+ }
743
+
744
+ testWidgets ('user role decreases -> compose box is replaced with the banner' , (tester) async {
745
+ final selfUser = eg.user (role: UserRole .administrator);
746
+ await prepareComposeBox (tester,
747
+ narrow: const ChannelNarrow (1 ),
748
+ selfUser: selfUser,
749
+ streams: [eg.stream (streamId: 1 , channelPostPolicy: ChannelPostPolicy .administrators)]);
750
+ checkComposeBox (isShown: true );
751
+
752
+ await changeUserRole (tester, user: selfUser, role: UserRole .moderator);
753
+ checkComposeBox (isShown: false );
754
+ });
755
+
756
+ testWidgets ('user role increases -> banner is replaced with the compose box' , (tester) async {
757
+ final selfUser = eg.user (role: UserRole .guest);
758
+ await prepareComposeBox (tester,
759
+ narrow: const ChannelNarrow (1 ),
760
+ selfUser: selfUser,
761
+ streams: [eg.stream (streamId: 1 , channelPostPolicy: ChannelPostPolicy .moderators)]);
762
+ checkComposeBox (isShown: false );
763
+
764
+ await changeUserRole (tester, user: selfUser, role: UserRole .administrator);
765
+ checkComposeBox (isShown: true );
766
+ });
767
+
768
+ testWidgets ('channel policy becomes stricter -> compose box is replaced with the banner' , (tester) async {
769
+ final selfUser = eg.user (role: UserRole .guest);
770
+ final channel = eg.stream (streamId: 1 , channelPostPolicy: ChannelPostPolicy .any);
771
+ await prepareComposeBox (tester,
772
+ narrow: const ChannelNarrow (1 ),
773
+ selfUser: selfUser,
774
+ streams: [channel]);
775
+ checkComposeBox (isShown: true );
776
+
777
+ await changeChannelPolicy (tester, channel: channel, policy: ChannelPostPolicy .fullMembers);
778
+ checkComposeBox (isShown: false );
779
+ });
780
+
781
+ testWidgets ('channel policy becomes less strict -> banner is replaced with the compose box' , (tester) async {
782
+ final selfUser = eg.user (role: UserRole .moderator);
783
+ final channel = eg.stream (streamId: 1 , channelPostPolicy: ChannelPostPolicy .administrators);
784
+ await prepareComposeBox (tester,
785
+ narrow: const ChannelNarrow (1 ),
786
+ selfUser: selfUser,
787
+ streams: [channel]);
788
+ checkComposeBox (isShown: false );
789
+
790
+ await changeChannelPolicy (tester, channel: channel, policy: ChannelPostPolicy .moderators);
791
+ checkComposeBox (isShown: true );
792
+ });
793
+ });
687
794
});
688
795
}
0 commit comments