mirror of
https://github.com/zulip/zulip.git
synced 2025-11-06 15:03:34 +00:00
user_groups: Add get_recursive_group_members.
This function goes through all subgroups recursively and returns the resultant set of the members of those subgroups in addition to the members of our target_group. This function is required in order to add the `everyone` pill to create channel flow. For the tests written in this commit, it uses the same pattern as the `get_recursive_subgroups` test. `is_user_in_group` could have been technically refactored to use `get_recursive_group_members`, but since the former returns early for direct members, I've let it be for now.
This commit is contained in:
committed by
Tim Abbott
parent
c7e59ed761
commit
9f7dc596f8
@@ -1,3 +1,4 @@
|
||||
import assert from "minimalistic-assert";
|
||||
import type {z} from "zod";
|
||||
|
||||
import * as blueslip from "./blueslip";
|
||||
@@ -204,6 +205,24 @@ export function get_recursive_subgroups(target_user_group: UserGroup): Set<numbe
|
||||
return subgroup_ids;
|
||||
}
|
||||
|
||||
export function get_recursive_group_members(target_user_group: UserGroup): Set<number> {
|
||||
const members = new Set(target_user_group.members);
|
||||
const subgroup_ids = get_recursive_subgroups(target_user_group);
|
||||
|
||||
if (subgroup_ids === undefined) {
|
||||
return members;
|
||||
}
|
||||
|
||||
for (const subgroup_id of subgroup_ids) {
|
||||
const subgroup = user_group_by_id_dict.get(subgroup_id);
|
||||
assert(subgroup !== undefined);
|
||||
for (const member of subgroup.members) {
|
||||
members.add(member);
|
||||
}
|
||||
}
|
||||
return members;
|
||||
}
|
||||
|
||||
export function is_user_in_group(user_group_id: number, user_id: number): boolean {
|
||||
const user_group = user_group_by_id_dict.get(user_group_id);
|
||||
if (user_group === undefined) {
|
||||
|
||||
@@ -190,6 +190,66 @@ run_test("get_recursive_subgroups", () => {
|
||||
assert.deepEqual(user_groups.get_recursive_subgroups(test), undefined);
|
||||
});
|
||||
|
||||
run_test("get_recursive_group_members", () => {
|
||||
const admins = {
|
||||
name: "Admins",
|
||||
description: "foo",
|
||||
id: 1,
|
||||
members: new Set([1]),
|
||||
is_system_group: false,
|
||||
direct_subgroup_ids: new Set([4]),
|
||||
};
|
||||
const all = {
|
||||
name: "Everyone",
|
||||
id: 2,
|
||||
members: new Set([2, 3]),
|
||||
is_system_group: false,
|
||||
direct_subgroup_ids: new Set([1, 3]),
|
||||
};
|
||||
const test = {
|
||||
name: "Test",
|
||||
id: 3,
|
||||
members: new Set([3, 4, 5]),
|
||||
is_system_group: false,
|
||||
direct_subgroup_ids: new Set([2]),
|
||||
};
|
||||
const foo = {
|
||||
name: "Foo",
|
||||
id: 4,
|
||||
members: new Set([6, 7]),
|
||||
is_system_group: false,
|
||||
direct_subgroup_ids: new Set([]),
|
||||
};
|
||||
|
||||
user_groups.add(admins);
|
||||
user_groups.add(all);
|
||||
user_groups.add(test);
|
||||
user_groups.add(foo);
|
||||
|
||||
// This test setup has a state that won't appear in real data: Groups 2 and 3
|
||||
// each contain the other. We test this corner case because it is a simple way
|
||||
// to verify whether our algorithm correctly avoids visiting groups multiple times
|
||||
// when determining recursive subgroups.
|
||||
// A test case that can occur in practice and would be problematic without this
|
||||
// optimization is a tree where each layer connects to every node in the next layer.
|
||||
assert.deepEqual([...user_groups.get_recursive_group_members(admins)].sort(), [1, 6, 7]);
|
||||
assert.deepEqual(
|
||||
[...user_groups.get_recursive_group_members(all)].sort(),
|
||||
[1, 2, 3, 4, 5, 6, 7],
|
||||
);
|
||||
assert.deepEqual(
|
||||
[...user_groups.get_recursive_group_members(test)].sort(),
|
||||
[1, 2, 3, 4, 5, 6, 7],
|
||||
);
|
||||
assert.deepEqual([...user_groups.get_recursive_group_members(foo)].sort(), [6, 7]);
|
||||
|
||||
user_groups.add_subgroups(foo.id, [9999]);
|
||||
const foo_group = user_groups.get_user_group_from_id(foo.id);
|
||||
blueslip.expect("error", "Could not find subgroup", 2);
|
||||
assert.deepEqual([...user_groups.get_recursive_group_members(foo_group)].sort(), [6, 7]);
|
||||
assert.deepEqual([...user_groups.get_recursive_group_members(test)].sort(), [3, 4, 5]);
|
||||
});
|
||||
|
||||
run_test("is_user_in_group", () => {
|
||||
const admins = {
|
||||
name: "Admins",
|
||||
|
||||
Reference in New Issue
Block a user