@@ -339,3 +339,174 @@ func TestTenantCapabilityHandler_Update(t *testing.T) {
339339 })
340340 }
341341}
342+
343+ func TestTenantCapabilityHandler_Get (t * testing.T ) {
344+ ctx := context .Background ()
345+ dbSession := testTenantCapabilityInitDB (t )
346+ defer dbSession .Close ()
347+
348+ testTenantCapabilitySetupSchema (t , dbSession )
349+
350+ ipOrg := "test-ip-org"
351+ tnOrg := "test-tn-org"
352+ tnOrgNoCeiling := "test-tn-org-no-ceiling"
353+ tnOrgNoTenant := "test-tn-org-no-tenant"
354+
355+ ipUser := cdbm .TestBuildUser (t , dbSession , uuid .NewString (), ipOrg , []string {authz .ProviderAdminRole })
356+ tnUser := cdbm .TestBuildUser (t , dbSession , uuid .NewString (), tnOrg , []string {authz .TenantAdminRole })
357+ tnUserNoCeiling := cdbm .TestBuildUser (t , dbSession , uuid .NewString (), tnOrgNoCeiling , []string {authz .TenantAdminRole })
358+ tnNonAdminUser := cdbm .TestBuildUser (t , dbSession , uuid .NewString (), tnOrg , []string {authz .ProviderAdminRole })
359+ noTenantUser := cdbm .TestBuildUser (t , dbSession , uuid .NewString (), tnOrgNoTenant , []string {authz .TenantAdminRole })
360+
361+ ip := cdbm .TestBuildInfrastructureProvider (t , dbSession , "Test Provider" , ipOrg , ipUser )
362+ ip2 := cdbm .TestBuildInfrastructureProvider (t , dbSession , "Test Provider 2" , ipOrg + "-2" , ipUser )
363+
364+ tn := testTenantCapabilityBuildTenant (t , dbSession , tnOrg , tnUser , true )
365+ tnNoCeiling := testTenantCapabilityBuildTenant (t , dbSession , tnOrgNoCeiling , tnUserNoCeiling , false )
366+
367+ site1 := cdbm .TestBuildSite (t , dbSession , ip , "Test Site 1" , ipUser )
368+ site2 := cdbm .TestBuildSite (t , dbSession , ip , "Test Site 2" , ipUser )
369+ site3 := cdbm .TestBuildSite (t , dbSession , ip2 , "Test Site 3" , ipUser )
370+
371+ // site1 enabled, site2 explicitly disabled, site3 (under ip2) enabled.
372+ cdbm .TestBuildTenantSiteCapabilityAssociation (t , dbSession , tn , site1 , true , tnUser )
373+ cdbm .TestBuildTenantSiteCapabilityAssociation (t , dbSession , tn , site2 , false , tnUser )
374+ cdbm .TestBuildTenantSiteCapabilityAssociation (t , dbSession , tn , site3 , true , tnUser )
375+
376+ cfg := common .GetTestConfig ()
377+ tracer , _ , ctx := common .TestCommonTraceProviderSetup (t , ctx )
378+
379+ tests := []struct {
380+ name string
381+ reqOrgName string
382+ tenantID string
383+ providerFilter string
384+ user * cdbm.User
385+ expectedStatus int
386+ expectedCeiling bool
387+ expectedSiteIDs []string
388+ verifyChildSpanner bool
389+ }{
390+ {
391+ name : "error when user not found in request context" ,
392+ reqOrgName : tnOrg ,
393+ tenantID : tn .ID .String (),
394+ user : nil ,
395+ expectedStatus : http .StatusInternalServerError ,
396+ },
397+ {
398+ name : "error when user is not a tenant admin" ,
399+ reqOrgName : tnOrg ,
400+ tenantID : tn .ID .String (),
401+ user : tnNonAdminUser ,
402+ expectedStatus : http .StatusForbidden ,
403+ },
404+ {
405+ name : "error when tenantId in URL is not a valid uuid" ,
406+ reqOrgName : tnOrg ,
407+ tenantID : "not-a-uuid" ,
408+ user : tnUser ,
409+ expectedStatus : http .StatusBadRequest ,
410+ },
411+ {
412+ name : "error when provider filter is not a valid uuid" ,
413+ reqOrgName : tnOrg ,
414+ tenantID : tn .ID .String (),
415+ providerFilter : "not-a-uuid" ,
416+ user : tnUser ,
417+ expectedStatus : http .StatusBadRequest ,
418+ },
419+ {
420+ name : "error when org has no tenant" ,
421+ reqOrgName : tnOrgNoTenant ,
422+ tenantID : tn .ID .String (),
423+ user : noTenantUser ,
424+ expectedStatus : http .StatusNotFound ,
425+ },
426+ {
427+ name : "error when tenant in URL does not match org tenant" ,
428+ reqOrgName : tnOrg ,
429+ tenantID : uuid .New ().String (),
430+ user : tnUser ,
431+ expectedStatus : http .StatusForbidden ,
432+ },
433+ {
434+ name : "success lists only enabled sites" ,
435+ reqOrgName : tnOrg ,
436+ tenantID : tn .ID .String (),
437+ user : tnUser ,
438+ expectedStatus : http .StatusOK ,
439+ expectedCeiling : true ,
440+ expectedSiteIDs : []string {site1 .ID .String (), site3 .ID .String ()},
441+ verifyChildSpanner : true ,
442+ },
443+ {
444+ name : "success filters enabled sites by provider" ,
445+ reqOrgName : tnOrg ,
446+ tenantID : tn .ID .String (),
447+ providerFilter : ip .ID .String (),
448+ user : tnUser ,
449+ expectedStatus : http .StatusOK ,
450+ expectedCeiling : true ,
451+ expectedSiteIDs : []string {site1 .ID .String ()},
452+ },
453+ {
454+ name : "success reports ceiling disabled and no sites" ,
455+ reqOrgName : tnOrgNoCeiling ,
456+ tenantID : tnNoCeiling .ID .String (),
457+ user : tnUserNoCeiling ,
458+ expectedStatus : http .StatusOK ,
459+ expectedCeiling : false ,
460+ expectedSiteIDs : []string {},
461+ },
462+ }
463+ for _ , tc := range tests {
464+ t .Run (tc .name , func (t * testing.T ) {
465+ e := echo .New ()
466+ target := "/"
467+ if tc .providerFilter != "" {
468+ target = "/?infrastructureProviderId=" + tc .providerFilter
469+ }
470+ req := httptest .NewRequest (http .MethodGet , target , nil )
471+ rec := httptest .NewRecorder ()
472+
473+ ec := e .NewContext (req , rec )
474+ ec .SetParamNames ("orgName" , "tenantId" )
475+ ec .SetParamValues (tc .reqOrgName , tc .tenantID )
476+ if tc .user != nil {
477+ ec .Set ("user" , tc .user )
478+ }
479+
480+ ctx = context .WithValue (ctx , otelecho .TracerKey , tracer )
481+ ec .SetRequest (ec .Request ().WithContext (ctx ))
482+
483+ h := GetTenantCapabilityHandler {
484+ dbSession : dbSession ,
485+ cfg : cfg ,
486+ }
487+ err := h .Handle (ec )
488+ assert .Nil (t , err )
489+
490+ if tc .expectedStatus != rec .Code {
491+ t .Errorf ("response: %v\n " , rec .Body .String ())
492+ }
493+ require .Equal (t , tc .expectedStatus , rec .Code )
494+
495+ if tc .expectedStatus == http .StatusOK {
496+ rsp := & model.APITenantCapabilityListResponse {}
497+ uerr := json .Unmarshal (rec .Body .Bytes (), rsp )
498+ assert .Nil (t , uerr )
499+ require .Len (t , rsp .Capabilities , 1 )
500+ capStatus := rsp .Capabilities [0 ]
501+ assert .Equal (t , model .CapabilityNameTargetedInstanceCreation , capStatus .CapabilityName )
502+ assert .Equal (t , tc .expectedCeiling , capStatus .CeilingEnabled )
503+ assert .ElementsMatch (t , tc .expectedSiteIDs , capStatus .SiteIDs )
504+ }
505+
506+ if tc .verifyChildSpanner {
507+ span := oteltrace .SpanFromContext (ec .Request ().Context ())
508+ assert .True (t , span .SpanContext ().IsValid ())
509+ }
510+ })
511+ }
512+ }
0 commit comments