@@ -37,6 +37,10 @@ type controlReportTestData struct {
3737 sysMapOrgSourceID string // org control matching sysControlA (the one to query)
3838 sysMapOrgTargetID string // org control matching sysControlB (expected in relatedControls)
3939 sysMapID string // the system-owned MappedControl
40+
41+ // ctrlToSubcontrolRelatedID is a subcontrol mapped directly to primaryControlID;
42+ // it must appear in primary's relatedControls with IsSubcontrol: true
43+ ctrlToSubcontrolRelatedID string
4044}
4145
4246// seedControlReportTestData enriches primaryControlID with a subcontrol, linked evidence,
@@ -95,6 +99,14 @@ func seedControlReportTestData(ctx context.Context, t *testing.T, primaryControl
9599 ToControlIDs : []string {tertiaryControlID },
96100 }).MustNew (ctx , t )
97101
102+ // control → subcontrol mapping: a subcontrol of tertiary is mapped directly to primary
103+ scOfTertiary := (& SubcontrolBuilder {client : suite .client , ControlID : tertiaryControlID }).MustNew (ctx , t )
104+ (& MappedControlBuilder {
105+ client : suite .client ,
106+ FromControlIDs : []string {primaryControlID },
107+ ToSubcontrolIDs : []string {scOfTertiary .ID },
108+ }).MustNew (ctx , t )
109+
98110 // system mapping scenario: unique refCodes per call prevent cross-test interference
99111 sysRefA := ulids .New ().String ()
100112 sysRefB := ulids .New ().String ()
@@ -134,19 +146,20 @@ func seedControlReportTestData(ctx context.Context, t *testing.T, primaryControl
134146 }).MustNew (ctx , t )
135147
136148 return & controlReportTestData {
137- primaryControlID : primaryControlID ,
138- secondaryControlID : secondaryControlID ,
139- tertiaryControlID : tertiaryControlID ,
140- subcontrolID : sc .ID ,
141- evidenceID : ev .ID ,
142- policyID : policy .ID ,
143- controlOwnerID : controlOwnerGroupID ,
144- forwardMappingID : forward .ID ,
145- reverseMappingID : reverse .ID ,
146- tertiaryMappingID : tertiary .ID ,
147- sysMapOrgSourceID : orgSrc .ID ,
148- sysMapOrgTargetID : orgTgt .ID ,
149- sysMapID : sysMap .ID ,
149+ primaryControlID : primaryControlID ,
150+ secondaryControlID : secondaryControlID ,
151+ tertiaryControlID : tertiaryControlID ,
152+ subcontrolID : sc .ID ,
153+ evidenceID : ev .ID ,
154+ policyID : policy .ID ,
155+ controlOwnerID : controlOwnerGroupID ,
156+ forwardMappingID : forward .ID ,
157+ reverseMappingID : reverse .ID ,
158+ tertiaryMappingID : tertiary .ID ,
159+ sysMapOrgSourceID : orgSrc .ID ,
160+ sysMapOrgTargetID : orgTgt .ID ,
161+ sysMapID : sysMap .ID ,
162+ ctrlToSubcontrolRelatedID : scOfTertiary .ID ,
150163 }
151164}
152165
@@ -268,10 +281,21 @@ func TestQueryControlReports(t *testing.T) {
268281 assert .Check (t , is .Len (edge .Node .EvidenceStatus .CountByStatus , 2 ))
269282 assert .Check (t , is .Equal (int64 (1 ), edge .Node .LinkedPolicies .TotalCount ))
270283 // secondary appears in both the forward and reverse MappedControl records;
271- // deduplication collapses it to one entry, plus tertiary = 2 total
272- assert .Check (t , is .Len (edge .Node .RelatedControls , 2 ))
284+ // deduplication collapses it to one entry; tertiary and the
285+ // directly-mapped subcontrol each add one more = 3 total
286+ assert .Check (t , is .Len (edge .Node .RelatedControls , 3 ))
273287 assert .Check (t , edge .Node .ControlOwner != nil )
274288 assert .Check (t , is .Equal (richData .controlOwnerID , edge .Node .ControlOwner .ID ))
289+
290+ // the subcontrol mapped directly to primary must appear with IsSubcontrol: true
291+ var foundSubcontrolRelated bool
292+ for _ , rc := range edge .Node .RelatedControls {
293+ if rc .ID == richData .ctrlToSubcontrolRelatedID {
294+ foundSubcontrolRelated = true
295+ assert .Check (t , rc .IsSubcontrol )
296+ }
297+ }
298+ assert .Check (t , foundSubcontrolRelated )
275299 }
276300
277301 // org control matching sysControlA should surface sysMapOrgTarget via system mapping
@@ -373,10 +397,21 @@ func TestQueryControlReportsByCategory(t *testing.T) {
373397 assert .Check (t , is .Len (c .EvidenceStatus .CountByStatus , 2 ))
374398 assert .Check (t , is .Equal (int64 (1 ), c .LinkedPolicies .TotalCount ))
375399 // secondary appears in both the forward and reverse MappedControl records;
376- // deduplication collapses it to one entry, plus tertiary = 2 total
377- assert .Check (t , is .Len (c .RelatedControls , 2 ))
400+ // deduplication collapses it to one entry; tertiary and the
401+ // directly-mapped subcontrol each add one more = 3 total
402+ assert .Check (t , is .Len (c .RelatedControls , 3 ))
378403 assert .Check (t , c .ControlOwner != nil )
379404 assert .Check (t , is .Equal (richData .controlOwnerID , c .ControlOwner .ID ))
405+
406+ // the subcontrol mapped directly to primary must appear with IsSubcontrol: true
407+ var foundSubcontrolRelated bool
408+ for _ , rc := range c .RelatedControls {
409+ if rc .ID == richData .ctrlToSubcontrolRelatedID {
410+ foundSubcontrolRelated = true
411+ assert .Check (t , rc .IsSubcontrol )
412+ }
413+ }
414+ assert .Check (t , foundSubcontrolRelated )
380415 }
381416
382417 // org control matching sysControlA should surface sysMapOrgTarget via system mapping
0 commit comments