@@ -381,3 +381,77 @@ func TestGraphIndexer_LabelSelector_LabelUpdateBreaksMatch(t *testing.T) {
381381 t .Fatalf ("expected 0 edges after pod label change, got %d: %v" , len (edges ), edges )
382382 }
383383}
384+
385+ // TestGraphIndexer_FieldPath_ClusterScopedTarget — TargetNamespaced=false gives empty namespace.
386+ func TestGraphIndexer_FieldPath_ClusterScopedTarget (t * testing.T ) {
387+ g , _ , idx := setupIndexer ()
388+
389+ clusterScoped := false
390+ g .SetDeclarations ("k8s" , "core::v1::Pod" , []resource.RelationshipDescriptor {
391+ {
392+ Type : resource .RelRunsOn ,
393+ TargetResourceKey : "core::v1::Node" ,
394+ Label : "runs on" ,
395+ TargetNamespaced : & clusterScoped ,
396+ Extractor : & resource.RelationshipExtractor {
397+ Method : "fieldPath" ,
398+ FieldPath : "spec.nodeName" ,
399+ },
400+ },
401+ })
402+
403+ pod := makeEntry ("core::v1::Pod" , "default" , "nginx" )
404+ raw := json .RawMessage (`{"spec":{"nodeName":"worker-1"}}` )
405+
406+ idx .OnAdd (pod , raw )
407+
408+ podNode := GraphNode {
409+ PluginID : "k8s" , ConnectionID : "c1" ,
410+ ResourceKey : "core::v1::Pod" , ID : "nginx" , Namespace : "default" ,
411+ }
412+ edges := g .EdgesFrom (podNode .Key ())
413+ if len (edges ) != 1 {
414+ t .Fatalf ("expected 1 edge, got %d" , len (edges ))
415+ }
416+ e := edges [0 ]
417+ if e .Target .Namespace != "" {
418+ t .Errorf ("expected empty namespace for cluster-scoped target, got %q" , e .Target .Namespace )
419+ }
420+ if e .Target .ID != "worker-1" {
421+ t .Errorf ("expected target ID 'worker-1', got %q" , e .Target .ID )
422+ }
423+ }
424+
425+ // TestGraphIndexer_FieldPath_NamespacedTargetDefault — nil TargetNamespaced inherits source namespace.
426+ func TestGraphIndexer_FieldPath_NamespacedTargetDefault (t * testing.T ) {
427+ g , _ , idx := setupIndexer ()
428+
429+ g .SetDeclarations ("k8s" , "core::v1::Pod" , []resource.RelationshipDescriptor {
430+ {
431+ Type : resource .RelUses ,
432+ TargetResourceKey : "core::v1::ConfigMap" ,
433+ Label : "uses" ,
434+ Extractor : & resource.RelationshipExtractor {
435+ Method : "fieldPath" ,
436+ FieldPath : "spec.volumes.0.configMap.name" ,
437+ },
438+ },
439+ })
440+
441+ pod := makeEntry ("core::v1::Pod" , "production" , "app-pod" )
442+ raw := json .RawMessage (`{"spec":{"volumes":[{"configMap":{"name":"app-config"}}]}}` )
443+
444+ idx .OnAdd (pod , raw )
445+
446+ podNode := GraphNode {
447+ PluginID : "k8s" , ConnectionID : "c1" ,
448+ ResourceKey : "core::v1::Pod" , ID : "app-pod" , Namespace : "production" ,
449+ }
450+ edges := g .EdgesFrom (podNode .Key ())
451+ if len (edges ) != 1 {
452+ t .Fatalf ("expected 1 edge, got %d" , len (edges ))
453+ }
454+ if edges [0 ].Target .Namespace != "production" {
455+ t .Errorf ("expected namespace 'production', got %q" , edges [0 ].Target .Namespace )
456+ }
457+ }
0 commit comments