@@ -750,6 +750,118 @@ components:
750750 assert .Contains (t , petEntry .DefinitionPath , "Pet" )
751751}
752752
753+ func TestSchemaId_IgnoredUnderExampleAndExamples (t * testing.T ) {
754+ t .Run ("example_payload" , func (t * testing.T ) {
755+ spec := `openapi: "3.1.0"
756+ info:
757+ title: Test API
758+ version: 1.0.0
759+ paths:
760+ /pets:
761+ get:
762+ responses:
763+ "200":
764+ description: ok
765+ content:
766+ application/json:
767+ schema:
768+ $id: "https://example.com/schemas/pet.json"
769+ type: object
770+ properties:
771+ id:
772+ type: string
773+ example:
774+ $id: "https://example.com/should-not-register"
775+ id: "1"
776+ `
777+ var rootNode yaml.Node
778+ err := yaml .Unmarshal ([]byte (spec ), & rootNode )
779+ assert .NoError (t , err )
780+
781+ config := CreateClosedAPIIndexConfig ()
782+ config .SpecAbsolutePath = "https://example.com/openapi.yaml"
783+ index := NewSpecIndexWithConfig (& rootNode , config )
784+ assert .NotNil (t , index )
785+
786+ allIds := index .GetAllSchemaIds ()
787+ assert .Len (t , allIds , 1 )
788+ assert .NotNil (t , allIds ["https://example.com/schemas/pet.json" ])
789+ assert .Nil (t , allIds ["https://example.com/should-not-register" ])
790+ })
791+
792+ t .Run ("examples_named_value" , func (t * testing.T ) {
793+ spec := `openapi: "3.1.0"
794+ info:
795+ title: Test API
796+ version: 1.0.0
797+ paths:
798+ /widgets:
799+ get:
800+ responses:
801+ "200":
802+ description: ok
803+ content:
804+ application/json:
805+ schema:
806+ $id: "https://example.com/schemas/widget.json"
807+ type: object
808+ examples:
809+ sample:
810+ value:
811+ $id: "https://example.com/fake-from-examples"
812+ foo: bar
813+ `
814+ var rootNode yaml.Node
815+ err := yaml .Unmarshal ([]byte (spec ), & rootNode )
816+ assert .NoError (t , err )
817+
818+ config := CreateClosedAPIIndexConfig ()
819+ config .SpecAbsolutePath = "https://example.com/openapi.yaml"
820+ index := NewSpecIndexWithConfig (& rootNode , config )
821+ assert .NotNil (t , index )
822+
823+ allIds := index .GetAllSchemaIds ()
824+ assert .Len (t , allIds , 1 )
825+ assert .NotNil (t , allIds ["https://example.com/schemas/widget.json" ])
826+ assert .Nil (t , allIds ["https://example.com/fake-from-examples" ])
827+ })
828+
829+ t .Run ("invalid_id_in_example_no_index_error" , func (t * testing.T ) {
830+ spec := `openapi: "3.1.0"
831+ info:
832+ title: Test API
833+ version: 1.0.0
834+ paths:
835+ /x:
836+ get:
837+ responses:
838+ "200":
839+ description: ok
840+ content:
841+ application/json:
842+ schema:
843+ type: object
844+ example:
845+ $id: "https://bad.com/schema#fragment"
846+ k: v
847+ `
848+ var rootNode yaml.Node
849+ err := yaml .Unmarshal ([]byte (spec ), & rootNode )
850+ assert .NoError (t , err )
851+
852+ config := CreateClosedAPIIndexConfig ()
853+ config .SpecAbsolutePath = "https://example.com/openapi.yaml"
854+ index := NewSpecIndexWithConfig (& rootNode , config )
855+ assert .NotNil (t , index )
856+
857+ assert .Len (t , index .GetAllSchemaIds (), 0 )
858+ for _ , e := range index .GetReferenceIndexErrors () {
859+ assert .False (t , strings .Contains (e .Error (), "invalid $id" ),
860+ "$id inside example must not be validated as schema $id: %v" , e )
861+ }
862+ })
863+ }
864+
753865func TestSchemaId_ExtractionWithInvalidId (t * testing.T ) {
754866 // OpenAPI 3.1 spec with invalid $id (contains fragment)
755867 spec := `openapi: "3.1.0"
0 commit comments