#![ cfg( feature = "integration" ) ]
mod inc;
use inc::test_helpers::create_test_client;
use api_xai::{ ChatCompletionRequest, Message, ClientApiAccessors };
#[ tokio::test ]
async fn test_chat_completion_basic()
{
let client = create_test_client();
let request = ChatCompletionRequest::former()
.model( "grok-2-1212".to_string() )
.messages( vec![ Message::user( "Say hello" ) ] )
.max_tokens( 20u32 )
.form();
let response = client.chat().create( request ).await
.expect( "Chat completion should succeed" );
assert!( !response.id.is_empty(), "Response should have an ID" );
assert_eq!( response.object, "chat.completion", "Object type should be chat.completion" );
assert!( !response.choices.is_empty(), "Response should have at least one choice" );
let first_choice = &response.choices[ 0 ];
assert_eq!( first_choice.index, 0, "First choice should have index 0" );
assert!( first_choice.message.content.is_some(), "Message should have content" );
let content = first_choice.message.content.as_ref().unwrap();
assert!( !content.is_empty(), "Content should not be empty" );
assert!( response.usage.prompt_tokens > 0, "Should have prompt tokens" );
assert!( response.usage.completion_tokens > 0, "Should have completion tokens" );
assert_eq!(
response.usage.total_tokens,
response.usage.prompt_tokens + response.usage.completion_tokens,
"Total tokens should equal sum of prompt and completion tokens"
);
println!( "✅ Basic chat completion test passed" );
println!( "Response : {content}" );
println!( "Usage : {} prompt + {} completion = {} total tokens",
response.usage.prompt_tokens,
response.usage.completion_tokens,
response.usage.total_tokens
);
}
#[ tokio::test ]
async fn test_chat_completion_with_system_message()
{
let client = create_test_client();
let request = ChatCompletionRequest::former()
.model( "grok-2-1212".to_string() )
.messages( vec![
Message::system( "You are a helpful assistant that speaks like a pirate" ),
Message::user( "Say hello" ),
] )
.max_tokens( 30u32 )
.form();
let response = client.chat().create( request ).await
.expect( "Chat completion with system message should succeed" );
assert!( !response.choices.is_empty() );
let content = response.choices[ 0 ].message.content.as_ref().unwrap();
assert!( !content.is_empty() );
println!( "✅ Chat with system message test passed" );
println!( "Pirate response : {content}" );
}
#[ tokio::test ]
async fn test_chat_completion_with_temperature()
{
let client = create_test_client();
let request = ChatCompletionRequest::former()
.model( "grok-2-1212".to_string() )
.messages( vec![ Message::user( "Count from 1 to 3" ) ] )
.temperature( 0.2 ) .max_tokens( 20u32 )
.form();
let response = client.chat().create( request ).await
.expect( "Chat completion with temperature should succeed" );
assert!( !response.choices.is_empty() );
let content = response.choices[ 0 ].message.content.as_ref().unwrap();
assert!( !content.is_empty() );
println!( "✅ Chat with temperature test passed" );
println!( "Response : {content}" );
}
#[ tokio::test ]
async fn test_chat_completion_with_max_tokens()
{
let client = create_test_client();
let request = ChatCompletionRequest::former()
.model( "grok-2-1212".to_string() )
.messages( vec![ Message::user( "Write a long story" ) ] )
.max_tokens( 10u32 ) .form();
let response = client.chat().create( request ).await
.expect( "Chat completion with max_tokens should succeed" );
assert!( !response.choices.is_empty() );
assert!(
response.usage.completion_tokens <= 10,
"Completion tokens should not exceed max_tokens"
);
let finish_reason = response.choices[ 0 ].finish_reason.as_deref();
assert!(
finish_reason == Some( "length" ) || finish_reason == Some( "stop" ),
"Finish reason should be 'length' or 'stop', got : {finish_reason:?}"
);
println!( "✅ Chat with max_tokens test passed" );
println!( "Finish reason : {finish_reason:?}" );
println!( "Completion tokens : {}", response.usage.completion_tokens );
}
#[ tokio::test ]
async fn test_chat_completion_with_multiple_messages()
{
let client = create_test_client();
let request = ChatCompletionRequest::former()
.model( "grok-2-1212".to_string() )
.messages( vec![
Message::user( "My name is Alice" ),
Message::assistant( "Hello Alice! Nice to meet you." ),
Message::user( "What is my name?" ),
] )
.max_tokens( 20u32 )
.form();
let response = client.chat().create( request ).await
.expect( "Chat completion with conversation history should succeed" );
assert!( !response.choices.is_empty() );
let content = response.choices[ 0 ].message.content.as_ref().unwrap();
assert!( !content.is_empty() );
println!( "✅ Chat with conversation history test passed" );
println!( "Response : {content}" );
}
#[ tokio::test ]
async fn test_chat_completion_model_grok_beta()
{
let client = create_test_client();
let request = ChatCompletionRequest::former()
.model( "grok-2-1212".to_string() )
.messages( vec![ Message::user( "Hello" ) ] )
.max_tokens( 10u32 )
.form();
let response = client.chat().create( request ).await
.expect( "Chat with grok-3 should succeed" );
assert!(
response.model.contains( "grok" ),
"Response model should contain 'grok', got : {}",
response.model
);
println!( "✅ Grok-beta model test passed" );
println!( "Model used : {}", response.model );
}
#[ tokio::test ]
async fn test_chat_completion_error_handling_invalid_model()
{
let client = create_test_client();
let request = ChatCompletionRequest::former()
.model( "nonexistent-model-12345".to_string() )
.messages( vec![ Message::user( "Hello" ) ] )
.form();
let result = client.chat().create( request ).await;
assert!( result.is_err(), "Should fail with invalid model" );
let error = result.unwrap_err();
let error_str = format!( "{error:?}" );
println!( "✅ Invalid model error handling test passed" );
println!( "Error : {error_str}" );
}
#[ tokio::test ]
async fn test_chat_completion_empty_message_handling()
{
let client = create_test_client();
let request = ChatCompletionRequest::former()
.model( "grok-2-1212".to_string() )
.messages( vec![ Message::user( "" ) ] )
.max_tokens( 10u32 )
.form();
let result = client.chat().create( request ).await;
match result {
Ok( response ) => {
println!( "✅ Empty message test : API accepted empty message" );
println!( "Response : {:?}", response.choices[ 0 ].message.content );
}
Err( e ) => {
println!( "✅ Empty message test : API rejected empty message (expected)" );
println!( "Error : {e:?}" );
}
}
}