Repository: getkin/kin-openapi
Pull request #822 (2023-07-27 17:38:08)

Fix Enum Query Parameters 
Query Parameters are evaluated as int64 vs. a float which is why reflect.DeepEqual fails. 


Patch:
diff --git a/openapi3/schema.go b/openapi3/schema.go
index 0dde607..29da9ef 100644
--- a/openapi3/schema.go
+++ b/openapi3/schema.go
@@ -1149,6 +1149,10 @@ func (schema *Schema) visitSetOperations(settings *schemaValidationSettings, val
 				if v == f {
 					return
 				}
+			case int64:
+				if v == float64(c) {
+					return
+				}
 			default:
 				if reflect.DeepEqual(v, value) {
 					return


Test patch:
diff --git a/openapi3filter/validation_enum_test.go b/openapi3filter/validation_enum_test.go
index 898c402..aae3a1f 100644
--- a/openapi3filter/validation_enum_test.go
+++ b/openapi3filter/validation_enum_test.go
@@ -12,7 +12,8 @@ import (
 )
 
 func TestValidationWithIntegerEnum(t *testing.T) {
-	const spec = `
+	t.Run("PUT Request", func(t *testing.T) {
+		const spec = `
 openapi: 3.0.0
 info:
   title: Example integer enum
@@ -41,56 +42,122 @@ paths:
           description: Ok
 `
 
-	loader := openapi3.NewLoader()
-	doc, err := loader.LoadFromData([]byte(spec))
-	require.NoError(t, err)
+		loader := openapi3.NewLoader()
+		doc, err := loader.LoadFromData([]byte(spec))
+		require.NoError(t, err)
 
-	router, err := legacyrouter.NewRouter(doc)
-	require.NoError(t, err)
+		router, err := legacyrouter.NewRouter(doc)
+		require.NoError(t, err)
 
-	tests := []struct {
-		data    []byte
-		wantErr bool
-	}{
-		{
-			[]byte(`{"exenum": 1}`),
-			false,
-		},
-		{
-			[]byte(`{"exenum": "1"}`),
-			true,
-		},
-		{
-			[]byte(`{"exenum": null}`),
-			false,
-		},
-		{
-			[]byte(`{}`),
-			false,
-		},
-	}
+		tests := []struct {
+			data    []byte
+			wantErr bool
+		}{
+			{
+				[]byte(`{"exenum": 1}`),
+				false,
+			},
+			{
+				[]byte(`{"exenum": "1"}`),
+				true,
+			},
+			{
+				[]byte(`{"exenum": null}`),
+				false,
+			},
+			{
+				[]byte(`{}`),
+				false,
+			},
+		}
 
-	for _, tt := range tests {
-		body := bytes.NewReader(tt.data)
-		req, err := http.NewRequest("PUT", "/sample", body)
+		for _, tt := range tests {
+			body := bytes.NewReader(tt.data)
+			req, err := http.NewRequest("PUT", "/sample", body)
+			require.NoError(t, err)
+			req.Header.Add(headerCT, "application/json")
+
+			route, pathParams, err := router.FindRoute(req)
+			require.NoError(t, err)
+
+			requestValidationInput := &RequestValidationInput{
+				Request:    req,
+				PathParams: pathParams,
+				Route:      route,
+			}
+			err = ValidateRequest(loader.Context, requestValidationInput)
+			if tt.wantErr {
+				require.Error(t, err)
+			} else {
+				require.NoError(t, err)
+			}
+		}
+	})
+
+	t.Run("GET Request", func(t *testing.T) {
+		const spec = `
+openapi: 3.0.0
+info:
+  title: Example integer enum
+  version: '0.1'
+paths:
+  /sample:
+    get:
+      parameters:
+        - in: query
+          name: exenum
+          schema:
+            type: integer
+            enum:
+              - 0
+              - 1
+              - 2
+              - 3
+      responses:
+        '200':
+          description: Ok
+`
+
+		loader := openapi3.NewLoader()
+		doc, err := loader.LoadFromData([]byte(spec))
 		require.NoError(t, err)
-		req.Header.Add(headerCT, "application/json")
 
-		route, pathParams, err := router.FindRoute(req)
+		router, err := legacyrouter.NewRouter(doc)
 		require.NoError(t, err)
 
-		requestValidationInput := &RequestValidationInput{
-			Request:    req,
-			PathParams: pathParams,
-			Route:      route,
+		tests := []struct {
+			exenum  string
+			wantErr bool
+		}{
+			{
+				"1",
+				false,
+			},
+			{
+				"4",
+				true,
+			},
 		}
-		err = ValidateRequest(loader.Context, requestValidationInput)
-		if tt.wantErr {
-			require.Error(t, err)
-		} else {
+
+		for _, tt := range tests {
+			req, err := http.NewRequest("GET", "/sample?exenum="+tt.exenum, nil)
+			require.NoError(t, err)
+			route, pathParams, err := router.FindRoute(req)
 			require.NoError(t, err)
+
+			requestValidationInput := &RequestValidationInput{
+				Request:    req,
+				PathParams: pathParams,
+				Route:      route,
+			}
+			err = ValidateRequest(loader.Context, requestValidationInput)
+			if tt.wantErr {
+				require.Error(t, err)
+			} else {
+				require.NoError(t, err)
+			}
 		}
-	}
+	})
 }
 
 func TestValidationWithStringEnum(t *testing.T) {