diff --git a/tests/e2e/management/management_client.py b/tests/e2e/management/management_client.py index d5147682018..2a686b596c0 100644 --- a/tests/e2e/management/management_client.py +++ b/tests/e2e/management/management_client.py @@ -35,6 +35,7 @@ from models import ( TeamDeleteBody, TeamInfoParams, TeamInfoResponse, + TeamListResponse, TeamMemberAddBody, TeamMemberDeleteBody, TeamMemberEntry, @@ -155,6 +156,19 @@ class ManagementClient: ) ).team_info + def team_list_ids(self) -> tuple[str, ...]: + return tuple( + entry.team_id + for entry in unwrap( + self.proxy.transport.get( + "/team/list", + headers=self.proxy.transport.master, + params=NoBody(), + response_type=TeamListResponse, + ) + ).root + ) + def team_info_status(self, team_id: str) -> ProbeResult: return self.proxy.transport.probe("/team/info", params=TeamInfoParams(team_id=team_id)) diff --git a/tests/e2e/management/test_management_e2e.py b/tests/e2e/management/test_management_e2e.py index 09a89862c5a..9cc46779296 100644 --- a/tests/e2e/management/test_management_e2e.py +++ b/tests/e2e/management/test_management_e2e.py @@ -227,6 +227,19 @@ class TestTeamRoutes: f"key generated under team {team_id} carries team_id {key_info.team_id!r} in /key/info" ) + @pytest.mark.covers("mgmt.team.list.happy_path") + def test_created_team_appears_in_team_list( + self, client: ManagementClient, resources: ResourceManager + ) -> None: + alias = f"e2e-mgmt-team-{unique_marker()}" + team_id = _create_team(client, resources, alias, ["gemini-2.5-flash"]) + + _ = _poll( + client, + lambda: team_id if team_id in client.team_list_ids() else None, + f"/team/list never included the created team {team_id}", + ) + @pytest.mark.covers("mgmt.team.member_add.persists") def test_member_add_and_delete_persist_to_team_info( self, client: ManagementClient, resources: ResourceManager diff --git a/tests/e2e/models.py b/tests/e2e/models.py index a03a5308168..36765610545 100644 --- a/tests/e2e/models.py +++ b/tests/e2e/models.py @@ -654,6 +654,15 @@ class TeamDeleteBody(BaseModel): team_ids: list[str] +class TeamListEntry(BaseModel): + team_id: str + + +class TeamListResponse(RootModel[list[TeamListEntry]]): + """GET /team/list answers with a bare array of team objects (not an object + wrapping them). Only team_id is read; pydantic ignores the rest.""" + + UserRole = Literal["proxy_admin", "proxy_admin_viewer", "internal_user", "internal_user_viewer"]