post_agent_spec.rb 7.9KB

    require 'spec_helper' require 'ostruct' describe Agents::PostAgent do before do @valid_options = { 'post_url' => "http://www.example.com", 'expected_receive_period_in_days' => 1, 'payload' => { 'default' => 'value' } } @valid_params = { name: "somename", options: @valid_options } @checker = Agents::PostAgent.new(@valid_params) @checker.user = users(:jane) @checker.save! @event = Event.new @event.agent = agents(:jane_weather_agent) @event.payload = { 'somekey' => 'somevalue', 'someotherkey' => { 'somekey' => 'value' } } @requests = 0 @sent_requests = Hash.new { |hash, method| hash[method] = [] } stub_request(:any, /:/).to_return { |request| method = request.method @requests += 1 @sent_requests[method] << req = OpenStruct.new(uri: request.uri) case method when :get, :delete req.data = request.uri.query else case request.headers['Content-Type'][/\A[^;\s]+/] when 'application/x-www-form-urlencoded' req.data = request.body when 'application/json' req.data = ActiveSupport::JSON.decode(request.body) else raise "unexpected Content-Type: #{content_type}" end end { status: 200, body: "ok" } } end it_behaves_like WebRequestConcern describe "making requests" do it "can make requests of each type" do %w[get put post patch delete].each.with_index(1) do |verb, index| @checker.options['method'] = verb @checker.should be_valid @checker.check @requests.should == index @sent_requests[verb.to_sym].length.should == 1 end end end describe "#receive" do it "can handle multiple events and merge the payloads with options['payload']" do event1 = Event.new event1.agent = agents(:bob_weather_agent) event1.payload = { 'xyz' => 'value1', 'message' => 'value2', 'default' => 'value2' } lambda { lambda { @checker.receive([@event, event1]) }.should change { @sent_requests[:post].length }.by(2) }.should_not change { @sent_requests[:get].length } @sent_requests[:post][0].data.should == @event.payload.merge('default' => 'value').to_query @sent_requests[:post][1].data.should == event1.payload.to_query end it "can make GET requests" do @checker.options['method'] = 'get' lambda { lambda { @checker.receive([@event]) }.should change { @sent_requests[:get].length }.by(1) }.should_not change { @sent_requests[:post].length } @sent_requests[:get][0].data.should == @event.payload.merge('default' => 'value').to_query end it "can make a GET request merging params in post_url, payload and event" do @checker.options['method'] = 'get' @checker.options['post_url'] = "http://example.com/a/path?existing_param=existing_value" @event.payload = { "some_param" => "some_value", "another_param" => "another_value" } @checker.receive([@event]) uri = @sent_requests[:get].first.uri # parameters are alphabetically sorted by Faraday uri.request_uri.should == "/a/path?another_param=another_value&default=value&existing_param=existing_value&some_param=some_value" end it "can skip merging the incoming event when no_merge is set, but it still interpolates" do @checker.options['no_merge'] = 'true' @checker.options['payload'] = { 'key' => 'it said: {{ someotherkey.somekey }}' } @checker.receive([@event]) @sent_requests[:post].first.data.should == { 'key' => 'it said: value' }.to_query end it "interpolates when receiving a payload" do @checker.options['post_url'] = "https://{{ domain }}/{{ variable }}?existing_param=existing_value" @event.payload = { 'domain' => 'google.com', 'variable' => 'a_variable' } @checker.receive([@event]) uri = @sent_requests[:post].first.uri uri.scheme.should == 'https' uri.host.should == 'google.com' uri.path.should == '/a_variable' uri.query.should == "existing_param=existing_value" end end describe "#check" do it "sends options['payload'] as a POST request" do lambda { @checker.check }.should change { @sent_requests[:post].length }.by(1) @sent_requests[:post][0].data.should == @checker.options['payload'].to_query end it "sends options['payload'] as JSON as a POST request" do @checker.options['content_type'] = 'json' lambda { @checker.check }.should change { @sent_requests[:post].length }.by(1) @sent_requests[:post][0].data.should == @checker.options['payload'] end it "sends options['payload'] as a GET request" do @checker.options['method'] = 'get' lambda { lambda { @checker.check }.should change { @sent_requests[:get].length }.by(1) }.should_not change { @sent_requests[:post].length } @sent_requests[:get][0].data.should == @checker.options['payload'].to_query end end describe "#working?" do it "checks if events have been received within expected receive period" do @checker.should_not be_working Agents::PostAgent.async_receive @checker.id, [@event.id] @checker.reload.should be_working two_days_from_now = 2.days.from_now stub(Time).now { two_days_from_now } @checker.reload.should_not be_working end end describe "validation" do before do @checker.should be_valid end it "should validate presence of post_url" do @checker.options['post_url'] = "" @checker.should_not be_valid end it "should validate presence of expected_receive_period_in_days" do @checker.options['expected_receive_period_in_days'] = "" @checker.should_not be_valid end it "should validate method as post, get, put, patch, or delete, defaulting to post" do @checker.options['method'] = "" @checker.method.should == "post" @checker.should be_valid @checker.options['method'] = "POST" @checker.method.should == "post" @checker.should be_valid @checker.options['method'] = "get" @checker.method.should == "get" @checker.should be_valid @checker.options['method'] = "patch" @checker.method.should == "patch" @checker.should be_valid @checker.options['method'] = "wut" @checker.method.should == "wut" @checker.should_not be_valid end it "should validate that no_merge is 'true' or 'false', if present" do @checker.options['no_merge'] = "" @checker.should be_valid @checker.options['no_merge'] = "true" @checker.should be_valid @checker.options['no_merge'] = "false" @checker.should be_valid @checker.options['no_merge'] = false @checker.should be_valid @checker.options['no_merge'] = true @checker.should be_valid @checker.options['no_merge'] = 'blarg' @checker.should_not be_valid end it "should validate payload as a hash, if present" do @checker.options['payload'] = "" @checker.should be_valid @checker.options['payload'] = "hello" @checker.should_not be_valid @checker.options['payload'] = ["foo", "bar"] @checker.should_not be_valid @checker.options['payload'] = { 'this' => 'that' } @checker.should be_valid end it "requires headers to be a hash, if present" do @checker.options['headers'] = [1,2,3] @checker.should_not be_valid @checker.options['headers'] = "hello world" @checker.should_not be_valid @checker.options['headers'] = "" @checker.should be_valid @checker.options['headers'] = {} @checker.should be_valid @checker.options['headers'] = { "Authorization" => "foo bar" } @checker.should be_valid end end end