user_groups: Add "subgroups" field to user group objects.

This commit also adds 'subgroups' field to the user_group present
in the event sent on creating a user group. We do not allow passing
the subgroups while creating a user group as of this commit, but added
the field in the event object to pass tests.
This commit is contained in:
Sahil Batra 2022-02-28 16:20:33 +05:30 committed by Tim Abbott
parent f9ae386050
commit da0b087962
9 changed files with 52 additions and 6 deletions

View File

@ -721,6 +721,7 @@ exports.fixtures = {
description: "mobile folks", description: "mobile folks",
members: [1], members: [1],
is_system_group: false, is_system_group: false,
subgroups: [2],
}, },
}, },

View File

@ -20,6 +20,13 @@ format used by the Zulip server that they are interacting with.
## Changes in Zulip 6.0 ## Changes in Zulip 6.0
**Feature level 127**
* [`GET /user_groups`](/api/get-user-groups),[`POST
/register`](/api/register-queue): Added `subgroups` field,
which is a list of IDs of all the subgroups of the user group, to
user group objects.
**Feature level 126** **Feature level 126**
* `POST /invites`, `POST /invites/multiuse`: Replaced `invite_expires_in_days` * `POST /invites`, `POST /invites/multiuse`: Replaced `invite_expires_in_days`

View File

@ -81,7 +81,9 @@ def promote_new_full_members() -> None:
update_users_in_full_members_system_group(realm) update_users_in_full_members_system_group(realm)
def do_send_create_user_group_event(user_group: UserGroup, members: List[UserProfile]) -> None: def do_send_create_user_group_event(
user_group: UserGroup, members: List[UserProfile], subgroups: Sequence[UserGroup] = []
) -> None:
event = dict( event = dict(
type="user_group", type="user_group",
op="add", op="add",
@ -91,6 +93,7 @@ def do_send_create_user_group_event(user_group: UserGroup, members: List[UserPro
description=user_group.description, description=user_group.description,
id=user_group.id, id=user_group.id,
is_system_group=user_group.is_system_group, is_system_group=user_group.is_system_group,
subgroups=[subgroup.id for subgroup in subgroups],
), ),
) )
send_event(user_group.realm, event, active_user_ids(user_group.realm_id)) send_event(user_group.realm, event, active_user_ids(user_group.realm_id))

View File

@ -1676,6 +1676,7 @@ group_type = DictType(
("id", int), ("id", int),
("name", str), ("name", str),
("members", ListType(int)), ("members", ListType(int)),
("subgroups", ListType(int)),
("description", str), ("description", str),
("is_system_group", bool), ("is_system_group", bool),
] ]

View File

@ -40,6 +40,7 @@ def user_groups_in_realm_serialized(realm: Realm) -> List[Dict[str, Any]]:
name=user_group.name, name=user_group.name,
description=user_group.description, description=user_group.description,
members=[], members=[],
subgroups=[],
is_system_group=user_group.is_system_group, is_system_group=user_group.is_system_group,
) )
@ -48,8 +49,16 @@ def user_groups_in_realm_serialized(realm: Realm) -> List[Dict[str, Any]]:
) )
for (user_group_id, user_profile_id) in membership: for (user_group_id, user_profile_id) in membership:
group_dicts[user_group_id]["members"].append(user_profile_id) group_dicts[user_group_id]["members"].append(user_profile_id)
group_membership = GroupGroupMembership.objects.filter(subgroup__realm=realm).values_list(
"subgroup_id", "supergroup_id"
)
for (subgroup_id, supergroup_id) in group_membership:
group_dicts[supergroup_id]["subgroups"].append(subgroup_id)
for group_dict in group_dicts.values(): for group_dict in group_dicts.values():
group_dict["members"] = sorted(group_dict["members"]) group_dict["members"] = sorted(group_dict["members"])
group_dict["subgroups"] = sorted(group_dict["subgroups"])
return sorted(group_dicts.values(), key=lambda group_dict: group_dict["id"]) return sorted(group_dicts.values(), key=lambda group_dict: group_dict["id"])

View File

@ -13807,6 +13807,14 @@ paths:
The integer user IDs of the user group members. The integer user IDs of the user group members.
items: items:
type: integer type: integer
subgroups:
type: array
description: |
The integer user group IDs of the subgroups.
**Changes**: New in Zulip 6.0 (feature level 127).
items:
type: integer
name: name:
type: string type: string
description: | description: |
@ -13832,6 +13840,7 @@ paths:
"id": 1, "id": 1,
"name": "hamletcharacters", "name": "hamletcharacters",
"members": [3, 4], "members": [3, 4],
"subgroups": [],
"is_system_group": false, "is_system_group": false,
}, },
{ {
@ -13839,6 +13848,7 @@ paths:
"id": 2, "id": 2,
"name": "other users", "name": "other users",
"members": [1, 2], "members": [1, 2],
"subgroups": [1, 2],
"is_system_group": true, "is_system_group": true,
}, },
], ],
@ -14650,6 +14660,15 @@ components:
description: | description: |
Array containing the id of the users who are Array containing the id of the users who are
members of this user group. members of this user group.
subgroups:
type: array
items:
type: integer
description: |
Array containing the id of the subgroups of this
user group.
**Changes**: New in Zulip 6.0 (feature level 127).
id: id:
type: integer type: integer
description: | description: |

View File

@ -1004,7 +1004,7 @@ class FetchQueriesTest(ZulipTestCase):
with mock.patch("zerver.lib.events.always_want") as want_mock: with mock.patch("zerver.lib.events.always_want") as want_mock:
fetch_initial_state_data(user) fetch_initial_state_data(user)
self.assert_length(queries, 35) self.assert_length(queries, 36)
expected_counts = dict( expected_counts = dict(
alert_words=1, alert_words=1,
@ -1027,7 +1027,7 @@ class FetchQueriesTest(ZulipTestCase):
realm_linkifiers=1, realm_linkifiers=1,
realm_playgrounds=1, realm_playgrounds=1,
realm_user=3, realm_user=3,
realm_user_groups=2, realm_user_groups=3,
realm_user_settings_defaults=1, realm_user_settings_defaults=1,
recent_private_conversations=1, recent_private_conversations=1,
starred_messages=1, starred_messages=1,

View File

@ -247,7 +247,7 @@ class HomeTest(ZulipTestCase):
set(result["Cache-Control"].split(", ")), {"must-revalidate", "no-store", "no-cache"} set(result["Cache-Control"].split(", ")), {"must-revalidate", "no-store", "no-cache"}
) )
self.assert_length(queries, 44) self.assert_length(queries, 45)
self.assert_length(cache_mock.call_args_list, 5) self.assert_length(cache_mock.call_args_list, 5)
html = result.content.decode() html = result.content.decode()
@ -420,7 +420,7 @@ class HomeTest(ZulipTestCase):
result = self._get_home_page() result = self._get_home_page()
self.check_rendered_logged_in_app(result) self.check_rendered_logged_in_app(result)
self.assert_length(cache_mock.call_args_list, 6) self.assert_length(cache_mock.call_args_list, 6)
self.assert_length(queries, 41) self.assert_length(queries, 42)
def test_num_queries_with_streams(self) -> None: def test_num_queries_with_streams(self) -> None:
main_user = self.example_user("hamlet") main_user = self.example_user("hamlet")
@ -451,7 +451,7 @@ class HomeTest(ZulipTestCase):
with queries_captured() as queries2: with queries_captured() as queries2:
result = self._get_home_page() result = self._get_home_page()
self.assert_length(queries2, 39) self.assert_length(queries2, 40)
# Do a sanity check that our new streams were in the payload. # Do a sanity check that our new streams were in the payload.
html = result.content.decode() html = result.content.decode()

View File

@ -50,6 +50,12 @@ class UserGroupTestCase(ZulipTestCase):
self.assertEqual(user_groups[0]["name"], "@role:owners") self.assertEqual(user_groups[0]["name"], "@role:owners")
self.assertEqual(user_groups[0]["description"], "Owners of this organization") self.assertEqual(user_groups[0]["description"], "Owners of this organization")
self.assertEqual(set(user_groups[0]["members"]), set(membership)) self.assertEqual(set(user_groups[0]["members"]), set(membership))
self.assertEqual(user_groups[0]["subgroups"], [])
admins_system_group = UserGroup.objects.get(name="@role:administrators", realm=realm)
self.assertEqual(user_groups[1]["id"], admins_system_group.id)
# Check that owners system group is present in "subgroups"
self.assertEqual(user_groups[1]["subgroups"], [user_group.id])
self.assertEqual(user_groups[8]["id"], empty_user_group.id) self.assertEqual(user_groups[8]["id"], empty_user_group.id)
self.assertEqual(user_groups[8]["name"], "newgroup") self.assertEqual(user_groups[8]["name"], "newgroup")