From 4c6d3376ef4bb76a3b0aea55a64ad3f9fa28745a Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Mon, 6 Oct 2025 08:27:19 +0530 Subject: [PATCH] test: handle failing ipaddr lookup --- .../lib/captain/tools/http_tool_spec.rb | 72 +++++++++---------- 1 file changed, 32 insertions(+), 40 deletions(-) diff --git a/spec/enterprise/lib/captain/tools/http_tool_spec.rb b/spec/enterprise/lib/captain/tools/http_tool_spec.rb index 4e53e0ae5..d48af2752 100644 --- a/spec/enterprise/lib/captain/tools/http_tool_spec.rb +++ b/spec/enterprise/lib/captain/tools/http_tool_spec.rb @@ -7,14 +7,6 @@ RSpec.describe Captain::Tools::HttpTool, type: :model do let(:tool) { described_class.new(assistant, custom_tool) } let(:tool_context) { Struct.new(:state).new({}) } - describe '#description' do - it 'returns the custom tool description' do - custom_tool.update!(description: 'Fetches order status from external API') - - expect(tool.description).to eq('Fetches order status from external API') - end - end - describe '#active?' do it 'returns true when custom tool is enabled' do custom_tool.update!(enabled: true) @@ -34,10 +26,10 @@ RSpec.describe Captain::Tools::HttpTool, type: :model do before do custom_tool.update!( http_method: 'GET', - endpoint_url: 'https://api.example.com/orders/123', + endpoint_url: 'https://example.com/orders/123', response_template: nil ) - stub_request(:get, 'https://api.example.com/orders/123') + stub_request(:get, 'https://example.com/orders/123') .to_return(status: 200, body: '{"status": "success"}') end @@ -45,7 +37,7 @@ RSpec.describe Captain::Tools::HttpTool, type: :model do result = tool.perform(tool_context) expect(result).to eq('{"status": "success"}') - expect(WebMock).to have_requested(:get, 'https://api.example.com/orders/123') + expect(WebMock).to have_requested(:get, 'https://example.com/orders/123') end end @@ -53,11 +45,11 @@ RSpec.describe Captain::Tools::HttpTool, type: :model do before do custom_tool.update!( http_method: 'POST', - endpoint_url: 'https://api.example.com/orders', + endpoint_url: 'https://example.com/orders', request_template: '{"order_id": "{{ order_id }}"}', response_template: nil ) - stub_request(:post, 'https://api.example.com/orders') + stub_request(:post, 'https://example.com/orders') .with(body: '{"order_id": "123"}', headers: { 'Content-Type' => 'application/json' }) .to_return(status: 200, body: '{"created": true}') end @@ -66,7 +58,7 @@ RSpec.describe Captain::Tools::HttpTool, type: :model do result = tool.perform(tool_context, order_id: '123') expect(result).to eq('{"created": true}') - expect(WebMock).to have_requested(:post, 'https://api.example.com/orders') + expect(WebMock).to have_requested(:post, 'https://example.com/orders') .with(body: '{"order_id": "123"}') end end @@ -74,10 +66,10 @@ RSpec.describe Captain::Tools::HttpTool, type: :model do context 'with template variables in URL' do before do custom_tool.update!( - endpoint_url: 'https://api.example.com/orders/{{ order_id }}', + endpoint_url: 'https://example.com/orders/{{ order_id }}', response_template: nil ) - stub_request(:get, 'https://api.example.com/orders/456') + stub_request(:get, 'https://example.com/orders/456') .to_return(status: 200, body: '{"order_id": "456"}') end @@ -85,7 +77,7 @@ RSpec.describe Captain::Tools::HttpTool, type: :model do result = tool.perform(tool_context, order_id: '456') expect(result).to eq('{"order_id": "456"}') - expect(WebMock).to have_requested(:get, 'https://api.example.com/orders/456') + expect(WebMock).to have_requested(:get, 'https://example.com/orders/456') end end @@ -94,10 +86,10 @@ RSpec.describe Captain::Tools::HttpTool, type: :model do custom_tool.update!( auth_type: 'bearer', auth_config: { 'token' => 'secret_bearer_token' }, - endpoint_url: 'https://api.example.com/data', + endpoint_url: 'https://example.com/data', response_template: nil ) - stub_request(:get, 'https://api.example.com/data') + stub_request(:get, 'https://example.com/data') .with(headers: { 'Authorization' => 'Bearer secret_bearer_token' }) .to_return(status: 200, body: '{"authenticated": true}') end @@ -106,7 +98,7 @@ RSpec.describe Captain::Tools::HttpTool, type: :model do result = tool.perform(tool_context) expect(result).to eq('{"authenticated": true}') - expect(WebMock).to have_requested(:get, 'https://api.example.com/data') + expect(WebMock).to have_requested(:get, 'https://example.com/data') .with(headers: { 'Authorization' => 'Bearer secret_bearer_token' }) end end @@ -116,10 +108,10 @@ RSpec.describe Captain::Tools::HttpTool, type: :model do custom_tool.update!( auth_type: 'basic', auth_config: { 'username' => 'user123', 'password' => 'pass456' }, - endpoint_url: 'https://api.example.com/data', + endpoint_url: 'https://example.com/data', response_template: nil ) - stub_request(:get, 'https://api.example.com/data') + stub_request(:get, 'https://example.com/data') .with(basic_auth: %w[user123 pass456]) .to_return(status: 200, body: '{"authenticated": true}') end @@ -128,7 +120,7 @@ RSpec.describe Captain::Tools::HttpTool, type: :model do result = tool.perform(tool_context) expect(result).to eq('{"authenticated": true}') - expect(WebMock).to have_requested(:get, 'https://api.example.com/data') + expect(WebMock).to have_requested(:get, 'https://example.com/data') .with(basic_auth: %w[user123 pass456]) end end @@ -138,10 +130,10 @@ RSpec.describe Captain::Tools::HttpTool, type: :model do custom_tool.update!( auth_type: 'api_key', auth_config: { 'key' => 'api_key_123', 'location' => 'header', 'name' => 'X-API-Key' }, - endpoint_url: 'https://api.example.com/data', + endpoint_url: 'https://example.com/data', response_template: nil ) - stub_request(:get, 'https://api.example.com/data') + stub_request(:get, 'https://example.com/data') .with(headers: { 'X-API-Key' => 'api_key_123' }) .to_return(status: 200, body: '{"authenticated": true}') end @@ -150,7 +142,7 @@ RSpec.describe Captain::Tools::HttpTool, type: :model do result = tool.perform(tool_context) expect(result).to eq('{"authenticated": true}') - expect(WebMock).to have_requested(:get, 'https://api.example.com/data') + expect(WebMock).to have_requested(:get, 'https://example.com/data') .with(headers: { 'X-API-Key' => 'api_key_123' }) end end @@ -158,10 +150,10 @@ RSpec.describe Captain::Tools::HttpTool, type: :model do context 'with response template' do before do custom_tool.update!( - endpoint_url: 'https://api.example.com/orders/123', + endpoint_url: 'https://example.com/orders/123', response_template: 'Order status: {{ response.status }}, ID: {{ response.order_id }}' ) - stub_request(:get, 'https://api.example.com/orders/123') + stub_request(:get, 'https://example.com/orders/123') .to_return(status: 200, body: '{"status": "shipped", "order_id": "123"}') end @@ -174,8 +166,8 @@ RSpec.describe Captain::Tools::HttpTool, type: :model do context 'when handling errors' do it 'returns generic error message on network failure' do - custom_tool.update!(endpoint_url: 'https://api.example.com/data') - stub_request(:get, 'https://api.example.com/data').to_raise(SocketError.new('Failed to connect')) + custom_tool.update!(endpoint_url: 'https://example.com/data') + stub_request(:get, 'https://example.com/data').to_raise(SocketError.new('Failed to connect')) result = tool.perform(tool_context) @@ -183,8 +175,8 @@ RSpec.describe Captain::Tools::HttpTool, type: :model do end it 'returns generic error message on timeout' do - custom_tool.update!(endpoint_url: 'https://api.example.com/data') - stub_request(:get, 'https://api.example.com/data').to_timeout + custom_tool.update!(endpoint_url: 'https://example.com/data') + stub_request(:get, 'https://example.com/data').to_timeout result = tool.perform(tool_context) @@ -192,8 +184,8 @@ RSpec.describe Captain::Tools::HttpTool, type: :model do end it 'returns generic error message on HTTP 404' do - custom_tool.update!(endpoint_url: 'https://api.example.com/data') - stub_request(:get, 'https://api.example.com/data').to_return(status: 404, body: 'Not found') + custom_tool.update!(endpoint_url: 'https://example.com/data') + stub_request(:get, 'https://example.com/data').to_return(status: 404, body: 'Not found') result = tool.perform(tool_context) @@ -201,8 +193,8 @@ RSpec.describe Captain::Tools::HttpTool, type: :model do end it 'returns generic error message on HTTP 500' do - custom_tool.update!(endpoint_url: 'https://api.example.com/data') - stub_request(:get, 'https://api.example.com/data').to_return(status: 500, body: 'Server error') + custom_tool.update!(endpoint_url: 'https://example.com/data') + stub_request(:get, 'https://example.com/data').to_return(status: 500, body: 'Server error') result = tool.perform(tool_context) @@ -210,8 +202,8 @@ RSpec.describe Captain::Tools::HttpTool, type: :model do end it 'logs error details' do - custom_tool.update!(endpoint_url: 'https://api.example.com/data') - stub_request(:get, 'https://api.example.com/data').to_raise(StandardError.new('Test error')) + custom_tool.update!(endpoint_url: 'https://example.com/data') + stub_request(:get, 'https://example.com/data').to_raise(StandardError.new('Test error')) expect(Rails.logger).to receive(:error).with(/HttpTool execution error.*Test error/) @@ -223,14 +215,14 @@ RSpec.describe Captain::Tools::HttpTool, type: :model do it 'correctly integrates URL rendering, body rendering, auth, and response formatting' do custom_tool.update!( http_method: 'POST', - endpoint_url: 'https://api.example.com/users/{{ user_id }}/orders', + endpoint_url: 'https://example.com/users/{{ user_id }}/orders', request_template: '{"product": "{{ product }}", "quantity": {{ quantity }}}', auth_type: 'bearer', auth_config: { 'token' => 'integration_token' }, response_template: 'Created order #{{ response.order_number }} for {{ response.product }}' ) - stub_request(:post, 'https://api.example.com/users/42/orders') + stub_request(:post, 'https://example.com/users/42/orders') .with( body: '{"product": "Widget", "quantity": 5}', headers: {