Files
clientsflow/research/chatwoot/spec/lib/captain/follow_up_service_spec.rb

165 lines
6.3 KiB
Ruby

require 'rails_helper'
RSpec.describe Captain::FollowUpService do
let(:account) { create(:account) }
let(:inbox) { create(:inbox, account: account) }
let(:conversation) { create(:conversation, account: account, inbox: inbox) }
let(:user_message) { 'Make it more concise' }
let(:follow_up_context) do
{
'event_name' => 'professional',
'original_context' => 'Please help me with this issue',
'last_response' => 'I would be happy to assist you with this matter.',
'conversation_history' => [
{ 'role' => 'user', 'content' => 'Make it shorter' },
{ 'role' => 'assistant', 'content' => 'Happy to help with this.' }
]
}
end
let(:service) do
described_class.new(
account: account,
follow_up_context: follow_up_context,
user_message: user_message,
conversation_display_id: conversation.display_id
)
end
before do
# Stub captain enabled check to allow specs to test base functionality
# without enterprise module interference
allow(account).to receive(:feature_enabled?).and_call_original
allow(account).to receive(:feature_enabled?).with('captain_tasks').and_return(true)
end
describe '#perform' do
context 'when conversation_display_id is provided' do
it 'resolves conversation for instrumentation' do
expect(service.send(:conversation)).to eq(conversation)
end
end
context 'when follow-up context exists' do
it 'constructs messages array with full conversation history' do
expect(service).to receive(:make_api_call) do |args|
messages = args[:messages]
expect(messages).to match(
[
a_hash_including(role: 'system', content: include('tone rewrite (professional)')),
{ role: 'user', content: 'Please help me with this issue' },
{ role: 'assistant', content: 'I would be happy to assist you with this matter.' },
{ role: 'user', content: 'Make it shorter' },
{ role: 'assistant', content: 'Happy to help with this.' },
{ role: 'user', content: 'Make it more concise' }
]
)
{ message: 'Refined response' }
end
service.perform
end
it 'returns updated follow-up context' do
allow(service).to receive(:make_api_call).and_return({ message: 'Refined response' })
result = service.perform
expect(result[:message]).to eq('Refined response')
expect(result[:follow_up_context]['last_response']).to eq('Refined response')
expect(result[:follow_up_context]['conversation_history'].length).to eq(4)
expect(result[:follow_up_context]['conversation_history'][-2]['content']).to eq('Make it more concise')
expect(result[:follow_up_context]['conversation_history'][-1]['content']).to eq('Refined response')
end
end
context 'when follow-up context is missing' do
let(:follow_up_context) { nil }
it 'returns error with 400 code' do
result = service.perform
expect(result[:error]).to eq('Follow-up context missing')
expect(result[:error_code]).to eq(400)
end
end
end
describe '#build_follow_up_system_prompt' do
it 'describes tone rewrite actions' do
%w[professional casual friendly confident straightforward].each do |tone|
session = { 'event_name' => tone }
prompt = service.send(:build_follow_up_system_prompt, session)
expect(prompt).to include("tone rewrite (#{tone})")
expect(prompt).to include('help them refine the result')
end
end
it 'describes fix_spelling_grammar action' do
session = { 'event_name' => 'fix_spelling_grammar' }
prompt = service.send(:build_follow_up_system_prompt, session)
expect(prompt).to include('spelling and grammar correction')
end
it 'describes improve action' do
session = { 'event_name' => 'improve' }
prompt = service.send(:build_follow_up_system_prompt, session)
expect(prompt).to include('message improvement')
end
it 'describes summarize action' do
session = { 'event_name' => 'summarize' }
prompt = service.send(:build_follow_up_system_prompt, session)
expect(prompt).to include('conversation summary')
end
it 'describes reply_suggestion action' do
session = { 'event_name' => 'reply_suggestion' }
prompt = service.send(:build_follow_up_system_prompt, session)
expect(prompt).to include('reply suggestion')
end
it 'describes label_suggestion action' do
session = { 'event_name' => 'label_suggestion' }
prompt = service.send(:build_follow_up_system_prompt, session)
expect(prompt).to include('label suggestion')
end
it 'uses event_name directly for unknown actions' do
session = { 'event_name' => 'custom_action' }
prompt = service.send(:build_follow_up_system_prompt, session)
expect(prompt).to include('custom_action')
end
end
describe '#describe_previous_action' do
it 'returns tone description for tone operations' do
expect(service.send(:describe_previous_action, 'professional')).to eq('tone rewrite (professional)')
expect(service.send(:describe_previous_action, 'casual')).to eq('tone rewrite (casual)')
expect(service.send(:describe_previous_action, 'friendly')).to eq('tone rewrite (friendly)')
expect(service.send(:describe_previous_action, 'confident')).to eq('tone rewrite (confident)')
expect(service.send(:describe_previous_action, 'straightforward')).to eq('tone rewrite (straightforward)')
end
it 'returns specific descriptions for other operations' do
expect(service.send(:describe_previous_action, 'fix_spelling_grammar')).to eq('spelling and grammar correction')
expect(service.send(:describe_previous_action, 'improve')).to eq('message improvement')
expect(service.send(:describe_previous_action, 'summarize')).to eq('conversation summary')
expect(service.send(:describe_previous_action, 'reply_suggestion')).to eq('reply suggestion')
expect(service.send(:describe_previous_action, 'label_suggestion')).to eq('label suggestion')
end
it 'returns event name for unknown operations' do
expect(service.send(:describe_previous_action, 'unknown')).to eq('unknown')
end
end
end