diff --git a/pkg/services/search/handlers.go b/pkg/services/search/handlers.go deleted file mode 100644 index 0ea07176dc0..00000000000 --- a/pkg/services/search/handlers.go +++ /dev/null @@ -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 -} diff --git a/pkg/services/search/handlers_test.go b/pkg/services/search/handlers_test.go deleted file mode 100644 index 5cf934cbc92..00000000000 --- a/pkg/services/search/handlers_test.go +++ /dev/null @@ -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") - }) - }) - - }) -} diff --git a/pkg/services/search/models.go b/pkg/services/search/hits.go similarity index 62% rename from pkg/services/search/models.go rename to pkg/services/search/hits.go index 454ff261732..8da535d7005 100644 --- a/pkg/services/search/models.go +++ b/pkg/services/search/hits.go @@ -1,7 +1,6 @@ package search import "strings" -import "github.com/grafana/grafana/pkg/models" 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) } - -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 -} diff --git a/pkg/services/search/service.go b/pkg/services/search/service.go new file mode 100644 index 00000000000..3da760cba12 --- /dev/null +++ b/pkg/services/search/service.go @@ -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 +} diff --git a/pkg/services/search/service_test.go b/pkg/services/search/service_test.go new file mode 100644 index 00000000000..120b4530b83 --- /dev/null +++ b/pkg/services/search/service_test.go @@ -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]) +}