@@ -3197,3 +3197,205 @@ components:
31973197 }
31983198}
31993199
3200+ func TestSchemaType_ValidateDiscriminator (t * testing.T ) {
3201+ tests := []struct {
3202+ name string
3203+ yaml string
3204+ expectedErrors []struct {
3205+ message string
3206+ path string
3207+ }
3208+ }{
3209+ {
3210+ name : "MissingProperty" ,
3211+ yaml : `openapi: 3.0.3
3212+ components:
3213+ schemas:
3214+ Pet:
3215+ type: object
3216+ properties:
3217+ name:
3218+ type: string
3219+ age:
3220+ type: integer
3221+ discriminator:
3222+ propertyName: petType
3223+ mapping:
3224+ dog: '#/components/schemas/Dog'
3225+ cat: '#/components/schemas/Cat'` ,
3226+ expectedErrors : []struct { message , path string }{
3227+ {
3228+ message : "discriminator property `petType` is not defined in schema properties" ,
3229+ path : "$.components.schemas['Pet'].discriminator" ,
3230+ },
3231+ },
3232+ },
3233+ {
3234+ name : "PropertyExists" ,
3235+ yaml : `openapi: 3.0.3
3236+ components:
3237+ schemas:
3238+ Pet:
3239+ type: object
3240+ properties:
3241+ petType:
3242+ type: string
3243+ name:
3244+ type: string
3245+ age:
3246+ type: integer
3247+ discriminator:
3248+ propertyName: petType
3249+ mapping:
3250+ dog: '#/components/schemas/Dog'
3251+ cat: '#/components/schemas/Cat'` ,
3252+ expectedErrors : []struct { message , path string }{},
3253+ },
3254+ {
3255+ name : "PropertyInAllOf" ,
3256+ yaml : `openapi: 3.0.3
3257+ components:
3258+ schemas:
3259+ Pet:
3260+ type: object
3261+ allOf:
3262+ - type: object
3263+ properties:
3264+ petType:
3265+ type: string
3266+ name:
3267+ type: string
3268+ discriminator:
3269+ propertyName: petType
3270+ mapping:
3271+ dog: '#/components/schemas/Dog'
3272+ cat: '#/components/schemas/Cat'` ,
3273+ expectedErrors : []struct { message , path string }{},
3274+ },
3275+ {
3276+ name : "PropertyInOneOf" ,
3277+ yaml : `openapi: 3.0.3
3278+ components:
3279+ schemas:
3280+ Pet:
3281+ type: object
3282+ oneOf:
3283+ - type: object
3284+ properties:
3285+ petType:
3286+ type: string
3287+ breed:
3288+ type: string
3289+ - type: object
3290+ properties:
3291+ petType:
3292+ type: string
3293+ color:
3294+ type: string
3295+ discriminator:
3296+ propertyName: petType
3297+ mapping:
3298+ dog: '#/components/schemas/Dog'
3299+ cat: '#/components/schemas/Cat'` ,
3300+ expectedErrors : []struct { message , path string }{},
3301+ },
3302+ {
3303+ name : "PropertyInAnyOf" ,
3304+ yaml : `openapi: 3.0.3
3305+ components:
3306+ schemas:
3307+ Pet:
3308+ type: object
3309+ anyOf:
3310+ - type: object
3311+ properties:
3312+ petType:
3313+ type: string
3314+ name:
3315+ type: string
3316+ discriminator:
3317+ propertyName: petType` ,
3318+ expectedErrors : []struct { message , path string }{},
3319+ },
3320+ {
3321+ name : "EmptyPropertyName" ,
3322+ yaml : `openapi: 3.0.3
3323+ components:
3324+ schemas:
3325+ Pet:
3326+ type: object
3327+ properties:
3328+ name:
3329+ type: string
3330+ discriminator:
3331+ propertyName: ""` ,
3332+ expectedErrors : []struct { message , path string }{
3333+ {
3334+ message : "discriminator object is missing required `propertyName` field" ,
3335+ path : "$.components.schemas['Pet'].discriminator" ,
3336+ },
3337+ },
3338+ },
3339+ {
3340+ name : "NoDiscriminator" ,
3341+ yaml : `openapi: 3.0.3
3342+ components:
3343+ schemas:
3344+ Pet:
3345+ type: object
3346+ properties:
3347+ name:
3348+ type: string
3349+ age:
3350+ type: integer` ,
3351+ expectedErrors : []struct { message , path string }{},
3352+ },
3353+ {
3354+ name : "WithoutMapping" ,
3355+ yaml : `openapi: 3.0.3
3356+ components:
3357+ schemas:
3358+ Pet:
3359+ type: object
3360+ properties:
3361+ petType:
3362+ type: string
3363+ name:
3364+ type: string
3365+ discriminator:
3366+ propertyName: petType` ,
3367+ expectedErrors : []struct { message , path string }{},
3368+ },
3369+ }
3370+
3371+ for _ , tt := range tests {
3372+ t .Run (tt .name , func (t * testing.T ) {
3373+ document , err := libopenapi .NewDocument ([]byte (tt .yaml ))
3374+ if err != nil {
3375+ t .Fatalf ("cannot create document: %v" , err )
3376+ }
3377+
3378+ m , _ := document .BuildV3Model ()
3379+ drDocument := drModel .NewDrDocument (m )
3380+
3381+ rule := buildOpenApiTestRuleAction ("$" , "schema-type-check" , "" , nil )
3382+ ctx := buildOpenApiTestContext (model .CastToRuleAction (rule .Then ), nil )
3383+
3384+ ctx .Document = document
3385+ ctx .DrDocument = drDocument
3386+ ctx .Rule = & rule
3387+
3388+ def := SchemaTypeCheck {}
3389+ res := def .RunRule (nil , ctx )
3390+
3391+ assert .Len (t , res , len (tt .expectedErrors ))
3392+ for i , expectedErr := range tt .expectedErrors {
3393+ if i < len (res ) {
3394+ assert .Equal (t , expectedErr .message , res [i ].Message )
3395+ assert .Equal (t , expectedErr .path , res [i ].Path )
3396+ }
3397+ }
3398+ })
3399+ }
3400+ }
3401+
0 commit comments