@@ -1136,8 +1136,7 @@ func TestWorkflowMutator_InsertBoundaryEvent_NoDelay(t *testing.T) {
11361136// ---------------------------------------------------------------------------
11371137
11381138func TestWorkflowMutator_SetActivityProperty_Page_New (t * testing.T ) {
1139- // Note: When TaskPage key doesn't pre-exist in BSON, dSet silently fails.
1140- // The key must be present (even as nil) for PAGE to work on a new activity.
1139+ // TaskPage key present with nil value — should be replaced with a new PageReference.
11411140 act := makeWfActivity ("Workflows$UserTask" , "Review" , "task1" )
11421141 act = append (act , bson.E {Key : "TaskPage" , Value : nil })
11431142 m := newMutator (makeWorkflowDoc (act ))
@@ -1157,7 +1156,8 @@ func TestWorkflowMutator_SetActivityProperty_Page_New(t *testing.T) {
11571156}
11581157
11591158func TestWorkflowMutator_SetActivityProperty_Page_MissingKey (t * testing.T ) {
1160- // BUG: dSet silently fails when TaskPage key is absent — pageRef is lost.
1159+ // Regression test: dSet silently failed when TaskPage key was absent.
1160+ // Fixed by appending the key to the activity and replacing it in the BSON tree.
11611161 act := makeWfActivity ("Workflows$UserTask" , "Review" , "task1" )
11621162 // No TaskPage field at all
11631163 m := newMutator (makeWorkflowDoc (act ))
@@ -1169,9 +1169,67 @@ func TestWorkflowMutator_SetActivityProperty_Page_MissingKey(t *testing.T) {
11691169
11701170 actDoc , _ := m .findActivityByCaption ("Review" , 0 )
11711171 taskPage := dGetDoc (actDoc , "TaskPage" )
1172- // This documents the bug: TaskPage is nil because dSet can't create new keys
1173- if taskPage != nil {
1174- t .Log ("BUG FIXED: TaskPage is now set even when key was absent" )
1172+ if taskPage == nil {
1173+ t .Fatal ("TaskPage should be set even when key was absent" )
1174+ }
1175+ if got := dGetString (taskPage , "Page" ); got != "MyModule.TaskPage" {
1176+ t .Errorf ("Page = %q, want MyModule.TaskPage" , got )
1177+ }
1178+ }
1179+
1180+ func TestWorkflowMutator_SetActivityProperty_Page_MissingKey_NestedSubFlow (t * testing.T ) {
1181+ // Exercises the recursive replaceActivity path: the target activity lives
1182+ // inside an outcome's sub-flow, not at the top level.
1183+ // Use distinct $IDs so replaceActivity cannot accidentally match the parent.
1184+ parentID := primitive.Binary {Subtype : 0x04 , Data : []byte {1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }}
1185+ nestedID := primitive.Binary {Subtype : 0x04 , Data : []byte {2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }}
1186+
1187+ nestedAct := bson.D {
1188+ {Key : "$ID" , Value : nestedID },
1189+ {Key : "$Type" , Value : "Workflows$UserTask" },
1190+ {Key : "Caption" , Value : "NestedReview" },
1191+ {Key : "Name" , Value : "nested1" },
1192+ }
1193+ // No TaskPage field at all on the nested activity.
1194+
1195+ outcome := bson.D {
1196+ {Key : "$ID" , Value : primitive.Binary {Subtype : 0x04 , Data : make ([]byte , 16 )}},
1197+ {Key : "$Type" , Value : "Workflows$BooleanOutcome" },
1198+ {Key : "Flow" , Value : bson.D {
1199+ {Key : "$ID" , Value : primitive.Binary {Subtype : 0x04 , Data : make ([]byte , 16 )}},
1200+ {Key : "$Type" , Value : "Workflows$Flow" },
1201+ {Key : "Activities" , Value : bson.A {int32 (3 ), nestedAct }},
1202+ }},
1203+ }
1204+ parentAct := bson.D {
1205+ {Key : "$ID" , Value : parentID },
1206+ {Key : "$Type" , Value : "Workflows$Decision" },
1207+ {Key : "Caption" , Value : "Check" },
1208+ {Key : "Name" , Value : "decision1" },
1209+ {Key : "Outcomes" , Value : bson.A {int32 (3 ), outcome }},
1210+ }
1211+ m := newMutator (makeWorkflowDoc (parentAct ))
1212+
1213+ if err := m .SetActivityProperty ("NestedReview" , 0 , "PAGE" , "MyModule.NestedPage" ); err != nil {
1214+ t .Fatalf ("SetActivityProperty PAGE on nested activity failed: %v" , err )
1215+ }
1216+
1217+ actDoc , _ := m .findActivityByCaption ("NestedReview" , 0 )
1218+ taskPage := dGetDoc (actDoc , "TaskPage" )
1219+ if taskPage == nil {
1220+ t .Fatal ("TaskPage should be set on nested activity even when key was absent" )
1221+ }
1222+ if got := dGetString (taskPage , "Page" ); got != "MyModule.NestedPage" {
1223+ t .Errorf ("Page = %q, want MyModule.NestedPage" , got )
1224+ }
1225+
1226+ // Verify parent decision still has its Outcomes intact.
1227+ parentDoc , _ := m .findActivityByCaption ("Check" , 0 )
1228+ if parentDoc == nil {
1229+ t .Fatal ("parent decision activity should still exist" )
1230+ }
1231+ if outcomes := dGet (parentDoc , "Outcomes" ); outcomes == nil {
1232+ t .Fatal ("parent decision Outcomes should still be present" )
11751233 }
11761234}
11771235
0 commit comments