Skip to content

Commit 6b47ff0

Browse files
committed
channel [nfc]: Move hasPostingPermission here
1 parent fab85ca commit 6b47ff0

File tree

4 files changed

+100
-100
lines changed

4 files changed

+100
-100
lines changed

lib/model/channel.dart

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,30 @@ mixin ChannelStore on UserStore {
138138
return true;
139139
}
140140
}
141+
142+
bool hasPostingPermission({
143+
required ZulipStream inChannel,
144+
required User user,
145+
required DateTime byDate,
146+
}) {
147+
final role = user.role;
148+
// We let the users with [unknown] role to send the message, then the server
149+
// will decide to accept it or not based on its actual role.
150+
if (role == UserRole.unknown) return true;
151+
152+
switch (inChannel.channelPostPolicy) {
153+
case ChannelPostPolicy.any: return true;
154+
case ChannelPostPolicy.fullMembers: {
155+
if (!role.isAtLeast(UserRole.member)) return false;
156+
return role == UserRole.member
157+
? hasPassedWaitingPeriod(user, byDate: byDate)
158+
: true;
159+
}
160+
case ChannelPostPolicy.moderators: return role.isAtLeast(UserRole.moderator);
161+
case ChannelPostPolicy.administrators: return role.isAtLeast(UserRole.administrator);
162+
case ChannelPostPolicy.unknown: return true;
163+
}
164+
}
141165
}
142166

143167
/// Whether and how a given [UserTopicEvent] will affect the results

lib/model/store.dart

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -624,30 +624,6 @@ class PerAccountStore extends PerAccountStoreBase with
624624

625625
final ChannelStoreImpl _channels;
626626

627-
bool hasPostingPermission({
628-
required ZulipStream inChannel,
629-
required User user,
630-
required DateTime byDate,
631-
}) {
632-
final role = user.role;
633-
// We let the users with [unknown] role to send the message, then the server
634-
// will decide to accept it or not based on its actual role.
635-
if (role == UserRole.unknown) return true;
636-
637-
switch (inChannel.channelPostPolicy) {
638-
case ChannelPostPolicy.any: return true;
639-
case ChannelPostPolicy.fullMembers: {
640-
if (!role.isAtLeast(UserRole.member)) return false;
641-
return role == UserRole.member
642-
? hasPassedWaitingPeriod(user, byDate: byDate)
643-
: true;
644-
}
645-
case ChannelPostPolicy.moderators: return role.isAtLeast(UserRole.moderator);
646-
case ChannelPostPolicy.administrators: return role.isAtLeast(UserRole.administrator);
647-
case ChannelPostPolicy.unknown: return true;
648-
}
649-
}
650-
651627
//|//////////////////////////////
652628
// Messages, and summaries of messages.
653629

test/model/channel_test.dart

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,82 @@ void main() {
455455
});
456456
});
457457

458+
group('hasPostingPermission', () {
459+
final testCases = [
460+
(ChannelPostPolicy.unknown, UserRole.unknown, true),
461+
(ChannelPostPolicy.unknown, UserRole.guest, true),
462+
(ChannelPostPolicy.unknown, UserRole.member, true),
463+
(ChannelPostPolicy.unknown, UserRole.moderator, true),
464+
(ChannelPostPolicy.unknown, UserRole.administrator, true),
465+
(ChannelPostPolicy.unknown, UserRole.owner, true),
466+
(ChannelPostPolicy.any, UserRole.unknown, true),
467+
(ChannelPostPolicy.any, UserRole.guest, true),
468+
(ChannelPostPolicy.any, UserRole.member, true),
469+
(ChannelPostPolicy.any, UserRole.moderator, true),
470+
(ChannelPostPolicy.any, UserRole.administrator, true),
471+
(ChannelPostPolicy.any, UserRole.owner, true),
472+
(ChannelPostPolicy.fullMembers, UserRole.unknown, true),
473+
(ChannelPostPolicy.fullMembers, UserRole.guest, false),
474+
// The fullMembers/member case gets its own tests further below.
475+
// (ChannelPostPolicy.fullMembers, UserRole.member, /* complicated */),
476+
(ChannelPostPolicy.fullMembers, UserRole.moderator, true),
477+
(ChannelPostPolicy.fullMembers, UserRole.administrator, true),
478+
(ChannelPostPolicy.fullMembers, UserRole.owner, true),
479+
(ChannelPostPolicy.moderators, UserRole.unknown, true),
480+
(ChannelPostPolicy.moderators, UserRole.guest, false),
481+
(ChannelPostPolicy.moderators, UserRole.member, false),
482+
(ChannelPostPolicy.moderators, UserRole.moderator, true),
483+
(ChannelPostPolicy.moderators, UserRole.administrator, true),
484+
(ChannelPostPolicy.moderators, UserRole.owner, true),
485+
(ChannelPostPolicy.administrators, UserRole.unknown, true),
486+
(ChannelPostPolicy.administrators, UserRole.guest, false),
487+
(ChannelPostPolicy.administrators, UserRole.member, false),
488+
(ChannelPostPolicy.administrators, UserRole.moderator, false),
489+
(ChannelPostPolicy.administrators, UserRole.administrator, true),
490+
(ChannelPostPolicy.administrators, UserRole.owner, true),
491+
];
492+
493+
for (final (ChannelPostPolicy policy, UserRole role, bool canPost) in testCases) {
494+
test('"${role.name}" user ${canPost ? 'can' : "can't"} post in channel '
495+
'with "${policy.name}" policy', () {
496+
final store = eg.store();
497+
final actual = store.hasPostingPermission(
498+
inChannel: eg.stream(channelPostPolicy: policy), user: eg.user(role: role),
499+
// [byDate] is not actually relevant for these test cases; for the
500+
// ones which it is, they're practiced below.
501+
byDate: DateTime.now());
502+
check(actual).equals(canPost);
503+
});
504+
}
505+
506+
group('"member" user posting in a channel with "fullMembers" policy', () {
507+
PerAccountStore localStore({required int realmWaitingPeriodThreshold}) =>
508+
eg.store(initialSnapshot: eg.initialSnapshot(
509+
realmWaitingPeriodThreshold: realmWaitingPeriodThreshold));
510+
511+
User memberUser({required String dateJoined}) => eg.user(
512+
role: UserRole.member, dateJoined: dateJoined);
513+
514+
test('a "full" member -> can post in the channel', () {
515+
final store = localStore(realmWaitingPeriodThreshold: 3);
516+
final hasPermission = store.hasPostingPermission(
517+
inChannel: eg.stream(channelPostPolicy: ChannelPostPolicy.fullMembers),
518+
user: memberUser(dateJoined: '2024-11-25T10:00+00:00'),
519+
byDate: DateTime.utc(2024, 11, 28, 10, 00));
520+
check(hasPermission).isTrue();
521+
});
522+
523+
test('not a "full" member -> cannot post in the channel', () {
524+
final store = localStore(realmWaitingPeriodThreshold: 3);
525+
final actual = store.hasPostingPermission(
526+
inChannel: eg.stream(channelPostPolicy: ChannelPostPolicy.fullMembers),
527+
user: memberUser(dateJoined: '2024-11-25T10:00+00:00'),
528+
byDate: DateTime.utc(2024, 11, 28, 09, 59));
529+
check(actual).isFalse();
530+
});
531+
});
532+
});
533+
458534
group('makeTopicKeyedMap', () {
459535
test('"a" equals "A"', () {
460536
final map = makeTopicKeyedMap<int>()

test/model/store_test.dart

Lines changed: 0 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -465,82 +465,6 @@ void main() {
465465
});
466466
});
467467

468-
group('PerAccountStore.hasPostingPermission', () {
469-
final testCases = [
470-
(ChannelPostPolicy.unknown, UserRole.unknown, true),
471-
(ChannelPostPolicy.unknown, UserRole.guest, true),
472-
(ChannelPostPolicy.unknown, UserRole.member, true),
473-
(ChannelPostPolicy.unknown, UserRole.moderator, true),
474-
(ChannelPostPolicy.unknown, UserRole.administrator, true),
475-
(ChannelPostPolicy.unknown, UserRole.owner, true),
476-
(ChannelPostPolicy.any, UserRole.unknown, true),
477-
(ChannelPostPolicy.any, UserRole.guest, true),
478-
(ChannelPostPolicy.any, UserRole.member, true),
479-
(ChannelPostPolicy.any, UserRole.moderator, true),
480-
(ChannelPostPolicy.any, UserRole.administrator, true),
481-
(ChannelPostPolicy.any, UserRole.owner, true),
482-
(ChannelPostPolicy.fullMembers, UserRole.unknown, true),
483-
(ChannelPostPolicy.fullMembers, UserRole.guest, false),
484-
// The fullMembers/member case gets its own tests further below.
485-
// (ChannelPostPolicy.fullMembers, UserRole.member, /* complicated */),
486-
(ChannelPostPolicy.fullMembers, UserRole.moderator, true),
487-
(ChannelPostPolicy.fullMembers, UserRole.administrator, true),
488-
(ChannelPostPolicy.fullMembers, UserRole.owner, true),
489-
(ChannelPostPolicy.moderators, UserRole.unknown, true),
490-
(ChannelPostPolicy.moderators, UserRole.guest, false),
491-
(ChannelPostPolicy.moderators, UserRole.member, false),
492-
(ChannelPostPolicy.moderators, UserRole.moderator, true),
493-
(ChannelPostPolicy.moderators, UserRole.administrator, true),
494-
(ChannelPostPolicy.moderators, UserRole.owner, true),
495-
(ChannelPostPolicy.administrators, UserRole.unknown, true),
496-
(ChannelPostPolicy.administrators, UserRole.guest, false),
497-
(ChannelPostPolicy.administrators, UserRole.member, false),
498-
(ChannelPostPolicy.administrators, UserRole.moderator, false),
499-
(ChannelPostPolicy.administrators, UserRole.administrator, true),
500-
(ChannelPostPolicy.administrators, UserRole.owner, true),
501-
];
502-
503-
for (final (ChannelPostPolicy policy, UserRole role, bool canPost) in testCases) {
504-
test('"${role.name}" user ${canPost ? 'can' : "can't"} post in channel '
505-
'with "${policy.name}" policy', () {
506-
final store = eg.store();
507-
final actual = store.hasPostingPermission(
508-
inChannel: eg.stream(channelPostPolicy: policy), user: eg.user(role: role),
509-
// [byDate] is not actually relevant for these test cases; for the
510-
// ones which it is, they're practiced below.
511-
byDate: DateTime.now());
512-
check(actual).equals(canPost);
513-
});
514-
}
515-
516-
group('"member" user posting in a channel with "fullMembers" policy', () {
517-
PerAccountStore localStore({required int realmWaitingPeriodThreshold}) =>
518-
eg.store(initialSnapshot: eg.initialSnapshot(
519-
realmWaitingPeriodThreshold: realmWaitingPeriodThreshold));
520-
521-
User memberUser({required String dateJoined}) => eg.user(
522-
role: UserRole.member, dateJoined: dateJoined);
523-
524-
test('a "full" member -> can post in the channel', () {
525-
final store = localStore(realmWaitingPeriodThreshold: 3);
526-
final hasPermission = store.hasPostingPermission(
527-
inChannel: eg.stream(channelPostPolicy: ChannelPostPolicy.fullMembers),
528-
user: memberUser(dateJoined: '2024-11-25T10:00+00:00'),
529-
byDate: DateTime.utc(2024, 11, 28, 10, 00));
530-
check(hasPermission).isTrue();
531-
});
532-
533-
test('not a "full" member -> cannot post in the channel', () {
534-
final store = localStore(realmWaitingPeriodThreshold: 3);
535-
final actual = store.hasPostingPermission(
536-
inChannel: eg.stream(channelPostPolicy: ChannelPostPolicy.fullMembers),
537-
user: memberUser(dateJoined: '2024-11-25T10:00+00:00'),
538-
byDate: DateTime.utc(2024, 11, 28, 09, 59));
539-
check(actual).isFalse();
540-
});
541-
});
542-
});
543-
544468
group('PerAccountStore.handleEvent', () {
545469
// Mostly this method just dispatches to ChannelStore and MessageStore etc.,
546470
// and so its tests generally live in the test files for those

0 commit comments

Comments
 (0)