mirror of
				https://github.com/zulip/zulip.git
				synced 2025-10-31 03:53:50 +00:00 
			
		
		
		
	groups: Allow excluding deactivated groups in 'GET /user_groups' response.
This commit is contained in:
		| @@ -29,6 +29,8 @@ format used by the Zulip server that they are interacting with. | ||||
|   the user group objects to identify deactivated user groups. | ||||
| * [`GET /events`](/api/get-events): When a user group is deactivated, | ||||
|   a `user_group` event with `op=update` is sent to clients. | ||||
| * [`GET /user_groups`](/api/get-user-groups): Added support for | ||||
|   excluding deactivated user groups from the response. | ||||
|  | ||||
| **Feature level 289** | ||||
|  | ||||
|   | ||||
| @@ -34,7 +34,7 @@ DESKTOP_WARNING_VERSION = "5.9.3" | ||||
| # new level means in api_docs/changelog.md, as well as "**Changes**" | ||||
| # entries in the endpoint's documentation in `zulip.yaml`. | ||||
|  | ||||
| API_FEATURE_LEVEL = 289  # return ID as key while subscribing to a stream. | ||||
| API_FEATURE_LEVEL = 290  # Last bumped for UserGroup.deactivated | ||||
|  | ||||
| # Bump the minor PROVISION_VERSION to indicate that folks should provision | ||||
| # only when going from an old version of the code to a newer version. Bump | ||||
|   | ||||
| @@ -513,7 +513,7 @@ def fetch_initial_state_data( | ||||
|         state["realm_playgrounds"] = get_realm_playgrounds(realm) | ||||
|  | ||||
|     if want("realm_user_groups"): | ||||
|         state["realm_user_groups"] = user_groups_in_realm_serialized(realm) | ||||
|         state["realm_user_groups"] = user_groups_in_realm_serialized(realm, allow_deactivated=True) | ||||
|  | ||||
|     if user_profile is not None: | ||||
|         settings_user = user_profile | ||||
|   | ||||
| @@ -472,7 +472,9 @@ def get_setting_value_for_user_group_object( | ||||
|     ) | ||||
|  | ||||
|  | ||||
| def user_groups_in_realm_serialized(realm: Realm) -> list[UserGroupDict]: | ||||
| def user_groups_in_realm_serialized( | ||||
|     realm: Realm, *, allow_deactivated: bool | ||||
| ) -> list[UserGroupDict]: | ||||
|     """This function is used in do_events_register code path so this code | ||||
|     should be performant.  We need to do 2 database queries because | ||||
|     Django's ORM doesn't properly support the left join between | ||||
| @@ -485,6 +487,9 @@ def user_groups_in_realm_serialized(realm: Realm) -> list[UserGroupDict]: | ||||
|         "can_mention_group__named_user_group", | ||||
|     ).filter(realm=realm) | ||||
|  | ||||
|     if not allow_deactivated: | ||||
|         realm_groups = realm_groups.filter(deactivated=False) | ||||
|  | ||||
|     membership = UserGroupMembership.objects.filter(user_group__realm=realm).values_list( | ||||
|         "user_group_id", "user_profile_id" | ||||
|     ) | ||||
|   | ||||
| @@ -19967,6 +19967,26 @@ paths: | ||||
|             **Note**: This endpoint is only available to [members and | ||||
|             administrators](/help/roles-and-permissions); bots and guests | ||||
|             cannot use this endpoint. | ||||
|       requestBody: | ||||
|         required: false | ||||
|         content: | ||||
|           application/x-www-form-urlencoded: | ||||
|             schema: | ||||
|               type: object | ||||
|               properties: | ||||
|                 allow_deactivated: | ||||
|                   description: | | ||||
|                     Whether to include deactivated user groups in the response. | ||||
| 
 | ||||
|                     **Changes**: New in Zulip 10.0 (feature level 290). Previously, | ||||
|                     deactivated user groups did not exist and thus would never be | ||||
|                     included in the response. | ||||
|                   type: boolean | ||||
|                   example: true | ||||
|                   default: false | ||||
|             encoding: | ||||
|               allow_deactivated: | ||||
|                 contentType: application/json | ||||
|       responses: | ||||
|         "200": | ||||
|           description: Success. | ||||
|   | ||||
| @@ -84,7 +84,7 @@ class UserGroupTestCase(ZulipTestCase): | ||||
|         assert user_group is not None | ||||
|         empty_user_group = check_add_user_group(realm, "newgroup", [], acting_user=None) | ||||
|  | ||||
|         user_groups = user_groups_in_realm_serialized(realm) | ||||
|         user_groups = user_groups_in_realm_serialized(realm, allow_deactivated=False) | ||||
|         self.assert_length(user_groups, 10) | ||||
|         self.assertEqual(user_groups[0]["id"], user_group.id) | ||||
|         self.assertEqual(user_groups[0]["name"], SystemGroups.NOBODY) | ||||
| @@ -141,7 +141,7 @@ class UserGroupTestCase(ZulipTestCase): | ||||
|             }, | ||||
|             acting_user=None, | ||||
|         ) | ||||
|         user_groups = user_groups_in_realm_serialized(realm) | ||||
|         user_groups = user_groups_in_realm_serialized(realm, allow_deactivated=False) | ||||
|         self.assertEqual(user_groups[10]["id"], new_user_group.id) | ||||
|         self.assertEqual(user_groups[10]["name"], "newgroup2") | ||||
|         self.assertEqual(user_groups[10]["description"], "") | ||||
| @@ -162,10 +162,33 @@ class UserGroupTestCase(ZulipTestCase): | ||||
|         ) | ||||
|         self.assertFalse(user_groups[0]["deactivated"]) | ||||
|  | ||||
|         do_deactivate_user_group(new_user_group, acting_user=None) | ||||
|         user_groups = user_groups_in_realm_serialized(realm) | ||||
|         another_new_group = check_add_user_group( | ||||
|             realm, "newgroup3", [self.example_user("hamlet")], acting_user=None | ||||
|         ) | ||||
|         add_subgroups_to_user_group( | ||||
|             new_user_group, [another_new_group, owners_system_group], acting_user=None | ||||
|         ) | ||||
|         do_deactivate_user_group(another_new_group, acting_user=None) | ||||
|         user_groups = user_groups_in_realm_serialized(realm, allow_deactivated=True) | ||||
|         self.assert_length(user_groups, 12) | ||||
|         self.assertEqual(user_groups[10]["id"], new_user_group.id) | ||||
|         self.assertTrue(user_groups[10]["deactivated"]) | ||||
|         self.assertEqual(user_groups[10]["name"], "newgroup2") | ||||
|         self.assertFalse(user_groups[10]["deactivated"]) | ||||
|         self.assertCountEqual( | ||||
|             user_groups[10]["direct_subgroup_ids"], [another_new_group.id, owners_system_group.id] | ||||
|         ) | ||||
|         self.assertEqual(user_groups[11]["id"], another_new_group.id) | ||||
|         self.assertEqual(user_groups[11]["name"], "newgroup3") | ||||
|         self.assertTrue(user_groups[11]["deactivated"]) | ||||
|  | ||||
|         user_groups = user_groups_in_realm_serialized(realm, allow_deactivated=False) | ||||
|         self.assert_length(user_groups, 11) | ||||
|         self.assertEqual(user_groups[10]["id"], new_user_group.id) | ||||
|         self.assertEqual(user_groups[10]["name"], "newgroup2") | ||||
|         self.assertFalse(user_groups[10]["deactivated"]) | ||||
|         self.assertCountEqual( | ||||
|             user_groups[10]["direct_subgroup_ids"], [another_new_group.id, owners_system_group.id] | ||||
|         ) | ||||
|  | ||||
|     def test_get_direct_user_groups(self) -> None: | ||||
|         othello = self.example_user("othello") | ||||
|   | ||||
| @@ -22,7 +22,7 @@ from zerver.decorator import require_member_or_admin, require_user_group_create_ | ||||
| from zerver.lib.exceptions import JsonableError | ||||
| from zerver.lib.mention import MentionBackend, silent_mention_syntax_for_user | ||||
| from zerver.lib.response import json_success | ||||
| from zerver.lib.typed_endpoint import PathOnly, typed_endpoint, typed_endpoint_without_parameters | ||||
| from zerver.lib.typed_endpoint import PathOnly, typed_endpoint | ||||
| from zerver.lib.user_groups import ( | ||||
|     AnonymousSettingGroupDict, | ||||
|     GroupSettingChangeRequest, | ||||
| @@ -93,9 +93,16 @@ def add_user_group( | ||||
|  | ||||
|  | ||||
| @require_member_or_admin | ||||
| @typed_endpoint_without_parameters | ||||
| def get_user_group(request: HttpRequest, user_profile: UserProfile) -> HttpResponse: | ||||
|     user_groups = user_groups_in_realm_serialized(user_profile.realm) | ||||
| @typed_endpoint | ||||
| def get_user_group( | ||||
|     request: HttpRequest, | ||||
|     user_profile: UserProfile, | ||||
|     *, | ||||
|     allow_deactivated: Json[bool] = False, | ||||
| ) -> HttpResponse: | ||||
|     user_groups = user_groups_in_realm_serialized( | ||||
|         user_profile.realm, allow_deactivated=allow_deactivated | ||||
|     ) | ||||
|     return json_success(request, data={"user_groups": user_groups}) | ||||
|  | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user