Fix the specs for HttpStatusAgent

- Raplace hand-made mocking for web requests with Webmock

- Stop overriding internal methods of Agent like `interpolated`, because
  that made the specs not reflect actual behavior
This commit is contained in:
Akinori MUSHA 2016-11-04 15:03:15 +09:00
parent 6d4fdd3196
commit c9e567edb3

View file

@ -1,53 +1,29 @@
require 'rails_helper' require 'rails_helper'
class MockResponse < Struct.new(:status, :headers, :url)
alias_method :to_hash, :to_h
end
describe 'HttpStatusAgent' do describe 'HttpStatusAgent' do
before do
let(:agent) do stub_request(:get, 'http://google.com/')
Agents::HttpStatusAgent.new(:name => SecureRandom.uuid, :options => valid_params).tap do |a|
a.service = services(:generic)
a.user = users(:jane)
a.options['url'] = 'http://google.com'
a.options['headers_to_save'] = 'Server'
a.save!
def a.interpolate_with(e, &block)
@the_event = e
block.call
end
def a.interpolated
@the_event.payload
end
def a.create_event event
@the_created_events ||= []
@the_created_events << event
end
def a.the_created_events
@the_created_events || []
end
def a.faraday
@faraday ||= Struct.new(:programmed_responses).new({}).tap do |f|
def f.get url
programmed_responses[url] || raise('invalid url')
end
def f.set url, response, time = nil
sleep(time/1000) if time
programmed_responses[url] = response
end
end
end
end
end end
let(:valid_params) { {} } let(:agent_options) do
{
url: 'http://google.com/',
headers_to_save: 'Server'
}
end
let(:agent) do
Agents::HttpStatusAgent.create!(
name: SecureRandom.uuid,
service: services(:generic),
user: users(:jane),
options: agent_options
)
end
def created_events
agent.events.reorder(id: :asc)
end
describe "working" do describe "working" do
it "should be working when the last status is 200" do it "should be working when the last status is 200" do
@ -77,27 +53,21 @@ describe 'HttpStatusAgent' do
end end
describe "check" do describe "check" do
let(:url) { "http://#{SecureRandom.uuid}/" }
before do let(:agent_options) do
{
def agent.interpolated url: url,
@interpolated ||= { :url => SecureRandom.uuid, :headers_to_save => '' } headers_to_save: ''
end }
def agent.check_this_url url, local_headers
@url = url
@local_headers = local_headers
end
def agent.checked_url
@url
end
end end
it "should check the url" do it "should check the url" do
stub = stub_request(:get, url)
agent.check agent.check
expect(agent.checked_url).to eq(agent.interpolated[:url])
expect(stub).to have_been_requested
end end
end end
@ -106,15 +76,22 @@ describe 'HttpStatusAgent' do
describe "with an event with a successful ping" do describe "with an event with a successful ping" do
let(:successful_url) { SecureRandom.uuid } let(:successful_url) { "http://#{SecureRandom.uuid}/" }
let(:status_code) { 200 } let(:status_code) { 200 }
let(:header) { SecureRandom.uuid } let(:header) { SecureRandom.uuid }
let(:header_value) { SecureRandom.uuid } let(:header_value) { SecureRandom.uuid }
before do
stub_request(:get, successful_url).to_return(status: status_code)
end
let(:agent_options) do
super().merge(url: successful_url)
end
let(:event_with_a_successful_ping) do let(:event_with_a_successful_ping) do
agent.faraday.set(successful_url, MockResponse.new(status_code, {}, successful_url)) Event.new(payload: { url: successful_url, headers_to_save: "" })
Event.new.tap { |e| e.payload = { url: successful_url, headers_to_save: "" } }
end end
let(:events) do let(:events) do
@ -123,17 +100,17 @@ describe 'HttpStatusAgent' do
it "should create one event" do it "should create one event" do
agent.receive events agent.receive events
expect(agent.the_created_events.count).to eq(1) expect(created_events.count).to eq(1)
end end
it "should note that the successful response succeeded" do it "should note that the successful response succeeded" do
agent.receive events agent.receive events
expect(agent.the_created_events[0][:payload]['response_received']).to eq(true) expect(created_events.last[:payload]['response_received']).to eq(true)
end end
it "should return the status code" do it "should return the status code" do
agent.receive events agent.receive events
expect(agent.the_created_events[0][:payload]['status']).to eq('200') expect(created_events.last[:payload]['status']).to eq('200')
end end
it "should remember the status" do it "should remember the status" do
@ -143,51 +120,68 @@ describe 'HttpStatusAgent' do
it "should record the time spent waiting for the reply" do it "should record the time spent waiting for the reply" do
agent.receive events agent.receive events
expect(agent.the_created_events[0][:payload]['elapsed_time']).not_to be_nil expect(created_events.last[:payload]['elapsed_time']).not_to be_nil
end end
it "should not return a header" do it "should not return a header" do
agent.receive events agent.receive events
expect(agent.the_created_events[0][:payload]['headers']).to be_nil expect(created_events.last[:payload]['headers']).to be_nil
end end
describe "but the last status code was 200" do describe "but the last status code was 200" do
before { agent.memory['last_status'] = '200' } before do
agent.memory['last_status'] = '200'
agent.save!
end
describe "and no duplication settings have been set" do describe "and no duplication settings have been set" do
it "should create one event" do it "should create one event" do
agent.receive events agent.receive events
expect(agent.the_created_events.count).to eq(1) expect(created_events.count).to eq(1)
end end
end end
describe "and change settings have been set to true" do describe "and change settings have been set to true" do
before { agent.options['changes_only'] = 'true' } before do
agent.options[:changes_only] = 'true'
agent.save!
end
it "should NOT create any events" do it "should NOT create any events" do
agent.receive events agent.receive events
expect(agent.the_created_events.count).to eq(0) expect(created_events.count).to eq(0)
end end
describe "but actually, the ping failed" do describe "but actually, the ping failed" do
let(:failing_url) { SecureRandom.uuid } let(:failing_url) { "http://#{SecureRandom.uuid}/" }
let(:event_with_a_failing_ping) { Event.new.tap { |e| e.payload = { url: failing_url, headers_to_save: "" } } } let(:event_with_a_failing_ping) do
Event.new(payload: { url: failing_url, headers_to_save: "" })
end
let(:events) do let(:events) do
[event_with_a_successful_ping, event_with_a_failing_ping] [event_with_a_successful_ping, event_with_a_failing_ping]
end end
before do
stub_request(:get, failing_url).to_return(status: 500)
end
it "should create an event" do it "should create an event" do
agent.receive events agent.receive events
expect(agent.the_created_events.count).to eq(1) expect(created_events.count).to eq(1)
end end
end end
end end
describe "and change settings have been set to false" do describe "and change settings have been set to false" do
before { agent.options['changes_only'] = 'false' } before do
agent.options[:changes_only] = 'false'
agent.save!
end
it "should create one event" do it "should create one event" do
agent.receive events agent.receive events
expect(agent.the_created_events.count).to eq(1) expect(created_events.count).to eq(1)
end end
end end
@ -198,7 +192,7 @@ describe 'HttpStatusAgent' do
it "should return the status code" do it "should return the status code" do
agent.receive events agent.receive events
expect(agent.the_created_events[0][:payload]['status']).to eq('500') expect(created_events.last[:payload]['status']).to eq('500')
end end
it "should remember the status" do it "should remember the status" do
@ -209,39 +203,41 @@ describe 'HttpStatusAgent' do
it "should return the original url" do it "should return the original url" do
agent.receive events agent.receive events
expect(agent.the_created_events[0][:payload]['url']).to eq(successful_url) expect(created_events.last[:payload]['url']).to eq(successful_url)
end end
it "should return the final url" do it "should return the final url" do
agent.receive events agent.receive events
expect(agent.the_created_events[0][:payload]['final_url']).to eq(successful_url) expect(created_events.last[:payload]['final_url']).to eq(successful_url)
end end
it "should return whether the url redirected" do it "should return whether the url redirected" do
agent.receive events agent.receive events
expect(agent.the_created_events[0][:payload]['redirected']).to eq(false) expect(created_events.last[:payload]['redirected']).to eq(false)
end end
describe "but the ping returns a status code of 0" do describe "but the ping returns a status code of 0" do
before do
stub_request(:get, successful_url).to_return(status: 0)
end
let(:event_with_a_successful_ping) do let(:event_with_a_successful_ping) do
agent.faraday.set(successful_url, MockResponse.new(0, {}, successful_url)) Event.new(payload: { url: successful_url, headers_to_save: "" })
Event.new.tap { |e| e.payload = { url: successful_url, headers_to_save: "" } }
end end
it "should create one event" do it "should create one event" do
agent.receive events agent.receive events
expect(agent.the_created_events.count).to eq(1) expect(created_events.count).to eq(1)
end end
it "should note that no response was received" do it "should note that no response was received" do
agent.receive events agent.receive events
expect(agent.the_created_events[0][:payload]['response_received']).to eq(false) expect(created_events.last[:payload]['response_received']).to eq(false)
end end
it "should return the original url" do it "should return the original url" do
agent.receive events agent.receive events
expect(agent.the_created_events[0][:payload]['url']).to eq(successful_url) expect(created_events.last[:payload]['url']).to eq(successful_url)
end end
it "should remember no status" do it "should remember no status" do
@ -253,77 +249,91 @@ describe 'HttpStatusAgent' do
end end
describe "but the ping returns a status code of -1" do describe "but the ping returns a status code of -1" do
before do
stub_request(:get, successful_url).to_return(status: -1)
end
let(:event_with_a_successful_ping) do let(:event_with_a_successful_ping) do
agent.faraday.set(successful_url, MockResponse.new(-1, {}, successful_url)) Event.new(payload: { url: successful_url, headers_to_save: "" })
Event.new.tap { |e| e.payload = { url: successful_url, headers_to_save: "" } }
end end
it "should create one event" do it "should create one event" do
agent.receive events agent.receive events
expect(agent.the_created_events.count).to eq(1) expect(created_events.count).to eq(1)
end end
it "should note that no response was received" do it "should note that no response was received" do
agent.receive events agent.receive events
expect(agent.the_created_events[0][:payload]['response_received']).to eq(false) expect(created_events.last[:payload]['response_received']).to eq(false)
end end
it "should return the original url" do it "should return the original url" do
agent.receive events agent.receive events
expect(agent.the_created_events[0][:payload]['url']).to eq(successful_url) expect(created_events.last[:payload]['url']).to eq(successful_url)
end end
end end
describe "and with one event with a failing ping" do describe "and with one event with a failing ping" do
let(:failing_url) { SecureRandom.uuid } let(:failing_url) { "http://#{SecureRandom.uuid}/" }
let(:event_with_a_failing_ping) { Event.new.tap { |e| e.payload = { url: failing_url, headers_to_save: "" } } } let(:event_with_a_failing_ping) do
Event.new(payload: { url: failing_url, headers_to_save: "" })
end
let(:events) do let(:events) do
[event_with_a_successful_ping, event_with_a_failing_ping] [event_with_a_successful_ping, event_with_a_failing_ping]
end end
before do
stub_request(:get, failing_url).to_raise(RuntimeError) #to_return(status: 500)
end
it "should create two events" do it "should create two events" do
agent.receive events agent.receive events
expect(agent.the_created_events.count).to eq(2) expect(created_events.count).to eq(2)
end end
it "should note that the failed response failed" do it "should note that the failed response failed" do
agent.receive events agent.receive events
expect(agent.the_created_events[1][:payload]['response_received']).to eq(false) expect(created_events[1][:payload]['response_received']).to eq(false)
end end
it "should note that the successful response succeeded" do it "should note that the successful response succeeded" do
agent.receive events agent.receive events
expect(agent.the_created_events[0][:payload]['response_received']).to eq(true) expect(created_events[0][:payload]['response_received']).to eq(true)
end end
it "should return the original url on both events" do it "should return the original url on both events" do
agent.receive events agent.receive events
expect(agent.the_created_events[0][:payload]['url']).to eq(successful_url) expect(created_events[0][:payload]['url']).to eq(successful_url)
expect(agent.the_created_events[1][:payload]['url']).to eq(failing_url) expect(created_events[1][:payload]['url']).to eq(failing_url)
end end
it "should record the time spent waiting for the reply" do it "should record the time spent waiting for the reply" do
agent.receive events agent.receive events
expect(agent.the_created_events[0][:payload]['elapsed_time']).not_to be_nil expect(created_events[0][:payload]['elapsed_time']).not_to be_nil
expect(agent.the_created_events[1][:payload]['elapsed_time']).not_to be_nil expect(created_events[1][:payload]['elapsed_time']).not_to be_nil
end end
end end
describe "with a header specified" do describe "with a header specified" do
before do
stub_request(:get, successful_url).to_return(
status: status_code,
headers: { header => header_value }
)
end
let(:event_with_a_successful_ping) do let(:event_with_a_successful_ping) do
agent.faraday.set(successful_url, MockResponse.new(status_code, {header => header_value}, successful_url)) Event.new(payload: { url: successful_url, headers_to_save: header })
Event.new.tap { |e| e.payload = { url: successful_url, headers_to_save: header } }
end end
it "should return the header value" do it "should return the header value" do
agent.receive events agent.receive events
expect(agent.the_created_events[0][:payload]['headers']).not_to be_nil event = created_events.last
expect(agent.the_created_events[0][:payload]['headers'][header]).to eq(header_value) expect(event[:payload]['headers']).not_to be_nil
expect(event[:payload]['headers'][header]).to eq(header_value)
end end
end end
@ -331,19 +341,28 @@ describe 'HttpStatusAgent' do
describe "with existing and non-existing headers specified" do describe "with existing and non-existing headers specified" do
let(:nonexistant_header) { SecureRandom.uuid } let(:nonexistant_header) { SecureRandom.uuid }
before do
stub_request(:get, successful_url).to_return(
status: status_code,
headers: { header => header_value }
)
end
let(:event_with_a_successful_ping) do let(:event_with_a_successful_ping) do
agent.faraday.set(successful_url, MockResponse.new(status_code, {header => header_value}, successful_url)) Event.new(payload: {
Event.new.tap { |e| e.payload = { url: successful_url, headers_to_save: header + "," + nonexistant_header } } url: successful_url,
headers_to_save: header + "," + nonexistant_header
})
end end
it "should return the existing header's value" do it "should return the existing header's value" do
agent.receive events agent.receive events
expect(agent.the_created_events[0][:payload]['headers'][header]).to eq(header_value) expect(created_events.last[:payload]['headers'][header]).to eq(header_value)
end end
it "should return nil for the nonexistant header" do it "should return nil for the nonexistant header" do
agent.receive events agent.receive events
expect(agent.the_created_events[0][:payload]['headers'][nonexistant_header]).to be_nil expect(created_events.last[:payload]['headers'][nonexistant_header]).to be_nil
end end
end end