From fdae18e14c52611305ca071de2048a6eb52d5b07 Mon Sep 17 00:00:00 2001 From: Dominik Vagner Date: Thu, 21 May 2026 15:27:34 +0200 Subject: [PATCH] RHINENG-25944: add search for the tags list endpoint Allow `/tags` to filter returned tags by matching the search term against tag namespace, key, and value. With this the `/tags` endpoint could be used in the frontend for tag filtering. --- docs/v3/openapi.json | 8 ++++++ manager/controllers/systemtags.go | 17 ++++++++---- manager/controllers/systemtags_test.go | 38 +++++++++++++++++++++++++- 3 files changed, 57 insertions(+), 6 deletions(-) diff --git a/docs/v3/openapi.json b/docs/v3/openapi.json index 0d22691a1..a838c8bb2 100644 --- a/docs/v3/openapi.json +++ b/docs/v3/openapi.json @@ -5656,6 +5656,14 @@ "type": "integer" } }, + { + "name": "search", + "in": "query", + "description": "Find matching text", + "schema": { + "type": "string" + } + }, { "name": "offset", "in": "query", diff --git a/manager/controllers/systemtags.go b/manager/controllers/systemtags.go index 5f02993d9..05fe05c7d 100644 --- a/manager/controllers/systemtags.go +++ b/manager/controllers/systemtags.go @@ -1,11 +1,12 @@ package controllers import ( - "app/base/database" - "app/base/utils" "errors" "net/http" + "app/base/database" + "app/base/utils" + "app/manager/middlewares" "github.com/gin-gonic/gin" @@ -48,6 +49,11 @@ var SystemTagsOpts = ListOpts{ }, StableSort: "tag", DefaultSort: "tag", + SearchFields: []string{ + "sq.tag->>'namespace'", + "sq.tag->>'key'", + "sq.tag->>'value'", + }, } // @Summary Show me systems tags applicable to this application @@ -55,9 +61,10 @@ var SystemTagsOpts = ListOpts{ // @ID listSystemTags // @Security RhIdentity // @Produce json -// @Param sort query string false "Sort field" Enums(tag, count) -// @Param limit query int fals "Limit for paging" -// @Param offset query int false "Offset for paging" +// @Param sort query string false "Sort field" Enums(tag, count) +// @Param limit query int false "Limit for paging" +// @Param search query string false "Find matching text" +// @Param offset query int false "Offset for paging" // @Success 200 {object} SystemTagsResponse // @Failure 400 {object} utils.ErrorResponse // @Failure 500 {object} utils.ErrorResponse diff --git a/manager/controllers/systemtags_test.go b/manager/controllers/systemtags_test.go index ec12e5b05..8ae8ba981 100644 --- a/manager/controllers/systemtags_test.go +++ b/manager/controllers/systemtags_test.go @@ -1,10 +1,11 @@ package controllers import ( - "app/base/core" "net/http" "testing" + "app/base/core" + "github.com/stretchr/testify/assert" ) @@ -76,3 +77,38 @@ func TestSystemTagsListBadRequestOnIdtSort(t *testing.T) { w := CreateRequestRouterWithAccount("GET", "/", "", "?sort=id", nil, "", SystemTagListHandler, 1) assert.Equal(t, 400, w.Code) } + +func TestSystemTagsListSearch(t *testing.T) { + core.SetupTest(t) + + w := CreateRequestRouterWithAccount("GET", "/", "", "?search=k3", nil, "", SystemTagListHandler, 1) + + var output SystemTagsResponse + CheckResponse(t, w, http.StatusOK, &output) + + assert.Equal(t, 2, len(output.Data)) + assert.Equal(t, 2, output.Meta.TotalItems) + assert.Equal(t, "k3", output.Meta.Search) + + assert.Equal(t, 1, output.Data[0].Count) + assert.Equal(t, "k3", output.Data[0].Tag.Key) + assert.Equal(t, "ns1", output.Data[0].Tag.Namespace) + assert.Equal(t, "val3", output.Data[0].Tag.Value) + + assert.Equal(t, 3, output.Data[1].Count) + assert.Equal(t, "k3", output.Data[1].Tag.Key) + assert.Equal(t, "ns1", output.Data[1].Tag.Namespace) + assert.Equal(t, "val4", output.Data[1].Tag.Value) +} + +func TestSystemTagsListSearchUnknown(t *testing.T) { + core.SetupTest(t) + + w := CreateRequestRouterWithAccount("GET", "/", "", "?search=unknown", nil, "", SystemTagListHandler, 1) + + var output SystemTagsResponse + CheckResponse(t, w, http.StatusOK, &output) + + assert.Equal(t, 0, len(output.Data)) + assert.Equal(t, "unknown", output.Meta.Search) +}