@@ -311,6 +311,75 @@ func TestResolveGroupsRef(t *testing.T) {
311311 },
312312 },
313313 },
314+ "GroupsRefEmpty" : {
315+ reason : "The Function should resolve groupsRef from XR spec" ,
316+ args : args {
317+ ctx : context .Background (),
318+ req : & fnv1.RunFunctionRequest {
319+ Meta : & fnv1.RequestMeta {Tag : "hello" },
320+ Input : resource .MustStructJSON (`{
321+ "apiVersion": "msgraph.fn.crossplane.io/v1alpha1",
322+ "kind": "Input",
323+ "queryType": "GroupObjectIDs",
324+ "groupsRef": "spec.groupConfig.groupNames",
325+ "target": "status.groupObjectIDs"
326+ }` ),
327+ Observed : & fnv1.State {
328+ Composite : & fnv1.Resource {
329+ Resource : resource .MustStructJSON (`{
330+ "apiVersion": "example.org/v1",
331+ "kind": "XR",
332+ "spec": {
333+ "groupConfig": {
334+ "groupNames": []
335+ }
336+ }
337+ }` ),
338+ },
339+ },
340+ Credentials : map [string ]* fnv1.Credentials {
341+ "azure-creds" : {
342+ Source : & fnv1.Credentials_CredentialData {CredentialData : creds },
343+ },
344+ },
345+ },
346+ },
347+ want : want {
348+ rsp : & fnv1.RunFunctionResponse {
349+ Meta : & fnv1.ResponseMeta {Tag : "hello" , Ttl : durationpb .New (response .DefaultTTL )},
350+ Conditions : []* fnv1.Condition {
351+ {
352+ Type : "FunctionSuccess" ,
353+ Status : fnv1 .Status_STATUS_CONDITION_TRUE ,
354+ Reason : "Success" ,
355+ Target : fnv1 .Target_TARGET_COMPOSITE_AND_CLAIM .Enum (),
356+ },
357+ },
358+ Results : []* fnv1.Result {
359+ {
360+ Severity : fnv1 .Severity_SEVERITY_NORMAL ,
361+ Message : `QueryType: "GroupObjectIDs"` ,
362+ Target : fnv1 .Target_TARGET_COMPOSITE .Enum (),
363+ },
364+ },
365+ Desired : & fnv1.State {
366+ Composite : & fnv1.Resource {
367+ Resource : resource .MustStructJSON (`{
368+ "apiVersion": "example.org/v1",
369+ "kind": "XR",
370+ "spec": {
371+ "groupConfig": {
372+ "groupNames": []
373+ }
374+ },
375+ "status": {
376+ "groupObjectIDs": []
377+ }}` ),
378+ },
379+ },
380+ },
381+ },
382+ },
314383 "GroupsRefNotFound" : {
315384 reason : "The Function should handle an error when groupsRef cannot be resolved" ,
316385 args : args {
@@ -371,11 +440,11 @@ func TestResolveGroupsRef(t *testing.T) {
371440 mockQuery := & MockGraphQuery {
372441 GraphQueryFunc : func (_ context.Context , _ map [string ]string , in * v1beta1.Input ) (interface {}, error ) {
373442 if in .QueryType == "GroupObjectIDs" {
374- if len (in .Groups ) == 0 {
443+ if in . FailOnEmpty != nil && * in . FailOnEmpty && len (in .Groups ) == 0 {
375444 return nil , errors .New ("no group names provided" )
376445 }
377446
378- var results []interface {}
447+ results := make ( []interface {}, 0 )
379448 for i , group := range in .Groups {
380449 if group == nil {
381450 continue
@@ -1089,6 +1158,75 @@ func TestResolveUsersRef(t *testing.T) {
10891158 },
10901159 },
10911160 },
1161+ "UsersRefEmpty" : {
1162+ reason : "The Function should resolve usersRef from XR spec" ,
1163+ args : args {
1164+ ctx : context .Background (),
1165+ req : & fnv1.RunFunctionRequest {
1166+ Meta : & fnv1.RequestMeta {Tag : "hello" },
1167+ Input : resource .MustStructJSON (`{
1168+ "apiVersion": "msgraph.fn.crossplane.io/v1alpha1",
1169+ "kind": "Input",
1170+ "queryType": "UserValidation",
1171+ "usersRef": "spec.userAccess.emails",
1172+ "target": "status.validatedUsers"
1173+ }` ),
1174+ Observed : & fnv1.State {
1175+ Composite : & fnv1.Resource {
1176+ Resource : resource .MustStructJSON (`{
1177+ "apiVersion": "example.org/v1",
1178+ "kind": "XR",
1179+ "spec": {
1180+ "userAccess": {
1181+ "emails": []
1182+ }
1183+ }
1184+ }` ),
1185+ },
1186+ },
1187+ Credentials : map [string ]* fnv1.Credentials {
1188+ "azure-creds" : {
1189+ Source : & fnv1.Credentials_CredentialData {CredentialData : creds },
1190+ },
1191+ },
1192+ },
1193+ },
1194+ want : want {
1195+ rsp : & fnv1.RunFunctionResponse {
1196+ Meta : & fnv1.ResponseMeta {Tag : "hello" , Ttl : durationpb .New (response .DefaultTTL )},
1197+ Conditions : []* fnv1.Condition {
1198+ {
1199+ Type : "FunctionSuccess" ,
1200+ Status : fnv1 .Status_STATUS_CONDITION_TRUE ,
1201+ Reason : "Success" ,
1202+ Target : fnv1 .Target_TARGET_COMPOSITE_AND_CLAIM .Enum (),
1203+ },
1204+ },
1205+ Results : []* fnv1.Result {
1206+ {
1207+ Severity : fnv1 .Severity_SEVERITY_NORMAL ,
1208+ Message : `QueryType: "UserValidation"` ,
1209+ Target : fnv1 .Target_TARGET_COMPOSITE .Enum (),
1210+ },
1211+ },
1212+ Desired : & fnv1.State {
1213+ Composite : & fnv1.Resource {
1214+ Resource : resource .MustStructJSON (`{
1215+ "apiVersion": "example.org/v1",
1216+ "kind": "XR",
1217+ "spec": {
1218+ "userAccess": {
1219+ "emails": []
1220+ }
1221+ },
1222+ "status": {
1223+ "validatedUsers": []
1224+ }}` ),
1225+ },
1226+ },
1227+ },
1228+ },
1229+ },
10921230 "UsersRefNotFound" : {
10931231 reason : "The Function should handle an error when usersRef cannot be resolved" ,
10941232 args : args {
@@ -1149,11 +1287,11 @@ func TestResolveUsersRef(t *testing.T) {
11491287 mockQuery := & MockGraphQuery {
11501288 GraphQueryFunc : func (_ context.Context , _ map [string ]string , in * v1beta1.Input ) (interface {}, error ) {
11511289 if in .QueryType == "UserValidation" {
1152- if len (in .Users ) == 0 {
1290+ if in . FailOnEmpty != nil && * in . FailOnEmpty && len (in .Users ) == 0 {
11531291 return nil , errors .New ("no users provided for validation" )
11541292 }
11551293
1156- var results []interface {}
1294+ results := make ( []interface {}, 0 )
11571295 for _ , user := range in .Users {
11581296 if user == nil {
11591297 continue
@@ -1498,6 +1636,75 @@ func TestResolveServicePrincipalsRef(t *testing.T) {
14981636 },
14991637 },
15001638 },
1639+ "ServicePrincipalsRefEmpty" : {
1640+ reason : "The Function should resolve servicePrincipalsRef from XR spec" ,
1641+ args : args {
1642+ ctx : context .Background (),
1643+ req : & fnv1.RunFunctionRequest {
1644+ Meta : & fnv1.RequestMeta {Tag : "hello" },
1645+ Input : resource .MustStructJSON (`{
1646+ "apiVersion": "msgraph.fn.crossplane.io/v1alpha1",
1647+ "kind": "Input",
1648+ "queryType": "ServicePrincipalDetails",
1649+ "servicePrincipalsRef": "spec.servicePrincipalConfig.names",
1650+ "target": "status.servicePrincipals"
1651+ }` ),
1652+ Observed : & fnv1.State {
1653+ Composite : & fnv1.Resource {
1654+ Resource : resource .MustStructJSON (`{
1655+ "apiVersion": "example.org/v1",
1656+ "kind": "XR",
1657+ "spec": {
1658+ "servicePrincipalConfig": {
1659+ "names": []
1660+ }
1661+ }
1662+ }` ),
1663+ },
1664+ },
1665+ Credentials : map [string ]* fnv1.Credentials {
1666+ "azure-creds" : {
1667+ Source : & fnv1.Credentials_CredentialData {CredentialData : creds },
1668+ },
1669+ },
1670+ },
1671+ },
1672+ want : want {
1673+ rsp : & fnv1.RunFunctionResponse {
1674+ Meta : & fnv1.ResponseMeta {Tag : "hello" , Ttl : durationpb .New (response .DefaultTTL )},
1675+ Conditions : []* fnv1.Condition {
1676+ {
1677+ Type : "FunctionSuccess" ,
1678+ Status : fnv1 .Status_STATUS_CONDITION_TRUE ,
1679+ Reason : "Success" ,
1680+ Target : fnv1 .Target_TARGET_COMPOSITE_AND_CLAIM .Enum (),
1681+ },
1682+ },
1683+ Results : []* fnv1.Result {
1684+ {
1685+ Severity : fnv1 .Severity_SEVERITY_NORMAL ,
1686+ Message : `QueryType: "ServicePrincipalDetails"` ,
1687+ Target : fnv1 .Target_TARGET_COMPOSITE .Enum (),
1688+ },
1689+ },
1690+ Desired : & fnv1.State {
1691+ Composite : & fnv1.Resource {
1692+ Resource : resource .MustStructJSON (`{
1693+ "apiVersion": "example.org/v1",
1694+ "kind": "XR",
1695+ "spec": {
1696+ "servicePrincipalConfig": {
1697+ "names": []
1698+ }
1699+ },
1700+ "status": {
1701+ "servicePrincipals": []
1702+ }}` ),
1703+ },
1704+ },
1705+ },
1706+ },
1707+ },
15011708 "ServicePrincipalsRefNotFound" : {
15021709 reason : "The Function should handle an error when servicePrincipalsRef cannot be resolved" ,
15031710 args : args {
@@ -1558,11 +1765,11 @@ func TestResolveServicePrincipalsRef(t *testing.T) {
15581765 mockQuery := & MockGraphQuery {
15591766 GraphQueryFunc : func (_ context.Context , _ map [string ]string , in * v1beta1.Input ) (interface {}, error ) {
15601767 if in .QueryType == "ServicePrincipalDetails" {
1561- if len (in .ServicePrincipals ) == 0 {
1768+ if in . FailOnEmpty != nil && * in . FailOnEmpty && len (in .ServicePrincipals ) == 0 {
15621769 return nil , errors .New ("no service principal names provided" )
15631770 }
15641771
1565- var results []interface {}
1772+ results := make ( []interface {}, 0 )
15661773 for i , sp := range in .ServicePrincipals {
15671774 if sp == nil {
15681775 continue
0 commit comments