Skip to content

Commit 3c9da46

Browse files
chrisbobbegnprice
authored andcommitted
api types: Use Flow enum for Role
1 parent 966c36a commit 3c9da46

File tree

7 files changed

+32
-54
lines changed

7 files changed

+32
-54
lines changed

src/__tests__/permissionSelectors-test.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ import invariant from 'invariant';
44
import { getOwnUser, tryGetActiveAccountState, getRealm } from '../selectors';
55
import {
66
Role,
7-
RoleValues,
8-
type RoleT,
97
CreatePublicOrPrivateStreamPolicy,
108
type CreatePublicOrPrivateStreamPolicyT,
119
CreateWebPublicStreamPolicy,
@@ -21,18 +19,20 @@ import rootReducer from '../boot/reducers';
2119
import { EVENT } from '../actionConstants';
2220
import * as eg from './lib/exampleData';
2321
import { EventTypes } from '../api/eventTypes';
24-
import { objectEntries } from '../flowPonyfill';
2522

2623
describe('roleIsAtLeast', () => {
2724
const { Owner, Admin, Moderator, Member, Guest } = Role;
2825

26+
const roleValues: $ReadOnlyArray<Role> = Array.from(Role.members());
27+
2928
// Keep this current with all possible roles, from least to most privilege.
3029
const kRolesAscending = [Guest, Member, Moderator, Admin, Owner];
31-
expect(RoleValues).toIncludeSameMembers(kRolesAscending);
32-
expect(RoleValues).toBeArrayOfSize(kRolesAscending.length);
30+
expect(roleValues).toIncludeSameMembers(kRolesAscending);
31+
expect(roleValues).toBeArrayOfSize(kRolesAscending.length);
3332

34-
objectEntries(Role).forEach(([thresholdRoleName, thresholdRole]) => {
35-
objectEntries(Role).forEach(([thisRoleName, thisRole]) => {
33+
const roleEntries = roleValues.map(role => [Role.getName(role), role]);
34+
roleEntries.forEach(([thresholdRoleName, thresholdRole]) => {
35+
roleEntries.forEach(([thisRoleName, thisRole]) => {
3636
const expected = kRolesAscending.indexOf(thisRole) >= kRolesAscending.indexOf(thresholdRole);
3737

3838
const testName = expected
@@ -86,7 +86,7 @@ describe('getCanCreatePublicStreams', () => {
8686
expected,
8787
}: {
8888
policy: CreatePublicOrPrivateStreamPolicyT,
89-
role: RoleT,
89+
role: Role,
9090
waitingPeriodPassed: boolean | void,
9191
expected: boolean,
9292
}) => {
@@ -166,7 +166,7 @@ describe('getCanCreatePrivateStreams', () => {
166166
expected,
167167
}: {
168168
policy: CreatePublicOrPrivateStreamPolicyT,
169-
role: RoleT,
169+
role: Role,
170170
waitingPeriodPassed: boolean | void,
171171
expected: boolean,
172172
}) => {
@@ -301,7 +301,7 @@ describe('getCanCreateWebPublicStreams', () => {
301301
expected,
302302
}: {
303303
policy: CreateWebPublicStreamPolicy,
304-
role: RoleT,
304+
role: Role,
305305
expected: boolean,
306306
}) => {
307307
const globalState = [

src/action-sheets/index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ import { getUnreadCountForTopic } from '../unread/unreadModel';
4040
import getIsNotificationEnabled from '../streams/getIsNotificationEnabled';
4141
import { getStreamTopicUrl, getStreamUrl } from '../utils/internalLinks';
4242
import { reactionTypeFromEmojiType } from '../emoji/data';
43-
import { Role, type RoleT } from '../api/permissionsTypes';
43+
import { Role } from '../api/permissionsTypes';
4444
import { roleIsAtLeast } from '../permissionSelectors';
4545
import { kNotificationBotEmail } from '../api/constants';
4646
import type { AppNavigationMethods } from '../nav/AppNavigator';
@@ -616,7 +616,7 @@ export const constructStreamActionButtons = (args: {|
616616
export const constructTopicActionButtons = (args: {|
617617
backgroundData: $ReadOnly<{
618618
mute: MuteState,
619-
ownUserRole: RoleT,
619+
ownUserRole: Role,
620620
subscriptions: Map<number, Subscription>,
621621
unread: UnreadState,
622622
...
@@ -853,7 +853,7 @@ export const showTopicActionSheet = (args: {|
853853
subscriptions: Map<number, Subscription>,
854854
unread: UnreadState,
855855
ownUser: User,
856-
ownUserRole: RoleT,
856+
ownUserRole: Role,
857857
zulipFeatureLevel: number,
858858
...
859859
}>,

src/api/modelTypes.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { typesEquivalent } from '../generics';
88
import { objectValues } from '../flowPonyfill';
99
import type { AvatarURL } from '../utils/avatar';
1010
import type { UserId } from './idTypes';
11-
import type { RoleT } from './permissionsTypes';
11+
import type { Role } from './permissionsTypes';
1212

1313
export type * from './idTypes';
1414

@@ -312,7 +312,7 @@ export type User = {|
312312
+bot_owner?: string,
313313

314314
// TODO(server-4.0): New in FL 59
315-
+role?: RoleT,
315+
+role?: Role,
316316

317317
// The ? is for future-proofing. Greg explains in 2020-02, at
318318
// https://github.com/zulip/zulip-mobile/pull/3789#discussion_r378554698 ,
@@ -400,7 +400,7 @@ export type CrossRealmBot = {|
400400
// +bot_owner?: string,
401401

402402
// TODO(server-4.0): New in FL 59
403-
+role?: RoleT,
403+
+role?: Role,
404404

405405
// The ? is for future-proofing. For bots it's always '':
406406
// https://github.com/zulip/zulip-mobile/pull/3789#issuecomment-581218576

src/api/permissionsTypes.js

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,40 +5,17 @@ import { objectValues } from '../flowPonyfill';
55

66
/**
77
* Organization-level role of a user.
8-
*/
9-
// Ideally both the type and enum would have the simple name; but a type
10-
// and value sharing a name is one nice TS feature that Flow lacks.
11-
// Or we could leapfrog TS and make this a Flow enum:
12-
// https://flow.org/en/docs/enums/
13-
// (TS has its own enums, but they are a mess.)
14-
// eslint-disable-next-line ft-flow/type-id-match
15-
export type RoleT = 100 | 200 | 300 | 400 | 600;
16-
17-
/**
18-
* An enum of all valid values for `RoleT`.
198
*
209
* Described in the server API doc, e.g., at `.role` in `realm_users` at
2110
* https://zulip.com/api/register-queue
22-
*
23-
* See RoleValues for the list of values.
2411
*/
25-
export const Role = {
26-
Owner: (100: 100),
27-
Admin: (200: 200),
28-
Moderator: (300: 300),
29-
Member: (400: 400),
30-
Guest: (600: 600),
31-
};
32-
33-
// Check that the enum indeed has all and exactly the values of the type.
34-
typesEquivalent<RoleT, $Values<typeof Role>>();
35-
36-
/**
37-
* A list of all valid values for `RoleT`.
38-
*
39-
* See Role for an enum to refer to these by meaningful names.
40-
*/
41-
export const RoleValues: $ReadOnlyArray<RoleT> = objectValues(Role);
12+
export enum Role {
13+
Owner = 100,
14+
Admin = 200,
15+
Moderator = 300,
16+
Member = 400,
17+
Guest = 600,
18+
}
4219

4320
/**
4421
* This organization's policy for which users can create public streams, or

src/permissionSelectors.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* @flow strict-local */
22
import type { PerAccountState, UserId } from './types';
33
import { ensureUnreachable } from './types';
4-
import { Role, type RoleT, CreateWebPublicStreamPolicy } from './api/permissionsTypes';
4+
import { Role, CreateWebPublicStreamPolicy } from './api/permissionsTypes';
55
import { getRealm, getOwnUser, getUserForId } from './selectors';
66

77
const { Guest, Member, Moderator, Admin, Owner } = Role;
@@ -13,7 +13,7 @@ const { Guest, Member, Moderator, Admin, Owner } = Role;
1313
* when the role changes while we're polling an event queue.
1414
*/
1515
// TODO(server-4.0): Probably just delete this and use User.role directly?
16-
export function getOwnUserRole(state: PerAccountState): RoleT {
16+
export function getOwnUserRole(state: PerAccountState): Role {
1717
const fromUserObject = getOwnUser(state).role;
1818

1919
if (fromUserObject !== undefined) {
@@ -38,8 +38,8 @@ export function getOwnUserRole(state: PerAccountState): RoleT {
3838
}
3939
}
4040

41-
export function roleIsAtLeast(thisRole: RoleT, thresholdRole: RoleT): boolean {
42-
return thisRole <= thresholdRole; // Roles with more privilege have lower numbers.
41+
export function roleIsAtLeast(thisRole: Role, thresholdRole: Role): boolean {
42+
return (thisRole: number) <= (thresholdRole: number); // Roles with more privilege have lower numbers.
4343
}
4444

4545
/**

src/users/__tests__/usersReducer-test.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { UploadedAvatarURL } from '../../utils/avatar';
66
import { EVENT_USER_ADD, EVENT } from '../../actionConstants';
77
import { EventTypes, type RealmUserUpdateEvent } from '../../api/eventTypes';
88
import type { User } from '../../types';
9-
import { RoleValues } from '../../api/permissionsTypes';
9+
import { Role } from '../../api/permissionsTypes';
1010
import usersReducer from '../usersReducer';
1111
import { randString } from '../../utils/misc';
1212

@@ -115,7 +115,8 @@ describe('usersReducer', () => {
115115
});
116116

117117
test('When the role of a user changes.', () => {
118-
check({ role: RoleValues[(RoleValues.indexOf(theUser.role) + 1) % RoleValues.length] });
118+
const roleValues = Array.from(Role.members());
119+
check({ role: roleValues[(roleValues.indexOf(theUser.role) + 1) % roleValues.length] });
119120
});
120121

121122
test("When a user's billing-admin status changes", () => {

src/webview/backgroundData.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import { getMute } from '../mute/muteModel';
3434
import { getUnread } from '../unread/unreadModel';
3535
import { getUserStatuses } from '../user-statuses/userStatusesModel';
3636
import { type UserStatusesState } from '../user-statuses/userStatusesCore';
37-
import { type RoleT } from '../api/permissionsTypes';
37+
import { Role } from '../api/permissionsTypes';
3838
import { getOwnUserRole } from '../permissionSelectors';
3939
import type { ServerEmojiData } from '../api/modelTypes';
4040

@@ -58,7 +58,7 @@ export type BackgroundData = $ReadOnly<{|
5858
allUsersById: Map<UserId, UserOrBot>,
5959
mutedUsers: MutedUsersState,
6060
ownUser: User,
61-
ownUserRole: RoleT,
61+
ownUserRole: Role,
6262
streams: Map<number, Stream>,
6363
subscriptions: Map<number, Subscription>,
6464
unread: UnreadState,

0 commit comments

Comments
 (0)