@@ -729,8 +729,9 @@ func TestNormalizeSchema_OptionsDependencies_NestedObject(t *testing.T) {
729729func TestNormalizeSchema_OptionsDependencies_NotInRequired (t * testing.T ) {
730730 t .Parallel ()
731731
732- // Schema with options.dependencies but the field is not in the required array
733- // The transformation should still add the if/then construct but not modify required
732+ // Schema with options.dependencies but the field is NOT in the required array.
733+ // options.dependencies is for UI visibility, NOT for making fields required.
734+ // Therefore, if the field was not originally required, we should NOT add if/then for it.
734735 schema := []byte (`
735736{
736737 "type": "object",
@@ -765,10 +766,10 @@ func TestNormalizeSchema_OptionsDependencies_NotInRequired(t *testing.T) {
765766 require .True (t , ok )
766767 assert .Equal (t , []any {"mode" }, required )
767768
768- // Check that allOf with if/then is still added
769- allOf , ok := result [ "allOf" ].([] any )
770- require . True ( t , ok )
771- require . Len (t , allOf , 1 )
769+ // Check that NO allOf was added - optional_field was not in required,
770+ // so we don't need conditional requirement logic
771+ _ , hasAllOf := result [ "allOf" ]
772+ assert . False (t , hasAllOf , "allOf should NOT be added for fields that were not originally required" )
772773}
773774
774775func TestNormalizeSchema_OptionsDependencies_Validation (t * testing.T ) {
@@ -962,6 +963,156 @@ func TestNormalizeSchema_ExistingAllOfIfThen(t *testing.T) {
962963 require .NoError (t , err , "Should pass validation when append_date=1 and append_date_format is provided" )
963964}
964965
966+ func TestNormalizeSchema_OptionsDependencies_MissingDependencyField (t * testing.T ) {
967+ t .Parallel ()
968+
969+ // This test uses the actual schema from kds-team.app-orchestration-trigger-queue-v2 component.
970+ // triggerActionOnFailure is NOT in the required array.
971+ // triggerActionOnFailure has options.dependencies: { waitUntilFinish: true }
972+ // actionOnFailureSettings has options.dependencies: { triggerActionOnFailure: true }
973+ schema := []byte (`
974+ {
975+ "type": "object",
976+ "required": ["waitUntilFinish", "#kbcToken", "kbcUrl", "orchestrationId"],
977+ "properties": {
978+ "waitUntilFinish": {
979+ "type": "boolean"
980+ },
981+ "triggerActionOnFailure": {
982+ "type": "boolean",
983+ "options": {
984+ "dependencies": {
985+ "waitUntilFinish": true
986+ }
987+ }
988+ },
989+ "actionOnFailureSettings": {
990+ "type": "object",
991+ "required": ["failureConfigurationId"],
992+ "properties": {
993+ "failureConfigurationId": {
994+ "type": "string"
995+ }
996+ },
997+ "options": {
998+ "dependencies": {
999+ "triggerActionOnFailure": true
1000+ }
1001+ }
1002+ },
1003+ "#kbcToken": {
1004+ "type": "string"
1005+ },
1006+ "kbcUrl": {
1007+ "type": "string"
1008+ },
1009+ "orchestrationId": {
1010+ "type": "string"
1011+ }
1012+ }
1013+ }
1014+ ` )
1015+
1016+ // Test 1: triggerActionOnFailure field is missing entirely (fire-and-forget config)
1017+ // This should PASS - actionOnFailureSettings should NOT be required
1018+ content1 := orderedmap .FromPairs ([]orderedmap.Pair {
1019+ {
1020+ Key : "parameters" ,
1021+ Value : orderedmap .FromPairs ([]orderedmap.Pair {
1022+ {Key : "waitUntilFinish" , Value : false },
1023+ {Key : "#kbcToken" , Value : "xxx" },
1024+ {Key : "kbcUrl" , Value : "-" },
1025+ {Key : "orchestrationId" , Value : "123" },
1026+ // triggerActionOnFailure is NOT present at all
1027+ }),
1028+ },
1029+ })
1030+ err := ValidateContent (schema , content1 )
1031+ require .NoError (t , err , "Should pass when triggerActionOnFailure field is missing (undefined)" )
1032+
1033+ // Test 2: triggerActionOnFailure is explicitly false
1034+ // This should PASS - actionOnFailureSettings should NOT be required
1035+ content2 := orderedmap .FromPairs ([]orderedmap.Pair {
1036+ {
1037+ Key : "parameters" ,
1038+ Value : orderedmap .FromPairs ([]orderedmap.Pair {
1039+ {Key : "waitUntilFinish" , Value : true },
1040+ {Key : "#kbcToken" , Value : "xxx" },
1041+ {Key : "kbcUrl" , Value : "-" },
1042+ {Key : "triggerActionOnFailure" , Value : false },
1043+ {Key : "orchestrationId" , Value : "123" },
1044+ }),
1045+ },
1046+ })
1047+ err = ValidateContent (schema , content2 )
1048+ require .NoError (t , err , "Should pass when triggerActionOnFailure is explicitly false" )
1049+
1050+ // Test 3: triggerActionOnFailure is true but actionOnFailureSettings is missing
1051+ // This should PASS - actionOnFailureSettings was NOT in the required array,
1052+ // options.dependencies is only for UI visibility, not for making fields required.
1053+ content3 := orderedmap .FromPairs ([]orderedmap.Pair {
1054+ {
1055+ Key : "parameters" ,
1056+ Value : orderedmap .FromPairs ([]orderedmap.Pair {
1057+ {Key : "waitUntilFinish" , Value : true },
1058+ {Key : "#kbcToken" , Value : "xxx" },
1059+ {Key : "kbcUrl" , Value : "-" },
1060+ {Key : "triggerActionOnFailure" , Value : true },
1061+ {Key : "orchestrationId" , Value : "123" },
1062+ }),
1063+ },
1064+ })
1065+ err = ValidateContent (schema , content3 )
1066+ require .NoError (t , err , "Should pass - actionOnFailureSettings was NOT in required, options.dependencies is for visibility only" )
1067+
1068+ // Test 4: triggerActionOnFailure is true and actionOnFailureSettings is provided but missing internal required field
1069+ // This should FAIL - failureConfigurationId is required WITHIN actionOnFailureSettings
1070+ content4 := orderedmap .FromPairs ([]orderedmap.Pair {
1071+ {
1072+ Key : "parameters" ,
1073+ Value : orderedmap .FromPairs ([]orderedmap.Pair {
1074+ {Key : "waitUntilFinish" , Value : true },
1075+ {Key : "#kbcToken" , Value : "xxx" },
1076+ {Key : "kbcUrl" , Value : "-" },
1077+ {Key : "triggerActionOnFailure" , Value : true },
1078+ {Key : "orchestrationId" , Value : "123" },
1079+ {
1080+ Key : "actionOnFailureSettings" ,
1081+ Value : orderedmap .FromPairs ([]orderedmap.Pair {
1082+ // missing failureConfigurationId
1083+ }),
1084+ },
1085+ }),
1086+ },
1087+ })
1088+ err = ValidateContent (schema , content4 )
1089+ require .Error (t , err , "Should fail - failureConfigurationId is required within actionOnFailureSettings" )
1090+ assert .Contains (t , err .Error (), "failureConfigurationId" )
1091+
1092+ // Test 5: triggerActionOnFailure is true and actionOnFailureSettings is provided with required field
1093+ // This should PASS
1094+ content5 := orderedmap .FromPairs ([]orderedmap.Pair {
1095+ {
1096+ Key : "parameters" ,
1097+ Value : orderedmap .FromPairs ([]orderedmap.Pair {
1098+ {Key : "waitUntilFinish" , Value : true },
1099+ {Key : "#kbcToken" , Value : "xxx" },
1100+ {Key : "kbcUrl" , Value : "-" },
1101+ {Key : "triggerActionOnFailure" , Value : true },
1102+ {Key : "orchestrationId" , Value : "123" },
1103+ {
1104+ Key : "actionOnFailureSettings" ,
1105+ Value : orderedmap .FromPairs ([]orderedmap.Pair {
1106+ {Key : "failureConfigurationId" , Value : "456" },
1107+ }),
1108+ },
1109+ }),
1110+ },
1111+ })
1112+ err = ValidateContent (schema , content5 )
1113+ require .NoError (t , err , "Should pass when actionOnFailureSettings is provided with required fields" )
1114+ }
1115+
9651116func getTestSchema () []byte {
9661117 return []byte (`
9671118{
0 commit comments