Chore: Refactor GoConvey into stdlib for search service (#19765)
* Refactor GoConvey into stdlib * Fix review comments
This commit is contained in:
@@ -1,75 +0,0 @@
|
|||||||
package search
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sort"
|
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
|
||||||
"github.com/grafana/grafana/pkg/registry"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
registry.RegisterService(&SearchService{})
|
|
||||||
}
|
|
||||||
|
|
||||||
type SearchService struct {
|
|
||||||
Bus bus.Bus `inject:""`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SearchService) Init() error {
|
|
||||||
s.Bus.AddHandler(s.searchHandler)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SearchService) searchHandler(query *Query) error {
|
|
||||||
dashQuery := FindPersistedDashboardsQuery{
|
|
||||||
Title: query.Title,
|
|
||||||
SignedInUser: query.SignedInUser,
|
|
||||||
IsStarred: query.IsStarred,
|
|
||||||
DashboardIds: query.DashboardIds,
|
|
||||||
Type: query.Type,
|
|
||||||
FolderIds: query.FolderIds,
|
|
||||||
Tags: query.Tags,
|
|
||||||
Limit: query.Limit,
|
|
||||||
Page: query.Page,
|
|
||||||
Permission: query.Permission,
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := bus.Dispatch(&dashQuery); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
hits := make(HitList, 0)
|
|
||||||
hits = append(hits, dashQuery.Result...)
|
|
||||||
|
|
||||||
// sort main result array
|
|
||||||
sort.Sort(hits)
|
|
||||||
|
|
||||||
// sort tags
|
|
||||||
for _, hit := range hits {
|
|
||||||
sort.Strings(hit.Tags)
|
|
||||||
}
|
|
||||||
|
|
||||||
// add isStarred info
|
|
||||||
if err := setIsStarredFlagOnSearchResults(query.SignedInUser.UserId, hits); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
query.Result = hits
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func setIsStarredFlagOnSearchResults(userId int64, hits []*Hit) error {
|
|
||||||
query := m.GetUserStarsQuery{UserId: userId}
|
|
||||||
if err := bus.Dispatch(&query); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, dash := range hits {
|
|
||||||
if _, exists := query.Result[dash.Id]; exists {
|
|
||||||
dash.IsStarred = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
package search
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
|
||||||
. "github.com/smartystreets/goconvey/convey"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestSearch(t *testing.T) {
|
|
||||||
|
|
||||||
Convey("Given search query", t, func() {
|
|
||||||
query := Query{Limit: 2000, SignedInUser: &m.SignedInUser{IsGrafanaAdmin: true}}
|
|
||||||
ss := &SearchService{}
|
|
||||||
|
|
||||||
bus.AddHandler("test", func(query *FindPersistedDashboardsQuery) error {
|
|
||||||
query.Result = HitList{
|
|
||||||
&Hit{Id: 16, Title: "CCAA", Type: "dash-db", Tags: []string{"BB", "AA"}},
|
|
||||||
&Hit{Id: 10, Title: "AABB", Type: "dash-db", Tags: []string{"CC", "AA"}},
|
|
||||||
&Hit{Id: 15, Title: "BBAA", Type: "dash-db", Tags: []string{"EE", "AA", "BB"}},
|
|
||||||
&Hit{Id: 25, Title: "bbAAa", Type: "dash-db", Tags: []string{"EE", "AA", "BB"}},
|
|
||||||
&Hit{Id: 17, Title: "FOLDER", Type: "dash-folder"},
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
bus.AddHandler("test", func(query *m.GetUserStarsQuery) error {
|
|
||||||
query.Result = map[int64]bool{10: true, 12: true}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
bus.AddHandler("test", func(query *m.GetSignedInUserQuery) error {
|
|
||||||
query.Result = &m.SignedInUser{IsGrafanaAdmin: true}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
Convey("That is empty", func() {
|
|
||||||
err := ss.searchHandler(&query)
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
|
|
||||||
Convey("should return sorted results", func() {
|
|
||||||
So(query.Result[0].Title, ShouldEqual, "FOLDER")
|
|
||||||
So(query.Result[1].Title, ShouldEqual, "AABB")
|
|
||||||
So(query.Result[2].Title, ShouldEqual, "BBAA")
|
|
||||||
So(query.Result[3].Title, ShouldEqual, "bbAAa")
|
|
||||||
So(query.Result[4].Title, ShouldEqual, "CCAA")
|
|
||||||
})
|
|
||||||
|
|
||||||
Convey("should return sorted tags", func() {
|
|
||||||
So(query.Result[3].Tags[0], ShouldEqual, "AA")
|
|
||||||
So(query.Result[3].Tags[1], ShouldEqual, "BB")
|
|
||||||
So(query.Result[3].Tags[2], ShouldEqual, "EE")
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package search
|
package search
|
||||||
|
|
||||||
import "strings"
|
import "strings"
|
||||||
import "github.com/grafana/grafana/pkg/models"
|
|
||||||
|
|
||||||
type HitType string
|
type HitType string
|
||||||
|
|
||||||
@@ -42,35 +41,3 @@ func (s HitList) Less(i, j int) bool {
|
|||||||
|
|
||||||
return strings.ToLower(s[i].Title) < strings.ToLower(s[j].Title)
|
return strings.ToLower(s[i].Title) < strings.ToLower(s[j].Title)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Query struct {
|
|
||||||
Title string
|
|
||||||
Tags []string
|
|
||||||
OrgId int64
|
|
||||||
SignedInUser *models.SignedInUser
|
|
||||||
Limit int64
|
|
||||||
Page int64
|
|
||||||
IsStarred bool
|
|
||||||
Type string
|
|
||||||
DashboardIds []int64
|
|
||||||
FolderIds []int64
|
|
||||||
Permission models.PermissionType
|
|
||||||
|
|
||||||
Result HitList
|
|
||||||
}
|
|
||||||
|
|
||||||
type FindPersistedDashboardsQuery struct {
|
|
||||||
Title string
|
|
||||||
OrgId int64
|
|
||||||
SignedInUser *models.SignedInUser
|
|
||||||
IsStarred bool
|
|
||||||
DashboardIds []int64
|
|
||||||
Type string
|
|
||||||
FolderIds []int64
|
|
||||||
Tags []string
|
|
||||||
Limit int64
|
|
||||||
Page int64
|
|
||||||
Permission models.PermissionType
|
|
||||||
|
|
||||||
Result HitList
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
package search
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sort"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
|
"github.com/grafana/grafana/pkg/models"
|
||||||
|
"github.com/grafana/grafana/pkg/registry"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
registry.RegisterService(&SearchService{})
|
||||||
|
}
|
||||||
|
|
||||||
|
type Query struct {
|
||||||
|
Title string
|
||||||
|
Tags []string
|
||||||
|
OrgId int64
|
||||||
|
SignedInUser *models.SignedInUser
|
||||||
|
Limit int64
|
||||||
|
Page int64
|
||||||
|
IsStarred bool
|
||||||
|
Type string
|
||||||
|
DashboardIds []int64
|
||||||
|
FolderIds []int64
|
||||||
|
Permission models.PermissionType
|
||||||
|
|
||||||
|
Result HitList
|
||||||
|
}
|
||||||
|
|
||||||
|
type FindPersistedDashboardsQuery struct {
|
||||||
|
Title string
|
||||||
|
OrgId int64
|
||||||
|
SignedInUser *models.SignedInUser
|
||||||
|
IsStarred bool
|
||||||
|
DashboardIds []int64
|
||||||
|
Type string
|
||||||
|
FolderIds []int64
|
||||||
|
Tags []string
|
||||||
|
Limit int64
|
||||||
|
Page int64
|
||||||
|
Permission models.PermissionType
|
||||||
|
|
||||||
|
Result HitList
|
||||||
|
}
|
||||||
|
|
||||||
|
type SearchService struct {
|
||||||
|
bus bus.Bus `inject:""`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SearchService) Init() error {
|
||||||
|
s.bus.AddHandler(s.searchHandler)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SearchService) searchHandler(query *Query) error {
|
||||||
|
dashboardQuery := FindPersistedDashboardsQuery{
|
||||||
|
Title: query.Title,
|
||||||
|
SignedInUser: query.SignedInUser,
|
||||||
|
IsStarred: query.IsStarred,
|
||||||
|
DashboardIds: query.DashboardIds,
|
||||||
|
Type: query.Type,
|
||||||
|
FolderIds: query.FolderIds,
|
||||||
|
Tags: query.Tags,
|
||||||
|
Limit: query.Limit,
|
||||||
|
Page: query.Page,
|
||||||
|
Permission: query.Permission,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := bus.Dispatch(&dashboardQuery); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
hits := sortedHits(dashboardQuery.Result)
|
||||||
|
|
||||||
|
if err := setStarredDashboards(query.SignedInUser.UserId, hits); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
query.Result = hits
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func sortedHits(unsorted HitList) HitList {
|
||||||
|
hits := make(HitList, 0)
|
||||||
|
hits = append(hits, unsorted...)
|
||||||
|
|
||||||
|
sort.Sort(hits)
|
||||||
|
|
||||||
|
for _, hit := range hits {
|
||||||
|
sort.Strings(hit.Tags)
|
||||||
|
}
|
||||||
|
|
||||||
|
return hits
|
||||||
|
}
|
||||||
|
|
||||||
|
func setStarredDashboards(userID int64, hits []*Hit) error {
|
||||||
|
query := models.GetUserStarsQuery{
|
||||||
|
UserId: userID,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := bus.Dispatch(&query); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, dashboard := range hits {
|
||||||
|
if _, ok := query.Result[dashboard.Id]; ok {
|
||||||
|
dashboard.IsStarred = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package search
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
|
"github.com/grafana/grafana/pkg/models"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSearch_SortedResults(t *testing.T) {
|
||||||
|
bus.AddHandler("test", func(query *FindPersistedDashboardsQuery) error {
|
||||||
|
query.Result = HitList{
|
||||||
|
&Hit{Id: 16, Title: "CCAA", Type: "dash-db", Tags: []string{"BB", "AA"}},
|
||||||
|
&Hit{Id: 10, Title: "AABB", Type: "dash-db", Tags: []string{"CC", "AA"}},
|
||||||
|
&Hit{Id: 15, Title: "BBAA", Type: "dash-db", Tags: []string{"EE", "AA", "BB"}},
|
||||||
|
&Hit{Id: 25, Title: "bbAAa", Type: "dash-db", Tags: []string{"EE", "AA", "BB"}},
|
||||||
|
&Hit{Id: 17, Title: "FOLDER", Type: "dash-folder"},
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
bus.AddHandler("test", func(query *models.GetUserStarsQuery) error {
|
||||||
|
query.Result = map[int64]bool{10: true, 12: true}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
bus.AddHandler("test", func(query *models.GetSignedInUserQuery) error {
|
||||||
|
query.Result = &models.SignedInUser{IsGrafanaAdmin: true}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
svc := &SearchService{}
|
||||||
|
|
||||||
|
query := &Query{
|
||||||
|
Limit: 2000,
|
||||||
|
SignedInUser: &models.SignedInUser{
|
||||||
|
IsGrafanaAdmin: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
err := svc.searchHandler(query)
|
||||||
|
require.Nil(t, err)
|
||||||
|
|
||||||
|
// Assert results are sorted.
|
||||||
|
assert.Equal(t, "FOLDER", query.Result[0].Title)
|
||||||
|
assert.Equal(t, "AABB", query.Result[1].Title)
|
||||||
|
assert.Equal(t, "BBAA", query.Result[2].Title)
|
||||||
|
assert.Equal(t, "bbAAa", query.Result[3].Title)
|
||||||
|
assert.Equal(t, "CCAA", query.Result[4].Title)
|
||||||
|
|
||||||
|
// Assert tags are sorted.
|
||||||
|
assert.Equal(t, "AA", query.Result[3].Tags[0])
|
||||||
|
assert.Equal(t, "BB", query.Result[3].Tags[1])
|
||||||
|
assert.Equal(t, "EE", query.Result[3].Tags[2])
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user