Unified Storage: Fix sortMeta always zero in legacy search api (#110779)

sort field is included in search request fields
This commit is contained in:
owensmallwood
2025-09-08 15:43:47 -06:00
committed by GitHub
parent c16548f378
commit ffcc0e8de0
2 changed files with 108 additions and 48 deletions
@@ -1977,6 +1977,10 @@ func (dr *DashboardServiceImpl) searchDashboardsThroughK8sRaw(ctx context.Contex
return dashboardv0.SearchResults{}, err
}
request.SortBy = append(request.SortBy, &resourcepb.ResourceSearchRequest_Sort{Field: sortName, Desc: isDesc})
// include the sort field in the response so we can populate SortMeta
if !slices.Contains(request.Fields, sortName) {
request.Fields = append(request.Fields, sortName)
}
}
res, err := dr.k8sclient.Search(ctx, query.OrgId, request)
@@ -1874,58 +1874,114 @@ func TestCountInFolders(t *testing.T) {
}
func TestSearchDashboardsThroughK8sRaw(t *testing.T) {
ctx := context.Background()
k8sCliMock := new(client.MockK8sHandler)
service := &DashboardServiceImpl{k8sclient: k8sCliMock}
query := &dashboards.FindPersistedDashboardsQuery{
OrgId: 1,
Sort: sort.SortAlphaAsc,
}
k8sCliMock.On("GetNamespace", mock.Anything, mock.Anything).Return("default")
k8sCliMock.On("Search", mock.Anything, mock.Anything, mock.MatchedBy(func(req *resourcepb.ResourceSearchRequest) bool {
return len(req.SortBy) == 1 &&
// should be converted to "title" due to ParseSortName
req.SortBy[0].Field == "title" &&
!req.SortBy[0].Desc
})).Return(&resourcepb.ResourceSearchResponse{
Results: &resourcepb.ResourceTable{
Columns: []*resourcepb.ResourceTableColumnDefinition{
{
Name: "title",
Type: resourcepb.ResourceTableColumnDefinition_STRING,
},
{
Name: "folder",
Type: resourcepb.ResourceTableColumnDefinition_STRING,
},
},
Rows: []*resourcepb.ResourceTableRow{
{
Key: &resourcepb.ResourceKey{
Name: "uid",
Resource: "dashboard",
t.Run("can search dashboards", func(t *testing.T) {
ctx := context.Background()
k8sCliMock := new(client.MockK8sHandler)
service := &DashboardServiceImpl{k8sclient: k8sCliMock}
query := &dashboards.FindPersistedDashboardsQuery{
OrgId: 1,
Sort: sort.SortAlphaAsc,
}
k8sCliMock.On("GetNamespace", mock.Anything, mock.Anything).Return("default")
k8sCliMock.On("Search", mock.Anything, mock.Anything, mock.MatchedBy(func(req *resourcepb.ResourceSearchRequest) bool {
// should include sort field only once
titleFieldCount := 0
for _, field := range req.Fields {
if field == "title" {
titleFieldCount++
}
}
return len(req.SortBy) == 1 &&
// should be converted to "title" due to ParseSortName
req.SortBy[0].Field == "title" &&
!req.SortBy[0].Desc &&
titleFieldCount == 1
})).Return(&resourcepb.ResourceSearchResponse{
Results: &resourcepb.ResourceTable{
Columns: []*resourcepb.ResourceTableColumnDefinition{
{
Name: "title",
Type: resourcepb.ResourceTableColumnDefinition_STRING,
},
Cells: [][]byte{
[]byte("Dashboard 1"),
[]byte("folder1"),
{
Name: "folder",
Type: resourcepb.ResourceTableColumnDefinition_STRING,
},
},
Rows: []*resourcepb.ResourceTableRow{
{
Key: &resourcepb.ResourceKey{
Name: "uid",
Resource: "dashboard",
},
Cells: [][]byte{
[]byte("Dashboard 1"),
[]byte("folder1"),
},
},
},
},
},
TotalHits: 1,
}, nil)
res, err := service.searchDashboardsThroughK8s(ctx, query)
require.NoError(t, err)
assert.Equal(t, []*dashboards.Dashboard{
{
UID: "uid",
OrgID: 1,
FolderUID: "folder1",
Title: "Dashboard 1",
Slug: "dashboard-1", // should be slugified
},
}, res)
assert.Equal(t, "dash-db", query.Type) // query type should be added
TotalHits: 1,
}, nil)
res, err := service.searchDashboardsThroughK8s(ctx, query)
require.NoError(t, err)
assert.Equal(t, []*dashboards.Dashboard{
{
UID: "uid",
OrgID: 1,
FolderUID: "folder1",
Title: "Dashboard 1",
Slug: "dashboard-1", // should be slugified
},
}, res)
assert.Equal(t, "dash-db", query.Type) // query type should be added
})
t.Run("search will include sort field in hit fields", func(t *testing.T) {
ctx := context.Background()
k8sCliMock := new(client.MockK8sHandler)
service := &DashboardServiceImpl{k8sclient: k8sCliMock}
query := &dashboards.FindPersistedDashboardsQuery{
OrgId: 1,
Sort: model.SortOption{Name: "viewed-recently-desc"},
}
k8sCliMock.On("GetNamespace", mock.Anything, mock.Anything).Return("default")
k8sCliMock.On("Search", mock.Anything, mock.Anything, mock.MatchedBy(func(req *resourcepb.ResourceSearchRequest) bool {
return len(req.SortBy) == 1 &&
req.SortBy[0].Field == "views_last_30_days" &&
req.SortBy[0].Desc &&
slices.Contains(req.Fields, "views_last_30_days")
})).Return(&resourcepb.ResourceSearchResponse{
Results: &resourcepb.ResourceTable{
Columns: []*resourcepb.ResourceTableColumnDefinition{
{
Name: "title",
Type: resourcepb.ResourceTableColumnDefinition_STRING,
},
{
Name: "folder",
Type: resourcepb.ResourceTableColumnDefinition_STRING,
},
},
Rows: []*resourcepb.ResourceTableRow{
{
Key: &resourcepb.ResourceKey{
Name: "uid",
Resource: "dashboard",
},
Cells: [][]byte{
[]byte("Dashboard 1"),
[]byte("folder1"),
},
},
},
},
TotalHits: 1,
}, nil)
_, err := service.searchDashboardsThroughK8s(ctx, query)
require.NoError(t, err)
})
}
func TestSearchProvisionedDashboardsThroughK8sRaw(t *testing.T) {