@@ -350,6 +350,73 @@ paths:
350350 schema :
351351 $ref : " #/components/schemas/BaseEmptySubschema"
352352
353+ /discriminator-nested-allof :
354+ post :
355+ tags :
356+ - discriminator
357+ summary : Nested Discriminator in allOf
358+ description : |
359+ Tests discriminators nested within allOf structures, where the discriminator
360+ and its property definition are inside an allOf item rather than at the top level.
361+ This is a common pattern when combining shared properties with discriminated unions.
362+
363+ Schema:
364+ ```yaml
365+ allOf:
366+ - $ref: '#/components/schemas/CommonProps'
367+ - oneOf:
368+ - $ref: '#/components/schemas/NestedVariantA'
369+ - $ref: '#/components/schemas/NestedVariantB'
370+ discriminator:
371+ propertyName: variantType
372+ mapping:
373+ variant-a: '#/components/schemas/NestedVariantA'
374+ variant-b: '#/components/schemas/NestedVariantB'
375+ ```
376+ requestBody :
377+ required : true
378+ content :
379+ application/json :
380+ schema :
381+ $ref : " #/components/schemas/NestedDiscriminatorBase"
382+ responses :
383+ " 200 " :
384+ description : Successful response
385+ content :
386+ application/json :
387+ schema :
388+ $ref : " #/components/schemas/NestedDiscriminatorBase"
389+
390+ /discriminator-doubly-nested :
391+ post :
392+ tags :
393+ - discriminator
394+ summary : Doubly Nested Discriminators (Issue # 1302 Full Scenario)
395+ description : |
396+ Tests the full scenario from issue #1302 with doubly-nested discriminators:
397+ - Outer level: allOf with discriminator on "type" selecting TypeA/TypeB/TypeC
398+ - TypeA: has allOf with its own nested discriminator on "mode"
399+ - TypeB: has allOf with its own nested discriminator on "mode"
400+ - TypeC: has discriminator on "mode" at root level (NOT in allOf)
401+
402+ This tests:
403+ 1. Discriminators nested in allOf are properly detected
404+ 2. Inner discriminators work after selecting outer type
405+ 3. TypeC pattern (discriminator at root) still works
406+ requestBody :
407+ required : true
408+ content :
409+ application/json :
410+ schema :
411+ $ref : " #/components/schemas/DoublyNestedBase"
412+ responses :
413+ " 200 " :
414+ description : Successful response
415+ content :
416+ application/json :
417+ schema :
418+ $ref : " #/components/schemas/DoublyNestedBase"
419+
353420components :
354421 schemas :
355422 BaseBasic :
@@ -569,3 +636,227 @@ components:
569636 type : object
570637 allOf :
571638 - $ref : " #/components/schemas/BaseEmptySubschema"
639+
640+ # Schemas for nested discriminator test
641+ CommonProps :
642+ type : object
643+ properties :
644+ id :
645+ type : string
646+ format : uuid
647+ description : Unique identifier
648+ createdAt :
649+ type : string
650+ format : date-time
651+ description : Creation timestamp
652+ required :
653+ - id
654+
655+ NestedDiscriminatorBase :
656+ allOf :
657+ - $ref : " #/components/schemas/CommonProps"
658+ - oneOf :
659+ - $ref : " #/components/schemas/NestedVariantA"
660+ - $ref : " #/components/schemas/NestedVariantB"
661+ discriminator :
662+ propertyName : variantType
663+ mapping :
664+ variant-a : " #/components/schemas/NestedVariantA"
665+ variant-b : " #/components/schemas/NestedVariantB"
666+
667+ NestedVariantA :
668+ type : object
669+ properties :
670+ variantType :
671+ type : string
672+ enum : ["variant-a"]
673+ configA :
674+ type : object
675+ properties :
676+ settingA1 :
677+ type : string
678+ settingA2 :
679+ type : integer
680+ required :
681+ - variantType
682+
683+ NestedVariantB :
684+ type : object
685+ properties :
686+ variantType :
687+ type : string
688+ enum : ["variant-b"]
689+ configB :
690+ type : object
691+ properties :
692+ settingB1 :
693+ type : boolean
694+ settingB2 :
695+ type : array
696+ items :
697+ type : string
698+ required :
699+ - variantType
700+
701+ # Test case for doubly-nested discriminators (issue #1302 full scenario)
702+ # Outer: allOf with discriminator on "type"
703+ # Inner: TypeA and TypeB each have their own discriminator on "mode"
704+ DoublyNestedBase :
705+ allOf :
706+ - $ref : " #/components/schemas/OuterCommonProps"
707+ - oneOf :
708+ - $ref : " #/components/schemas/OuterTypeA"
709+ - $ref : " #/components/schemas/OuterTypeB"
710+ - $ref : " #/components/schemas/OuterTypeC"
711+ discriminator :
712+ propertyName : type
713+ mapping :
714+ type-a : " #/components/schemas/OuterTypeA"
715+ type-b : " #/components/schemas/OuterTypeB"
716+ type-c : " #/components/schemas/OuterTypeC"
717+
718+ OuterCommonProps :
719+ type : object
720+ properties :
721+ id :
722+ type : string
723+ format : uuid
724+ name :
725+ type : string
726+
727+ # TypeA: has allOf with its own nested discriminator
728+ OuterTypeA :
729+ title : TypeA
730+ allOf :
731+ - $ref : " #/components/schemas/InnerCommonProps"
732+ - oneOf :
733+ - $ref : " #/components/schemas/ModeA1"
734+ - $ref : " #/components/schemas/ModeA2"
735+ discriminator :
736+ propertyName : mode
737+ mapping :
738+ mode-a1 : " #/components/schemas/ModeA1"
739+ mode-a2 : " #/components/schemas/ModeA2"
740+ properties :
741+ type :
742+ type : string
743+ enum : ["type-a"]
744+ required :
745+ - type
746+
747+ # TypeB: also has allOf with its own nested discriminator
748+ OuterTypeB :
749+ title : TypeB
750+ allOf :
751+ - $ref : " #/components/schemas/InnerCommonProps"
752+ - oneOf :
753+ - $ref : " #/components/schemas/ModeB1"
754+ - $ref : " #/components/schemas/ModeB2"
755+ discriminator :
756+ propertyName : mode
757+ mapping :
758+ mode-b1 : " #/components/schemas/ModeB1"
759+ mode-b2 : " #/components/schemas/ModeB2"
760+ properties :
761+ type :
762+ type : string
763+ enum : ["type-b"]
764+ required :
765+ - type
766+
767+ # TypeC: has discriminator at root (NOT in allOf)
768+ OuterTypeC :
769+ title : TypeC
770+ type : object
771+ oneOf :
772+ - $ref : " #/components/schemas/ModeC1"
773+ - $ref : " #/components/schemas/ModeC2"
774+ discriminator :
775+ propertyName : mode
776+ mapping :
777+ mode-c1 : " #/components/schemas/ModeC1"
778+ mode-c2 : " #/components/schemas/ModeC2"
779+ properties :
780+ type :
781+ type : string
782+ enum : ["type-c"]
783+ required :
784+ - type
785+
786+ InnerCommonProps :
787+ type : object
788+ properties :
789+ timestamp :
790+ type : string
791+ format : date-time
792+
793+ ModeA1 :
794+ type : object
795+ properties :
796+ mode :
797+ type : string
798+ enum : ["mode-a1"]
799+ settingA1 :
800+ type : string
801+ required :
802+ - mode
803+
804+ ModeA2 :
805+ type : object
806+ properties :
807+ mode :
808+ type : string
809+ enum : ["mode-a2"]
810+ settingA2 :
811+ type : number
812+ required :
813+ - mode
814+
815+ ModeB1 :
816+ type : object
817+ properties :
818+ mode :
819+ type : string
820+ enum : ["mode-b1"]
821+ settingB1 :
822+ type : boolean
823+ required :
824+ - mode
825+
826+ ModeB2 :
827+ type : object
828+ properties :
829+ mode :
830+ type : string
831+ enum : ["mode-b2"]
832+ settingB2 :
833+ type : array
834+ items :
835+ type : string
836+ required :
837+ - mode
838+
839+ ModeC1 :
840+ type : object
841+ properties :
842+ mode :
843+ type : string
844+ enum : ["mode-c1"]
845+ settingC1 :
846+ type : integer
847+ required :
848+ - mode
849+
850+ ModeC2 :
851+ type : object
852+ properties :
853+ mode :
854+ type : string
855+ enum : ["mode-c2"]
856+ settingC2 :
857+ type : object
858+ properties :
859+ nested :
860+ type : string
861+ required :
862+ - mode
0 commit comments