chatterbox 0.6.2 → 0.8.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.markdown +17 -1
- data/README.markdown +68 -22
- data/Rakefile +10 -1
- data/VERSION.yml +2 -2
- data/chatterbox.gemspec +11 -3
- data/examples/example_helper.rb +1 -1
- data/examples/lib/chatterbox/exception_notification/extracter_example.rb +10 -5
- data/examples/lib/chatterbox/exception_notification/presenter_example.rb +59 -37
- data/examples/lib/chatterbox/rails_catcher_controller_example.rb +2 -2
- data/examples/lib/chatterbox/services/campfire_example.rb +0 -0
- data/examples/lib/chatterbox/services/email/mailer_example.rb +10 -4
- data/examples/lib/chatterbox/services/email_example.rb +26 -22
- data/examples/lib/chatterbox_example.rb +31 -7
- data/features/api.feature +20 -0
- data/features/email_service.feature +46 -0
- data/features/services.feature +30 -0
- data/features/step_definitions/email_service_steps.rb +31 -0
- data/features/support/env.rb +71 -0
- data/lib/chatterbox.rb +13 -3
- data/lib/chatterbox/exception_notification/extracter.rb +2 -2
- data/lib/chatterbox/exception_notification/presenter.rb +36 -36
- data/lib/chatterbox/rails_catcher.rb +0 -1
- data/lib/chatterbox/services/campfire.rb +8 -0
- data/lib/chatterbox/services/email.rb +11 -11
- data/lib/chatterbox/services/email/mailer.rb +3 -3
- metadata +11 -3
- data/.treasure_map.rb +0 -22
data/CHANGELOG.markdown
CHANGED
@@ -1,4 +1,20 @@
|
|
1
|
-
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
### 0.8.1
|
4
|
+
- Make sure Arrays format nicely for ExceptionNotification, so backtraces are easy to read
|
5
|
+
|
6
|
+
### 0.8.0
|
7
|
+
- Simplify API - prefer :summary and :body at top level, instead of inside a nested :message hash
|
8
|
+
- Simplify output for exception notification; using pretty print so hashes render well, even if they are nested
|
9
|
+
- Deprecate `Chatterbox#handle_notice` -- use `#notify` instead; will be removed for 1.0
|
10
|
+
- Any user provided data sent to ExceptionNotification will be rendered first in the body, as we assume its the application specific data and most useful; details like the environment vars and Ruby/Rails details will follow beneath
|
11
|
+
|
12
|
+
### 0.7.0
|
13
|
+
- Add ability to configure `summary_prefix` for emails, for common case of "[my-app] " prefix line in the subject line for emails
|
14
|
+
|
15
|
+
### 0.6.2
|
16
|
+
- Change to ExceptionNotification: render any other data in the hash that is not
|
17
|
+
enumerated in 'ordered sections'
|
2
18
|
|
3
19
|
### 0.6.1
|
4
20
|
- Handle case where there is no Rails Root defined
|
data/README.markdown
CHANGED
@@ -1,25 +1,81 @@
|
|
1
1
|
Chatterbox
|
2
2
|
==========================================
|
3
3
|
|
4
|
-
|
4
|
+
Chatterbox is a library to send notifications and messages over whatever service you like, whether it be email, Twitter, Campfire, IRC, or some combination therein. The goal of Chatterbox is to be able to send a message from your application via whatever service the user prefers simple by tweaking the configuration hash that gets sent to Chatterbox.
|
5
|
+
|
6
|
+
Publishing and subscribing to notifications can be decoupled easily, so bring your own message queue, web service, database, or whatever to act as an intermediary. Or keep it simple and wire Chatterbox directly - its your choice.
|
5
7
|
|
6
8
|
## Installing and Running
|
7
9
|
|
8
10
|
For plain old gem install:
|
9
11
|
|
10
|
-
gem install chatterbox
|
12
|
+
gem install chatterbox
|
11
13
|
|
12
14
|
To install within a Rails app, add the following to your environment.rb file:
|
13
15
|
|
14
|
-
config.gem "chatterbox"
|
16
|
+
config.gem "chatterbox"
|
15
17
|
|
16
18
|
Then run:
|
17
19
|
|
18
20
|
rake gems:install
|
19
21
|
|
22
|
+
## Services
|
23
|
+
|
24
|
+
Services are used to send notifications in Chatterbox. Chatterbox comes with an email service for use out of the box, which uses ActionMailer and works pretty much how you would expect.
|
25
|
+
|
26
|
+
## Email Service Configuration
|
27
|
+
|
28
|
+
Register the email service to handle messages that get sent to Chatterbox:
|
29
|
+
|
30
|
+
Chatterbox::Publishers.register do |notice|
|
31
|
+
Chatterbox::Services::Email.deliver(notice)
|
32
|
+
end
|
33
|
+
|
34
|
+
Then, wherever you want to send email, do this:
|
35
|
+
|
36
|
+
options = {
|
37
|
+
:summary => "your subject line here", :body => "Email body here",
|
38
|
+
:config => { :to => "joe@example.com", :from => "donotreply@example.com" },
|
39
|
+
}
|
40
|
+
Chatterbox.notify(options)
|
41
|
+
|
42
|
+
You can configure defaults for the email service:
|
43
|
+
|
44
|
+
Chatterbox::Services::Email.configure({
|
45
|
+
:to => "joe@example.com",
|
46
|
+
:from => "jane@example.com",
|
47
|
+
:summary_prefix => "[my-prefix] "
|
48
|
+
})
|
49
|
+
|
50
|
+
Then when you deliver messages, the provided options will be merged with the defaults:
|
51
|
+
|
52
|
+
Chatterbox.notify(:message => { :summary => "my subject" })
|
53
|
+
|
54
|
+
Sends:
|
55
|
+
|
56
|
+
To: joe@example.com
|
57
|
+
From: jane@example.com
|
58
|
+
Subject: [my-prefix] my subject
|
59
|
+
|
60
|
+
While the following overrides the default to and from addresses...
|
61
|
+
|
62
|
+
options = {
|
63
|
+
:summary => "my subject",
|
64
|
+
:config => { :to => "distro@example.com", :from => "reply@example.com" },
|
65
|
+
}
|
66
|
+
Chatterbox.notify(options)
|
67
|
+
|
68
|
+
Sends:
|
69
|
+
|
70
|
+
To: distro@example.com
|
71
|
+
From: reply@example.com
|
72
|
+
Subject: [my-prefix] my subject
|
73
|
+
|
20
74
|
## Exception Notification
|
21
75
|
|
22
|
-
One of the most handy use cases Chatterbox was developed for
|
76
|
+
One of the most handy use cases Chatterbox was developed for is exception notification. Chatterbox can be configured for Rails exception catching from controllers, and can be used in a plain Ruby app as well.
|
77
|
+
|
78
|
+
To setup Chatterbox for Rails exception notification, install it as a gem with the instructions above, then configure it inside an initializer:
|
23
79
|
|
24
80
|
Chatterbox::Services::Email.configure :to => "errors@example.com", :from => "donotreply@example.com"
|
25
81
|
|
@@ -35,33 +91,23 @@ then wire the `RailsCatcher` in your `ApplicationController`:
|
|
35
91
|
|
36
92
|
And you are done! Exceptions thrown in controllers will automatically be processed and sent by Chatterbox, and then raised to be handled (or not handled) as normally.
|
37
93
|
|
38
|
-
## Example: Sending Emails
|
39
|
-
---------------------------------------
|
40
|
-
|
41
|
-
Register the email service to handle messages that get sent to Chatterbox:
|
42
|
-
|
43
|
-
Chatterbox::Publishers.register do |notice|
|
44
|
-
Chatterbox::Services::Email.deliver(notice)
|
45
|
-
end
|
46
|
-
|
47
|
-
Then, wherever you want to send email, do this:
|
48
|
-
|
49
|
-
message = {
|
50
|
-
:config => { :to => "joe@example.com", :from => "donotreply@example.com" },
|
51
|
-
:message => { :summary => "your subject line here", :body => "Email body here" }
|
52
|
-
}
|
53
|
-
Chatterbox.handle_notice(options)
|
54
94
|
|
55
95
|
Bugs & Patches
|
56
96
|
--------------
|
97
|
+
Please submit to [Github Issues](http://github.com/rsanheim/chatterbox/TODO).
|
98
|
+
|
99
|
+
All patches must have spec coverage and a passing build, or they will be pushed back.
|
100
|
+
|
101
|
+
You can easily verify your build by pushing the project to [RunCodeRun](http://runcoderun.com). View the [master build](http://runcoderun.com/rsanheim/chatterbox) to confirm that HEAD is stable and passing.
|
57
102
|
|
58
103
|
Links
|
59
104
|
-------------
|
60
105
|
|
61
106
|
Contributors
|
62
107
|
------------
|
63
|
-
* Rob Sanheim
|
108
|
+
* Rob Sanheim (creator)
|
109
|
+
* Chad Humphries (API ideas)
|
64
110
|
|
65
111
|
Copyrights
|
66
112
|
------------
|
67
|
-
|
113
|
+
Copyright © 2008-2009 Rob Sanheim under the MIT license
|
data/Rakefile
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'rake'
|
2
|
+
require 'cucumber/rake/task'
|
2
3
|
|
3
4
|
begin
|
4
5
|
require 'jeweler'
|
@@ -31,7 +32,15 @@ Micronaut::RakeTask.new(:rcov) do |examples|
|
|
31
32
|
examples.rcov = true
|
32
33
|
end
|
33
34
|
|
34
|
-
|
35
|
+
Cucumber::Rake::Task.new :features do |t|
|
36
|
+
t.cucumber_opts = %w{--format progress}
|
37
|
+
end
|
38
|
+
|
39
|
+
if RUBY_VERSION == '1.9.1'
|
40
|
+
task :default => [:examples, :features]
|
41
|
+
else
|
42
|
+
task :default => [:rcov, :features]
|
43
|
+
end
|
35
44
|
|
36
45
|
begin
|
37
46
|
%w{sdoc sdoc-helpers rdiscount}.each { |name| gem name }
|
data/VERSION.yml
CHANGED
data/chatterbox.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{chatterbox}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.8.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Rob Sanheim"]
|
12
|
-
s.date = %q{2009-11-
|
12
|
+
s.date = %q{2009-11-26}
|
13
13
|
s.description = %q{Send notifications and messages. However you want.}
|
14
14
|
s.email = %q{rsanheim@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -18,7 +18,6 @@ Gem::Specification.new do |s|
|
|
18
18
|
]
|
19
19
|
s.files = [
|
20
20
|
".gitignore",
|
21
|
-
".treasure_map.rb",
|
22
21
|
"CHANGELOG.markdown",
|
23
22
|
"LICENSE",
|
24
23
|
"README.markdown",
|
@@ -32,10 +31,16 @@ Gem::Specification.new do |s|
|
|
32
31
|
"examples/lib/chatterbox/exception_notification_example.rb",
|
33
32
|
"examples/lib/chatterbox/rails_catcher_controller_example.rb",
|
34
33
|
"examples/lib/chatterbox/rails_catcher_example.rb",
|
34
|
+
"examples/lib/chatterbox/services/campfire_example.rb",
|
35
35
|
"examples/lib/chatterbox/services/email/mailer_example.rb",
|
36
36
|
"examples/lib/chatterbox/services/email_example.rb",
|
37
37
|
"examples/lib/chatterbox/services_example.rb",
|
38
38
|
"examples/lib/chatterbox_example.rb",
|
39
|
+
"features/api.feature",
|
40
|
+
"features/email_service.feature",
|
41
|
+
"features/services.feature",
|
42
|
+
"features/step_definitions/email_service_steps.rb",
|
43
|
+
"features/support/env.rb",
|
39
44
|
"init.rb",
|
40
45
|
"lib/chatterbox.rb",
|
41
46
|
"lib/chatterbox/exception_notification.rb",
|
@@ -44,10 +49,12 @@ Gem::Specification.new do |s|
|
|
44
49
|
"lib/chatterbox/exception_notification/rails_extracter.rb",
|
45
50
|
"lib/chatterbox/rails_catcher.rb",
|
46
51
|
"lib/chatterbox/services.rb",
|
52
|
+
"lib/chatterbox/services/campfire.rb",
|
47
53
|
"lib/chatterbox/services/email.rb",
|
48
54
|
"lib/chatterbox/services/email/mailer.rb",
|
49
55
|
"lib/chatterbox/services/email/views/chatterbox/services/email/mailer/message.erb",
|
50
56
|
"rails/init.rb",
|
57
|
+
"tmp/.gitignore",
|
51
58
|
"todo.markdown",
|
52
59
|
"views/chatterbox/mailer/exception_notification.erb"
|
53
60
|
]
|
@@ -64,6 +71,7 @@ Gem::Specification.new do |s|
|
|
64
71
|
"examples/lib/chatterbox/exception_notification_example.rb",
|
65
72
|
"examples/lib/chatterbox/rails_catcher_controller_example.rb",
|
66
73
|
"examples/lib/chatterbox/rails_catcher_example.rb",
|
74
|
+
"examples/lib/chatterbox/services/campfire_example.rb",
|
67
75
|
"examples/lib/chatterbox/services/email/mailer_example.rb",
|
68
76
|
"examples/lib/chatterbox/services/email_example.rb",
|
69
77
|
"examples/lib/chatterbox/services_example.rb",
|
data/examples/example_helper.rb
CHANGED
@@ -4,11 +4,9 @@ require 'chatterbox/exception_notification'
|
|
4
4
|
describe Chatterbox::ExceptionNotification::Extracter do
|
5
5
|
|
6
6
|
describe "notice" do
|
7
|
-
it "merges
|
8
|
-
|
9
|
-
data
|
10
|
-
data[:ruby_info][:ruby_version].should == RUBY_VERSION
|
11
|
-
data[:ruby_info][:ruby_platform].should == RUBY_PLATFORM
|
7
|
+
it "merges default summary if none provided" do
|
8
|
+
data = Chatterbox::ExceptionNotification::Extracter.new({}).notice
|
9
|
+
data[:summary].should == "N/A"
|
12
10
|
end
|
13
11
|
|
14
12
|
it "merges environment hash" do
|
@@ -17,6 +15,13 @@ describe Chatterbox::ExceptionNotification::Extracter do
|
|
17
15
|
data[:environment].should == ENV.to_hash
|
18
16
|
end
|
19
17
|
|
18
|
+
it "merges ruby info" do
|
19
|
+
hsh = {}
|
20
|
+
data = Chatterbox::ExceptionNotification::Extracter.new(hsh).notice
|
21
|
+
data[:ruby_info][:ruby_version].should == RUBY_VERSION
|
22
|
+
data[:ruby_info][:ruby_platform].should == RUBY_PLATFORM
|
23
|
+
end
|
24
|
+
|
20
25
|
it "should extract exception info from an exception in a hash" do
|
21
26
|
exception = RuntimeError.new("Your zing bats got mixed up with the snosh frazzles.")
|
22
27
|
data = Chatterbox::ExceptionNotification::Extracter.new(:exception => exception, :other_info => "yo dawg").notice
|
@@ -6,6 +6,12 @@ describe Chatterbox::ExceptionNotification::Presenter do
|
|
6
6
|
describe "body" do
|
7
7
|
it "should render sections in order" do
|
8
8
|
options = {
|
9
|
+
:request => {
|
10
|
+
:parameters => {
|
11
|
+
:remote_ip => "10.0.0.1",
|
12
|
+
:array => [1,2,3]
|
13
|
+
}
|
14
|
+
},
|
9
15
|
:environment => { "PATH" => "/usr/bin" },
|
10
16
|
:error_message => "ActionView::MissingTemplate: Missing template projects/show.erb in view path app/views",
|
11
17
|
:ruby_info => {
|
@@ -17,33 +23,68 @@ describe Chatterbox::ExceptionNotification::Presenter do
|
|
17
23
|
expected =<<EOL
|
18
24
|
Error Message
|
19
25
|
----------
|
20
|
-
|
26
|
+
ActionView::MissingTemplate: Missing template projects/show.erb in view path app/views
|
27
|
+
|
28
|
+
Request
|
29
|
+
----------
|
30
|
+
parameters: {"remote_ip"=>"10.0.0.1", "array"=>[1, 2, 3]}
|
21
31
|
|
22
32
|
Environment
|
23
33
|
----------
|
24
|
-
PATH: /usr/bin
|
34
|
+
PATH: "/usr/bin"
|
25
35
|
|
26
36
|
Ruby Info
|
27
37
|
----------
|
28
|
-
ruby_platform: darwin
|
29
|
-
ruby_version: 1.8.6
|
38
|
+
ruby_platform: "darwin"
|
39
|
+
ruby_version: "1.8.6"
|
30
40
|
EOL
|
31
|
-
presenter.
|
41
|
+
presenter.render_body.strip.should == expected.strip
|
32
42
|
end
|
33
43
|
|
34
|
-
it "renders
|
35
|
-
options = {
|
44
|
+
it "renders 'extra' sections before explicitly named, ordered sections" do
|
45
|
+
options = {
|
46
|
+
:environment => { "PATH" => "/usr/bin" },
|
47
|
+
:special_details => "alert! system compromised in sector 8!"
|
48
|
+
}
|
36
49
|
presenter = Chatterbox::ExceptionNotification::Presenter.new(options)
|
37
50
|
expected =<<EOL
|
38
|
-
|
51
|
+
Special Details
|
39
52
|
----------
|
40
|
-
|
53
|
+
alert! system compromised in sector 8!
|
41
54
|
|
42
|
-
|
55
|
+
Environment
|
43
56
|
----------
|
44
|
-
|
57
|
+
PATH: "/usr/bin"
|
45
58
|
EOL
|
46
|
-
presenter.
|
59
|
+
presenter.render_body.strip.should == expected.strip
|
60
|
+
end
|
61
|
+
|
62
|
+
it "renders unordered sections" do
|
63
|
+
options = {:error_message => "Runtime error has occured", :details => "values and things"}
|
64
|
+
presenter = Chatterbox::ExceptionNotification::Presenter.new(options)
|
65
|
+
expected =<<EOL
|
66
|
+
Details
|
67
|
+
----------
|
68
|
+
values and things
|
69
|
+
EOL
|
70
|
+
presenter.render_body.should include(expected)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "renders backtrace cleanly" do
|
74
|
+
backtrace = ["/codes/file.rb:52:in `some_method'",
|
75
|
+
"/codes/file.rb:10:in `different_method'",
|
76
|
+
"/gems/some_gem/gem_name.rb:104:in `main'"]
|
77
|
+
options = { :backtrace => backtrace }
|
78
|
+
presenter = Chatterbox::ExceptionNotification::Presenter.new(options)
|
79
|
+
expected =<<EOL
|
80
|
+
Backtrace
|
81
|
+
----------
|
82
|
+
/codes/file.rb:52:in `some_method'
|
83
|
+
/codes/file.rb:10:in `different_method'
|
84
|
+
/gems/some_gem/gem_name.rb:104:in `main'
|
85
|
+
|
86
|
+
EOL
|
87
|
+
presenter.render_body.should == expected
|
47
88
|
end
|
48
89
|
end
|
49
90
|
|
@@ -64,7 +105,7 @@ EOL
|
|
64
105
|
end
|
65
106
|
end
|
66
107
|
|
67
|
-
describe "
|
108
|
+
describe "render_hash" do
|
68
109
|
it "outputs hashes in key sorted order" do
|
69
110
|
hash = {
|
70
111
|
"my-key" => "something",
|
@@ -74,31 +115,12 @@ EOL
|
|
74
115
|
}
|
75
116
|
presenter = Chatterbox::ExceptionNotification::Presenter.new
|
76
117
|
expected =<<-EOL
|
77
|
-
abcdefg: foo
|
78
|
-
my-key: something
|
79
|
-
nanite: something
|
80
|
-
zephyr: something
|
118
|
+
abcdefg: "foo"
|
119
|
+
my-key: "something"
|
120
|
+
nanite: "something"
|
121
|
+
zephyr: "something"
|
81
122
|
EOL
|
82
|
-
presenter.
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
describe "prettyify_output" do
|
87
|
-
it "should strip leading --- from to_yaml and retrun pretty output for hashes" do
|
88
|
-
hash = { "my-key" => "some string value", "my-other-key" => "something" }
|
89
|
-
presenter = Chatterbox::ExceptionNotification::Presenter.new
|
90
|
-
output = presenter.inspect_value(hash)
|
91
|
-
# NOTE: Handling different hash order below, between 1.8.x and 1.9.1
|
92
|
-
actual_lines = output.split("\n")
|
93
|
-
expected_lines = ["my-key: some string value", "my-other-key: something"]
|
94
|
-
expected_lines.each { |line| actual_lines.should include(line) }
|
95
|
-
end
|
96
|
-
|
97
|
-
it "should strip leading --- from strings" do
|
98
|
-
presenter = Chatterbox::ExceptionNotification::Presenter.new
|
99
|
-
output = presenter.inspect_value("just a simple string")
|
100
|
-
output.should == "just a simple string"
|
123
|
+
presenter.render_hash(hash).should == expected
|
101
124
|
end
|
102
125
|
end
|
103
|
-
|
104
126
|
end
|
@@ -76,7 +76,7 @@ describe WidgetsController do
|
|
76
76
|
end
|
77
77
|
|
78
78
|
it "ignores anything configured on the ignore list" do
|
79
|
-
Chatterbox.expects(:
|
79
|
+
Chatterbox.expects(:notify).never
|
80
80
|
begin
|
81
81
|
@controller.rescue_action_in_public(RuntimeError.new)
|
82
82
|
rescue RuntimeError; end
|
@@ -99,7 +99,7 @@ describe WidgetsController do
|
|
99
99
|
end
|
100
100
|
|
101
101
|
it "ignores anything configured on the ignore list" do
|
102
|
-
Chatterbox.expects(:
|
102
|
+
Chatterbox.expects(:notify).never
|
103
103
|
begin
|
104
104
|
@controller.rescue_action_in_public(RuntimeError.new)
|
105
105
|
rescue RuntimeError; end
|
File without changes
|
@@ -6,17 +6,24 @@ describe Chatterbox::Services::Email::Mailer do
|
|
6
6
|
|
7
7
|
describe "wiring the email" do
|
8
8
|
it "should set subject to the summary" do
|
9
|
-
email = Chatterbox::Services::Email::Mailer.create_message(valid_options
|
9
|
+
email = Chatterbox::Services::Email::Mailer.create_message(valid_options(:summary => "check this out"))
|
10
10
|
email.subject.should == "check this out"
|
11
11
|
end
|
12
12
|
|
13
|
+
it "should use :summary_prefix if provided" do
|
14
|
+
options = valid_options.dup
|
15
|
+
options[:config] = valid_options[:config].merge(:summary_prefix => "[my-app] [notifications] ")
|
16
|
+
email = Chatterbox::Services::Email::Mailer.create_message(options)
|
17
|
+
email.subject.should == "[my-app] [notifications] here is a message"
|
18
|
+
end
|
19
|
+
|
13
20
|
it "should not require a body (for emails that are subject only)" do
|
14
|
-
email = Chatterbox::Services::Email::Mailer.create_message(valid_options.merge(:
|
21
|
+
email = Chatterbox::Services::Email::Mailer.create_message(valid_options.merge(:body => nil))
|
15
22
|
email.body.should be_blank # not nil for some reason -- ActionMailer provides an empty string somewhere
|
16
23
|
end
|
17
24
|
|
18
25
|
it "should set body to the body" do
|
19
|
-
email = Chatterbox::Services::Email::Mailer.create_message(valid_options
|
26
|
+
email = Chatterbox::Services::Email::Mailer.create_message(valid_options(:body => "here is my body"))
|
20
27
|
email.body.should == "here is my body"
|
21
28
|
end
|
22
29
|
|
@@ -27,7 +34,6 @@ describe Chatterbox::Services::Email::Mailer do
|
|
27
34
|
end
|
28
35
|
|
29
36
|
describe "content type" do
|
30
|
-
|
31
37
|
it "can be set" do
|
32
38
|
Chatterbox::Services::Email::Mailer.create_message(valid_options.merge(:config => { :content_type => "text/html"})).content_type.should == "text/html"
|
33
39
|
end
|
@@ -20,14 +20,14 @@ describe Chatterbox::Services::Email do
|
|
20
20
|
end
|
21
21
|
|
22
22
|
it "should preserve HashWithIndifferentAccess with explicit options" do
|
23
|
-
options = { :
|
23
|
+
options = { :summary => "foo", :config => { :to => "a", :from => "a" } }.with_indifferent_access
|
24
24
|
service = Chatterbox::Services::Email.new(options)
|
25
25
|
service.options.should be_instance_of(HashWithIndifferentAccess)
|
26
26
|
service.options[:config].should be_instance_of(HashWithIndifferentAccess)
|
27
27
|
end
|
28
28
|
|
29
29
|
it "should preserve HashWithIndifferentAccess with default configuration" do
|
30
|
-
options = { :
|
30
|
+
options = { :summary => "foo" }.with_indifferent_access
|
31
31
|
Chatterbox::Services::Email.configure :to => "default-to@example.com", :from => "default-from@example.com"
|
32
32
|
service = Chatterbox::Services::Email.new(options)
|
33
33
|
service.options.should be_instance_of(HashWithIndifferentAccess)
|
@@ -36,51 +36,55 @@ describe Chatterbox::Services::Email do
|
|
36
36
|
end
|
37
37
|
|
38
38
|
describe "validations" do
|
39
|
-
|
40
|
-
|
41
|
-
Chatterbox::Services::Email.deliver(:config => { :from => "foo", :to => "foo"})
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
39
|
+
describe ":summary requirement" do
|
40
|
+
it "allows top level :summary" do
|
41
|
+
Chatterbox::Services::Email.deliver(:summary => "summary!", :config => { :from => "foo", :to => "foo"})
|
42
|
+
end
|
43
|
+
|
44
|
+
it "allows nested :message for backwards compatibility" do
|
45
|
+
Chatterbox::Services::Email.deliver(:message => {:summary => "summary!"}, :config => { :from => "foo", :to => "foo"})
|
46
|
+
end
|
47
|
+
|
48
|
+
it "requires top level :summary" do
|
49
|
+
lambda {
|
50
|
+
Chatterbox::Services::Email.deliver(:config => { :from => "foo", :to => "foo"})
|
51
|
+
}.should raise_error(ArgumentError, /Must provide a :summary for your message/)
|
52
|
+
end
|
49
53
|
end
|
50
54
|
|
51
|
-
it "
|
55
|
+
it "requires :to address" do
|
52
56
|
lambda {
|
53
|
-
Chatterbox::Services::Email.deliver(:
|
57
|
+
Chatterbox::Services::Email.deliver(:summary => "", :config => { :from => "anyone" })
|
54
58
|
}.should raise_error(ArgumentError, /Must provide :to in the :config/)
|
55
59
|
end
|
56
60
|
|
57
|
-
it "
|
61
|
+
it "requires :from address" do
|
58
62
|
lambda {
|
59
|
-
Chatterbox::Services::Email.deliver(:
|
63
|
+
Chatterbox::Services::Email.deliver(:summary => "", :config => { :to => "anyone"})
|
60
64
|
}.should raise_error(ArgumentError, /Must provide :from in the :config/)
|
61
65
|
end
|
62
66
|
end
|
63
67
|
|
64
68
|
describe "default_configuration=" do
|
65
|
-
it "
|
69
|
+
it "defaults to empty hash" do
|
66
70
|
Chatterbox::Services::Email.default_configuration.should == {}
|
67
71
|
end
|
68
72
|
|
69
|
-
it "
|
73
|
+
it "sets default configuration into :config" do
|
70
74
|
Chatterbox::Services::Email.configure :to => "to@example.com", :from => "from@example.com"
|
71
75
|
Chatterbox::Services::Email.default_configuration.should == { :to => "to@example.com", :from => "from@example.com"}
|
72
76
|
end
|
73
77
|
|
74
|
-
it "
|
78
|
+
it "uses default configuration if no per-message configuration provided" do
|
75
79
|
Chatterbox::Services::Email.configure :to => "to@example.com", :from => "from@example.com"
|
76
|
-
mail = Chatterbox::Services::Email.deliver(:
|
80
|
+
mail = Chatterbox::Services::Email.deliver(:summary => "summary")
|
77
81
|
mail.to.should == ["to@example.com"]
|
78
82
|
mail.from.should == ["from@example.com"]
|
79
83
|
end
|
80
84
|
|
81
|
-
it "
|
85
|
+
it "allows per message configuration (if provided) to override default configuration" do
|
82
86
|
Chatterbox::Services::Email.configure :to => "default-to@example.com", :from => "default-from@example.com"
|
83
|
-
mail = Chatterbox::Services::Email.deliver(:
|
87
|
+
mail = Chatterbox::Services::Email.deliver(:summary => "summary",
|
84
88
|
:config => { :to => "joe@example.com", :from => "harry@example.com"} )
|
85
89
|
mail.to.should == ["joe@example.com"]
|
86
90
|
mail.from.should == ["harry@example.com"]
|
@@ -4,19 +4,36 @@ describe Chatterbox do
|
|
4
4
|
|
5
5
|
before { Chatterbox::Publishers.clear! }
|
6
6
|
|
7
|
-
describe "
|
7
|
+
describe "notify" do
|
8
8
|
it "should return notification" do
|
9
|
-
Chatterbox.
|
9
|
+
Chatterbox.notify("message").should == "message"
|
10
10
|
end
|
11
11
|
|
12
|
-
it "should publish the
|
12
|
+
it "should publish the notification" do
|
13
13
|
Chatterbox.expects(:publish_notice).with({})
|
14
|
-
Chatterbox.
|
14
|
+
Chatterbox.notify({})
|
15
15
|
end
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
describe "handle_notice alias" do
|
18
|
+
it "is an publishes notification" do
|
19
|
+
Chatterbox.expects(:publish_notice).with({})
|
20
|
+
ActiveSupport::Deprecation.silence do
|
21
|
+
Chatterbox.handle_notice({})
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
it "is deprecated" do
|
26
|
+
Chatterbox.expects(:deprecate).with("Chatterbox#handle_notice is deprecated and will be removed from Chatterbox 1.0. Call Chatterbox#notify instead.", anything)
|
27
|
+
Chatterbox.handle_notice("message")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "deprecation" do
|
33
|
+
it "uses ActiveSupport's Deprecation#warn" do
|
34
|
+
stack = caller
|
35
|
+
ActiveSupport::Deprecation.expects(:warn).with("deprecation warning here", stack)
|
36
|
+
Chatterbox.deprecate("deprecation warning here", stack)
|
20
37
|
end
|
21
38
|
end
|
22
39
|
|
@@ -60,4 +77,11 @@ describe Chatterbox do
|
|
60
77
|
end
|
61
78
|
end
|
62
79
|
|
80
|
+
describe "register" do
|
81
|
+
it "registers publisher" do
|
82
|
+
pub = Chatterbox.register { "publisher" }
|
83
|
+
Chatterbox::Publishers.publishers.should == [pub]
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
63
87
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Feature: Chatterbox API
|
2
|
+
|
3
|
+
As a Chatterbox user
|
4
|
+
I want to send messages using a simple API
|
5
|
+
So that I can deliver many different types of notifications using different services
|
6
|
+
|
7
|
+
Scenario: API ideas
|
8
|
+
Given a file named "api_testing.rb" with:
|
9
|
+
"""
|
10
|
+
Chatterbox.notify(:summary => "subject", :body => "body",
|
11
|
+
:via => { :service => :email, :to => "jdoe@example.com", :from => "foo.com" },
|
12
|
+
:via => { :service => :twitter, :to => "rsanheim" },
|
13
|
+
:via => { :destinations => ["my-inbox", "joes-house" }
|
14
|
+
|
15
|
+
Chatterbox.notify(:summary => "subject", :body => "body") do |via|
|
16
|
+
via.email :to => "jdoe@example.com", :from => "foo.com"
|
17
|
+
via.twitter :to => "twitter"
|
18
|
+
end
|
19
|
+
"""
|
20
|
+
|
@@ -0,0 +1,46 @@
|
|
1
|
+
Feature: Sending email
|
2
|
+
|
3
|
+
As a Chatterbox user
|
4
|
+
I want to send emails using the same options as any other service
|
5
|
+
So that I can deliver notifications over email
|
6
|
+
|
7
|
+
Scenario: Simple email sending
|
8
|
+
Given a file named "simple_email_sending.rb" with:
|
9
|
+
"""
|
10
|
+
require "chatterbox"
|
11
|
+
require "chatterbox/services/email"
|
12
|
+
ActionMailer::Base.delivery_method = :test
|
13
|
+
|
14
|
+
Chatterbox::Publishers.register do |notice|
|
15
|
+
Chatterbox::Services::Email.deliver(notice)
|
16
|
+
end
|
17
|
+
Chatterbox.notify :summary => "subject", :body => "body",
|
18
|
+
:config => { :to => "joe@example.com", :from => "sender@example.com" }
|
19
|
+
puts ActionMailer::Base.deliveries.last.encoded
|
20
|
+
"""
|
21
|
+
When I run "simple_email_sending.rb"
|
22
|
+
Then the exit code should be 0
|
23
|
+
And the stdout should match "To: joe@example.com"
|
24
|
+
|
25
|
+
Scenario: Sending with default configuration
|
26
|
+
Given a file named "default_configuration_email_send.rb" with:
|
27
|
+
"""
|
28
|
+
require "chatterbox"
|
29
|
+
require "chatterbox/services/email"
|
30
|
+
ActionMailer::Base.delivery_method = :test
|
31
|
+
|
32
|
+
Chatterbox::Publishers.register do |notice|
|
33
|
+
Chatterbox::Services::Email.deliver(notice)
|
34
|
+
end
|
35
|
+
Chatterbox::Services::Email.configure({
|
36
|
+
:to => "to@example.com", :from => "from@example.com", :summary_prefix => "[CUKE] "
|
37
|
+
})
|
38
|
+
Chatterbox.notify :message => { :summary => "subject goes here!", :body => "body" }
|
39
|
+
puts ActionMailer::Base.deliveries.last.encoded
|
40
|
+
"""
|
41
|
+
When I run "default_configuration_email_send.rb"
|
42
|
+
Then the exit code should be 0
|
43
|
+
And the stdout should match "To: to@example.com"
|
44
|
+
And the stdout should match "From: from@example.com"
|
45
|
+
And the stdout should match "Subject: [CUKE] subject goes here!"
|
46
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
Feature: Configurable Services
|
2
|
+
|
3
|
+
As a Chatterbox user
|
4
|
+
I want to be able to configure only the services I need
|
5
|
+
So that I can avoid unnecessary dependecies
|
6
|
+
|
7
|
+
Scenario: No services loaded
|
8
|
+
Given a file named "no_services_loaded.rb" with:
|
9
|
+
"""
|
10
|
+
require "chatterbox"
|
11
|
+
require "spec"
|
12
|
+
require "spec/expectations"
|
13
|
+
Chatterbox::Services.constants.should == []
|
14
|
+
"""
|
15
|
+
When I run "no_services_loaded.rb"
|
16
|
+
Then the exit code should be 0
|
17
|
+
|
18
|
+
Scenario: Email service only
|
19
|
+
Given a file named "email_service_only.rb" with:
|
20
|
+
"""
|
21
|
+
require "chatterbox"
|
22
|
+
require "chatterbox/services/email"
|
23
|
+
require "spec"
|
24
|
+
require "spec/expectations"
|
25
|
+
Chatterbox::Services.constants.size.should == 1
|
26
|
+
Chatterbox::Services.constants.first.to_sym.should == :Email
|
27
|
+
"""
|
28
|
+
When I run "email_service_only.rb"
|
29
|
+
Then the exit code should be 0
|
30
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
Given %r{^a file named "([^"]+)" with:$} do |file_name, code|
|
2
|
+
create_file(file_name, code)
|
3
|
+
end
|
4
|
+
|
5
|
+
When /^I run "([^\"]*)"$/ do |command|
|
6
|
+
ruby command
|
7
|
+
end
|
8
|
+
|
9
|
+
Then /^the exit code should be (\d+)$/ do |exit_code|
|
10
|
+
if last_exit_code != exit_code.to_i
|
11
|
+
raise "Did not exit with #{exit_code}, but with #{last_exit_code}. Standard error:\n#{last_stderr}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
Then /^the (.*) should match (.*)$/ do |stream, string_or_regex|
|
16
|
+
written = case(stream)
|
17
|
+
when 'stdout' then last_stdout
|
18
|
+
when 'stderr' then last_stderr
|
19
|
+
else raise "Unknown stream: #{stream}"
|
20
|
+
end
|
21
|
+
written.should smart_match(string_or_regex)
|
22
|
+
end
|
23
|
+
|
24
|
+
Then /^the (.*) should not match (.*)$/ do |stream, string_or_regex|
|
25
|
+
written = case(stream)
|
26
|
+
when 'stdout' then last_stdout
|
27
|
+
when 'stderr' then last_stderr
|
28
|
+
else raise "Unknown stream: #{stream}"
|
29
|
+
end
|
30
|
+
written.should_not smart_match(string_or_regex)
|
31
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
require 'pathname'
|
3
|
+
require 'spec'
|
4
|
+
require 'spec/expectations'
|
5
|
+
|
6
|
+
class ChatterboxWorld
|
7
|
+
|
8
|
+
def root
|
9
|
+
@root ||= Pathname(__FILE__).join(*%w[.. .. ..]).expand_path
|
10
|
+
end
|
11
|
+
|
12
|
+
def working_dir
|
13
|
+
@working_dir ||= root.join(*%w[tmp cuke_generated]).expand_path
|
14
|
+
@working_dir.mkpath
|
15
|
+
@working_dir
|
16
|
+
end
|
17
|
+
|
18
|
+
def chatterbox_lib
|
19
|
+
root.join("lib")
|
20
|
+
end
|
21
|
+
|
22
|
+
def create_file(file_name, contents)
|
23
|
+
file_path = File.join(working_dir, file_name)
|
24
|
+
File.open(file_path, "w") { |f| f << contents }
|
25
|
+
end
|
26
|
+
|
27
|
+
def stderr_file
|
28
|
+
return @stderr_file if @stderr_file
|
29
|
+
@stderr_file = Tempfile.new('chatterbox_stderr')
|
30
|
+
@stderr_file.close
|
31
|
+
@stderr_file
|
32
|
+
end
|
33
|
+
|
34
|
+
def last_stderr
|
35
|
+
@stderr
|
36
|
+
end
|
37
|
+
|
38
|
+
def last_stdout
|
39
|
+
@stdout
|
40
|
+
end
|
41
|
+
|
42
|
+
def last_exit_code
|
43
|
+
@exit_code
|
44
|
+
end
|
45
|
+
|
46
|
+
def ruby(args)
|
47
|
+
Dir.chdir(working_dir) do
|
48
|
+
cmd = %[ruby -I#{chatterbox_lib} -rrubygems #{args} 2> #{stderr_file.path}]
|
49
|
+
@stdout = `#{cmd}`
|
50
|
+
end
|
51
|
+
@stderr = IO.read(stderr_file.path)
|
52
|
+
@exit_code = $?.to_i
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
World do
|
57
|
+
ChatterboxWorld.new
|
58
|
+
end
|
59
|
+
|
60
|
+
Spec::Matchers.define :smart_match do |expected|
|
61
|
+
match do |actual|
|
62
|
+
case expected
|
63
|
+
when /^\/.*\/?$/
|
64
|
+
actual =~ eval(expected)
|
65
|
+
when /^".*"$/
|
66
|
+
actual.index(eval(expected))
|
67
|
+
else
|
68
|
+
false
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/lib/chatterbox.rb
CHANGED
@@ -1,21 +1,31 @@
|
|
1
1
|
require 'active_support'
|
2
2
|
|
3
3
|
module Chatterbox
|
4
|
-
def
|
4
|
+
def notify(message)
|
5
5
|
publish_notice(message)
|
6
6
|
message
|
7
7
|
end
|
8
8
|
|
9
|
-
alias_method :notify, :handle_notice
|
10
|
-
|
11
9
|
def publish_notice(message)
|
12
10
|
Publishers.publishers.each { |p| p.call(message.with_indifferent_access) }
|
13
11
|
end
|
14
12
|
|
13
|
+
def handle_notice(message)
|
14
|
+
warning = "Chatterbox#handle_notice is deprecated and will be removed from Chatterbox 1.0. Call Chatterbox#notify instead."
|
15
|
+
deprecate(warning, caller)
|
16
|
+
notify(message)
|
17
|
+
end
|
18
|
+
|
19
|
+
def deprecate(message, callstack)
|
20
|
+
ActiveSupport::Deprecation.warn(message, callstack)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Retrieve (lazily loaded) logger; defaults to a nil Logger
|
15
24
|
def logger
|
16
25
|
@logger ||= Logger.new(nil)
|
17
26
|
end
|
18
27
|
|
28
|
+
# Set default logger for Chatterbox to use; mostly for development and debugging purposes
|
19
29
|
def logger=(logger)
|
20
30
|
@logger = logger
|
21
31
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'yaml'
|
2
|
+
require 'pp'
|
2
3
|
|
3
4
|
module Chatterbox::ExceptionNotification
|
4
5
|
class Presenter
|
@@ -18,66 +19,65 @@ module Chatterbox::ExceptionNotification
|
|
18
19
|
end
|
19
20
|
|
20
21
|
def to_message
|
21
|
-
{ :
|
22
|
+
{ :summary => summary,
|
23
|
+
:body => render_body,
|
22
24
|
:config => @config }
|
23
25
|
end
|
24
26
|
|
25
|
-
def
|
27
|
+
def error_details
|
26
28
|
[:error_message, :request, :backtrace, :environment, :ruby_info, :rails_info]
|
27
29
|
end
|
28
30
|
|
29
|
-
def
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
35
|
-
options.keys.each do |other_sections|
|
36
|
-
output = render_section(other_sections)
|
37
|
-
body << output if output
|
38
|
-
end
|
31
|
+
def render_body
|
32
|
+
processed_keys = []
|
33
|
+
extra_sections = options.keys - error_details
|
34
|
+
body = render_sections(extra_sections, processed_keys)
|
35
|
+
body << render_sections(error_details, processed_keys)
|
39
36
|
body
|
40
37
|
end
|
41
38
|
|
42
|
-
def
|
39
|
+
def render_sections(keys, already_processed)
|
40
|
+
keys.inject(String.new) do |str, key|
|
41
|
+
output = render_section(key, already_processed)
|
42
|
+
str << output if output
|
43
|
+
str
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def render_section(key, processed_keys = [])
|
48
|
+
processed_keys << key
|
43
49
|
return nil unless options.key?(key)
|
44
|
-
output = key.to_s.titleize
|
45
|
-
output << "\n"
|
50
|
+
output = "#{key.to_s.titleize}\n"
|
46
51
|
output << "----------\n"
|
47
|
-
output <<
|
52
|
+
output << render_obj(options[key])
|
53
|
+
output << "\n"
|
48
54
|
output
|
49
55
|
end
|
50
56
|
|
51
|
-
# Taken from exception_notification - thanks Jamis.
|
52
|
-
def inspect_value(value)
|
53
|
-
object_to_yaml(value).strip
|
54
|
-
end
|
55
|
-
|
56
|
-
def object_to_yaml(object)
|
57
|
-
result = ""
|
58
|
-
result << render_obj(object)
|
59
|
-
result
|
60
|
-
end
|
61
|
-
|
62
57
|
def render_obj(object)
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
58
|
+
case object
|
59
|
+
when Hash then render_hash(object)
|
60
|
+
when Array then render_array(object)
|
61
|
+
else render_object(object)
|
67
62
|
end
|
68
63
|
end
|
69
|
-
|
70
|
-
def
|
71
|
-
object.
|
64
|
+
|
65
|
+
def render_array(object)
|
66
|
+
render_object(object.join("\n"))
|
67
|
+
end
|
68
|
+
|
69
|
+
def render_object(object)
|
70
|
+
"#{object}\n"
|
72
71
|
end
|
73
72
|
|
74
|
-
# renders hashes with keys in sorted order
|
73
|
+
# renders hashes with keys in alpha-sorted order
|
75
74
|
def render_hash(hsh)
|
76
75
|
str = ""
|
77
76
|
indiff_hsh = hsh.with_indifferent_access
|
78
77
|
indiff_hsh.keys.sort.each do |key|
|
78
|
+
str << "#{key}: "
|
79
79
|
value = indiff_hsh[key]
|
80
|
-
|
80
|
+
PP::pp(value, str)
|
81
81
|
end
|
82
82
|
str
|
83
83
|
end
|
@@ -21,6 +21,7 @@ module Chatterbox::Services
|
|
21
21
|
def initialize(options = {})
|
22
22
|
@options = options
|
23
23
|
merge_configs
|
24
|
+
merge_message
|
24
25
|
validate_options
|
25
26
|
end
|
26
27
|
|
@@ -30,37 +31,36 @@ module Chatterbox::Services
|
|
30
31
|
|
31
32
|
private
|
32
33
|
|
34
|
+
def merge_message
|
35
|
+
if @options[:message]
|
36
|
+
@options.merge!(@options[:message])
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
33
40
|
def merge_configs
|
34
41
|
@options[:config] ||= {}
|
35
42
|
@options[:config] = self.class.default_configuration.merge(options[:config])
|
36
43
|
end
|
37
44
|
|
38
45
|
def validate_options
|
39
|
-
|
40
|
-
require_message_keys(:summary)
|
46
|
+
require_summary
|
41
47
|
|
42
48
|
require_config
|
43
49
|
require_config_keys(:to, :from)
|
44
50
|
end
|
45
51
|
|
46
|
-
def require_message
|
47
|
-
raise(ArgumentError, "Must configure with a :message - you provided #{options.inspect}") unless options.key?(:message)
|
48
|
-
end
|
49
|
-
|
50
52
|
def require_config
|
51
53
|
raise(ArgumentError, "Must configure with a :config or set default_configuration") unless options.key?(:config)
|
52
54
|
end
|
53
55
|
|
54
56
|
def require_config_keys(*keys)
|
55
57
|
Array(keys).each do |key|
|
56
|
-
raise(ArgumentError, "Must provide #{key.inspect} in the :config
|
58
|
+
raise(ArgumentError, "Must provide #{key.inspect} in the :config - you provided:\n#{options.inspect}") unless options[:config].key?(key)
|
57
59
|
end
|
58
60
|
end
|
59
61
|
|
60
|
-
def
|
61
|
-
|
62
|
-
raise(ArgumentError, "Must provide #{key.inspect} in the :message") unless options[:message].key?(key)
|
63
|
-
end
|
62
|
+
def require_summary
|
63
|
+
raise(ArgumentError, "Must provide a :summary for your message - you provided:\n#{options.inspect}") unless options.key?(:summary)
|
64
64
|
end
|
65
65
|
end
|
66
66
|
end
|
@@ -19,10 +19,10 @@ module Chatterbox::Services
|
|
19
19
|
bcc data[:config][:bcc] if data[:config][:bcc]
|
20
20
|
cc data[:config][:cc] if data[:config][:cc]
|
21
21
|
|
22
|
-
subject data[:
|
23
|
-
body data[:
|
22
|
+
subject [data[:config][:summary_prefix], data[:summary]].join
|
23
|
+
body data[:body] if data[:body]
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chatterbox
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rob Sanheim
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-11-
|
12
|
+
date: 2009-11-26 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -63,7 +63,6 @@ extra_rdoc_files:
|
|
63
63
|
- README.markdown
|
64
64
|
files:
|
65
65
|
- .gitignore
|
66
|
-
- .treasure_map.rb
|
67
66
|
- CHANGELOG.markdown
|
68
67
|
- LICENSE
|
69
68
|
- README.markdown
|
@@ -77,10 +76,16 @@ files:
|
|
77
76
|
- examples/lib/chatterbox/exception_notification_example.rb
|
78
77
|
- examples/lib/chatterbox/rails_catcher_controller_example.rb
|
79
78
|
- examples/lib/chatterbox/rails_catcher_example.rb
|
79
|
+
- examples/lib/chatterbox/services/campfire_example.rb
|
80
80
|
- examples/lib/chatterbox/services/email/mailer_example.rb
|
81
81
|
- examples/lib/chatterbox/services/email_example.rb
|
82
82
|
- examples/lib/chatterbox/services_example.rb
|
83
83
|
- examples/lib/chatterbox_example.rb
|
84
|
+
- features/api.feature
|
85
|
+
- features/email_service.feature
|
86
|
+
- features/services.feature
|
87
|
+
- features/step_definitions/email_service_steps.rb
|
88
|
+
- features/support/env.rb
|
84
89
|
- init.rb
|
85
90
|
- lib/chatterbox.rb
|
86
91
|
- lib/chatterbox/exception_notification.rb
|
@@ -89,10 +94,12 @@ files:
|
|
89
94
|
- lib/chatterbox/exception_notification/rails_extracter.rb
|
90
95
|
- lib/chatterbox/rails_catcher.rb
|
91
96
|
- lib/chatterbox/services.rb
|
97
|
+
- lib/chatterbox/services/campfire.rb
|
92
98
|
- lib/chatterbox/services/email.rb
|
93
99
|
- lib/chatterbox/services/email/mailer.rb
|
94
100
|
- lib/chatterbox/services/email/views/chatterbox/services/email/mailer/message.erb
|
95
101
|
- rails/init.rb
|
102
|
+
- tmp/.gitignore
|
96
103
|
- todo.markdown
|
97
104
|
- views/chatterbox/mailer/exception_notification.erb
|
98
105
|
has_rdoc: true
|
@@ -131,6 +138,7 @@ test_files:
|
|
131
138
|
- examples/lib/chatterbox/exception_notification_example.rb
|
132
139
|
- examples/lib/chatterbox/rails_catcher_controller_example.rb
|
133
140
|
- examples/lib/chatterbox/rails_catcher_example.rb
|
141
|
+
- examples/lib/chatterbox/services/campfire_example.rb
|
134
142
|
- examples/lib/chatterbox/services/email/mailer_example.rb
|
135
143
|
- examples/lib/chatterbox/services/email_example.rb
|
136
144
|
- examples/lib/chatterbox/services_example.rb
|
data/.treasure_map.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
map_for(:chatterbox) do |map|
|
2
|
-
|
3
|
-
map.keep_a_watchful_eye_for 'lib', 'examples', 'rails'
|
4
|
-
|
5
|
-
# map.add_mapping %r%examples/(.*)_example\.rb% do |match|
|
6
|
-
# ["examples/#{match[1]}_example.rb"]
|
7
|
-
# end
|
8
|
-
#
|
9
|
-
# map.add_mapping %r%examples/example_helper\.rb% do |match|
|
10
|
-
# Dir["examples/**/*_example.rb"]
|
11
|
-
# end
|
12
|
-
#
|
13
|
-
# map.add_mapping %r%lib/(.*)\.rb% do |match|
|
14
|
-
# Dir["examples/#{match[1]}_example.rb"]
|
15
|
-
# end
|
16
|
-
|
17
|
-
map.add_mapping %r%rails/(.*)\.rb% do |match|
|
18
|
-
["examples/#{match[1]}_example.rb"]
|
19
|
-
end
|
20
|
-
|
21
|
-
|
22
|
-
end
|