features/steps/notifications_steps.rb in flapjack-1.6.0 vs features/steps/notifications_steps.rb in flapjack-2.0.0b1

- old
+ new

@@ -1,334 +1,478 @@ +require 'flapjack/data/check' +require 'flapjack/data/contact' +require 'flapjack/data/medium' +require 'flapjack/data/rule' +require 'flapjack/data/tag' -# copied from flapjack-populator -# TODO use Flapjack::Data::Contact.add -def add_contact(contact = {}) - @notifier_redis.multi do |multi| - multi.del("contact:#{contact['id']}") - multi.del("contact_media:#{contact['id']}") - multi.hset("contact:#{contact['id']}", 'first_name', contact['first_name']) - multi.hset("contact:#{contact['id']}", 'last_name', contact['last_name']) - multi.hset("contact:#{contact['id']}", 'email', contact['email']) - contact['media'].each_pair {|medium, address| - multi.hset("contact_media:#{contact['id']}", medium, address) - } +require 'flapjack/gateways/aws_sns' +require 'flapjack/gateways/email' +require 'flapjack/gateways/sms_messagenet' +require 'flapjack/gateways/sms_nexmo' + +def find_or_create_contact(contact_data) + contact = Flapjack::Data::Contact.intersect(:name => contact_data[:name]).all.first + if contact.nil? + contact = Flapjack::Data::Contact.new(:name => contact_data[:name]) + expect(contact.save).to be true end -end -Given /^the user wants to receive SMS notifications for entity '([\w\.\-]+)'$/ do |entity| - add_contact( 'id' => '0999', - 'first_name' => 'John', - 'last_name' => 'Smith', - 'email' => 'johns@example.dom', - 'media' => {'sms' => '+61888888888'} ) - Flapjack::Data::Entity.add({'id' => '5000', - 'name' => entity, - 'contacts' => ["0999"]}, - :redis => @notifier_redis ) + contact end -Given /^the user wants to receive Nexmo SMS notifications for entity '([\w\.\-]+)'$/ do |entity| - add_contact( 'id' => '0999', - 'first_name' => 'John', - 'last_name' => 'Smith', - 'email' => 'johns@example.dom', - 'media' => {'sms_nexmo' => '+61888888888'} ) - Flapjack::Data::Entity.add({'id' => '5000', - 'name' => entity, - 'contacts' => ["0999"]}, - :redis => @notifier_redis ) +def find_or_create_check(check_data) + check = Flapjack::Data::Check.intersect(:name => check_data[:name]).all.first + + if check.nil? + check = Flapjack::Data::Check.new(:name => check_data[:name], :enabled => true) + expect(check.save).to be true + + entity_name, check_name = check_data[:name].split(':', 2) + + tags = entity_name.split('.', 2).map(&:downcase) + + check_name.split(' ').map(&:downcase) + + tags = tags.collect do |tag_name| + Flapjack::Data::Tag.lock do + tag = Flapjack::Data::Tag.intersect(:name => tag_name).all.first + if tag.nil? + tag = Flapjack::Data::Tag.new(:name => tag_name) + expect(tag.save).to be true + end + tag + end + end + check.tags.add(*tags) unless tags.empty? + end + + check end -Given /^the user wants to receive SNS notifications for entity '([\w\.\-]+)'$/ do |entity| - add_contact( 'id' => '0999', - 'first_name' => 'John', - 'last_name' => 'Smith', - 'email' => 'johns@example.dom', - 'media' => {'sns' => 'arn:aws:sns:us-east-1:698519295917:My-Topic'} ) - Flapjack::Data::Entity.add({'id' => '5000', - 'name' => entity, - 'contacts' => ["0999"]}, - :redis => @notifier_redis ) +Given /^the following contacts exist:$/ do |contacts| + contacts.hashes.each do |contact_data| + contact = Flapjack::Data::Contact.find_by_id(contact_data['id']) + expect(contact).to be nil + contact = Flapjack::Data::Contact.new( + :id => contact_data['id'], + :name => contact_data['name'], + :timezone => contact_data['timezone'] + ) + expect(contact.save).to be true + end end -Given /^the user wants to receive email notifications for entity '([\w\.\-]+)'$/ do |entity| - add_contact( 'id' => '0999', - 'first_name' => 'John', - 'last_name' => 'Smith', - 'email' => 'johns@example.dom', - 'media' => {'email' => 'johns@example.dom'} ) - Flapjack::Data::Entity.add({'id' => '5000', - 'name' => entity, - 'contacts' => ["0999"]}, - :redis => @notifier_redis ) +Given /^the following checks exist:$/ do |checks| + checks.hashes.each do |check_data| + check = Flapjack::Data::Check.find_by_id(check_data['id']) + expect(check).to be nil + + check = Flapjack::Data::Check.new( + :id => check_data['id'], + :name => check_data['name'], + :enabled => true + ) + expect(check.save).to be true + + unless check_data['tags'].nil? || check_data['tags'].strip.empty? + tags = check_data['tags'].split(',').map(&:strip).collect do |tag_name| + Flapjack::Data::Tag.lock do + tag = Flapjack::Data::Tag.intersect(:name => tag_name).all.first + if tag.nil? + tag = Flapjack::Data::Tag.new(:name => tag_name) + tag.save + end + tag + end + end + check.tags.add(*tags) unless tags.empty? + end + end end -Given /^the user wants to receive SMS notifications for entity '([\w\.\-]+)' and email notifications for entity '([\w\.\-]+)'$/ do |entity1, entity2| - add_contact( 'id' => '0998', - 'first_name' => 'John', - 'last_name' => 'Smith', - 'email' => 'johns@example.dom', - 'media' => {'sms' => '+61888888888'} ) - add_contact( 'id' => '0999', - 'first_name' => 'John', - 'last_name' => 'Smith', - 'email' => 'johns@example.dom', - 'media' => {'email' => 'johns@example.dom'} ) - Flapjack::Data::Entity.add({'id' => '5000', - 'name' => entity1, - 'contacts' => ["0998"]}, - :redis => @notifier_redis ) - Flapjack::Data::Entity.add({'id' => '5001', - 'name' => entity2, - 'contacts' => ["0999"]}, - :redis => @notifier_redis ) +Given /^the following media exist:$/ do |media| + media.hashes.each do |medium_data| + contact = Flapjack::Data::Contact.find_by_id(medium_data['contact_id']) + expect(contact).not_to be nil + + medium = Flapjack::Data::Medium.find_by_id(medium_data['id']) + expect(medium).to be nil + medium = Flapjack::Data::Medium.new( + :id => medium_data['id'], + :transport => medium_data['transport'], + :address => medium_data['address'], + :interval => medium_data['interval'].to_i * 60, + :rollup_threshold => medium_data['rollup_threshold'].to_i + ) + expect(medium.save).to be true + contact.media << medium + end end -# TODO create the notification object in redis, flag the relevant operation as -# only needing that part running, split up the before block that covers these -When /^an event notification is generated for entity '([\w\.\-]+)'$/ do |entity| - event = Flapjack::Data::Event.new('type' => 'service', - 'state' => 'critical', - 'summary' => '100% packet loss', - 'entity' => entity, - 'check' => 'ping') +Given /^the following rules exist:$/ do |rules| + rules.hashes.each do |rule_data| + contact = Flapjack::Data::Contact.find_by_id(rule_data['contact_id']) + expect(contact).not_to be nil - notification_type = Flapjack::Data::Notification.type_for_event(event) + time_zone = contact.time_zone + expect(time_zone).to be_an ActiveSupport::TimeZone - entity_check = Flapjack::Data::EntityCheck.for_entity_name(entity, 'ping', :redis => @redis) - max_notified_severity = entity_check.max_notified_severity_of_current_failure + rule = Flapjack::Data::Rule.find_by_id(rule_data['id']) + expect(rule).to be nil - severity = Flapjack::Data::Notification.severity_for_event(event, max_notified_severity) - last_state = entity_check.historical_state_before(event.time) + conditions = rule_data['condition'].split(',').map(&:strip).join(',') - Flapjack::Data::Notification.add('notifications', event, - :type => notification_type, :severity => severity, :last_state => last_state, - :redis => @notifier_redis) - drain_notifications -end + rule = Flapjack::Data::Rule.new( + :id => rule_data['id'], + :name => rule_data['name'], + :enabled => true, + :blackhole => ['1', 't', 'true', 'y', 'yes'].include?((rule_data['blackhole'] || '').strip.downcase), + :strategy => rule_data['strategy'], + :conditions_list => conditions.empty? ? nil : conditions + ) -Then /^an SMS notification for entity '([\w\.\-]+)' should be queued for the user$/ do |entity| - queue = redis_peek('sms_notifications') - expect(queue.select {|n| n['event_id'] =~ /#{entity}:ping/ }).not_to be_empty -end + unless rule_data['time_restriction'].nil? + tr = rule_data['time_restriction'].strip + unless tr.empty? + rule.time_restriction = case tr + when '8-18 weekdays' + weekdays_8_18 = IceCube::Schedule.new(time_zone.local(2013,2,1,8,0,0), :duration => 60 * 60 * 10) + weekdays_8_18.add_recurrence_rule(IceCube::Rule.weekly.day(:monday, :tuesday, :wednesday, :thursday, :friday)) + weekdays_8_18 + end + end + end + expect(rule.save).to be true -Then /^a Nexmo SMS notification for entity '([\w\.\-]+)' should be queued for the user$/ do |entity| - queue = redis_peek('sms_nexmo_notifications') - expect(queue.select {|n| n['event_id'] =~ /#{entity}:ping/ }).not_to be_empty -end + contact.rules << rule -Then /^an SNS notification for entity '([\w\.\-]+)' should be queued for the user$/ do |entity| - queue = redis_peek('sns_notifications') - expect(queue.select {|n| n['event_id'] =~ /#{entity}:ping/ }).not_to be_empty -end + unless rule_data['tags'].nil? || rule_data['tags'].strip.empty? + tags = rule_data['tags'].split(',').map(&:strip).collect do |tag_name| + Flapjack::Data::Tag.lock do + tag = Flapjack::Data::Tag.intersect(:name => tag_name).all.first + if tag.nil? + tag = Flapjack::Data::Tag.new(:name => tag_name) + expect(tag.save).to be true + end + tag + end + end + rule.tags.add(*tags) # unless tags.empty? + end -Then /^an email notification for entity '([\w\.\-]+)' should be queued for the user$/ do |entity| - queue = redis_peek('email_notifications') - expect(queue.select {|n| n['event_id'] =~ /#{entity}:ping/ }).not_to be_empty + unless rule_data['media_ids'].nil? || rule_data['media_ids'].strip.empty? + media_ids = rule_data['media_ids'].split(',').map(&:strip) + media = Flapjack::Data::Medium.find_by_ids(*media_ids) + expect(media.map(&:id)).to match_array(media_ids) + rule.media.add(*media) # unless media.empty? + end + end end -Then /^an SMS notification for entity '([\w\.\-]+)' should not be queued for the user$/ do |entity| - queue = redis_peek('sms_notifications') - expect(queue.select {|n| n['event_id'] =~ /#{entity}:ping/ }).to be_empty -end +Given /^(?:a|the) user wants to receive SMS alerts for check '(.+)'$/ do |check_name| + contact = find_or_create_contact(:name => 'John Smith') -Then /^an Nexmo SMS notification for entity '([\w\.\-]+)' should not be queued for the user$/ do |entity| - queue = redis_peek('sms_nexmo_notifications') - expect(queue.select {|n| n['event_id'] =~ /#{entity}:ping/ }).to be_empty -end + sms = Flapjack::Data::Medium.new(:transport => 'sms', + :address => '+61888888888', :interval => 600) + expect(sms.save).to be true + contact.media << sms -Then /^an email notification for entity '([\w\.\-]+)' should not be queued for the user$/ do |entity| - queue = redis_peek('email_notifications') - expect(queue.select {|n| n['event_id'] =~ /#{entity}:ping/ }).to be_empty -end + check = find_or_create_check(:name => check_name) -Given /^a user SMS notification has been queued for entity '([\w\.\-]+)'$/ do |entity| - Flapjack::Data::Entity.add({'id' => '5000', - 'name' => entity}, - :redis => @redis ) - @sms_notification = {'notification_type' => 'problem', - 'contact_first_name' => 'John', - 'contact_last_name' => 'Smith', - 'state' => 'critical', - 'summary' => 'Socket timeout after 10 seconds', - 'time' => Time.now.to_i, - 'event_id' => "#{entity}:ping", - 'address' => '+61412345678', - 'id' => 1, - 'state_duration' => 30, - 'duration' => 45} + acceptor = Flapjack::Data::Rule.new(:enabled => true, :blackhole => false, + :conditions_list => 'critical', :strategy => 'all_tags') + expect(acceptor.save).to be true - Flapjack::Data::Alert.add('sms_notifications', @sms_notification, - :redis => @notifier_redis) -end + contact.rules << acceptor -Given /^a user Nexmo SMS notification has been queued for entity '([\w\.\-]+)'$/ do |entity| - Flapjack::Data::Entity.add({'id' => '5000', - 'name' => entity}, - :redis => @redis ) - @sms_nexmo_notification = {'notification_type' => 'problem', - 'contact_first_name' => 'John', - 'contact_last_name' => 'Smith', - 'state' => 'critical', - 'summary' => 'Socket timeout after 10 seconds', - 'time' => Time.now.to_i, - 'event_id' => "#{entity}:ping", - 'address' => '+61412345678', - 'id' => 1, - 'state_duration' => 30, - 'duration' => 45} + Flapjack::Data::Tag.lock(Flapjack::Data::Check, Flapjack::Data::Rule) do - Flapjack::Data::Alert.add('sms_nexmo_notifications', @sms_nexmo_notification, - :redis => @notifier_redis) + tags = check_name.gsub(/\./, '_').split(':', 2).collect do |tag_name| + Flapjack::Data::Tag.lock do + tag = Flapjack::Data::Tag.intersect(:name => tag_name).all.first + if tag.nil? + tag = Flapjack::Data::Tag.new(:name => tag_name) + expect(tag.save).to be true + end + tag + end + end + acceptor.tags.add(*tags) unless tags.empty? + check.tags.add(*tags) unless tags.empty? + end + + acceptor.media << sms end -Given /^a user SNS notification has been queued for entity '([\w\.\-]+)'$/ do |entity| - Flapjack::Data::Entity.add({'id' => '5000', - 'name' => entity}, - :redis => @redis ) - @sns_notification = {'notification_type' => 'problem', - 'contact_first_name' => 'John', - 'contact_last_name' => 'Smith', - 'state' => 'critical', - 'summary' => 'Socket timeout after 10 seconds', - 'time' => Time.now.to_i, - 'event_id' => "#{entity}:ping", - 'address' => 'arn:aws:sns:us-east-1:698519295917:My-Topic', - 'id' => 1, - 'state_duration' => 30, - 'duration' => 45} +Given /^(?:a|the) user wants to receive Nexmo alerts for check '(.+)'$/ do |check_name| + contact = find_or_create_contact(:name => 'John Smith') - Flapjack::Data::Alert.add('sns_notifications', @sns_notification, - :redis => @notifier_redis) -end + nexmo = Flapjack::Data::Medium.new(:transport => 'sms_nexmo', + :address => '+61888888888', :interval => 600) + expect(nexmo.save).to be true + contact.media << nexmo -Given /^a user email notification has been queued for entity '([\w\.\-]+)'$/ do |entity| - Flapjack::Data::Entity.add({'id' => '5001', - 'name' => entity}, - :redis => @redis ) - @email_notification = {'notification_type' => 'problem', - 'contact_first_name' => 'John', - 'contact_last_name' => 'Smith', - 'state' => 'critical', - 'summary' => 'Socket timeout after 10 seconds', - 'time' => Time.now.to_i, - 'event_id' => "#{entity}:ping", - 'address' => 'johns@example.dom', - 'id' => 2, - 'state_duration' => 30, - 'duration' => 3600} + check = find_or_create_check(:name => check_name) - Flapjack::Data::Alert.add('email_notifications', @email_notification, - :redis => @notifier_redis) + acceptor = Flapjack::Data::Rule.new(:enabled => true, :blackhole => false, + :conditions_list => 'critical', :strategy => 'all_tags') + expect(acceptor.save).to be true + + contact.rules << acceptor + + Flapjack::Data::Tag.lock(Flapjack::Data::Check, Flapjack::Data::Rule) do + tags = check_name.gsub(/\./, '_').split(':', 2).collect do |tag_name| + tag = Flapjack::Data::Tag.intersect(:name => tag_name).all.first + if tag.nil? + tag = Flapjack::Data::Tag.new(:name => tag_name) + expect(tag.save).to be true + end + tag + end + acceptor.tags.add(*tags) + check.tags.add(*tags) + end + + acceptor.media << nexmo end -When /^the SMS notification handler runs successfully$/ do - @request = stub_request(:get, /^#{Regexp.escape(Flapjack::Gateways::SmsMessagenet::MESSAGENET_DEFAULT_URL)}/) +Given /^(?:a|the) user wants to receive email alerts for check '(.+)'$/ do |check_name| + contact = find_or_create_contact(:name => 'Jane Smith') - @sms_messagenet = Flapjack::Gateways::SmsMessagenet.new(:config => { - 'username' => 'abcd', 'password' => 'efgh' - }, :redis_config => @redis_opts, :logger => @logger) + email = Flapjack::Data::Medium.new(:transport => 'email', + :address => 'janes@example.dom', :interval => 600) + expect(email.save).to be true + contact.media << email - drain_alerts('sms_notifications', @sms_messagenet) + check = find_or_create_check(:name => check_name) + + acceptor = Flapjack::Data::Rule.new(:enabled => true, :blackhole => false, + :conditions_list => 'critical', :strategy => 'all_tags') + expect(acceptor.save).to be true + + contact.rules << acceptor + + Flapjack::Data::Tag.lock(Flapjack::Data::Check, Flapjack::Data::Rule) do + tags = check_name.gsub(/\./, '_').split(':', 2).collect do |tag_name| + Flapjack::Data::Tag.lock do + tag = Flapjack::Data::Tag.intersect(:name => tag_name).all.first + if tag.nil? + tag = Flapjack::Data::Tag.new(:name => tag_name) + expect(tag.save).to be true + end + tag + end + end + acceptor.tags.add(*tags) unless tags.empty? + check.tags.add(*tags) unless tags.empty? + end + + acceptor.media << email end -When /^the Nexmo SMS notification handler runs successfully$/ do - # poor man's stubbing - Nexmo::Client.class_eval { - def send_message(args = {}) +Given /^(?:a|the) user wants to receive SNS alerts for check '(.+)'$/ do |check_name| + contact = find_or_create_contact(:name => 'James Smithson') + + sns = Flapjack::Data::Medium.new(:transport => 'sns', + :address => 'arn:aws:sns:us-east-1:698519295917:My-Topic', :interval => 600) + expect(sns.save).to be true + contact.media << sns + + check = find_or_create_check(:name => check_name) + + acceptor = Flapjack::Data::Rule.new(:enabled => true, :blackhole => false, + :conditions_list => 'critical', :strategy => 'all_tags') + expect(acceptor.save).to be true + + contact.rules << acceptor + + Flapjack::Data::Tag.lock(Flapjack::Data::Check, Flapjack::Data::Rule) do + tags = check_name.gsub(/\./, '_').split(':', 2).collect do |tag_name| + Flapjack::Data::Tag.lock do + tag = Flapjack::Data::Tag.intersect(:name => tag_name).all.first + if tag.nil? + tag = Flapjack::Data::Tag.new(:name => tag_name) + expect(tag.save).to be true + end + tag + end end - } - @sms_nexmo = Flapjack::Gateways::SmsNexmo.new(:config => { - 'api_key' => 'THEAPIKEY', 'secret' => 'secret', 'from' => 'someone', - }, :redis_config => @redis_opts, :logger => @logger) + acceptor.tags.add(*tags) unless tags.empty? + check.tags.add(*tags) unless tags.empty? + end - drain_alerts('sms_nexmo_notifications', @sms_nexmo) + acceptor.media << sns end -When /^the SNS notification handler runs successfully$/ do - @request = stub_request(:post, /amazonaws\.com/) +When /^an event notification is generated for check '(.+)'$/ do |check_name| + timestamp = Time.now - @aws_sns = Flapjack::Gateways::AwsSns.new(:config => { - 'access_key' => "AKIAIOSFODNN7EXAMPLE", - 'secret_key' => "secret" - }, :redis_config => @redis_opts, :logger => @logger) + event = Flapjack::Data::Event.new('state' => 'critical', + 'summary' => '100% packet loss', + 'entity' => check_name.split(':', 2).first, + 'check' => check_name.split(':', 2).last, + 'time' => timestamp) - drain_alerts('sns_notifications', @aws_sns) + Flapjack::Data::Check.lock(Flapjack::Data::State, Flapjack::Data::Notification) do + + check = Flapjack::Data::Check.intersect(:name => check_name).all.first + expect(check).not_to be_nil + + state = Flapjack::Data::State.new(:created_at => timestamp, :updated_at => timestamp, + :condition => 'critical') + state.save + check.states << state + check.most_severe = state + + notification = Flapjack::Data::Notification.new( + :condition_duration => 0.0, + :severity => 'critical', + :duration => event.duration, + ) + + unless notification.save + raise "Couldn't save notification: #{notification.errors.full_messages.inspect}" + end + + notification.state = state + check.notifications << notification + @notifier.instance_variable_get('@queue').push(notification) + end + + drain_notifications end -When /^the SMS notification handler fails to send an SMS$/ do - @request = stub_request(:get, /^#{Regexp.escape(Flapjack::Gateways::SmsMessagenet::MESSAGENET_DEFAULT_URL)}/).to_return(:status => [500, "Internal Server Error"]) +Then /^an? (SMS|Nexmo|SNS|email) alert for check '(.+)' should( not)? be queued$/ do |medium, check_name, neg| + med = case medium + when 'Nexmo' + 'sms_nexmo' + else + medium.downcase + end + queue = redis_peek("#{med}_notifications", Flapjack::Data::Alert) + expect(queue.select {|n| n.check.name == check_name }). + send((neg ? :to : :not_to), be_empty) +end - @sms_messagenet = Flapjack::Gateways::SmsMessagenet.new(:config => { - 'username' => 'abcd', 'password' => 'efgh' - }, :redis_config => @redis_opts, :logger => @logger) +Given /^an? (SMS|Nexmo|SNS|email) alert has been queued for check '(.+)'$/ do |media_transport, check_name| + check = Flapjack::Data::Check.intersect(:name => check_name).all.first + expect(check).not_to be_nil - drain_alerts('sms_notifications', @sms_messagenet) + @alert = Flapjack::Data::Alert.new( + :condition => 'critical', + :condition_duration => 15.0, + :time => Time.now) + + unless @alert.save + raise "Couldn't save alert: #{@alert.errors.full_messages.inspect}" + end + + med = case media_transport + when 'Nexmo' + 'sms_nexmo' + else + media_transport.downcase + end + + medium = Flapjack::Data::Medium.intersect(:transport => med).all.first + expect(medium).not_to be_nil + + medium.alerts << @alert + check.alerts << @alert end -When /^the SNS notification handler fails to send an SMS$/ do - @request = stub_request(:post, /amazonaws\.com/).to_return(:status => [500, "Internal Server Error"]) +# TODO may need to get more complex, depending which SMS provider is used +When /^the SMS alert handler runs successfully$/ do + @request = stub_request(:get, /^#{Regexp.escape('https://www.messagenet.com.au/dotnet/Lodge.asmx/LodgeSMSMessage')}/) + @sms = Flapjack::Gateways::SmsMessagenet.new(:config => {'username' => 'abcd', 'password' => 'efgh'}) + @sms.send(:handle_alert, @alert) +end - @aws_sns = Flapjack::Gateways::AwsSns.new(:config => { - 'access_key' => "AKIAIOSFODNN7EXAMPLE", - 'secret_key' => "secret" - }, :redis_config => @redis_opts, :logger => @logger) +When /^the SMS alert handler fails to send an SMS$/ do + @request = stub_request(:get, /^#{Regexp.escape('https://www.messagenet.com.au/dotnet/Lodge.asmx/LodgeSMSMessage')}/).to_return(:status => [500, "Internal Server Error"]) + @sms = Flapjack::Gateways::SmsMessagenet.new(:config => {'username' => 'abcd', 'password' => 'efgh'}) + @sms.send(:handle_alert, @alert) +end - drain_alerts('sns_notifications', @aws_sns) +When /^the Nexmo alert handler runs successfully$/ do + @request = stub_request(:post, /^#{Regexp.escape('https://rest.nexmo.com/sms/json')}/). + to_return(:headers => {'Content-type' => 'application/json'}, + :body => Flapjack.dump_json(:messages => [{:status => '0', :'message-id' => 'abc'}])) + @sms_nexmo = Flapjack::Gateways::SmsNexmo.new(:config => {'api_key' => 'THEAPIKEY', 'secret' => 'secret', 'from' => 'someone'}) + @sms_nexmo.send(:handle_alert, @alert) end -When /^the email notification handler runs successfully$/ do - # poor man's stubbing - EM::P::SmtpClient.class_eval { - def self.send(args = {}) - me = MockEmailer.new - me.set_deferred_status :succeeded, OpenStruct.new(:code => 250) - me +When /^the email alert handler runs successfully$/ do + @email = Flapjack::Gateways::Email.new(:config => {'smtp_config' => {'host' => '127.0.0.1', 'port' => 2525, 'from' => 'flapjack@example.com'}}) + @email.send(:handle_alert, @alert) +end + +When /^the email alert handler fails to send an email$/ do + module Mail + class TestMailer + alias_method :"orig_deliver!", :"deliver!" + def deliver!(mail); raise RuntimeError.new; end end - } + end - @email = Flapjack::Gateways::Email.new(:config => { - 'smtp_config' => {'host' => '127.0.0.1', - 'port' => 2525, - 'from' => 'flapjack@example'} - }, :redis_config => @redis_opts, :logger => @logger) + @email = Flapjack::Gateways::Email.new(:config => {'smtp_config' => {'host' => '127.0.0.1', 'port' => 2525, 'from' => 'flapjack@example.com'}}) + begin + @email.send(:handle_alert, @alert) + rescue RuntimeError + end - drain_alerts('email_notifications', @email) + module Mail + class TestMailer + alias_method :"deliver!", :"orig_deliver!" + end + end end -When /^the email notification handler fails to send an email$/ do - # poor man's stubbing - EM::P::SmtpClient.class_eval { - def self.send(args = {}) - me = MockEmailer.new - me.set_deferred_status :failed, OpenStruct.new(:code => 500) - me - end - } +When /^the SNS alert handler runs successfully$/ do + @request = stub_request(:post, /amazonaws\.com/) + @sns = Flapjack::Gateways::AwsSns.new(:config => { + 'access_key' => "AKIAIOSFODNN7EXAMPLE", + 'secret_key' => "secret"}) + @sns.send(:handle_alert, @alert) +end - @email = Flapjack::Gateways::Email.new(:config => { - 'smtp_config' => {'host' => '127.0.0.1', - 'port' => 2525, - 'from' => 'flapjack@example'} - }, :redis_config => @redis_opts, :logger => @logger) +When /^the SNS alert handler fails to send an SMS$/ do + @request = stub_request(:post, /amazonaws\.com/).to_return(:status => [500, "Internal Server Error"]) + @sns = Flapjack::Gateways::AwsSns.new(:config => { + 'access_key' => "AKIAIOSFODNN7EXAMPLE", + 'secret_key' => "secret"}) + @sns.send(:handle_alert, @alert) +end - drain_alerts('email_notifications', @email) +Then /^the user should receive an SMS alert$/ do + expect(@request).to have_been_requested + expect(@sms.sent).to eq(1) end -Then /^the user should( not)? receive an SMS notification$/ do |negativity| +Then /^the user should receive an SNS alert$/ do expect(@request).to have_been_requested - expect(@sms_messagenet.instance_variable_get('@sent')).to eq(negativity.nil? ? 1 : 0) + expect(@sns.sent).to eq(1) end -Then /^the user should( not)? receive an Nexmo SMS notification$/ do |negativity| - expect(@sms_nexmo.instance_variable_get('@sent')).to eq(negativity.nil? ? 1 : 0) +Then /^the user should receive a Nexmo alert$/ do + expect(@request).to have_been_requested + expect(@sms_nexmo.sent).to eq(1) end -Then /^the user should( not)? receive an SNS notification$/ do |negativity| +Then /^the user should receive an email alert$/ do + expect(Mail::TestMailer.deliveries.length).to eq(1) + expect(@email.sent).to eq(1) +end + +Then /^the user should not receive an SMS alert$/ do expect(@request).to have_been_requested - expect(@aws_sns.instance_variable_get('@sent')).to eq(negativity.nil? ? 1 : 0) + expect(@sms.sent).to eq(0) end -Then /^the user should( not)? receive an email notification$/ do |negativity| - expect(@email.instance_variable_get('@sent')).to eq(negativity.nil? ? 1 : 0) +Then /^the user should not receive an SNS alert$/ do + expect(@request).to have_been_requested + expect(@sns.sent).to eq(0) end +Then /^the user should not receive an email alert$/ do + expect(Mail::TestMailer.deliveries).to be_empty + expect(@email.sent).to eq(0) +end