-
Notifications
You must be signed in to change notification settings - Fork 160
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
compose_box: Replace compose box with a banner when cannot post in a channel #886
base: main
Are you sure you want to change the base?
Changes from 1 commit
ffb3238
9616005
6cf3dd9
d1c16a9
5aaad2d
dc9a330
58276c3
be0d74d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -1071,26 +1071,8 @@ class _FixedDestinationComposeBoxState extends State<_FixedDestinationComposeBox | |||||||||||||||||||||||||||||||||
super.dispose(); | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
Widget? _errorBanner(BuildContext context) { | ||||||||||||||||||||||||||||||||||
if (widget.narrow case DmNarrow(:final otherRecipientIds)) { | ||||||||||||||||||||||||||||||||||
final store = PerAccountStoreWidget.of(context); | ||||||||||||||||||||||||||||||||||
final hasDeactivatedUser = otherRecipientIds.any((id) => | ||||||||||||||||||||||||||||||||||
!(store.users[id]?.isActive ?? true)); | ||||||||||||||||||||||||||||||||||
if (hasDeactivatedUser) { | ||||||||||||||||||||||||||||||||||
return _ErrorBanner(label: ZulipLocalizations.of(context) | ||||||||||||||||||||||||||||||||||
.errorBannerDeactivatedDmLabel); | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
return null; | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
@override | ||||||||||||||||||||||||||||||||||
Widget build(BuildContext context) { | ||||||||||||||||||||||||||||||||||
final errorBanner = _errorBanner(context); | ||||||||||||||||||||||||||||||||||
if (errorBanner != null) { | ||||||||||||||||||||||||||||||||||
return _ComposeBoxContainer(child: errorBanner); | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
return _ComposeBoxLayout( | ||||||||||||||||||||||||||||||||||
contentController: _contentController, | ||||||||||||||||||||||||||||||||||
contentFocusNode: _contentFocusNode, | ||||||||||||||||||||||||||||||||||
|
@@ -1128,8 +1110,37 @@ class ComposeBox extends StatelessWidget { | |||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
Widget? _errorBanner(BuildContext context) { | ||||||||||||||||||||||||||||||||||
final store = PerAccountStoreWidget.of(context); | ||||||||||||||||||||||||||||||||||
final selfUser = store.users[store.selfUserId]!; | ||||||||||||||||||||||||||||||||||
switch (narrow) { | ||||||||||||||||||||||||||||||||||
case ChannelNarrow narrow: | ||||||||||||||||||||||||||||||||||
final channel = store.streams[narrow.streamId]!; | ||||||||||||||||||||||||||||||||||
return channel.hasPostingPermission(selfUser, byDate: DateTime.now(), realmWaitingPeriodThreshold: store.realmWaitingPeriodThreshold) | ||||||||||||||||||||||||||||||||||
? null : _ErrorBanner(label: ZulipLocalizations.of(context).errorBannerCannotPostInChannelLabel); | ||||||||||||||||||||||||||||||||||
case TopicNarrow narrow: | ||||||||||||||||||||||||||||||||||
final channel = store.streams[narrow.streamId]!; | ||||||||||||||||||||||||||||||||||
return channel.hasPostingPermission(selfUser, byDate: DateTime.now(), realmWaitingPeriodThreshold: store.realmWaitingPeriodThreshold) | ||||||||||||||||||||||||||||||||||
? null : _ErrorBanner(label: ZulipLocalizations.of(context).errorBannerCannotPostInChannelLabel); | ||||||||||||||||||||||||||||||||||
Comment on lines
+1117
to
+1124
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Then we can simplify this to:
Suggested change
|
||||||||||||||||||||||||||||||||||
case DmNarrow(:final otherRecipientIds): | ||||||||||||||||||||||||||||||||||
final hasDeactivatedUser = otherRecipientIds.any((id) => | ||||||||||||||||||||||||||||||||||
!(store.users[id]?.isActive ?? true)); | ||||||||||||||||||||||||||||||||||
return hasDeactivatedUser ? _ErrorBanner(label: ZulipLocalizations.of(context) | ||||||||||||||||||||||||||||||||||
.errorBannerDeactivatedDmLabel) : null; | ||||||||||||||||||||||||||||||||||
Comment on lines
+1128
to
+1129
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: to make the lines shorter:
Suggested change
|
||||||||||||||||||||||||||||||||||
case CombinedFeedNarrow(): | ||||||||||||||||||||||||||||||||||
case MentionsNarrow(): | ||||||||||||||||||||||||||||||||||
case StarredMessagesNarrow(): | ||||||||||||||||||||||||||||||||||
return null; | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
@override | ||||||||||||||||||||||||||||||||||
Widget build(BuildContext context) { | ||||||||||||||||||||||||||||||||||
final errorBanner = _errorBanner(context); | ||||||||||||||||||||||||||||||||||
if (errorBanner != null) { | ||||||||||||||||||||||||||||||||||
return _ComposeBoxContainer(child: errorBanner); | ||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
final narrow = this.narrow; | ||||||||||||||||||||||||||||||||||
switch (narrow) { | ||||||||||||||||||||||||||||||||||
case ChannelNarrow(): | ||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -395,8 +395,10 @@ void main() { | |||||||||||||
}); | ||||||||||||||
}); | ||||||||||||||
|
||||||||||||||
group('compose box in DMs with deactivated users', () { | ||||||||||||||
Finder contentFieldFinder() => find.descendant( | ||||||||||||||
group('compose box replacing with error banner', () { | ||||||||||||||
final zulipLocalizations = GlobalLocalizations.zulipLocalizations; | ||||||||||||||
|
||||||||||||||
Finder inputFieldFinder() => find.descendant( | ||||||||||||||
of: find.byType(ComposeBox), | ||||||||||||||
matching: find.byType(TextField)); | ||||||||||||||
|
||||||||||||||
|
@@ -405,97 +407,249 @@ void main() { | |||||||||||||
matching: find.widgetWithIcon(IconButton, icon)); | ||||||||||||||
|
||||||||||||||
void checkComposeBoxParts({required bool areShown}) { | ||||||||||||||
check(contentFieldFinder().evaluate().length).equals(areShown ? 1 : 0); | ||||||||||||||
final inputFieldCount = inputFieldFinder().evaluate().length; | ||||||||||||||
areShown ? check(inputFieldCount).isGreaterThan(0) : check(inputFieldCount).equals(0); | ||||||||||||||
check(attachButtonFinder(Icons.attach_file).evaluate().length).equals(areShown ? 1 : 0); | ||||||||||||||
check(attachButtonFinder(Icons.image).evaluate().length).equals(areShown ? 1 : 0); | ||||||||||||||
check(attachButtonFinder(Icons.camera_alt).evaluate().length).equals(areShown ? 1 : 0); | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
void checkBanner({required bool isShown}) { | ||||||||||||||
final bannerTextFinder = find.text(GlobalLocalizations.zulipLocalizations | ||||||||||||||
.errorBannerDeactivatedDmLabel); | ||||||||||||||
check(bannerTextFinder.evaluate().length).equals(isShown ? 1 : 0); | ||||||||||||||
void checkBannerWithLabel(String label, {required bool isShown}) { | ||||||||||||||
check(find.text(label).evaluate().length).equals(isShown ? 1 : 0); | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
void checkComposeBox({required bool isShown}) { | ||||||||||||||
void checkComposeBoxIsShown(bool isShown, {required String bannerLabel}) { | ||||||||||||||
checkComposeBoxParts(areShown: isShown); | ||||||||||||||
checkBanner(isShown: !isShown); | ||||||||||||||
checkBannerWithLabel(bannerLabel, isShown: !isShown); | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
Future<void> changeUserStatus(WidgetTester tester, | ||||||||||||||
{required User user, required bool isActive}) async { | ||||||||||||||
await store.handleEvent(RealmUserUpdateEvent(id: 1, | ||||||||||||||
userId: user.userId, isActive: isActive)); | ||||||||||||||
await tester.pump(); | ||||||||||||||
} | ||||||||||||||
group('in DMs with deactivated users', () { | ||||||||||||||
void checkComposeBox({required bool isShown}) => checkComposeBoxIsShown(isShown, | ||||||||||||||
bannerLabel: zulipLocalizations.errorBannerDeactivatedDmLabel); | ||||||||||||||
|
||||||||||||||
DmNarrow dmNarrowWith(User otherUser) => DmNarrow.withUser(otherUser.userId, | ||||||||||||||
selfUserId: eg.selfUser.userId); | ||||||||||||||
Future<void> changeUserStatus(WidgetTester tester, | ||||||||||||||
{required User user, required bool isActive}) async { | ||||||||||||||
await store.handleEvent(RealmUserUpdateEvent(id: 1, | ||||||||||||||
userId: user.userId, isActive: isActive)); | ||||||||||||||
await tester.pump(); | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
DmNarrow groupDmNarrowWith(List<User> otherUsers) => DmNarrow.withOtherUsers( | ||||||||||||||
otherUsers.map((u) => u.userId), selfUserId: eg.selfUser.userId); | ||||||||||||||
DmNarrow dmNarrowWith(User otherUser) => DmNarrow.withUser(otherUser.userId, | ||||||||||||||
selfUserId: eg.selfUser.userId); | ||||||||||||||
|
||||||||||||||
group('1:1 DMs', () { | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like we are both moving tests to groups and adding the new tests. |
||||||||||||||
testWidgets('compose box replaced with a banner', (tester) async { | ||||||||||||||
final deactivatedUser = eg.user(isActive: false); | ||||||||||||||
await prepareComposeBox(tester, narrow: dmNarrowWith(deactivatedUser), | ||||||||||||||
users: [deactivatedUser]); | ||||||||||||||
checkComposeBox(isShown: false); | ||||||||||||||
}); | ||||||||||||||
DmNarrow groupDmNarrowWith(List<User> otherUsers) => DmNarrow.withOtherUsers( | ||||||||||||||
otherUsers.map((u) => u.userId), selfUserId: eg.selfUser.userId); | ||||||||||||||
|
||||||||||||||
testWidgets('active user becomes deactivated -> ' | ||||||||||||||
'compose box is replaced with a banner', (tester) async { | ||||||||||||||
final activeUser = eg.user(isActive: true); | ||||||||||||||
await prepareComposeBox(tester, narrow: dmNarrowWith(activeUser), | ||||||||||||||
users: [activeUser]); | ||||||||||||||
checkComposeBox(isShown: true); | ||||||||||||||
group('1:1 DMs', () { | ||||||||||||||
testWidgets('compose box replaced with a banner', (tester) async { | ||||||||||||||
final deactivatedUser = eg.user(isActive: false); | ||||||||||||||
await prepareComposeBox(tester, narrow: dmNarrowWith(deactivatedUser), | ||||||||||||||
users: [deactivatedUser]); | ||||||||||||||
checkComposeBox(isShown: false); | ||||||||||||||
}); | ||||||||||||||
|
||||||||||||||
await changeUserStatus(tester, user: activeUser, isActive: false); | ||||||||||||||
checkComposeBox(isShown: false); | ||||||||||||||
testWidgets('active user becomes deactivated -> ' | ||||||||||||||
'compose box is replaced with a banner', (tester) async { | ||||||||||||||
final activeUser = eg.user(isActive: true); | ||||||||||||||
await prepareComposeBox(tester, narrow: dmNarrowWith(activeUser), | ||||||||||||||
users: [activeUser]); | ||||||||||||||
checkComposeBox(isShown: true); | ||||||||||||||
|
||||||||||||||
await changeUserStatus(tester, user: activeUser, isActive: false); | ||||||||||||||
checkComposeBox(isShown: false); | ||||||||||||||
}); | ||||||||||||||
|
||||||||||||||
testWidgets('deactivated user becomes active -> ' | ||||||||||||||
'banner is replaced with the compose box', (tester) async { | ||||||||||||||
final deactivatedUser = eg.user(isActive: false); | ||||||||||||||
await prepareComposeBox(tester, narrow: dmNarrowWith(deactivatedUser), | ||||||||||||||
users: [deactivatedUser]); | ||||||||||||||
checkComposeBox(isShown: false); | ||||||||||||||
|
||||||||||||||
await changeUserStatus(tester, user: deactivatedUser, isActive: true); | ||||||||||||||
checkComposeBox(isShown: true); | ||||||||||||||
}); | ||||||||||||||
}); | ||||||||||||||
|
||||||||||||||
testWidgets('deactivated user becomes active -> ' | ||||||||||||||
'banner is replaced with the compose box', (tester) async { | ||||||||||||||
final deactivatedUser = eg.user(isActive: false); | ||||||||||||||
await prepareComposeBox(tester, narrow: dmNarrowWith(deactivatedUser), | ||||||||||||||
users: [deactivatedUser]); | ||||||||||||||
checkComposeBox(isShown: false); | ||||||||||||||
group('group DMs', () { | ||||||||||||||
testWidgets('compose box replaced with a banner', (tester) async { | ||||||||||||||
final deactivatedUsers = [eg.user(isActive: false), eg.user(isActive: false)]; | ||||||||||||||
await prepareComposeBox(tester, narrow: groupDmNarrowWith(deactivatedUsers), | ||||||||||||||
users: deactivatedUsers); | ||||||||||||||
checkComposeBox(isShown: false); | ||||||||||||||
}); | ||||||||||||||
|
||||||||||||||
await changeUserStatus(tester, user: deactivatedUser, isActive: true); | ||||||||||||||
checkComposeBox(isShown: true); | ||||||||||||||
testWidgets('at least one user becomes deactivated -> ' | ||||||||||||||
'compose box is replaced with a banner', (tester) async { | ||||||||||||||
final activeUsers = [eg.user(isActive: true), eg.user(isActive: true)]; | ||||||||||||||
await prepareComposeBox(tester, narrow: groupDmNarrowWith(activeUsers), | ||||||||||||||
users: activeUsers); | ||||||||||||||
checkComposeBox(isShown: true); | ||||||||||||||
|
||||||||||||||
await changeUserStatus(tester, user: activeUsers[0], isActive: false); | ||||||||||||||
checkComposeBox(isShown: false); | ||||||||||||||
}); | ||||||||||||||
|
||||||||||||||
testWidgets('all deactivated users become active -> ' | ||||||||||||||
'banner is replaced with the compose box', (tester) async { | ||||||||||||||
final deactivatedUsers = [eg.user(isActive: false), eg.user(isActive: false)]; | ||||||||||||||
await prepareComposeBox(tester, narrow: groupDmNarrowWith(deactivatedUsers), | ||||||||||||||
users: deactivatedUsers); | ||||||||||||||
checkComposeBox(isShown: false); | ||||||||||||||
|
||||||||||||||
await changeUserStatus(tester, user: deactivatedUsers[0], isActive: true); | ||||||||||||||
checkComposeBox(isShown: false); | ||||||||||||||
|
||||||||||||||
await changeUserStatus(tester, user: deactivatedUsers[1], isActive: true); | ||||||||||||||
checkComposeBox(isShown: true); | ||||||||||||||
}); | ||||||||||||||
}); | ||||||||||||||
}); | ||||||||||||||
|
||||||||||||||
group('group DMs', () { | ||||||||||||||
testWidgets('compose box replaced with a banner', (tester) async { | ||||||||||||||
final deactivatedUsers = [eg.user(isActive: false), eg.user(isActive: false)]; | ||||||||||||||
await prepareComposeBox(tester, narrow: groupDmNarrowWith(deactivatedUsers), | ||||||||||||||
users: deactivatedUsers); | ||||||||||||||
checkComposeBox(isShown: false); | ||||||||||||||
group('in topic/channel narrow according to channel post policy', () { | ||||||||||||||
void checkComposeBox({required bool isShown}) => checkComposeBoxIsShown(isShown, | ||||||||||||||
bannerLabel: zulipLocalizations.errorBannerCannotPostInChannelLabel); | ||||||||||||||
|
||||||||||||||
final testCases = [ | ||||||||||||||
(ChannelPostPolicy.unknown, UserRole.unknown, true), | ||||||||||||||
(ChannelPostPolicy.unknown, UserRole.guest, true), | ||||||||||||||
(ChannelPostPolicy.unknown, UserRole.member, true), | ||||||||||||||
(ChannelPostPolicy.unknown, UserRole.moderator, true), | ||||||||||||||
(ChannelPostPolicy.unknown, UserRole.administrator, true), | ||||||||||||||
(ChannelPostPolicy.unknown, UserRole.owner, true), | ||||||||||||||
(ChannelPostPolicy.any, UserRole.unknown, true), | ||||||||||||||
(ChannelPostPolicy.any, UserRole.guest, true), | ||||||||||||||
(ChannelPostPolicy.any, UserRole.member, true), | ||||||||||||||
(ChannelPostPolicy.any, UserRole.moderator, true), | ||||||||||||||
(ChannelPostPolicy.any, UserRole.administrator, true), | ||||||||||||||
(ChannelPostPolicy.any, UserRole.owner, true), | ||||||||||||||
(ChannelPostPolicy.fullMembers, UserRole.unknown, true), | ||||||||||||||
(ChannelPostPolicy.fullMembers, UserRole.guest, false), | ||||||||||||||
(ChannelPostPolicy.fullMembers, UserRole.member, true), | ||||||||||||||
(ChannelPostPolicy.fullMembers, UserRole.moderator, true), | ||||||||||||||
(ChannelPostPolicy.fullMembers, UserRole.administrator, true), | ||||||||||||||
(ChannelPostPolicy.fullMembers, UserRole.owner, true), | ||||||||||||||
(ChannelPostPolicy.moderators, UserRole.unknown, true), | ||||||||||||||
(ChannelPostPolicy.moderators, UserRole.guest, false), | ||||||||||||||
(ChannelPostPolicy.moderators, UserRole.member, false), | ||||||||||||||
(ChannelPostPolicy.moderators, UserRole.moderator, true), | ||||||||||||||
(ChannelPostPolicy.moderators, UserRole.administrator, true), | ||||||||||||||
(ChannelPostPolicy.moderators, UserRole.owner, true), | ||||||||||||||
(ChannelPostPolicy.administrators, UserRole.unknown, true), | ||||||||||||||
(ChannelPostPolicy.administrators, UserRole.guest, false), | ||||||||||||||
(ChannelPostPolicy.administrators, UserRole.member, false), | ||||||||||||||
(ChannelPostPolicy.administrators, UserRole.moderator, false), | ||||||||||||||
(ChannelPostPolicy.administrators, UserRole.administrator, true), | ||||||||||||||
(ChannelPostPolicy.administrators, UserRole.owner, true), | ||||||||||||||
]; | ||||||||||||||
|
||||||||||||||
for (final testCase in testCases) { | ||||||||||||||
final (ChannelPostPolicy policy, UserRole role, bool canPost) = testCase; | ||||||||||||||
Comment on lines
+546
to
+547
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit:
Suggested change
Comment on lines
+546
to
+547
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit:
Suggested change
|
||||||||||||||
|
||||||||||||||
testWidgets('"${role.name}" user ${canPost ? 'can' : "can't"} post in channel with "${policy.name}" policy', (tester) async { | ||||||||||||||
final selfUser = eg.user(role: role); | ||||||||||||||
await prepareComposeBox(tester, | ||||||||||||||
narrow: const ChannelNarrow(1), | ||||||||||||||
selfUser: selfUser, | ||||||||||||||
streams: [eg.stream(streamId: 1, channelPostPolicy: policy)]); | ||||||||||||||
checkComposeBox(isShown: canPost); | ||||||||||||||
}); | ||||||||||||||
|
||||||||||||||
testWidgets('"${role.name}" user ${canPost ? 'can' : "can't"} post in topic with "${policy.name}" channel policy', (tester) async { | ||||||||||||||
final selfUser = eg.user(role: role); | ||||||||||||||
await prepareComposeBox(tester, | ||||||||||||||
narrow: const TopicNarrow(1, 'topic'), | ||||||||||||||
selfUser: selfUser, | ||||||||||||||
streams: [eg.stream(streamId: 1, channelPostPolicy: policy)]); | ||||||||||||||
checkComposeBox(isShown: canPost); | ||||||||||||||
}); | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
group('only "full member" user can post in channel with "fullMembers" policy', () { | ||||||||||||||
testWidgets('"full member" -> can post in channel', (tester) async { | ||||||||||||||
final selfUser = eg.user(role: UserRole.member, | ||||||||||||||
dateJoined: DateTime.now().subtract(const Duration(days: 30)).toIso8601String()); | ||||||||||||||
await prepareComposeBox(tester, | ||||||||||||||
narrow: const ChannelNarrow(1), | ||||||||||||||
selfUser: selfUser, | ||||||||||||||
realmWaitingPeriodThreshold: 30, | ||||||||||||||
streams: [eg.stream(streamId: 1, channelPostPolicy: ChannelPostPolicy.fullMembers)]); | ||||||||||||||
checkComposeBox(isShown: true); | ||||||||||||||
}); | ||||||||||||||
|
||||||||||||||
testWidgets('not a "full member" -> cannot post in channel', (tester) async { | ||||||||||||||
final selfUser = eg.user(role: UserRole.member, | ||||||||||||||
dateJoined: DateTime.now().subtract(const Duration(days: 29)).toIso8601String()); | ||||||||||||||
await prepareComposeBox(tester, | ||||||||||||||
narrow: const ChannelNarrow(1), | ||||||||||||||
selfUser: selfUser, | ||||||||||||||
realmWaitingPeriodThreshold: 30, | ||||||||||||||
streams: [eg.stream(streamId: 1, channelPostPolicy: ChannelPostPolicy.fullMembers)]); | ||||||||||||||
checkComposeBox(isShown: false); | ||||||||||||||
}); | ||||||||||||||
}); | ||||||||||||||
|
||||||||||||||
testWidgets('at least one user becomes deactivated -> ' | ||||||||||||||
'compose box is replaced with a banner', (tester) async { | ||||||||||||||
final activeUsers = [eg.user(isActive: true), eg.user(isActive: true)]; | ||||||||||||||
await prepareComposeBox(tester, narrow: groupDmNarrowWith(activeUsers), | ||||||||||||||
users: activeUsers); | ||||||||||||||
Future<void> changeUserRole(WidgetTester tester, | ||||||||||||||
{required User user, required UserRole role}) async { | ||||||||||||||
await store.handleEvent(RealmUserUpdateEvent(id: 1, | ||||||||||||||
userId: user.userId, role: role)); | ||||||||||||||
await tester.pump(); | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
Future<void> changeChannelPolicy(WidgetTester tester, | ||||||||||||||
{required ZulipStream channel, required ChannelPostPolicy policy}) async { | ||||||||||||||
await store.handleEvent(eg.channelUpdateEvent(channel, | ||||||||||||||
property: ChannelPropertyName.channelPostPolicy, value: policy)); | ||||||||||||||
await tester.pump(); | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
testWidgets('user role decreases -> compose box is replaced with the banner', (tester) async { | ||||||||||||||
final selfUser = eg.user(role: UserRole.administrator); | ||||||||||||||
await prepareComposeBox(tester, | ||||||||||||||
narrow: const ChannelNarrow(1), | ||||||||||||||
selfUser: selfUser, | ||||||||||||||
streams: [eg.stream(streamId: 1, channelPostPolicy: ChannelPostPolicy.administrators)]); | ||||||||||||||
checkComposeBox(isShown: true); | ||||||||||||||
|
||||||||||||||
await changeUserStatus(tester, user: activeUsers[0], isActive: false); | ||||||||||||||
await changeUserRole(tester, user: selfUser, role: UserRole.moderator); | ||||||||||||||
checkComposeBox(isShown: false); | ||||||||||||||
}); | ||||||||||||||
|
||||||||||||||
testWidgets('all deactivated users become active -> ' | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, the deletion is a bit far apart from where it was re-added. A goal of restructuring the change would be that we have one commit that moves the old tests, and one that only adds the new ones. |
||||||||||||||
'banner is replaced with the compose box', (tester) async { | ||||||||||||||
final deactivatedUsers = [eg.user(isActive: false), eg.user(isActive: false)]; | ||||||||||||||
await prepareComposeBox(tester, narrow: groupDmNarrowWith(deactivatedUsers), | ||||||||||||||
users: deactivatedUsers); | ||||||||||||||
testWidgets('user role increases -> banner is replaced with the compose box', (tester) async { | ||||||||||||||
final selfUser = eg.user(role: UserRole.guest); | ||||||||||||||
await prepareComposeBox(tester, | ||||||||||||||
narrow: const ChannelNarrow(1), | ||||||||||||||
selfUser: selfUser, | ||||||||||||||
streams: [eg.stream(streamId: 1, channelPostPolicy: ChannelPostPolicy.moderators)]); | ||||||||||||||
checkComposeBox(isShown: false); | ||||||||||||||
|
||||||||||||||
await changeUserStatus(tester, user: deactivatedUsers[0], isActive: true); | ||||||||||||||
await changeUserRole(tester, user: selfUser, role: UserRole.administrator); | ||||||||||||||
checkComposeBox(isShown: true); | ||||||||||||||
}); | ||||||||||||||
|
||||||||||||||
testWidgets('channel policy becomes stricter -> compose box is replaced with the banner', (tester) async { | ||||||||||||||
final selfUser = eg.user(role: UserRole.guest); | ||||||||||||||
final channel = eg.stream(streamId: 1, channelPostPolicy: ChannelPostPolicy.any); | ||||||||||||||
await prepareComposeBox(tester, | ||||||||||||||
narrow: const ChannelNarrow(1), | ||||||||||||||
selfUser: selfUser, | ||||||||||||||
streams: [channel]); | ||||||||||||||
checkComposeBox(isShown: true); | ||||||||||||||
|
||||||||||||||
await changeChannelPolicy(tester, channel: channel, policy: ChannelPostPolicy.fullMembers); | ||||||||||||||
checkComposeBox(isShown: false); | ||||||||||||||
}); | ||||||||||||||
|
||||||||||||||
testWidgets('channel policy becomes less strict -> banner is replaced with the compose box', (tester) async { | ||||||||||||||
final selfUser = eg.user(role: UserRole.moderator); | ||||||||||||||
final channel = eg.stream(streamId: 1, channelPostPolicy: ChannelPostPolicy.administrators); | ||||||||||||||
await prepareComposeBox(tester, | ||||||||||||||
narrow: const ChannelNarrow(1), | ||||||||||||||
selfUser: selfUser, | ||||||||||||||
streams: [channel]); | ||||||||||||||
checkComposeBox(isShown: false); | ||||||||||||||
|
||||||||||||||
await changeUserStatus(tester, user: deactivatedUsers[1], isActive: true); | ||||||||||||||
await changeChannelPolicy(tester, channel: channel, policy: ChannelPostPolicy.moderators); | ||||||||||||||
checkComposeBox(isShown: true); | ||||||||||||||
}); | ||||||||||||||
}); | ||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: let's extract
ZulipLocalizations.of(context)
as a variable