mirror of https://github.com/zulip/zulip.git
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:
parent
f9ae386050
commit
da0b087962
|
@ -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],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -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`
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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),
|
||||||
]
|
]
|
||||||
|
|
|
@ -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"])
|
||||||
|
|
||||||
|
|
|
@ -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: |
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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")
|
||||||
|
|
Loading…
Reference in New Issue