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
11 changes: 11 additions & 0 deletions pkg/codegen/merge_schemas.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,17 @@ func mergeOpenapiSchemas(s1, s2 openapi3.Schema, allOf bool) (openapi3.Schema, e
return openapi3.Schema{}, errors.New("merging two schemas with discriminators is not supported")
}

// For allOf merges, propagate a discriminator if only one schema has it.
// Merging two different discriminators is not supported.
if s1.Discriminator != nil && s2.Discriminator != nil {
return openapi3.Schema{}, errors.New("merging two schemas with discriminators is not supported")
}
if s1.Discriminator != nil {
result.Discriminator = s1.Discriminator
} else if s2.Discriminator != nil {
result.Discriminator = s2.Discriminator
}

return result, nil
}

Expand Down
68 changes: 68 additions & 0 deletions pkg/codegen/merge_schemas_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package codegen

import (
"testing"

"github.com/getkin/kin-openapi/openapi3"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestMergeOpenapiSchemas_DiscriminatorPropagation(t *testing.T) {
disc := &openapi3.Discriminator{
PropertyName: "type",
}

t.Run("allOf with single discriminator on s1 propagates it", func(t *testing.T) {
s1 := openapi3.Schema{Discriminator: disc}
s2 := openapi3.Schema{}

result, err := mergeOpenapiSchemas(s1, s2, true)
require.NoError(t, err)
assert.Equal(t, disc, result.Discriminator)
})

t.Run("allOf with single discriminator on s2 propagates it", func(t *testing.T) {
s1 := openapi3.Schema{}
s2 := openapi3.Schema{Discriminator: disc}

result, err := mergeOpenapiSchemas(s1, s2, true)
require.NoError(t, err)
assert.Equal(t, disc, result.Discriminator)
})

t.Run("allOf with discriminators on both schemas errors", func(t *testing.T) {
disc2 := &openapi3.Discriminator{PropertyName: "kind"}
s1 := openapi3.Schema{Discriminator: disc}
s2 := openapi3.Schema{Discriminator: disc2}

_, err := mergeOpenapiSchemas(s1, s2, true)
require.Error(t, err)
assert.Contains(t, err.Error(), "discriminators")
})

t.Run("allOf with no discriminators succeeds with nil discriminator", func(t *testing.T) {
s1 := openapi3.Schema{}
s2 := openapi3.Schema{}

result, err := mergeOpenapiSchemas(s1, s2, true)
require.NoError(t, err)
assert.Nil(t, result.Discriminator)
})

t.Run("non-allOf with discriminator on s1 errors", func(t *testing.T) {
s1 := openapi3.Schema{Discriminator: disc}
s2 := openapi3.Schema{}

_, err := mergeOpenapiSchemas(s1, s2, false)
require.Error(t, err)
})

t.Run("non-allOf with discriminator on s2 errors", func(t *testing.T) {
s1 := openapi3.Schema{}
s2 := openapi3.Schema{Discriminator: disc}

_, err := mergeOpenapiSchemas(s1, s2, false)
require.Error(t, err)
})
}