@@ -2657,3 +2657,94 @@ paths:
26572657 assert .True (t , validB )
26582658 assert .Len (t , errsB , 0 )
26592659}
2660+
2661+ // TestValidateHttpResponse_DiscriminatorOneOf tests that response validation works correctly
2662+ // when the response schema uses oneOf with a discriminator and $ref to component schemas.
2663+ // This is a regression test for https://github.com/pb33f/libopenapi-validator/issues/247
2664+ // where the validator would fail with "json-pointer not found" because discriminator refs
2665+ // were preserved (Bundle mode) instead of fully inlined (Validation mode).
2666+ func TestValidateHttpResponse_DiscriminatorOneOf (t * testing.T ) {
2667+ spec := `openapi: 3.1.0
2668+ info:
2669+ title: Discriminator OneOf Response Test
2670+ version: 1.0.0
2671+ paths:
2672+ /fields:
2673+ get:
2674+ responses:
2675+ '200':
2676+ description: OK
2677+ content:
2678+ application/json:
2679+ schema:
2680+ $ref: '#/components/schemas/Field'
2681+ components:
2682+ schemas:
2683+ BooleanField:
2684+ type: object
2685+ required:
2686+ - field_type
2687+ - default_value
2688+ properties:
2689+ field_type:
2690+ type: string
2691+ const: boolean
2692+ default_value:
2693+ type: boolean
2694+ StringField:
2695+ type: object
2696+ required:
2697+ - field_type
2698+ - max_length
2699+ properties:
2700+ field_type:
2701+ type: string
2702+ const: string
2703+ max_length:
2704+ type: integer
2705+ minimum: 1
2706+ Field:
2707+ oneOf:
2708+ - $ref: '#/components/schemas/BooleanField'
2709+ - $ref: '#/components/schemas/StringField'
2710+ discriminator:
2711+ propertyName: field_type`
2712+
2713+ doc , err := libopenapi .NewDocument ([]byte (spec ))
2714+ require .NoError (t , err )
2715+
2716+ v , errs := NewValidator (doc )
2717+ require .Empty (t , errs )
2718+
2719+ // Valid BooleanField response
2720+ body , _ := json .Marshal (map [string ]interface {}{
2721+ "field_type" : "boolean" ,
2722+ "default_value" : true ,
2723+ })
2724+ request , _ := http .NewRequest (http .MethodGet , "https://example.com/fields" , nil )
2725+ response := & http.Response {
2726+ StatusCode : 200 ,
2727+ Header : http.Header {"Content-Type" : []string {"application/json" }},
2728+ Body : io .NopCloser (bytes .NewBuffer (body )),
2729+ }
2730+
2731+ valid , validationErrors := v .ValidateHttpResponse (request , response )
2732+ assert .True (t , valid , "response validation should pass for valid discriminator oneOf payload" )
2733+ assert .Empty (t , validationErrors , "no validation errors expected" )
2734+
2735+ // Valid StringField response
2736+ body2 , _ := json .Marshal (map [string ]interface {}{
2737+ "field_type" : "string" ,
2738+ "max_length" : 255 ,
2739+ })
2740+ request2 , _ := http .NewRequest (http .MethodGet , "https://example.com/fields" , nil )
2741+ response2 := & http.Response {
2742+ StatusCode : 200 ,
2743+ Header : http.Header {"Content-Type" : []string {"application/json" }},
2744+ Body : io .NopCloser (bytes .NewBuffer (body2 )),
2745+ }
2746+
2747+ valid2 , validationErrors2 := v .ValidateHttpResponse (request2 , response2 )
2748+ assert .True (t , valid2 , "response validation should pass for valid StringField payload" )
2749+ assert .Empty (t , validationErrors2 , "no validation errors expected for StringField" )
2750+ }
0 commit comments