@@ -664,7 +664,8 @@ async fn provider_type_allows_empty_credentials_for_refresh(
664664 credential. refresh . as_ref ( ) . is_some_and ( |refresh| {
665665 matches ! (
666666 refresh. strategy,
667- ProviderCredentialRefreshStrategy :: Oauth2ClientCredentials
667+ ProviderCredentialRefreshStrategy :: Oauth2RefreshToken
668+ | ProviderCredentialRefreshStrategy :: Oauth2ClientCredentials
668669 | ProviderCredentialRefreshStrategy :: GoogleServiceAccountJwt
669670 )
670671 } )
@@ -1221,8 +1222,8 @@ mod tests {
12211222 use openshell_core:: proto:: {
12221223 DeleteProviderProfileRequest , GetProviderProfileRequest , ImportProviderProfilesRequest ,
12231224 L7Allow , L7Rule , LintProviderProfilesRequest , ListProviderProfilesRequest , NetworkBinary ,
1224- NetworkEndpoint , ProviderProfile , ProviderProfileCategory , ProviderProfileImportItem ,
1225- Sandbox , SandboxSpec ,
1225+ NetworkEndpoint , ProviderCredentialRefresh , ProviderCredentialRefreshMaterial ,
1226+ ProviderProfile , ProviderProfileCategory , ProviderProfileImportItem , Sandbox , SandboxSpec ,
12261227 } ;
12271228 use openshell_core:: { ObjectId , ObjectName } ;
12281229 use std:: collections:: HashMap ;
@@ -2181,12 +2182,11 @@ mod tests {
21812182
21822183 #[ tokio:: test]
21832184 async fn provider_validation_errors ( ) {
2184- let store = Store :: connect ( "sqlite::memory:?cache=shared" )
2185- . await
2186- . unwrap ( ) ;
2185+ let state = test_server_state ( ) . await ;
2186+ let store = state. store . as_ref ( ) ;
21872187
21882188 let create_missing_type = create_provider_record (
2189- & store,
2189+ store,
21902190 Provider {
21912191 metadata : Some ( openshell_core:: proto:: datamodel:: v1:: ObjectMeta {
21922192 id : String :: new ( ) ,
@@ -2205,7 +2205,7 @@ mod tests {
22052205 assert_eq ! ( create_missing_type. code( ) , Code :: InvalidArgument ) ;
22062206
22072207 let create_missing_credentials = create_provider_record (
2208- & store,
2208+ store,
22092209 Provider {
22102210 metadata : Some ( openshell_core:: proto:: datamodel:: v1:: ObjectMeta {
22112211 id : String :: new ( ) ,
@@ -2224,7 +2224,7 @@ mod tests {
22242224 assert_eq ! ( create_missing_credentials. code( ) , Code :: InvalidArgument ) ;
22252225
22262226 let refresh_bootstrap_provider = create_provider_record (
2227- & store,
2227+ store,
22282228 Provider {
22292229 metadata : Some ( openshell_core:: proto:: datamodel:: v1:: ObjectMeta {
22302230 id : String :: new ( ) ,
@@ -2242,14 +2242,83 @@ mod tests {
22422242 . unwrap ( ) ;
22432243 assert ! ( refresh_bootstrap_provider. credentials. is_empty( ) ) ;
22442244
2245- let get_err = get_provider_record ( & store, "" ) . await . unwrap_err ( ) ;
2245+ handle_import_provider_profiles (
2246+ & state,
2247+ Request :: new ( ImportProviderProfilesRequest {
2248+ profiles : vec ! [ ProviderProfileImportItem {
2249+ profile: Some ( ProviderProfile {
2250+ id: "delegated-refresh-api" . to_string( ) ,
2251+ display_name: "Delegated Refresh API" . to_string( ) ,
2252+ description: String :: new( ) ,
2253+ category: ProviderProfileCategory :: Messaging as i32 ,
2254+ credentials: vec![ openshell_core:: proto:: ProviderProfileCredential {
2255+ name: "access_token" . to_string( ) ,
2256+ description: String :: new( ) ,
2257+ env_vars: vec![ "DELEGATED_ACCESS_TOKEN" . to_string( ) ] ,
2258+ required: true ,
2259+ auth_style: "bearer" . to_string( ) ,
2260+ header_name: "authorization" . to_string( ) ,
2261+ query_param: String :: new( ) ,
2262+ refresh: Some ( ProviderCredentialRefresh {
2263+ strategy: ProviderCredentialRefreshStrategy :: Oauth2RefreshToken
2264+ as i32 ,
2265+ token_url: "https://login.example/token" . to_string( ) ,
2266+ scopes: vec![ "https://example.test/.default" . to_string( ) ] ,
2267+ refresh_before_seconds: 300 ,
2268+ max_lifetime_seconds: 3600 ,
2269+ material: vec![
2270+ ProviderCredentialRefreshMaterial {
2271+ name: "client_id" . to_string( ) ,
2272+ description: String :: new( ) ,
2273+ required: true ,
2274+ secret: false ,
2275+ } ,
2276+ ProviderCredentialRefreshMaterial {
2277+ name: "refresh_token" . to_string( ) ,
2278+ description: String :: new( ) ,
2279+ required: true ,
2280+ secret: true ,
2281+ } ,
2282+ ] ,
2283+ } ) ,
2284+ } ] ,
2285+ endpoints: vec![ ] ,
2286+ binaries: vec![ ] ,
2287+ inference_capable: false ,
2288+ } ) ,
2289+ source: "delegated-refresh-api.yaml" . to_string( ) ,
2290+ } ] ,
2291+ } ) ,
2292+ )
2293+ . await
2294+ . unwrap ( ) ;
2295+ let delegated_refresh_bootstrap_provider = create_provider_record (
2296+ store,
2297+ Provider {
2298+ metadata : Some ( openshell_core:: proto:: datamodel:: v1:: ObjectMeta {
2299+ id : String :: new ( ) ,
2300+ name : "delegated-refresh-no-token-yet" . to_string ( ) ,
2301+ created_at_ms : 1_000_000 ,
2302+ labels : HashMap :: new ( ) ,
2303+ } ) ,
2304+ r#type : "delegated-refresh-api" . to_string ( ) ,
2305+ credentials : HashMap :: new ( ) ,
2306+ config : HashMap :: new ( ) ,
2307+ credential_expires_at_ms : HashMap :: new ( ) ,
2308+ } ,
2309+ )
2310+ . await
2311+ . unwrap ( ) ;
2312+ assert ! ( delegated_refresh_bootstrap_provider. credentials. is_empty( ) ) ;
2313+
2314+ let get_err = get_provider_record ( store, "" ) . await . unwrap_err ( ) ;
22462315 assert_eq ! ( get_err. code( ) , Code :: InvalidArgument ) ;
22472316
2248- let delete_err = delete_provider_record ( & store, "" ) . await . unwrap_err ( ) ;
2317+ let delete_err = delete_provider_record ( store, "" ) . await . unwrap_err ( ) ;
22492318 assert_eq ! ( delete_err. code( ) , Code :: InvalidArgument ) ;
22502319
22512320 let update_missing_err = update_provider_record (
2252- & store,
2321+ store,
22532322 Provider {
22542323 metadata : Some ( openshell_core:: proto:: datamodel:: v1:: ObjectMeta {
22552324 id : String :: new ( ) ,
0 commit comments