test: add specs for assistant chat service

This commit is contained in:
Shivam Mishra
2025-04-04 13:13:57 +05:30
parent 1a78a9243f
commit 731d616e7c
2 changed files with 161 additions and 0 deletions
@@ -0,0 +1,160 @@
require 'rails_helper'
RSpec.describe Captain::Llm::AssistantChatService do
let(:captain_assistant) { create(:captain_assistant) }
let(:service) { described_class.new(assistant: captain_assistant) }
let(:client) { instance_double(OpenAI::Client) }
before do
create(:installation_config, name: 'CAPTAIN_OPEN_AI_API_KEY', value: 'test-key')
allow(OpenAI::Client).to receive(:new).and_return(client)
end
describe '#generate_response' do
let(:input) { 'How can I help you?' }
let(:previous_messages) { [{ role: 'user', content: 'Previous message' }] }
let(:openai_response) do
{
'choices' => [
{
'message' => {
'content' => {
reasoning: 'This is a helpful response',
response: 'I can assist you with your questions.'
}.to_json
}
}
]
}
end
context 'when successful' do
before do
allow(client).to receive(:chat).and_return(openai_response)
end
it 'generates a response with input' do
response = service.generate_response(input)
expect(response).to eq({
'reasoning' => 'This is a helpful response',
'response' => 'I can assist you with your questions.'
})
end
it 'generates a response with input and previous messages' do
response = service.generate_response(input, previous_messages)
expect(response).to eq({
'reasoning' => 'This is a helpful response',
'response' => 'I can assist you with your questions.'
})
end
it 'includes previous messages in the chat parameters' do
service.generate_response(input, previous_messages)
expect(client).to have_received(:chat) do |params|
messages = params[:parameters][:messages]
expect(messages).to include(
hash_including(role: 'user', content: 'Previous message')
)
end
end
it 'includes system message in the chat parameters' do
service.generate_response(input)
expect(client).to have_received(:chat) do |params|
messages = params[:parameters][:messages]
expect(messages.first[:role]).to eq('system')
expect(messages.first[:content]).to include(captain_assistant.config['product_name'])
end
end
end
context 'when input is empty' do
let(:input) { '' }
before do
allow(client).to receive(:chat).and_return(openai_response)
end
it 'does not add empty input to messages' do
service.generate_response(input)
expect(client).to have_received(:chat) do |params|
messages = params[:parameters][:messages]
expect(messages.pluck(:role)).not_to include('user')
end
end
end
context 'with documentation search' do
let(:openai_response_with_tool) do
{
'choices' => [
{
'message' => {
'tool_calls' => [
{
'id' => 'call_123',
'function' => {
'name' => 'search_documentation',
'arguments' => { 'search_query' => 'test query' }.to_json
}
}
]
}
}
]
}
end
let(:search_results) { "Question: Test\nAnswer: Test answer" }
before do
allow(client).to receive(:chat).and_return(openai_response_with_tool, openai_response)
allow(service).to receive(:fetch_documentation).and_return(search_results)
end
it 'handles documentation search tool calls' do
response = service.generate_response(input)
expect(response).to eq({
'reasoning' => 'This is a helpful response',
'response' => 'I can assist you with your questions.'
})
expect(client).to have_received(:chat).twice
end
end
end
describe '#chat_parameters' do
before do
allow(client).to receive(:chat).and_return(
{
'choices' => [
{
'message' => {
'content' => {
reasoning: 'Test reasoning',
response: 'Test response'
}.to_json
}
}
]
}
)
end
it 'includes correct model and response format' do
service.generate_response('test')
expect(client).to have_received(:chat) do |params|
parameters = params[:parameters]
expect(parameters[:model]).to eq('gpt-4o-mini')
expect(parameters[:response_format]).to eq({ type: 'json_object' })
expect(parameters[:tools]).to include(
hash_including(
type: 'function',
function: hash_including(name: 'search_documentation')
)
)
end
end
end
end
+1
View File
@@ -3,5 +3,6 @@ FactoryBot.define do
sequence(:name) { |n| "Assistant #{n}" }
description { 'Test description' }
association :account
config { { 'product_name' => 'Test Product', 'feature_memory' => true, 'feature_faq' => true } }
end
end