1
0
mirror of https://github.com/rancher/steve.git synced 2025-09-16 07:18:28 +00:00

Add a missing test to verify we're parsing indirect queries correctly.

This commit is contained in:
Eric Promislow
2025-04-24 17:55:33 -07:00
parent 1c02848a7d
commit 8085c8beb2
3 changed files with 52 additions and 22 deletions

View File

@@ -25,11 +25,11 @@ const (
// ListOptions represents the query parameters that may be included in a list request. // ListOptions represents the query parameters that may be included in a list request.
type ListOptions struct { type ListOptions struct {
ChunkSize int ChunkSize int `json:"chunkSize"`
Resume string Resume string `json:"resume"`
Filters []OrFilter Filters []OrFilter `json:"orFilters"`
SortList SortList SortList SortList `json:"sortList"`
Pagination Pagination Pagination Pagination `json:"pagination"`
} }
// Filter represents a field to filter by. // Filter represents a field to filter by.
@@ -40,12 +40,12 @@ type ListOptions struct {
// //
// If more than one value is given for the `Match` field, we do an "IN (<values>)" test // If more than one value is given for the `Match` field, we do an "IN (<values>)" test
type Filter struct { type Filter struct {
Field []string Field []string `json:"fields"`
Matches []string Matches []string `json:"matches"`
Op Op Op Op `json:"op"`
Partial bool Partial bool `json:"partial"`
IsIndirect bool IsIndirect bool `json:"isIndirect"`
IndirectFields []string IndirectFields []string `json:"indirectFields"`
} }
// OrFilter represents a set of possible fields to filter by, where an item may match any filter in the set to be included in the result. // OrFilter represents a set of possible fields to filter by, where an item may match any filter in the set to be included in the result.
@@ -59,20 +59,20 @@ type OrFilter struct {
// The order is represented by prefixing the sort key by '-', e.g. sort=-metadata.name. // The order is represented by prefixing the sort key by '-', e.g. sort=-metadata.name.
// e.g. To sort internal clusters first followed by clusters in alpha order: sort=-spec.internal,spec.displayName // e.g. To sort internal clusters first followed by clusters in alpha order: sort=-spec.internal,spec.displayName
type Sort struct { type Sort struct {
Fields []string Fields []string `json:"fields"`
Order SortOrder Order SortOrder `json:"order"`
IsIndirect bool IsIndirect bool `json:"isIndirect"`
IndirectFields []string IndirectFields []string `json:"indirectFields"`
} }
type SortList struct { type SortList struct {
SortDirectives []Sort SortDirectives []Sort `json:"sortDirectives"`
} }
// Pagination represents how to return paginated results. // Pagination represents how to return paginated results.
type Pagination struct { type Pagination struct {
PageSize int PageSize int `json:"pageSize"`
Page int Page int `json:"page"`
} }
func NewSortList() *SortList { func NewSortList() *SortList {

View File

@@ -73,11 +73,14 @@ func k8sRequirementToOrFilter(requirement queryparser.Requirement) (sqltypes.Fil
values := requirement.Values() values := requirement.Values()
queryFields := splitQuery(requirement.Key()) queryFields := splitQuery(requirement.Key())
op, usePartialMatch, err := k8sOpToRancherOp(requirement.Operator()) op, usePartialMatch, err := k8sOpToRancherOp(requirement.Operator())
isIndirect, indirectFields := requirement.IndirectInfo()
return sqltypes.Filter{ return sqltypes.Filter{
Field: queryFields, Field: queryFields,
Matches: values, Matches: values,
Op: op, Op: op,
Partial: usePartialMatch, Partial: usePartialMatch,
IsIndirect: isIndirect,
IndirectFields: indirectFields,
}, err }, err
} }

View File

@@ -370,6 +370,33 @@ func TestParseQuery(t *testing.T) {
}, },
}, },
}) })
tests = append(tests, testCase{
description: "ParseQuery() with an indirect labels filter param should create an indirect labels-specific filter.",
req: &types.APIRequest{
Request: &http.Request{
URL: &url.URL{RawQuery: "filter=metadata.labels[grover.example.com/fish]=>[_v1][Foods][foodCode][country]=japan"},
},
},
expectedLO: sqltypes.ListOptions{
ChunkSize: defaultLimit,
Filters: []sqltypes.OrFilter{
{
Filters: []sqltypes.Filter{
{
Field: []string{"metadata", "labels", "grover.example.com/fish"},
Matches: []string{"japan"},
Op: sqltypes.Eq,
IsIndirect: true,
IndirectFields: []string{"_v1", "Foods", "foodCode", "country"},
},
},
},
},
Pagination: sqltypes.Pagination{
Page: 1,
},
},
})
tests = append(tests, testCase{ tests = append(tests, testCase{
description: "ParseQuery() with multiple filter params, should include multiple or filters.", description: "ParseQuery() with multiple filter params, should include multiple or filters.",
req: &types.APIRequest{ req: &types.APIRequest{