adding an event_email_agent which immediately sends emails instead of queueing them

Albert Sun 11 years ago
parent
commit
fa1fd0b04d
2 changed files with 116 additions and 0 deletions
  1. 57 0
      app/models/agents/event_email_agent.rb
  2. 59 0
      spec/models/agents/event_email_agent_spec.rb

+ 57 - 0
app/models/agents/event_email_agent.rb

@@ -0,0 +1,57 @@
1
+module Agents
2
+  class EventEmailAgent < Agent
3
+    MAIN_KEYS = %w[title message text main value].map(&:to_sym)
4
+
5
+    cannot_be_scheduled!
6
+    cannot_create_events!
7
+
8
+    description <<-MD
9
+      The EventEmailAgent sends any events it receives via email.
10
+      The email will be sent to your account's address and will have a `subject` and an optional `headline` before
11
+      listing the Events.  If the Events' payloads contain a `:message`, that will be highlighted, otherwise everything in
12
+      their payloads will be shown.
13
+
14
+      Set `expected_receive_period_in_days` to the maximum amount of time that you'd expect to pass between Events being received by this Agent.
15
+    MD
16
+
17
+    def default_options
18
+      {
19
+          :subject => "You have a notification!",
20
+          :headline => "Your notification:",
21
+          :expected_receive_period_in_days => "2"
22
+      }
23
+    end
24
+
25
+    def working?
26
+      last_receive_at && last_receive_at > options[:expected_receive_period_in_days].to_i.days.ago && !recent_error_logs?
27
+    end
28
+
29
+    def validate_options
30
+      errors.add(:base, "subject and expected_receive_period_in_days are required") unless options[:subject].present? && options[:expected_receive_period_in_days].present?
31
+    end
32
+
33
+    def receive(incoming_events)
34
+      incoming_events.each do |event|
35
+        log "Sending digest mail to #{user.email} with event #{event.id}"
36
+        SystemMailer.delay.send_message(:to => user.email, :subject => options[:subject], :headline => options[:headline], :groups => [present(event.payload)])
37
+      end
38
+    end
39
+
40
+    def present(payload)
41
+      if payload.is_a?(Hash)
42
+        payload = ActiveSupport::HashWithIndifferentAccess.new(payload)
43
+        MAIN_KEYS.each do |key|
44
+          return { :title => payload[key].to_s, :entries => present_hash(payload, key) } if payload.has_key?(key)
45
+        end
46
+
47
+        { :title => "Event", :entries => present_hash(payload) }
48
+      else
49
+        { :title => payload.to_s, :entries => [] }
50
+      end
51
+    end
52
+
53
+    def present_hash(hash, skip_key = nil)
54
+      hash.to_a.sort_by {|a| a.first.to_s }.map { |k, v| "#{k}: #{v}" unless k.to_s == skip_key.to_s }.compact
55
+    end
56
+  end
57
+end

+ 59 - 0
spec/models/agents/event_email_agent_spec.rb

@@ -0,0 +1,59 @@
1
+require 'spec_helper'
2
+
3
+describe Agents::EventEmailAgent do
4
+  def get_message_part(mail, content_type)
5
+    mail.body.parts.find { |p| p.content_type.match content_type }.body.raw_source
6
+  end
7
+
8
+  before do
9
+    @checker = Agents::EventEmailAgent.new(:name => "something", :options => { :expected_receive_period_in_days => 2, :subject => "something interesting" })
10
+    @checker.user = users(:bob)
11
+    @checker.save!
12
+  end
13
+
14
+  after do
15
+    ActionMailer::Base.deliveries = []
16
+  end
17
+
18
+  describe "#receive" do
19
+    it "immediately sends any payloads it receives" do
20
+      ActionMailer::Base.deliveries.should == []
21
+
22
+      event1 = Event.new
23
+      event1.agent = agents(:bob_rain_notifier_agent)
24
+      event1.payload = "Something you should know about"
25
+      event1.save!
26
+
27
+      event2 = Event.new
28
+      event2.agent = agents(:bob_weather_agent)
29
+      event2.payload = "Something else you should know about"
30
+      event2.save!
31
+
32
+      Agents::EventEmailAgent.async_receive(@checker.id, [event1.id])
33
+      Agents::EventEmailAgent.async_receive(@checker.id, [event2.id])
34
+
35
+      ActionMailer::Base.deliveries.count.should == 2
36
+      ActionMailer::Base.deliveries.last.to.should == ["bob@example.com"]
37
+      ActionMailer::Base.deliveries.last.subject.should == "something interesting"
38
+      get_message_part(ActionMailer::Base.deliveries.last, /plain/).strip.should == "Something else you should know about"
39
+      get_message_part(ActionMailer::Base.deliveries.first, /plain/).strip.should == "Something you should know about"
40
+    end
41
+
42
+    it "can receive complex events and send them on" do
43
+      stub_request(:any, /wunderground/).to_return(:body => File.read(Rails.root.join("spec/data_fixtures/weather.json")), :status => 200)
44
+      stub.any_instance_of(Agents::WeatherAgent).is_tomorrow?(anything) { true }
45
+      @checker.sources << agents(:bob_weather_agent)
46
+
47
+      Agent.async_check(agents(:bob_weather_agent).id)
48
+
49
+      Agent.receive!
50
+
51
+      plain_email_text = get_message_part(ActionMailer::Base.deliveries.last, /plain/).strip
52
+      html_email_text = get_message_part(ActionMailer::Base.deliveries.last, /html/).strip
53
+
54
+      plain_email_text.should =~ /avehumidity/
55
+      html_email_text.should =~ /avehumidity/
56
+    end
57
+
58
+  end
59
+end