diff --git a/pkg/registry/apis/scope/find.go b/pkg/registry/apis/scope/find.go index 6ec96193448..b4b4213d1b3 100644 --- a/pkg/registry/apis/scope/find.go +++ b/pkg/registry/apis/scope/find.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "net/http" + "strings" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/apis/meta/internalversion" @@ -66,15 +67,18 @@ func (r *findREST) Connect(ctx context.Context, name string, opts runtime.Object return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { parent := req.URL.Query().Get("parent") + query := req.URL.Query().Get("query") results := &scope.TreeResults{} raw, err := r.scopeNodeStorage.List(ctx, &internalversion.ListOptions{ Limit: 1000, }) + if err != nil { responder.Error(err) return } + all, ok := raw.(*scope.ScopeNodeList) if !ok { responder.Error(fmt.Errorf("expected ScopeNodeList")) @@ -82,18 +86,30 @@ func (r *findREST) Connect(ctx context.Context, name string, opts runtime.Object } for _, item := range all.Items { - if parent != item.Spec.ParentName { - continue // Someday this will have an index in raw storage on parentName - } - results.Items = append(results.Items, scope.TreeItem{ - NodeID: item.Name, - NodeType: item.Spec.NodeType, - Title: item.Spec.Title, - Description: item.Spec.Description, - LinkType: item.Spec.LinkType, - LinkID: item.Spec.LinkID, - }) + filterAndAppendItem(item, parent, query, results) } + responder.Object(200, results) }), nil } + +func filterAndAppendItem(item scope.ScopeNode, parent string, query string, results *scope.TreeResults) { + if parent != item.Spec.ParentName { + return // Someday this will have an index in raw storage on parentName + } + + // skip if query is passed and title doesn't match. + // HasPrefix is not the end goal but something that that gets us started. + if query != "" && !strings.HasPrefix(item.Spec.Title, query) { + return + } + + results.Items = append(results.Items, scope.TreeItem{ + NodeID: item.Name, + NodeType: item.Spec.NodeType, + Title: item.Spec.Title, + Description: item.Spec.Description, + LinkType: item.Spec.LinkType, + LinkID: item.Spec.LinkID, + }) +} diff --git a/pkg/registry/apis/scope/find_test.go b/pkg/registry/apis/scope/find_test.go new file mode 100644 index 00000000000..caea3e604fb --- /dev/null +++ b/pkg/registry/apis/scope/find_test.go @@ -0,0 +1,71 @@ +package scope + +import ( + "testing" + + scope "github.com/grafana/grafana/pkg/apis/scope/v0alpha1" + "github.com/stretchr/testify/require" +) + +func TestFilterAndAppendItem(t *testing.T) { + tcs := []struct { + Description string + + ParentName string + Title string + + QueryParam string + ParentParam string + + ExpectedMatches int + }{ + { + Description: "Matching parent without query param", + ParentName: "ParentNumberOne", + Title: "item", + QueryParam: "", + ParentParam: "ParentNumberOne", + ExpectedMatches: 1, + }, + { + Description: "Not matching parent", + ParentName: "ParentNumberOne", + Title: "itemOne", + QueryParam: "itemTwo", + ParentParam: "ParentNumberTwo", + ExpectedMatches: 0, + }, + { + Description: "Matching parent and query param", + ParentName: "ParentNumberOne", + Title: "itemOne", + QueryParam: "itemOne", + ParentParam: "ParentNumberOne", + ExpectedMatches: 1, + }, + { + Description: "matching parent but not matching query param", + ParentName: "ParentNumberOne", + Title: "itemOne", + QueryParam: "itemTwo", + ParentParam: "ParentNumberOne", + ExpectedMatches: 0, + }, + } + + for _, tc := range tcs { + results := &scope.TreeResults{} + item := scope.ScopeNode{ + Spec: scope.ScopeNodeSpec{ + ParentName: tc.ParentName, + Title: tc.Title, + Description: "item description", + NodeType: "item type", + LinkType: "item link type", + LinkID: "item link ID", + }, + } + filterAndAppendItem(item, tc.ParentParam, tc.QueryParam, results) + require.Equal(t, len(results.Items), tc.ExpectedMatches, tc.Description) + } +}