#![ cfg( feature = "enabled" ) ]
#[ test ]
fn client_build_accepts_custom_environment_implementor()
{
use api_openai_compatible::{ Client, OpenAiCompatEnvironment, OpenAiCompatError, Result };
use core::time::Duration;
use reqwest::header;
#[ derive( Debug, Clone ) ]
struct CustomEnv;
#[ allow( clippy::unnecessary_literal_bound ) ]
impl OpenAiCompatEnvironment for CustomEnv
{
fn api_key( &self ) -> &str { "sk-custom-test" }
fn base_url( &self ) -> &str { "http://127.0.0.1:1/" }
fn timeout( &self ) -> Duration { Duration::from_secs( 5 ) }
fn headers( &self ) -> Result< header::HeaderMap >
{
let mut map = header::HeaderMap::new();
let auth = format!( "Bearer {}", self.api_key() )
.parse::< header::HeaderValue >()
.map_err( | e | OpenAiCompatError::InvalidApiKey( e.to_string() ) )?;
map.insert( header::AUTHORIZATION, auth );
map.insert(
header::CONTENT_TYPE,
header::HeaderValue::from_static( "application/json" ),
);
Ok( map )
}
}
let client = Client::build( CustomEnv );
assert!(
client.is_ok(),
"Client::build must accept a custom OpenAiCompatEnvironment implementor; got: {:?}",
client.err(),
);
}
#[ cfg( feature = "integration" ) ]
#[ tokio::test ]
async fn client_get_models_succeeds_with_real_key()
{
use api_openai_compatible::{ Client, OpenAiCompatEnvironmentImpl };
let ws = workspace_tools::workspace()
.expect( "workspace root must be resolvable" );
let api_key = ws.load_secret_key( "OPENAI_API_KEY", "-secrets.sh" )
.expect( "OPENAI_API_KEY must be set in secret/-secrets.sh" );
let env = OpenAiCompatEnvironmentImpl::new( &api_key )
.expect( "environment construction must succeed" );
let client = Client::build( env )
.expect( "Client::build() must succeed" );
let result : Result< serde_json::Value, _ > = client.get( "models" ).await;
assert!(
result.is_ok(),
"GET models with a valid API key must return Ok; got: {:?}",
result.err(),
);
let body = result.unwrap();
assert!(
body.is_object(),
"response body must be a JSON object; got: {body}",
);
}
#[ cfg( feature = "integration" ) ]
#[ tokio::test ]
async fn client_get_models_returns_api_error_with_fake_key()
{
use api_openai_compatible::{ Client, OpenAiCompatEnvironmentImpl };
let env = OpenAiCompatEnvironmentImpl::new( "sk-fake-integration-test" )
.expect( "environment construction must succeed with any non-empty key" );
let client = Client::build( env )
.expect( "Client::build() must succeed" );
let result : Result< serde_json::Value, _ > = client.get( "models" ).await;
assert!(
result.is_err(),
"GET models with a fake key must return Err, not Ok",
);
let err_msg = result.unwrap_err().to_string();
assert!(
err_msg.contains( "API error" ),
"error must contain 'API error' category prefix; got: {err_msg}",
);
}
#[ cfg( feature = "integration" ) ]
#[ tokio::test ]
async fn client_post_chat_returns_api_error_with_fake_key()
{
use api_openai_compatible::{ Client, OpenAiCompatEnvironmentImpl };
let env = OpenAiCompatEnvironmentImpl::new( "sk-fake-integration-test" )
.expect( "environment construction must succeed with any non-empty key" );
let client = Client::build( env )
.expect( "Client::build() must succeed" );
let body = serde_json::json!({
"model": "gpt-4o",
"messages": [ { "role": "user", "content": "Hi" } ]
});
let result : Result< serde_json::Value, _ > = client.post( "chat/completions", &body ).await;
assert!(
result.is_err(),
"POST chat/completions with a fake key must return Err, not Ok",
);
let err_msg = result.unwrap_err().to_string();
assert!(
err_msg.contains( "API error" ),
"error must contain 'API error' category prefix; got: {err_msg}",
);
}