Skip to content

Commit 874503b

Browse files
k2tzumidaveshanley
authored andcommitted
Fix: enum with nullable property to automatically include null value in validation
1 parent d8d2c68 commit 874503b

2 files changed

Lines changed: 115 additions & 0 deletions

File tree

helpers/schema_compiler.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,26 @@ func transformNullableSchema(schema map[string]interface{}) map[string]interface
207207
schema["oneOf"] = oneOfSlice
208208
}
209209

210+
// Handle enum values - add null if nullable but not already in enum
211+
enum, hasEnum := schema["enum"]
212+
if hasEnum {
213+
if enumSlice, ok := enum.([]interface{}); ok {
214+
// Check if null is already in enum
215+
hasNull := false
216+
for _, v := range enumSlice {
217+
if v == nil {
218+
hasNull = true
219+
break
220+
}
221+
}
222+
// Add null if not present
223+
if !hasNull {
224+
enumSlice = append(enumSlice, nil)
225+
schema["enum"] = enumSlice
226+
}
227+
}
228+
}
229+
210230
return schema
211231
}
212232

helpers/schema_compiler_test.go

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,3 +704,98 @@ func TestTransformTypeForCoercion_EdgeCases(t *testing.T) {
704704
result = transformTypeForCoercion([]interface{}{"string"})
705705
assert.Equal(t, []interface{}{"string"}, result)
706706
}
707+
708+
func TestTransformNullableSchema_EnumWithoutNull(t *testing.T) {
709+
// Test case: nullable: true with enum that doesn't contain null
710+
// Expected: null should be automatically added to the enum
711+
schema := map[string]interface{}{
712+
"type": "string",
713+
"enum": []interface{}{
714+
"active",
715+
"inactive",
716+
"pending",
717+
"archived",
718+
},
719+
"nullable": true,
720+
}
721+
722+
result := transformNullableSchema(schema)
723+
724+
// nullable keyword should be removed
725+
_, hasNullable := result["nullable"]
726+
assert.False(t, hasNullable)
727+
728+
// type should be converted to array including null
729+
schemaType, ok := result["type"]
730+
require.True(t, ok)
731+
732+
typeArray, ok := schemaType.([]interface{})
733+
require.True(t, ok)
734+
assert.Contains(t, typeArray, "string")
735+
assert.Contains(t, typeArray, "null")
736+
737+
// enum should contain null
738+
enum, ok := result["enum"]
739+
require.True(t, ok)
740+
741+
enumSlice, ok := enum.([]interface{})
742+
require.True(t, ok)
743+
assert.Len(t, enumSlice, 5) // original 4 values + null
744+
assert.Contains(t, enumSlice, "active")
745+
assert.Contains(t, enumSlice, "inactive")
746+
assert.Contains(t, enumSlice, "pending")
747+
assert.Contains(t, enumSlice, "archived")
748+
assert.Contains(t, enumSlice, nil)
749+
}
750+
751+
func TestTransformNullableSchema_EnumWithNull(t *testing.T) {
752+
// Test case: nullable: true with enum that already contains null
753+
// Expected: null should NOT be added twice
754+
schema := map[string]interface{}{
755+
"type": "string",
756+
"enum": []interface{}{
757+
"active",
758+
"inactive",
759+
"pending",
760+
"archived",
761+
nil,
762+
},
763+
"nullable": true,
764+
}
765+
766+
result := transformNullableSchema(schema)
767+
768+
// nullable keyword should be removed
769+
_, hasNullable := result["nullable"]
770+
assert.False(t, hasNullable)
771+
772+
// type should be converted to array including null
773+
schemaType, ok := result["type"]
774+
require.True(t, ok)
775+
776+
typeArray, ok := schemaType.([]interface{})
777+
require.True(t, ok)
778+
assert.Contains(t, typeArray, "string")
779+
assert.Contains(t, typeArray, "null")
780+
781+
// enum should still contain only one null (not duplicated)
782+
enum, ok := result["enum"]
783+
require.True(t, ok)
784+
785+
enumSlice, ok := enum.([]interface{})
786+
require.True(t, ok)
787+
assert.Len(t, enumSlice, 5) // original 5 values (no duplication)
788+
assert.Contains(t, enumSlice, "active")
789+
assert.Contains(t, enumSlice, "inactive")
790+
assert.Contains(t, enumSlice, "pending")
791+
assert.Contains(t, enumSlice, "archived")
792+
793+
// Count how many nulls are in the enum
794+
nullCount := 0
795+
for _, v := range enumSlice {
796+
if v == nil {
797+
nullCount++
798+
}
799+
}
800+
assert.Equal(t, 1, nullCount, "enum should contain exactly one null value")
801+
}

0 commit comments

Comments
 (0)