@@ -1086,6 +1086,110 @@ describe('findObsByFormField', () => {
10861086 expect ( matchedObs . length ) . toBe ( 1 ) ;
10871087 expect ( matchedObs [ 0 ] ) . toBe ( obsList [ 3 ] ) ;
10881088 } ) ;
1089+
1090+ it ( 'Should scope concept fallback to the parent obsGroup when field has a groupId' , ( ) => {
1091+ // Scenario: A form has two obsGroups — "Blood Tests" and "Urine Tests" — whose
1092+ // child fields share the same "Result Value" concept. When editing an encounter
1093+ // that only has Urine Test data, the Blood Test child field should NOT steal the
1094+ // Urine Test obs via concept fallback.
1095+ const resultValueConcept = 'shared-result-value-concept-uuid' ;
1096+
1097+ const bloodTestResultField : FormField = {
1098+ label : 'Blood Test Result' ,
1099+ type : 'obs' ,
1100+ questionOptions : { rendering : 'number' , concept : resultValueConcept } ,
1101+ id : 'blood_test_result' ,
1102+ meta : { groupId : 'bloodTestGroup' } ,
1103+ } ;
1104+
1105+ const urineResultObs = {
1106+ uuid : 'urine-result-obs-uuid' ,
1107+ concept : { uuid : resultValueConcept } ,
1108+ formFieldNamespace : 'rfe-forms' ,
1109+ formFieldPath : 'rfe-forms-urine_test_result' ,
1110+ } ;
1111+
1112+ const urineGroupObs = {
1113+ uuid : 'urine-group-obs-uuid' ,
1114+ concept : { uuid : 'urine-group-concept' } ,
1115+ formFieldNamespace : 'rfe-forms' ,
1116+ formFieldPath : 'rfe-forms-urineTestGroup' ,
1117+ groupMembers : [ urineResultObs ] ,
1118+ } ;
1119+
1120+ const flatObs = [ urineGroupObs , urineResultObs ] ;
1121+
1122+ // Blood test field should NOT match the urine test obs
1123+ const matched = findObsByFormField ( flatObs , [ ] , bloodTestResultField ) ;
1124+ expect ( matched . length ) . toBe ( 0 ) ;
1125+ } ) ;
1126+
1127+ it ( 'Should allow concept fallback within the correct parent obsGroup' , ( ) => {
1128+ const resultValueConcept = 'shared-result-value-concept-uuid' ;
1129+
1130+ const urineResultField : FormField = {
1131+ label : 'Urine Test Result' ,
1132+ type : 'obs' ,
1133+ questionOptions : { rendering : 'number' , concept : resultValueConcept } ,
1134+ id : 'urine_test_result_v2' , // different ID so path match fails
1135+ meta : { groupId : 'urineTestGroup' } ,
1136+ } ;
1137+
1138+ const urineResultObs = {
1139+ uuid : 'urine-result-obs-uuid' ,
1140+ concept : { uuid : resultValueConcept } ,
1141+ formFieldNamespace : 'rfe-forms' ,
1142+ formFieldPath : 'rfe-forms-urine_test_result' , // doesn't match field ID
1143+ } ;
1144+
1145+ const urineGroupObs = {
1146+ uuid : 'urine-group-obs-uuid' ,
1147+ concept : { uuid : 'urine-group-concept' } ,
1148+ formFieldNamespace : 'rfe-forms' ,
1149+ formFieldPath : 'rfe-forms-urineTestGroup' ,
1150+ groupMembers : [ urineResultObs ] ,
1151+ } ;
1152+
1153+ const flatObs = [ urineGroupObs , urineResultObs ] ;
1154+
1155+ // Urine result field SHOULD match via concept fallback (correct group)
1156+ const matched = findObsByFormField ( flatObs , [ ] , urineResultField ) ;
1157+ expect ( matched . length ) . toBe ( 1 ) ;
1158+ expect ( matched [ 0 ] ) . toBe ( urineResultObs ) ;
1159+ } ) ;
1160+
1161+ it ( 'Should preserve backward compatibility when parent obsGroup has no formFieldPath' , ( ) => {
1162+ const resultValueConcept = 'shared-result-value-concept-uuid' ;
1163+
1164+ const childField : FormField = {
1165+ label : 'Test Result' ,
1166+ type : 'obs' ,
1167+ questionOptions : { rendering : 'number' , concept : resultValueConcept } ,
1168+ id : 'test_result' ,
1169+ meta : { groupId : 'labTestGroup' } ,
1170+ } ;
1171+
1172+ const resultObs = {
1173+ uuid : 'result-obs-uuid' ,
1174+ concept : { uuid : resultValueConcept } ,
1175+ formFieldNamespace : 'rfe-forms' ,
1176+ formFieldPath : 'rfe-forms-old_field_id' ,
1177+ } ;
1178+
1179+ // Parent group saved from an older form version without formFieldPath
1180+ const groupObs = {
1181+ uuid : 'group-obs-uuid' ,
1182+ concept : { uuid : 'group-concept' } ,
1183+ groupMembers : [ resultObs ] ,
1184+ } ;
1185+
1186+ const flatObs = [ groupObs , resultObs ] ;
1187+
1188+ // No formFieldPath on parent → backward compat → allow fallback
1189+ const matched = findObsByFormField ( flatObs , [ ] , childField ) ;
1190+ expect ( matched . length ) . toBe ( 1 ) ;
1191+ expect ( matched [ 0 ] ) . toBe ( resultObs ) ;
1192+ } ) ;
10891193} ) ;
10901194
10911195describe ( 'ObsAdapter - handling nested obsGroups' , ( ) => {
0 commit comments