From 3492a5d7cfaa3f8e7552a433f20260d44b239897 Mon Sep 17 00:00:00 2001 From: Leszek Lugin Date: Fri, 23 Aug 2024 20:58:40 +0200 Subject: [PATCH] Add: bool request option filter --- pkg/query/filter/request.go | 2 +- pkg/query/filter/type.go | 1 + pkg/query/filter/type_enum.go | 7 +++-- pkg/query/filter/validation.go | 4 +++ pkg/query/filter/validation_test.go | 44 +++++++++++++++++++++++++++++ 5 files changed, 55 insertions(+), 3 deletions(-) diff --git a/pkg/query/filter/request.go b/pkg/query/filter/request.go index eb08939..9d54b0e 100644 --- a/pkg/query/filter/request.go +++ b/pkg/query/filter/request.go @@ -38,7 +38,7 @@ type ReadableValue[T any] struct { // RequestOptionType configures the type of control for a field in a request option. type RequestOptionType struct { - Type ControlType `json:"type" enums:"string,float,integer,enum"` + Type ControlType `json:"type" enums:"string,float,integer,enum,bool"` } // RequestField represents a field in a request diff --git a/pkg/query/filter/type.go b/pkg/query/filter/type.go index 7be1a6e..80d3632 100644 --- a/pkg/query/filter/type.go +++ b/pkg/query/filter/type.go @@ -9,6 +9,7 @@ package filter /* ControlType ENUM( + bool enum float integer diff --git a/pkg/query/filter/type_enum.go b/pkg/query/filter/type_enum.go index cb49d87..0f526ad 100644 --- a/pkg/query/filter/type_enum.go +++ b/pkg/query/filter/type_enum.go @@ -12,10 +12,9 @@ package filter import ( "database/sql/driver" + "errors" "fmt" "strings" - - "errors" ) const ( @@ -301,6 +300,8 @@ func (x CompareOperator) Value() (driver.Value, error) { } const ( + // ControlTypeBool is a ControlType of type bool. + ControlTypeBool ControlType = "bool" // ControlTypeEnum is a ControlType of type enum. ControlTypeEnum ControlType = "enum" // ControlTypeFloat is a ControlType of type float. @@ -320,6 +321,7 @@ const ( var ErrInvalidControlType = fmt.Errorf("not a valid ControlType, try [%s]", strings.Join(_ControlTypeNames, ", ")) var _ControlTypeNames = []string{ + string(ControlTypeBool), string(ControlTypeEnum), string(ControlTypeFloat), string(ControlTypeInteger), @@ -349,6 +351,7 @@ func (x ControlType) IsValid() bool { } var _ControlTypeValue = map[string]ControlType{ + "bool": ControlTypeBool, "enum": ControlTypeEnum, "float": ControlTypeFloat, "integer": ControlTypeInteger, diff --git a/pkg/query/filter/validation.go b/pkg/query/filter/validation.go index 51ef527..a99c615 100644 --- a/pkg/query/filter/validation.go +++ b/pkg/query/filter/validation.go @@ -110,6 +110,10 @@ func validateFieldValueType(requestOption RequestOption, fieldName string, field if _, ok := fieldValue.(float64); !ok { return NewValidationError("field '%s' must be from type '%s'", fieldName, requestOption.Control.Type) } + } else if requestOption.Control.Type == ControlTypeBool { + if _, ok := fieldValue.(bool); !ok { + return NewValidationError("field '%s' must be from type '%s'", fieldName, requestOption.Control.Type) + } } else if requestOption.Control.Type == ControlTypeString || requestOption.Control.Type == ControlTypeEnum || requestOption.Control.Type == ControlTypeUuid { if _, ok := fieldValue.(string); !ok { diff --git a/pkg/query/filter/validation_test.go b/pkg/query/filter/validation_test.go index dfc856d..eb888a8 100644 --- a/pkg/query/filter/validation_test.go +++ b/pkg/query/filter/validation_test.go @@ -550,3 +550,47 @@ func TestFloatRequestOption(t *testing.T) { assert.Equal(t, validationError.Error(), "field 'optionName' must be from type 'float'") }) } + +func TestBoolRequestOption(t *testing.T) { + var requestOptions []RequestOption + + setup := func(t *testing.T) { + requestOptions = []RequestOption{ + { + Name: ReadableValue[string]{ + Value: "optionName", + }, + Control: RequestOptionType{ + Type: ControlTypeBool, + }, + Operators: []ReadableValue[CompareOperator]{ + { + Value: CompareOperatorContains, + }, + { + Value: CompareOperatorDoesNotContain, + }, + }, + MultiSelect: false, + }, + } + } + + t.Run("shouldReturnErrorOnInvalidValueDataType", func(t *testing.T) { + setup(t) + + err := ValidateFilter(&Request{ + Operator: LogicOperatorAnd, + Fields: []RequestField{ + { + Name: "optionName", + Operator: CompareOperatorContains, + Value: "0", + }, + }, + }, requestOptions) + var validationError *ValidationError + assert.True(t, errors.As(err, &validationError)) + assert.Equal(t, validationError.Error(), "field 'optionName' must be from type 'bool'") + }) +}