diff --git a/CHANGELOG.md b/CHANGELOG.md index cee21a54..68569af4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Fixed + +- Fix team search when filtering resources by @vadimkerr ([#1680](https://github.com/grafana/oncall/pull/1680)) + ## v1.2.6 (2023-03-30) ### Fixed diff --git a/engine/apps/api/tests/test_team.py b/engine/apps/api/tests/test_team.py index 1eb8be04..2f2259cb 100644 --- a/engine/apps/api/tests/test_team.py +++ b/engine/apps/api/tests/test_team.py @@ -45,6 +45,49 @@ def test_list_teams( assert response.json() == expected_payload +@pytest.mark.django_db +@pytest.mark.parametrize( + "search,team_names", + [ + ("", [GENERAL_TEAM.name, "team 1", "team 2"]), + ("team", [GENERAL_TEAM.name, "team 1", "team 2"]), + ("no team", [GENERAL_TEAM.name]), + ("team ", [GENERAL_TEAM.name, "team 1", "team 2"]), + ("team 1", [GENERAL_TEAM.name, "team 1"]), + ], +) +def test_list_teams_search_by_name( + make_organization, + make_team, + make_user_for_organization, + make_token_for_organization, + make_user_auth_headers, + search, + team_names, +): + organization = make_organization() + user = make_user_for_organization(organization) + _, token = make_token_for_organization(organization) + + for team_name in team_names: + if team_name != GENERAL_TEAM.name: + make_team(organization, name=team_name) + + client = APIClient() + + url = reverse("api-internal:team-list") + f"?search={search}" + response = client.get(url, format="json", **make_user_auth_headers(user, token)) + assert response.status_code == status.HTTP_200_OK + + expected_json = [ + get_payload_from_team(organization.teams.get(name=team_name)) + if team_name != GENERAL_TEAM.name + else get_payload_from_team(GENERAL_TEAM) + for team_name in team_names + ] + assert response.json() == expected_json + + @pytest.mark.django_db def test_list_teams_for_non_member( make_organization, diff --git a/engine/apps/api/views/team.py b/engine/apps/api/views/team.py index a7395483..3cfb827a 100644 --- a/engine/apps/api/views/team.py +++ b/engine/apps/api/views/team.py @@ -1,6 +1,6 @@ from rest_framework import mixins, viewsets +from rest_framework.filters import SearchFilter from rest_framework.permissions import IsAuthenticated -from rest_framework.response import Response from apps.api.permissions import RBACPermission from apps.api.serializers.team import TeamSerializer @@ -23,17 +23,15 @@ class TeamViewSet(PublicPrimaryKeyMixin, mixins.ListModelMixin, mixins.UpdateMod } serializer_class = TeamSerializer + filter_backends = [SearchFilter] + search_fields = ["name"] def get_queryset(self): return self.request.user.available_teams - def list(self, request, *args, **kwargs): - queryset = self.filter_queryset(self.get_queryset()) + def filter_queryset(self, queryset): + """ + Adds general team to the queryset in a way that it always shows up first (even when not searched for). + """ general_team = Team(public_primary_key="null", name="No team", email=None, avatar_url=None) - - page = self.paginate_queryset(queryset) - if page is not None: - serializer = self.get_serializer([general_team] + list(page), many=True) - return self.get_paginated_response(serializer.data) - serializer = self.get_serializer([general_team] + list(queryset), many=True) - return Response(serializer.data) + return [general_team] + list(super().filter_queryset(queryset))