Skip to content

Commit 9f37937

Browse files
committed
tuned coverage
1 parent ce71525 commit 9f37937

File tree

3 files changed

+64
-22
lines changed

3 files changed

+64
-22
lines changed

openapi_vocabulary/discriminator.go

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,11 @@ type discriminatorExtension struct {
1313
mapping map[string]string // value -> schema reference
1414
}
1515

16+
// Validate validates the discriminator property exists in the instance
1617
func (d *discriminatorExtension) Validate(ctx *jsonschema.ValidatorContext, v any) {
17-
// Validate that discriminator structure is correct
18-
// For now, we only validate the structure, not the discriminator semantics
19-
// Full discriminator validation would require schema resolution which is complex
18+
obj, _ := v.(map[string]any)
2019

21-
obj, ok := v.(map[string]any)
22-
if !ok {
23-
return // discriminator only applies to objects
24-
}
25-
26-
// Check if discriminator property exists in the object
20+
// check if discriminator property exists in the object
2721
if d.propertyName != "" {
2822
if _, exists := obj[d.propertyName]; !exists {
2923
ctx.AddError(&DiscriminatorPropertyMissingError{
@@ -33,14 +27,13 @@ func (d *discriminatorExtension) Validate(ctx *jsonschema.ValidatorContext, v an
3327
}
3428
}
3529

36-
// compileDiscriminator compiles the discriminator keyword
37-
func CompileDiscriminator(ctx *jsonschema.CompilerContext, obj map[string]any, version VersionType) (jsonschema.SchemaExt, error) {
30+
// CompileDiscriminator compiles the OpenAPI discriminator keyword
31+
func CompileDiscriminator(_ *jsonschema.CompilerContext, obj map[string]any, _ VersionType) (jsonschema.SchemaExt, error) {
3832
v, exists := obj["discriminator"]
3933
if !exists {
4034
return nil, nil
4135
}
4236

43-
// Validate discriminator structure
4437
discriminator, ok := v.(map[string]any)
4538
if !ok {
4639
return nil, &OpenAPIKeywordError{
@@ -49,7 +42,6 @@ func CompileDiscriminator(ctx *jsonschema.CompilerContext, obj map[string]any, v
4942
}
5043
}
5144

52-
// Extract propertyName (required)
5345
propertyNameValue, exists := discriminator["propertyName"]
5446
if !exists {
5547
return nil, &OpenAPIKeywordError{
@@ -66,7 +58,6 @@ func CompileDiscriminator(ctx *jsonschema.CompilerContext, obj map[string]any, v
6658
}
6759
}
6860

69-
// Extract mapping (optional)
7061
var mapping map[string]string
7162
if mappingValue, exists := discriminator["mapping"]; exists {
7263
mappingObj, ok := mappingValue.(map[string]any)

openapi_vocabulary/vocabulary.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,45 +38,43 @@ func NewOpenAPIVocabularyWithCoercion(version VersionType, allowCoercion bool) *
3838
}
3939

4040
// compileOpenAPIKeywords compiles all OpenAPI-specific keywords found in the schema object
41-
func compileOpenAPIKeywords(ctx *jsonschema.CompilerContext, obj map[string]any, version VersionType, allowCoercion bool) (jsonschema.SchemaExt, error) {
41+
func compileOpenAPIKeywords(ctx *jsonschema.CompilerContext,
42+
obj map[string]any,
43+
version VersionType,
44+
allowCoercion bool) (jsonschema.SchemaExt, error) {
45+
4246
var extensions []jsonschema.SchemaExt
4347

44-
// Handle nullable keyword
4548
if ext, err := CompileNullable(ctx, obj, version); err != nil {
4649
return nil, err
4750
} else if ext != nil {
4851
extensions = append(extensions, ext)
4952
}
5053

51-
// Handle discriminator keyword
5254
if ext, err := CompileDiscriminator(ctx, obj, version); err != nil {
5355
return nil, err
5456
} else if ext != nil {
5557
extensions = append(extensions, ext)
5658
}
5759

58-
// Handle example keyword
5960
if ext, err := CompileExample(ctx, obj, version); err != nil {
6061
return nil, err
6162
} else if ext != nil {
6263
extensions = append(extensions, ext)
6364
}
6465

65-
// Handle deprecated keyword
6666
if ext, err := CompileDeprecated(ctx, obj, version); err != nil {
6767
return nil, err
6868
} else if ext != nil {
6969
extensions = append(extensions, ext)
7070
}
7171

72-
// Handle scalar coercion (applies to all schemas with coercible types)
7372
if ext, err := CompileCoercion(ctx, obj, allowCoercion); err != nil {
7473
return nil, err
7574
} else if ext != nil {
7675
extensions = append(extensions, ext)
7776
}
7877

79-
// Return combined extension if any keywords were found
8078
if len(extensions) == 0 {
8179
return nil, nil
8280
}

openapi_vocabulary/vocabulary_test.go

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,10 @@ func TestDiscriminatorValidation_NonObjectValue(t *testing.T) {
703703
schemaJSON := `{
704704
"type": "object",
705705
"discriminator": {
706-
"propertyName": "type"
706+
"propertyName": "type",
707+
"mapping": {
708+
"dog": "#/components/schemas/Dog",
709+
}
707710
}
708711
}`
709712

@@ -726,3 +729,53 @@ func TestDiscriminatorValidation_NonObjectValue(t *testing.T) {
726729
// Should get type validation error, not discriminator error
727730
assert.NotContains(t, err.Error(), "discriminator property")
728731
}
732+
733+
func TestDiscriminatorValidation_DiscriminatorBadMapping(t *testing.T) {
734+
schemaJSON := `{
735+
"type": "object",
736+
"discriminator": {
737+
"propertyName": "type",
738+
"mapping": "not an object"
739+
}
740+
}`
741+
742+
schema, err := jsonschema.UnmarshalJSON(strings.NewReader(schemaJSON))
743+
assert.NoError(t, err)
744+
745+
compiler := jsonschema.NewCompiler()
746+
compiler.RegisterVocabulary(NewOpenAPIVocabulary(Version30))
747+
compiler.AssertVocabs()
748+
749+
err = compiler.AddResource("test.json", schema)
750+
assert.NoError(t, err)
751+
752+
_, err = compiler.Compile("test.json")
753+
assert.Error(t, err)
754+
assert.Equal(t, "OpenAPI keyword 'discriminator': discriminator mapping must be an object", err.Error())
755+
}
756+
757+
func TestDiscriminatorValidation_BadMappingType(t *testing.T) {
758+
schemaJSON := `{
759+
"type": "object",
760+
"discriminator": {
761+
"propertyName": "type",
762+
"mapping": {
763+
"fish": 12345
764+
}
765+
}
766+
}`
767+
768+
schema, err := jsonschema.UnmarshalJSON(strings.NewReader(schemaJSON))
769+
assert.NoError(t, err)
770+
771+
compiler := jsonschema.NewCompiler()
772+
compiler.RegisterVocabulary(NewOpenAPIVocabulary(Version30))
773+
compiler.AssertVocabs()
774+
775+
err = compiler.AddResource("test.json", schema)
776+
assert.NoError(t, err)
777+
778+
_, err = compiler.Compile("test.json")
779+
assert.Error(t, err)
780+
assert.Equal(t, "OpenAPI keyword 'discriminator': discriminator mapping values must be strings", err.Error())
781+
}

0 commit comments

Comments
 (0)