Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions internal/test/issues/issue-2232/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package: issue2232
output: issue2232.gen.go
generate:
std-http-server: true
models: true
3 changes: 3 additions & 0 deletions internal/test/issues/issue-2232/generate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package issue2232

//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=config.yaml spec.yaml
260 changes: 260 additions & 0 deletions internal/test/issues/issue-2232/issue2232.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 41 additions & 0 deletions internal/test/issues/issue-2232/issue2232_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package issue2232

import (
"reflect"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

// TestExtraTagsOnQueryParams verifies that x-oapi-codegen-extra-tags is applied
// to query parameter struct fields regardless of whether the extension is placed
// at the parameter level or at the schema level within the parameter.
// This is a regression test for https://github.com/oapi-codegen/oapi-codegen/issues/2232
func TestExtraTagsOnQueryParams(t *testing.T) {
paramType := reflect.TypeOf(GetEndpointParams{})

t.Run("parameter-level extension", func(t *testing.T) {
field, ok := paramType.FieldByName("EnvParamLevel")
require.True(t, ok, "field EnvParamLevel should exist")

assert.Equal(t, `required,oneof=dev live`, field.Tag.Get("validate"),
"x-oapi-codegen-extra-tags at parameter level should produce validate tag")
})

t.Run("schema-level extension", func(t *testing.T) {
field, ok := paramType.FieldByName("EnvSchemaLevel")
require.True(t, ok, "field EnvSchemaLevel should exist")

assert.Equal(t, `required,oneof=dev live`, field.Tag.Get("validate"),
"x-oapi-codegen-extra-tags at schema level within a parameter should produce validate tag")
})

t.Run("schema-level extension on optional param", func(t *testing.T) {
field, ok := paramType.FieldByName("Limit")
require.True(t, ok, "field Limit should exist")

assert.Equal(t, `min=0,max=100`, field.Tag.Get("validate"),
"x-oapi-codegen-extra-tags at schema level within an optional parameter should produce validate tag")
})
}
46 changes: 46 additions & 0 deletions internal/test/issues/issue-2232/spec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
openapi: "3.0.3"
info:
title: test
version: 1.0.0
paths:
/v1/endpoint:
get:
operationId: GetEndpoint
parameters:
- name: env_param_level
in: query
required: true
schema:
type: string
enum:
- dev
- live
x-oapi-codegen-extra-tags:
validate: "required,oneof=dev live"
- name: env_schema_level
in: query
required: true
schema:
type: string
enum:
- dev
- live
x-oapi-codegen-extra-tags:
validate: "required,oneof=dev live"
- name: limit
in: query
required: false
schema:
type: integer
x-oapi-codegen-extra-tags:
validate: "min=0,max=100"
responses:
"200":
description: Success
content:
application/json:
schema:
type: object
properties:
message:
type: string
13 changes: 12 additions & 1 deletion pkg/codegen/operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -925,13 +925,24 @@ func GenerateParamsTypes(op OperationDefinition) []TypeDefinition {
Schema: param.Schema,
})
}
// Merge extensions from the schema level and the parameter level.
// Parameter-level extensions take precedence over schema-level ones.
extensions := make(map[string]any)
if param.Spec.Schema != nil && param.Spec.Schema.Value != nil {
for k, v := range param.Spec.Schema.Value.Extensions {
extensions[k] = v
}
}
for k, v := range param.Spec.Extensions {
extensions[k] = v
}
prop := Property{
Description: param.Spec.Description,
JsonFieldName: param.ParamName,
Required: param.Required,
Schema: pSchema,
NeedsFormTag: param.Style() == "form",
Extensions: param.Spec.Extensions,
Extensions: extensions,
}
s.Properties = append(s.Properties, prop)
}
Expand Down