Skip to content

Commit f0cd0d5

Browse files
committed
user-groups: Remove deactivated users from groups
As newly required to support Zulip Server 10+; see #5899. Fixes: #5899
1 parent c63407f commit f0cd0d5

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed

src/user-groups/__tests__/userGroupsReducer-test.js

+42
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* @flow strict-local */
22

33
import deepFreeze from 'deep-freeze';
4+
import invariant from 'invariant';
45

56
import * as eg from '../../__tests__/lib/exampleData';
67
import {
@@ -11,6 +12,7 @@ import {
1112
EVENT_USER_GROUP_REMOVE_MEMBERS,
1213
} from '../../actionConstants';
1314
import userGroupsReducer from '../userGroupsReducer';
15+
import eventToAction from '../../events/eventToAction';
1416

1517
describe('userGroupsReducer', () => {
1618
describe('REGISTER_COMPLETE', () => {
@@ -192,4 +194,44 @@ describe('userGroupsReducer', () => {
192194
).toEqual([{ ...group1, members: [user1.user_id, user4.user_id] }, group2]);
193195
});
194196
});
197+
198+
describe('realm_user op: update', () => {
199+
test('a user is deactivated', () => {
200+
const user1 = eg.makeUser();
201+
const user2 = eg.makeUser();
202+
const user3 = eg.makeUser();
203+
204+
const group1 = eg.makeUserGroup({ members: [user1.user_id, user2.user_id, user3.user_id] });
205+
const group2 = eg.makeUserGroup({ members: [user2.user_id, user1.user_id] });
206+
const group3 = eg.makeUserGroup({ members: [user1.user_id] });
207+
208+
const event = {
209+
id: 0,
210+
type: 'realm_user',
211+
op: 'update',
212+
person: { user_id: user1.user_id, is_active: false },
213+
};
214+
215+
const prevUserGroupsState = deepFreeze([group1, group2, group3]);
216+
const prevPerAccountState = eg.reduxStatePlus({
217+
users: [user1, user2, user3],
218+
userGroups: prevUserGroupsState,
219+
});
220+
const action = eventToAction(prevPerAccountState, event);
221+
222+
expect(action).not.toBeNull();
223+
invariant(action != null, 'action not null');
224+
225+
const actualState = userGroupsReducer(prevUserGroupsState, action);
226+
227+
expect(actualState).toEqual([
228+
{ ...group1, members: [user2.user_id, user3.user_id] },
229+
{ ...group2, members: [user2.user_id] },
230+
231+
// A newly-empty group is not pruned; when a group is deactivated,
232+
// we expect a user_group/remove event.
233+
{ ...group3, members: [] },
234+
]);
235+
});
236+
});
195237
});

src/user-groups/userGroupsReducer.js

+29
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@
22
import type { UserGroupsState, PerAccountApplicableAction } from '../types';
33
import {
44
REGISTER_COMPLETE,
5+
EVENT,
56
EVENT_USER_GROUP_ADD,
67
EVENT_USER_GROUP_REMOVE,
78
EVENT_USER_GROUP_UPDATE,
89
EVENT_USER_GROUP_ADD_MEMBERS,
910
EVENT_USER_GROUP_REMOVE_MEMBERS,
1011
RESET_ACCOUNT_DATA,
1112
} from '../actionConstants';
13+
import { EventTypes } from '../api/eventTypes';
1214
import { NULL_ARRAY } from '../nullObjects';
1315

1416
const initialState: UserGroupsState = NULL_ARRAY;
@@ -69,6 +71,33 @@ export default (
6971
case EVENT_USER_GROUP_REMOVE_MEMBERS:
7072
return eventUserGroupRemoveMembers(state, action);
7173

74+
case EVENT: {
75+
const { event } = action;
76+
switch (event.type) {
77+
case EventTypes.realm_user: {
78+
switch (event.op) {
79+
case 'update': {
80+
const { person } = event;
81+
if (person.is_active === false) {
82+
return state.map(g => ({
83+
...g,
84+
members: g.members.filter(m => m !== person.user_id),
85+
}));
86+
}
87+
88+
return state;
89+
}
90+
91+
default:
92+
return state;
93+
}
94+
}
95+
96+
default:
97+
return state;
98+
}
99+
}
100+
72101
default:
73102
return state;
74103
}

0 commit comments

Comments
 (0)