hatless-hoptoad_notifier 2.2.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/CHANGELOG +149 -0
  2. data/INSTALL +25 -0
  3. data/MIT-LICENSE +22 -0
  4. data/README.rdoc +382 -0
  5. data/Rakefile +217 -0
  6. data/SUPPORTED_RAILS_VERSIONS +9 -0
  7. data/TESTING.rdoc +8 -0
  8. data/generators/hoptoad/hoptoad_generator.rb +54 -0
  9. data/generators/hoptoad/lib/insert_commands.rb +34 -0
  10. data/generators/hoptoad/lib/rake_commands.rb +24 -0
  11. data/generators/hoptoad/templates/capistrano_hook.rb +6 -0
  12. data/generators/hoptoad/templates/hoptoad_notifier_tasks.rake +25 -0
  13. data/generators/hoptoad/templates/initializer.rb +6 -0
  14. data/lib/hoptoad_notifier/backtrace.rb +99 -0
  15. data/lib/hoptoad_notifier/capistrano.rb +20 -0
  16. data/lib/hoptoad_notifier/configuration.rb +232 -0
  17. data/lib/hoptoad_notifier/notice.rb +318 -0
  18. data/lib/hoptoad_notifier/rack.rb +40 -0
  19. data/lib/hoptoad_notifier/rails/action_controller_catcher.rb +29 -0
  20. data/lib/hoptoad_notifier/rails/controller_methods.rb +58 -0
  21. data/lib/hoptoad_notifier/rails/error_lookup.rb +33 -0
  22. data/lib/hoptoad_notifier/rails.rb +37 -0
  23. data/lib/hoptoad_notifier/rails3_tasks.rb +90 -0
  24. data/lib/hoptoad_notifier/railtie.rb +23 -0
  25. data/lib/hoptoad_notifier/sender.rb +63 -0
  26. data/lib/hoptoad_notifier/tasks.rb +97 -0
  27. data/lib/hoptoad_notifier/version.rb +3 -0
  28. data/lib/hoptoad_notifier.rb +148 -0
  29. data/lib/hoptoad_tasks.rb +40 -0
  30. data/lib/rails/generators/hoptoad/hoptoad_generator.rb +64 -0
  31. data/lib/templates/rescue.erb +91 -0
  32. data/rails/init.rb +1 -0
  33. data/script/integration_test.rb +38 -0
  34. data/test/backtrace_test.rb +118 -0
  35. data/test/catcher_test.rb +324 -0
  36. data/test/configuration_test.rb +208 -0
  37. data/test/helper.rb +239 -0
  38. data/test/hoptoad_tasks_test.rb +138 -0
  39. data/test/logger_test.rb +85 -0
  40. data/test/notice_test.rb +443 -0
  41. data/test/notifier_test.rb +222 -0
  42. data/test/rack_test.rb +58 -0
  43. data/test/rails_initializer_test.rb +36 -0
  44. data/test/sender_test.rb +123 -0
  45. metadata +204 -0
data/test/helper.rb ADDED
@@ -0,0 +1,239 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+
4
+ gem 'jferris-mocha', '>= 0.9.5.0.1241126838'
5
+
6
+ $LOAD_PATH << File.join(File.dirname(__FILE__), *%w[.. vendor ginger lib])
7
+ $LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
8
+
9
+ require 'shoulda'
10
+ require 'mocha'
11
+
12
+ require 'ginger'
13
+
14
+ require 'action_controller'
15
+ require 'action_controller/test_process'
16
+ require 'active_record'
17
+ require 'active_record/base'
18
+ require 'active_support'
19
+ require 'nokogiri'
20
+ require 'rack'
21
+
22
+ require "hoptoad_notifier"
23
+
24
+ begin require 'redgreen'; rescue LoadError; end
25
+
26
+ module TestMethods
27
+ def rescue_action e
28
+ raise e
29
+ end
30
+
31
+ def do_raise
32
+ raise "Hoptoad"
33
+ end
34
+
35
+ def do_not_raise
36
+ render :text => "Success"
37
+ end
38
+
39
+ def do_raise_ignored
40
+ raise ActiveRecord::RecordNotFound.new("404")
41
+ end
42
+
43
+ def do_raise_not_ignored
44
+ raise ActiveRecord::StatementInvalid.new("Statement invalid")
45
+ end
46
+
47
+ def manual_notify
48
+ notify_hoptoad(Exception.new)
49
+ render :text => "Success"
50
+ end
51
+
52
+ def manual_notify_ignored
53
+ notify_hoptoad(ActiveRecord::RecordNotFound.new("404"))
54
+ render :text => "Success"
55
+ end
56
+ end
57
+
58
+ class HoptoadController < ActionController::Base
59
+ include TestMethods
60
+ end
61
+
62
+ class Test::Unit::TestCase
63
+ def request(action = nil, method = :get, user_agent = nil, params = {})
64
+ @request = ActionController::TestRequest.new
65
+ @request.action = action ? action.to_s : ""
66
+
67
+ if user_agent
68
+ if @request.respond_to?(:user_agent=)
69
+ @request.user_agent = user_agent
70
+ else
71
+ @request.env["HTTP_USER_AGENT"] = user_agent
72
+ end
73
+ end
74
+ @request.query_parameters = @request.query_parameters.merge(params)
75
+ @response = ActionController::TestResponse.new
76
+ @controller.process(@request, @response)
77
+ end
78
+
79
+ # Borrowed from ActiveSupport 2.3.2
80
+ def assert_difference(expression, difference = 1, message = nil, &block)
81
+ b = block.send(:binding)
82
+ exps = Array.wrap(expression)
83
+ before = exps.map { |e| eval(e, b) }
84
+
85
+ yield
86
+
87
+ exps.each_with_index do |e, i|
88
+ error = "#{e.inspect} didn't change by #{difference}"
89
+ error = "#{message}.\n#{error}" if message
90
+ assert_equal(before[i] + difference, eval(e, b), error)
91
+ end
92
+ end
93
+
94
+ def assert_no_difference(expression, message = nil, &block)
95
+ assert_difference expression, 0, message, &block
96
+ end
97
+
98
+ def stub_sender
99
+ stub('sender', :send_to_hoptoad => nil)
100
+ end
101
+
102
+ def stub_sender!
103
+ HoptoadNotifier.sender = stub_sender
104
+ end
105
+
106
+ def stub_notice
107
+ stub('notice', :to_xml => 'some yaml', :ignore? => false)
108
+ end
109
+
110
+ def stub_notice!
111
+ returning stub_notice do |notice|
112
+ HoptoadNotifier::Notice.stubs(:new => notice)
113
+ end
114
+ end
115
+
116
+ def create_dummy
117
+ HoptoadNotifier::DummySender.new
118
+ end
119
+
120
+ def reset_config
121
+ HoptoadNotifier.configuration = nil
122
+ HoptoadNotifier.configure do |config|
123
+ config.api_key = 'abc123'
124
+ end
125
+ end
126
+
127
+ def clear_backtrace_filters
128
+ HoptoadNotifier.configuration.backtrace_filters.clear
129
+ end
130
+
131
+ def build_exception
132
+ raise
133
+ rescue => caught_exception
134
+ caught_exception
135
+ end
136
+
137
+ def build_notice_data(exception = nil)
138
+ exception ||= build_exception
139
+ {
140
+ :api_key => 'abc123',
141
+ :error_class => exception.class.name,
142
+ :error_message => "#{exception.class.name}: #{exception.message}",
143
+ :backtrace => exception.backtrace,
144
+ :environment => { 'PATH' => '/bin', 'REQUEST_URI' => '/users/1' },
145
+ :request => {
146
+ :params => { 'controller' => 'users', 'action' => 'show', 'id' => '1' },
147
+ :rails_root => '/path/to/application',
148
+ :url => "http://test.host/users/1"
149
+ },
150
+ :session => {
151
+ :key => '123abc',
152
+ :data => { 'user_id' => '5', 'flash' => { 'notice' => 'Logged in successfully' } }
153
+ }
154
+ }
155
+ end
156
+
157
+ def assert_caught_and_sent
158
+ assert !HoptoadNotifier.sender.collected.empty?
159
+ end
160
+
161
+ def assert_caught_and_not_sent
162
+ assert HoptoadNotifier.sender.collected.empty?
163
+ end
164
+
165
+ def assert_array_starts_with(expected, actual)
166
+ assert_respond_to actual, :to_ary
167
+ array = actual.to_ary.reverse
168
+ expected.reverse.each_with_index do |value, i|
169
+ assert_equal value, array[i]
170
+ end
171
+ end
172
+
173
+ def assert_valid_node(document, xpath, content)
174
+ nodes = document.xpath(xpath)
175
+ assert nodes.any?{|node| node.content == content },
176
+ "Expected xpath #{xpath} to have content #{content}, " +
177
+ "but found #{nodes.map { |n| n.content }} in #{nodes.size} matching nodes." +
178
+ "Document:\n#{document.to_s}"
179
+ end
180
+ end
181
+
182
+ module DefinesConstants
183
+ def setup
184
+ @defined_constants = []
185
+ end
186
+
187
+ def teardown
188
+ @defined_constants.each do |constant|
189
+ Object.__send__(:remove_const, constant)
190
+ end
191
+ end
192
+
193
+ def define_constant(name, value)
194
+ Object.const_set(name, value)
195
+ @defined_constants << name
196
+ end
197
+ end
198
+
199
+ # Also stolen from AS 2.3.2
200
+ class Array
201
+ # Wraps the object in an Array unless it's an Array. Converts the
202
+ # object to an Array using #to_ary if it implements that.
203
+ def self.wrap(object)
204
+ case object
205
+ when nil
206
+ []
207
+ when self
208
+ object
209
+ else
210
+ if object.respond_to?(:to_ary)
211
+ object.to_ary
212
+ else
213
+ [object]
214
+ end
215
+ end
216
+ end
217
+
218
+ end
219
+
220
+ class CollectingSender
221
+ attr_reader :collected
222
+
223
+ def initialize
224
+ @collected = []
225
+ end
226
+
227
+ def send_to_hoptoad(data)
228
+ @collected << data
229
+ end
230
+ end
231
+
232
+ class FakeLogger
233
+ def info(*args); end
234
+ def debug(*args); end
235
+ def warn(*args); end
236
+ def error(*args); end
237
+ def fatal(*args); end
238
+ end
239
+
@@ -0,0 +1,138 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+ require 'rubygems'
3
+
4
+ require File.dirname(__FILE__) + '/../lib/hoptoad_tasks'
5
+ require 'fakeweb'
6
+
7
+ FakeWeb.allow_net_connect = false
8
+
9
+ class HoptoadTasksTest < Test::Unit::TestCase
10
+ def successful_response(body = "")
11
+ response = Net::HTTPSuccess.new('1.2', '200', 'OK')
12
+ response.stubs(:body).returns(body)
13
+ return response
14
+ end
15
+
16
+ def unsuccessful_response(body = "")
17
+ response = Net::HTTPClientError.new('1.2', '200', 'OK')
18
+ response.stubs(:body).returns(body)
19
+ return response
20
+ end
21
+
22
+ context "being quiet" do
23
+ setup { HoptoadTasks.stubs(:puts) }
24
+
25
+ context "in a configured project" do
26
+ setup { HoptoadNotifier.configure { |config| config.api_key = "1234123412341234" } }
27
+
28
+ context "on deploy({})" do
29
+ setup { @output = HoptoadTasks.deploy({}) }
30
+
31
+ before_should "complain about missing rails env" do
32
+ HoptoadTasks.expects(:puts).with(regexp_matches(/rails environment/i))
33
+ end
34
+
35
+ should "return false" do
36
+ assert !@output
37
+ end
38
+ end
39
+
40
+ context "given valid options" do
41
+ setup { @options = {:rails_env => "staging"} }
42
+
43
+ context "on deploy(options)" do
44
+ setup { @output = HoptoadTasks.deploy(@options) }
45
+
46
+ before_should "post to http://hoptoadapp.com/deploys.txt" do
47
+ URI.stubs(:parse).with('http://hoptoadapp.com/deploys.txt').returns(:uri)
48
+ Net::HTTP.expects(:post_form).with(:uri, kind_of(Hash)).returns(successful_response)
49
+ end
50
+
51
+ before_should "use the project api key" do
52
+ Net::HTTP.expects(:post_form).
53
+ with(kind_of(URI), has_entries('api_key' => "1234123412341234")).
54
+ returns(successful_response)
55
+ end
56
+
57
+ before_should "use send the rails_env param" do
58
+ Net::HTTP.expects(:post_form).
59
+ with(kind_of(URI), has_entries("deploy[rails_env]" => "staging")).
60
+ returns(successful_response)
61
+ end
62
+
63
+ [:local_username, :scm_repository, :scm_revision].each do |key|
64
+ before_should "use send the #{key} param if it's passed in." do
65
+ @options[key] = "value"
66
+ Net::HTTP.expects(:post_form).
67
+ with(kind_of(URI), has_entries("deploy[#{key}]" => "value")).
68
+ returns(successful_response)
69
+ end
70
+ end
71
+
72
+ before_should "use the :api_key param if it's passed in." do
73
+ @options[:api_key] = "value"
74
+ Net::HTTP.expects(:post_form).
75
+ with(kind_of(URI), has_entries("api_key" => "value")).
76
+ returns(successful_response)
77
+ end
78
+
79
+ before_should "puts the response body on success" do
80
+ HoptoadTasks.expects(:puts).with("body")
81
+ Net::HTTP.expects(:post_form).with(any_parameters).returns(successful_response('body'))
82
+ end
83
+
84
+ before_should "puts the response body on failure" do
85
+ HoptoadTasks.expects(:puts).with("body")
86
+ Net::HTTP.expects(:post_form).with(any_parameters).returns(unsuccessful_response('body'))
87
+ end
88
+
89
+ should "return false on failure", :before => lambda {
90
+ Net::HTTP.expects(:post_form).with(any_parameters).returns(unsuccessful_response('body'))
91
+ } do
92
+ assert !@output
93
+ end
94
+
95
+ should "return true on success", :before => lambda {
96
+ Net::HTTP.expects(:post_form).with(any_parameters).returns(successful_response('body'))
97
+ } do
98
+ assert @output
99
+ end
100
+ end
101
+ end
102
+ end
103
+
104
+ context "in a configured project with custom host" do
105
+ setup do
106
+ HoptoadNotifier.configure do |config|
107
+ config.api_key = "1234123412341234"
108
+ config.host = "custom.host"
109
+ end
110
+ end
111
+
112
+ context "on deploy(:rails_env => 'staging')" do
113
+ setup { @output = HoptoadTasks.deploy(:rails_env => "staging") }
114
+
115
+ before_should "post to the custom host" do
116
+ URI.stubs(:parse).with('http://custom.host/deploys.txt').returns(:uri)
117
+ Net::HTTP.expects(:post_form).with(:uri, kind_of(Hash)).returns(successful_response)
118
+ end
119
+ end
120
+ end
121
+
122
+ context "when not configured" do
123
+ setup { HoptoadNotifier.configure { |config| config.api_key = "" } }
124
+
125
+ context "on deploy(:rails_env => 'staging')" do
126
+ setup { @output = HoptoadTasks.deploy(:rails_env => "staging") }
127
+
128
+ before_should "complain about missing api key" do
129
+ HoptoadTasks.expects(:puts).with(regexp_matches(/api key/i))
130
+ end
131
+
132
+ should "return false" do
133
+ assert !@output
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,85 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class LoggerTest < Test::Unit::TestCase
4
+ def stub_http(response, body = nil)
5
+ response.stubs(:body => body) if body
6
+ @http = stub(:post => response,
7
+ :read_timeout= => nil,
8
+ :open_timeout= => nil,
9
+ :use_ssl= => nil)
10
+ Net::HTTP.stubs(:new).returns(@http)
11
+ end
12
+
13
+ def send_notice
14
+ HoptoadNotifier.sender.send_to_hoptoad('data')
15
+ end
16
+
17
+ def stub_verbose_log
18
+ HoptoadNotifier.stubs(:write_verbose_log)
19
+ end
20
+
21
+ def assert_logged(expected)
22
+ assert_received(HoptoadNotifier, :write_verbose_log) do |expect|
23
+ expect.with {|actual| actual =~ expected }
24
+ end
25
+ end
26
+
27
+ def assert_not_logged(expected)
28
+ assert_received(HoptoadNotifier, :write_verbose_log) do |expect|
29
+ expect.with {|actual| actual =~ expected }.never
30
+ end
31
+ end
32
+
33
+ def configure
34
+ HoptoadNotifier.configure { |config| }
35
+ end
36
+
37
+ should "report that notifier is ready when configured" do
38
+ stub_verbose_log
39
+ configure
40
+ assert_logged /Notifier (.*) ready/
41
+ end
42
+
43
+ should "not report that notifier is ready when internally configured" do
44
+ stub_verbose_log
45
+ HoptoadNotifier.configure(true) { |config| }
46
+ assert_not_logged /.*/
47
+ end
48
+
49
+ should "print environment info a successful notification without a body" do
50
+ reset_config
51
+ stub_verbose_log
52
+ stub_http(Net::HTTPSuccess)
53
+ send_notice
54
+ assert_logged /Environment Info:/
55
+ assert_not_logged /Response from Hoptoad:/
56
+ end
57
+
58
+ should "print environment info on a failed notification without a body" do
59
+ reset_config
60
+ stub_verbose_log
61
+ stub_http(Net::HTTPError)
62
+ send_notice
63
+ assert_logged /Environment Info:/
64
+ assert_not_logged /Response from Hoptoad:/
65
+ end
66
+
67
+ should "print environment info and response on a success with a body" do
68
+ reset_config
69
+ stub_verbose_log
70
+ stub_http(Net::HTTPSuccess, 'test')
71
+ send_notice
72
+ assert_logged /Environment Info:/
73
+ assert_logged /Response from Hoptoad:/
74
+ end
75
+
76
+ should "print environment info and response on a failure with a body" do
77
+ reset_config
78
+ stub_verbose_log
79
+ stub_http(Net::HTTPError, 'test')
80
+ send_notice
81
+ assert_logged /Environment Info:/
82
+ assert_logged /Response from Hoptoad:/
83
+ end
84
+
85
+ end