@@ -12,6 +12,7 @@ import (
1212 "github.com/theopenlane/core/common/enums"
1313 "github.com/theopenlane/core/internal/graphapi/testclient"
1414 "github.com/theopenlane/core/internal/testutils"
15+ "github.com/theopenlane/utils/ulids"
1516)
1617
1718// controlReportTestData holds entity IDs seeded by seedControlReportTestData
@@ -29,18 +30,32 @@ type controlReportTestData struct {
2930 reverseMappingID string
3031 // tertiaryMappingID maps primary → tertiary, adding one more unique related control
3132 tertiaryMappingID string
33+
34+ // system mapping fields: system-owned controls are mapped together; org controls with
35+ // matching refCode+framework confirm that system mappings surface in relatedControls
36+ sysMapOrgSourceID string // org control matching sysControlA (the one to query)
37+ sysMapOrgTargetID string // org control matching sysControlB (expected in relatedControls)
38+ sysMapID string // the system-owned MappedControl
3239}
3340
3441// seedControlReportTestData enriches primaryControlID with a subcontrol, linked evidence,
35- // an internal policy, and three mapped controls to exercise deduplication.
36- // All three controls must already exist in the context's org.
42+ // an internal policy, and three org-owned mapped controls to exercise deduplication.
43+ // It also creates a system-owned mapping between two new system controls and matching
44+ // org controls to verify that system mappings surface in relatedControls.
45+ // All three input controls must already exist in the context's org.
3746//
38- // Mappings created :
47+ // Org mappings on primary :
3948// - forward: primary → secondary
4049// - reverse: secondary → primary (secondary appears twice, deduped to one relatedControl)
4150// - tertiary: primary → tertiary (unique second related control)
4251//
52+ // System mapping:
53+ // - sysControlA and sysControlB are system-owned with unique refCode+"SOC2" framework
54+ // - sysMapOrgSource/sysMapOrgTarget are org-owned with the same refCode+framework
55+ // - querying sysMapOrgSource's relatedControls should return sysMapOrgTarget via the system mapping
56+ //
4357// Expected relatedControls for primary: [secondary, tertiary] (2 unique entries).
58+ // Expected relatedControls for sysMapOrgSource: [sysMapOrgTarget] (1 entry via system mapping).
4459func seedControlReportTestData (ctx context.Context , t * testing.T , primaryControlID , secondaryControlID , tertiaryControlID string ) * controlReportTestData {
4560 t .Helper ()
4661
@@ -79,6 +94,44 @@ func seedControlReportTestData(ctx context.Context, t *testing.T, primaryControl
7994 ToControlIDs : []string {tertiaryControlID },
8095 }).MustNew (ctx , t )
8196
97+ // system mapping scenario: unique refCodes per call prevent cross-test interference
98+ sysRefA := ulids .New ().String ()
99+ sysRefB := ulids .New ().String ()
100+ sysFramework := lo .ToPtr ("SOC 2" )
101+
102+ sysControlA := (& ControlBuilder {
103+ client : suite .client ,
104+ RefCode : sysRefA ,
105+ ReferenceFramework : sysFramework ,
106+ }).MustNew (sharedSystemAdminUser .UserCtx , t )
107+
108+ sysControlB := (& ControlBuilder {
109+ client : suite .client ,
110+ RefCode : sysRefB ,
111+ ReferenceFramework : sysFramework ,
112+ }).MustNew (sharedSystemAdminUser .UserCtx , t )
113+
114+ // system-owned mapped control linking sysControlA → sysControlB
115+ sysMap := (& MappedControlBuilder {
116+ client : suite .client ,
117+ FromControlIDs : []string {sysControlA .ID },
118+ ToControlIDs : []string {sysControlB .ID },
119+ }).MustNew (sharedSystemAdminUser .UserCtx , t )
120+
121+ // org-owned controls that mirror the system controls by refCode+framework;
122+ // getOrgMappedControlsInfo resolves sysControlB's refCode to orgTgt
123+ orgSrc := (& ControlBuilder {
124+ client : suite .client ,
125+ RefCode : sysRefA ,
126+ ReferenceFramework : sysFramework ,
127+ }).MustNew (ctx , t )
128+
129+ orgTgt := (& ControlBuilder {
130+ client : suite .client ,
131+ RefCode : sysRefB ,
132+ ReferenceFramework : sysFramework ,
133+ }).MustNew (ctx , t )
134+
82135 return & controlReportTestData {
83136 primaryControlID : primaryControlID ,
84137 secondaryControlID : secondaryControlID ,
@@ -89,6 +142,9 @@ func seedControlReportTestData(ctx context.Context, t *testing.T, primaryControl
89142 forwardMappingID : forward .ID ,
90143 reverseMappingID : reverse .ID ,
91144 tertiaryMappingID : tertiary .ID ,
145+ sysMapOrgSourceID : orgSrc .ID ,
146+ sysMapOrgTargetID : orgTgt .ID ,
147+ sysMapID : sysMap .ID ,
92148 }
93149}
94150
@@ -98,22 +154,26 @@ func TestQueryControlReports(t *testing.T) {
98154 localTestOrg := suite .seedOrgOwner (t )
99155 orgUser := suite .seedOrgOwner (t )
100156
101- orgOwnedCount := int64 (11 )
102- controlIDs := []string {}
103-
104- for range orgOwnedCount {
105- control := (& ControlBuilder {client : suite .client }).MustNew (localTestOrg .owner .UserCtx , t )
106- controlIDs = append (controlIDs , control .ID )
157+ // create 8 filler controls first (oldest) so that the enriched controls and the
158+ // system-mapping controls created inside the seed fall in the first page (CreatedAt DESC)
159+ for range 8 {
160+ (& ControlBuilder {client : suite .client }).MustNew (localTestOrg .owner .UserCtx , t )
107161 }
108162
109163 // system-owned controls must not appear in controlReports results (resolver filters SystemOwned: false);
110164 // the hook sets system_owned = true automatically when it sees a system admin caller
111- for range int64 ( 3 ) {
165+ for range 3 {
112166 (& ControlBuilder {client : suite .client }).MustNew (sharedSystemAdminUser .UserCtx , t )
113167 }
114168
115- // enrich the first three org-owned controls with associated data so enrichment paths are exercised
116- richData := seedControlReportTestData (localTestOrg .owner .UserCtx , t , controlIDs [0 ], controlIDs [1 ], controlIDs [2 ])
169+ // create primary/secondary/tertiary after the fillers so they appear in the first page
170+ primary := (& ControlBuilder {client : suite .client }).MustNew (localTestOrg .owner .UserCtx , t )
171+ secondary := (& ControlBuilder {client : suite .client }).MustNew (localTestOrg .owner .UserCtx , t )
172+ tertiary := (& ControlBuilder {client : suite .client }).MustNew (localTestOrg .owner .UserCtx , t )
173+
174+ // seed adds 2 more org controls (sysMapOrgSource, sysMapOrgTarget) → 8+3+2 = 13 total
175+ orgOwnedCount := int64 (13 )
176+ richData := seedControlReportTestData (localTestOrg .owner .UserCtx , t , primary .ID , secondary .ID , tertiary .ID )
117177
118178 testCases := []struct {
119179 name string
@@ -208,6 +268,11 @@ func TestQueryControlReports(t *testing.T) {
208268 // deduplication collapses it to one entry, plus tertiary = 2 total
209269 assert .Check (t , is .Len (edge .Node .RelatedControls , 2 ))
210270 }
271+
272+ // org control matching sysControlA should surface sysMapOrgTarget via system mapping
273+ if edge .Node .ID == richData .sysMapOrgSourceID {
274+ assert .Check (t , is .Len (edge .Node .RelatedControls , 1 ))
275+ }
211276 }
212277 } else {
213278 assert .Check (t , is .Equal (int64 (0 ), resp .ControlReports .TotalCount ))
@@ -305,16 +370,23 @@ func TestQueryControlReportsByCategory(t *testing.T) {
305370 // deduplication collapses it to one entry, plus tertiary = 2 total
306371 assert .Check (t , is .Len (c .RelatedControls , 2 ))
307372 }
373+
374+ // org control matching sysControlA should surface sysMapOrgTarget via system mapping
375+ if c .ID == richData .sysMapOrgSourceID {
376+ assert .Check (t , is .Len (c .RelatedControls , 1 ))
377+ }
308378 }
309379
310380 catCounts [cat .Category ] = len (cat .Controls )
311381 totalControls += len (cat .Controls )
312382 }
313383
314- assert .Check (t , is .Equal (4 , totalControls ))
384+ // seed adds orgSrc and orgTgt (no category) on top of the 4 directly created controls:
385+ // 2 (cat1) + 1 (cat2) + 1 (no cat) + orgSrc + orgTgt = 6
386+ assert .Check (t , is .Equal (6 , totalControls ))
315387 assert .Check (t , is .Equal (2 , catCounts [cat1 ]))
316388 assert .Check (t , is .Equal (1 , catCounts [cat2 ]))
317- assert .Check (t , is .Equal (1 , catCounts ["" ]))
389+ assert .Check (t , is .Equal (3 , catCounts ["" ]))
318390 }
319391
320392 if tc .where != nil && tc .where .Category != nil {
0 commit comments