@@ -207,7 +207,7 @@ def test_discriminator_specification_example
207
207
assert_equal ( [ [ 'format' , '/components/schemas/Dog/allOf/1/properties/packSize' ] ] , schemer . validate ( invalid_pack_size ) . map { |error | error . values_at ( 'type' , 'schema_pointer' ) } )
208
208
assert_equal ( [ [ 'required' , '/components/schemas/Pet' ] , [ 'discriminator' , '/components/schemas/Pet' ] ] , schemer . validate ( missing_pet_type ) . map { |error | error . values_at ( 'type' , 'schema_pointer' ) } )
209
209
assert_equal ( [ [ 'required' , '/components/schemas/Pet' ] , [ 'required' , '/components/schemas/Cat/allOf/1' ] ] , schemer . validate ( missing_name ) . map { |error | error . values_at ( 'type' , 'schema_pointer' ) } )
210
- assert_raises ( JSONSchemer :: UnknownRef ) { schemer . validate ( invalid_pet_type ) }
210
+ assert_equal ( [ [ 'discriminator' , '/components/schemas/Pet' ] ] , schemer . validate ( invalid_pet_type ) . map { | error | error . values_at ( 'type' , 'schema_pointer' ) } )
211
211
end
212
212
213
213
def test_all_of_discriminator
@@ -447,6 +447,51 @@ def test_all_of_discriminator_with_non_discriminator_ref
447
447
assert_equal ( [ [ 'required' , '/components/schemas/Pet' ] , [ 'discriminator' , '/components/schemas/Pet' ] , [ 'required' , '/components/schemas/Other' ] ] , schemer . validate ( { } ) . map { |error | error . values_at ( 'type' , 'schema_pointer' ) } )
448
448
end
449
449
450
+ def test_all_of_discriminator_with_remote_ref
451
+ schema = {
452
+ '$id' => 'http://example.com/schema' ,
453
+ 'discriminator' => {
454
+ 'propertyName' => 'petType' ,
455
+ 'mapping' => {
456
+ 'Dog' => 'http://example.com/dog'
457
+ }
458
+ }
459
+ }
460
+ schemer = JSONSchemer . schema (
461
+ schema ,
462
+ :meta_schema => JSONSchemer . openapi31 ,
463
+ :ref_resolver => {
464
+ URI ( 'http://example.com/schema' ) => schema ,
465
+ URI ( 'http://example.com/cat' ) => {
466
+ 'allOf' => [
467
+ { '$ref' => 'http://example.com/schema' } ,
468
+ CAT_SCHEMA
469
+ ]
470
+ } ,
471
+ URI ( 'http://example.com/dog' ) => {
472
+ 'allOf' => [
473
+ { '$ref' => 'http://example.com/schema' } ,
474
+ DOG_SCHEMA
475
+ ]
476
+ }
477
+ } . to_proc
478
+ )
479
+
480
+ assert ( schemer . valid_schema? )
481
+ refute ( schemer . valid? ( CAT ) )
482
+ assert ( schemer . valid? ( CAT . merge ( 'petType' => 'http://example.com/cat' ) ) )
483
+ assert ( schemer . valid? ( DOG ) )
484
+
485
+ invalid_cat = INVALID_CAT . merge ( 'petType' => 'http://example.com/cat' )
486
+ invalid_cat_result = schemer . validate ( invalid_cat , output_format : 'basic' , resolve_enumerators : true )
487
+ assert_equal ( '/discriminator/allOf/1/properties/name/type' , invalid_cat_result . dig ( 'errors' , 0 , 'keywordLocation' ) )
488
+ assert_equal ( 'http://example.com/cat#/allOf/1/properties/name/type' , invalid_cat_result . dig ( 'errors' , 0 , 'absoluteKeywordLocation' ) )
489
+
490
+ invalid_dog_result = schemer . validate ( INVALID_DOG , output_format : 'basic' , resolve_enumerators : true )
491
+ assert_equal ( '/discriminator/allOf/1/properties/bark/type' , invalid_dog_result . dig ( 'errors' , 0 , 'keywordLocation' ) )
492
+ assert_equal ( 'http://example.com/dog#/allOf/1/properties/bark/type' , invalid_dog_result . dig ( 'errors' , 0 , 'absoluteKeywordLocation' ) )
493
+ end
494
+
450
495
def test_any_of_discriminator_without_matching_schema
451
496
openapi = {
452
497
'openapi' => '3.1.0' ,
@@ -513,6 +558,60 @@ def test_one_of_discriminator_without_matching_schema
513
558
assert_equal ( [ [ 'discriminator' , '/components/schemas/MyResponseType' ] ] , schemer . validate ( INVALID_LIZARD ) . map { |error | error . values_at ( 'type' , 'schema_pointer' ) } )
514
559
end
515
560
561
+ def test_any_of_discriminator_ignores_nested_schemas
562
+ openapi = {
563
+ 'openapi' => '3.1.0' ,
564
+ 'components' => {
565
+ 'schemas' => {
566
+ 'MyResponseType' => {
567
+ 'anyOf' => [
568
+ { '$ref' => '#/components/schemas/Cat' } ,
569
+ { '$ref' => '#/components/schemas/Cat/$defs/nah' }
570
+ ] ,
571
+ 'discriminator' => {
572
+ 'propertyName' => 'petType'
573
+ }
574
+ } ,
575
+ 'Cat' => CAT_SCHEMA . merge ( '$defs' => { 'nah' => { } } )
576
+ }
577
+ }
578
+ }
579
+
580
+ schemer = JSONSchemer . openapi ( openapi ) . schema ( 'MyResponseType' )
581
+
582
+ assert ( schemer . valid_schema? )
583
+ assert ( schemer . valid? ( CAT ) )
584
+ refute ( schemer . valid? ( CAT . merge ( 'petType' => 'nah' ) ) )
585
+ refute ( schemer . valid? ( CAT . merge ( 'petType' => 'Cat/$defs/nah' ) ) )
586
+ end
587
+
588
+ def test_one_of_discriminator_ignores_nested_schemas
589
+ openapi = {
590
+ 'openapi' => '3.1.0' ,
591
+ 'components' => {
592
+ 'schemas' => {
593
+ 'MyResponseType' => {
594
+ 'oneOf' => [
595
+ { '$ref' => '#/components/schemas/Cat' } ,
596
+ { '$ref' => '#/components/schemas/Cat/$defs/nah' }
597
+ ] ,
598
+ 'discriminator' => {
599
+ 'propertyName' => 'petType'
600
+ }
601
+ } ,
602
+ 'Cat' => CAT_SCHEMA . merge ( '$defs' => { 'nah' => { } } )
603
+ }
604
+ }
605
+ }
606
+
607
+ schemer = JSONSchemer . openapi ( openapi ) . schema ( 'MyResponseType' )
608
+
609
+ assert ( schemer . valid_schema? )
610
+ assert ( schemer . valid? ( CAT ) )
611
+ refute ( schemer . valid? ( CAT . merge ( 'petType' => 'nah' ) ) )
612
+ refute ( schemer . valid? ( CAT . merge ( 'petType' => 'Cat/$defs/nah' ) ) )
613
+ end
614
+
516
615
def test_discrimator_mapping
517
616
openapi = {
518
617
'openapi' => '3.1.0' ,
@@ -542,7 +641,7 @@ def test_discrimator_mapping
542
641
543
642
assert ( schemer . valid_schema? )
544
643
assert ( schemer . valid? ( CAT . merge ( 'petType' => 'c' ) ) )
545
- assert ( schemer . valid? ( MISTY . merge ( 'petType' => 'Cat' ) ) )
644
+ refute ( schemer . valid? ( MISTY . merge ( 'petType' => 'Cat' ) ) )
546
645
assert_equal ( [ '/components/schemas/Cat/properties/name' ] , schemer . validate ( INVALID_CAT . merge ( 'petType' => 'c' ) ) . map { |error | error . fetch ( 'schema_pointer' ) } )
547
646
assert ( schemer . valid? ( DOG . merge ( 'petType' => 'd' ) ) )
548
647
assert_equal ( [ '/components/schemas/Dog/properties/bark' ] , schemer . validate ( INVALID_DOG . merge ( 'petType' => 'dog' ) ) . map { |error | error . fetch ( 'schema_pointer' ) } )
@@ -585,8 +684,9 @@ def test_non_json_pointer_discriminator
585
684
assert ( schemer . valid? ( CAT ) )
586
685
assert ( schemer . valid? ( MISTY ) )
587
686
assert_equal ( [ '/components/schemas/Cat/properties/name' ] , schemer . validate ( INVALID_CAT ) . map { |error | error . fetch ( 'schema_pointer' ) } )
588
- assert ( schemer . valid? ( DOG ) )
589
- assert_equal ( [ '/components/schemas/Dog/properties/bark' ] , schemer . validate ( INVALID_DOG ) . map { |error | error . fetch ( 'schema_pointer' ) } )
687
+ refute ( schemer . valid? ( DOG ) )
688
+ assert_equal ( [ '/components/schemas/MyResponseType' ] , schemer . validate ( INVALID_DOG ) . map { |error | error . fetch ( 'schema_pointer' ) } )
689
+ assert_equal ( [ '/components/schemas/Dog/properties/bark' ] , schemer . validate ( INVALID_DOG . merge ( 'petType' => 'dog' ) ) . map { |error | error . fetch ( 'schema_pointer' ) } )
590
690
assert ( schemer . valid? ( LIZARD ) )
591
691
assert_equal ( [ '/components/schemas/Lizard/properties/lovesRocks' ] , schemer . validate ( INVALID_LIZARD ) . map { |error | error . fetch ( 'schema_pointer' ) } )
592
692
assert ( schemer . valid? ( MONSTER ) )
0 commit comments