require 'spec_helper' describe Sumo::QueryBuilder do subject { Sumo::QueryBuilder.new('fake-creds') } describe '.new' do context 'when the correct types of arguments are supplied' do subject { Sumo::QueryBuilder.new('auth', 'q' => 'error') } it 'creates a new QueryBuilder' do subject.creds.should == 'auth' subject.opts.should == { 'q' => 'error' } end end context 'when invalid arguments are supplied' do it 'raises an error' do expect { Sumo::QueryBuilder.new(:symbol, 1) } .to raise_error(Sumo::Error::TypeError) end end end describe '#query' do it 'adds a query to the request' do subject.query('alpha').opts.should == { 'q' => 'alpha' } end end describe '#to' do it 'adds an end time to the request' do subject.to('now').opts.should == { 'to' => 'now' } end end describe '#from' do it 'adds an end time to the request' do subject.from('-15m').opts.should == { 'from' => '-15m' } end end describe '#time_zone' do it 'adds a time zone to the request' do subject.time_zone('UTC').opts.should == { 'tz' => 'UTC' } end end describe '#format' do it 'adds a format to the request' do subject.format('JSON').opts.should == { 'format' => 'JSON' } end end describe '#execute' do let(:creds) { 'user@example.com:pass' } let(:encoded) { Base64.encode64(creds) } let(:conn) { double(:connection) } let(:query) { { 'q' => 'production', 'from' => '-30m', 'to' => '-15m', 'tz' => 'UTC', 'format' => 'json' } } subject { Sumo::QueryBuilder.new(creds).query('production') .from('-30m') .to('-15m') .time_zone('UTC') .format('json') } before do subject.stub(:connection).and_return(conn) conn.stub(:get) .with(:path => '/api/v1/logs/search', :query => query, :headers => { 'Authorization' => "Basic #{encoded}" }) .and_return(resp) end context 'when the server responds' do let(:resp) { double(:response, :body => '{}', :status => 200) } it 'parses the response' do subject.execute.should == '{}' end end context 'when the server does not respond' do let(:resp) { double(:response, :body => nil, :status => 504) } it 'raises an error' do expect { subject.execute }.to raise_error(Sumo::Error::RequestError) end end end describe 'integration', :vcr do # WARNING: If you are going to change this VCR, modify the credentials so # that they are valid, record the VCR, remove the credentials from it, and # change the below variable back to its original form. let(:creds) { 'aladdin@swipely.com:open sesame' } context 'when the request is valid' do let(:result) { JSON.parse(subject.execute) } subject { Sumo::QueryBuilder.new(creds).query('nginx') } it 'compiles and sends the query to the server' do result.length.should_not be_zero result.should be_all { |hash| %w(_sourcecategory _raw _sourcehost _receipttime _sourcename _messagetime).all? { |key| hash.has_key?(key) } } end end context 'when the request is invalid' do subject { Sumo::QueryBuilder.new(creds).query('nginx').to('nonsense') } it 'raises an error' do expect { subject.execute }.to raise_error(Sumo::Error::RequestError) end end end end