test: handle failing ipaddr lookup

This commit is contained in:
Shivam Mishra
2025-10-06 08:27:19 +05:30
parent 3e955b450b
commit 4c6d3376ef

View File

@@ -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: {