hatless-hoptoad_notifier 2.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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/rails/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'hoptoad_notifier/rails'
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'logger'
4
+ require 'fileutils'
5
+
6
+ RAILS_ENV = "production"
7
+ RAILS_ROOT = FileUtils.pwd
8
+ RAILS_DEFAULT_LOGGER = Logger.new(STDOUT)
9
+
10
+ $: << File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
11
+ require 'hoptoad_notifier'
12
+ require 'rails/init'
13
+
14
+ fail "Please supply an API Key as the first argument" if ARGV.empty?
15
+
16
+ host = ARGV[1]
17
+ host ||= "hoptoadapp.com"
18
+
19
+ secure = (ARGV[2] == "secure")
20
+
21
+ exception = begin
22
+ raise "Testing hoptoad notifier with secure = #{secure}. If you can see this, it works."
23
+ rescue => foo
24
+ foo
25
+ end
26
+
27
+ HoptoadNotifier.configure do |config|
28
+ config.secure = secure
29
+ config.host = host
30
+ config.api_key = ARGV.first
31
+ end
32
+ puts "Configuration:"
33
+ HoptoadNotifier.configuration.to_hash.each do |key, value|
34
+ puts sprintf("%25s: %s", key.to_s, value.inspect.slice(0, 55))
35
+ end
36
+ puts "Sending #{secure ? "" : "in"}secure notification to project with key #{ARGV.first}"
37
+ HoptoadNotifier.notify(exception)
38
+
@@ -0,0 +1,118 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class BacktraceTest < Test::Unit::TestCase
4
+
5
+ should "parse a backtrace into lines" do
6
+ array = [
7
+ "app/models/user.rb:13:in `magic'",
8
+ "app/controllers/users_controller.rb:8:in `index'"
9
+ ]
10
+
11
+ backtrace = HoptoadNotifier::Backtrace.parse(array)
12
+
13
+ line = backtrace.lines.first
14
+ assert_equal '13', line.number
15
+ assert_equal 'app/models/user.rb', line.file
16
+ assert_equal 'magic', line.method
17
+
18
+ line = backtrace.lines.last
19
+ assert_equal '8', line.number
20
+ assert_equal 'app/controllers/users_controller.rb', line.file
21
+ assert_equal 'index', line.method
22
+ end
23
+
24
+ should "be equal with equal lines" do
25
+ one = build_backtrace_array
26
+ two = one.dup
27
+ assert_equal one, two
28
+
29
+ assert_equal HoptoadNotifier::Backtrace.parse(one), HoptoadNotifier::Backtrace.parse(two)
30
+ end
31
+
32
+ should "parse massive one-line exceptions into multiple lines" do
33
+ original_backtrace = HoptoadNotifier::Backtrace.
34
+ parse(["one:1:in `one'\n two:2:in `two'\n three:3:in `three`"])
35
+ expected_backtrace = HoptoadNotifier::Backtrace.
36
+ parse(["one:1:in `one'", "two:2:in `two'", "three:3:in `three`"])
37
+
38
+ assert_equal expected_backtrace, original_backtrace
39
+ end
40
+
41
+ context "with a project root" do
42
+ setup do
43
+ @project_root = '/some/path'
44
+ HoptoadNotifier.configure {|config| config.project_root = @project_root }
45
+ end
46
+
47
+ teardown do
48
+ reset_config
49
+ end
50
+
51
+ should "filter out the project root" do
52
+ backtrace_with_root = HoptoadNotifier::Backtrace.parse(
53
+ ["#{@project_root}/app/models/user.rb:7:in `latest'",
54
+ "#{@project_root}/app/controllers/users_controller.rb:13:in `index'",
55
+ "/lib/something.rb:41:in `open'"],
56
+ :filters => default_filters)
57
+ backtrace_without_root = HoptoadNotifier::Backtrace.parse(
58
+ ["[PROJECT_ROOT]/app/models/user.rb:7:in `latest'",
59
+ "[PROJECT_ROOT]/app/controllers/users_controller.rb:13:in `index'",
60
+ "/lib/something.rb:41:in `open'"])
61
+
62
+ assert_equal backtrace_without_root, backtrace_with_root
63
+ end
64
+ end
65
+
66
+ context "with a blank project root" do
67
+ setup do
68
+ HoptoadNotifier.configure {|config| config.project_root = '' }
69
+ end
70
+
71
+ teardown do
72
+ reset_config
73
+ end
74
+
75
+ should "not filter line numbers with respect to any project root" do
76
+ backtrace = ["/app/models/user.rb:7:in `latest'",
77
+ "/app/controllers/users_controller.rb:13:in `index'",
78
+ "/lib/something.rb:41:in `open'"]
79
+
80
+ backtrace_with_root =
81
+ HoptoadNotifier::Backtrace.parse(backtrace, :filters => default_filters)
82
+
83
+ backtrace_without_root =
84
+ HoptoadNotifier::Backtrace.parse(backtrace)
85
+
86
+ assert_equal backtrace_without_root, backtrace_with_root
87
+ end
88
+ end
89
+
90
+ should "remove notifier trace" do
91
+ inside_notifier = ['lib/hoptoad_notifier.rb:13:in `voodoo`']
92
+ outside_notifier = ['users_controller:8:in `index`']
93
+
94
+ without_inside = HoptoadNotifier::Backtrace.parse(outside_notifier)
95
+ with_inside = HoptoadNotifier::Backtrace.parse(inside_notifier + outside_notifier,
96
+ :filters => default_filters)
97
+
98
+ assert_equal without_inside, with_inside
99
+ end
100
+
101
+ should "run filters on the backtrace" do
102
+ filters = [lambda { |line| line.sub('foo', 'bar') }]
103
+ input = HoptoadNotifier::Backtrace.parse(["foo:13:in `one'", "baz:14:in `two'"],
104
+ :filters => filters)
105
+ expected = HoptoadNotifier::Backtrace.parse(["bar:13:in `one'", "baz:14:in `two'"])
106
+ assert_equal expected, input
107
+ end
108
+
109
+ def build_backtrace_array
110
+ ["app/models/user.rb:13:in `magic'",
111
+ "app/controllers/users_controller.rb:8:in `index'"]
112
+ end
113
+
114
+ def default_filters
115
+ HoptoadNotifier::Configuration::DEFAULT_BACKTRACE_FILTERS
116
+ end
117
+
118
+ end
@@ -0,0 +1,324 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class ActionControllerCatcherTest < Test::Unit::TestCase
4
+
5
+ include DefinesConstants
6
+
7
+ def setup
8
+ super
9
+ reset_config
10
+ HoptoadNotifier.sender = CollectingSender.new
11
+ define_constant('RAILS_ROOT', '/path/to/rails/root')
12
+ end
13
+
14
+ def ignore(exception_class)
15
+ HoptoadNotifier.configuration.ignore << exception_class
16
+ end
17
+
18
+ def build_controller_class(&definition)
19
+ returning Class.new(ActionController::Base) do |klass|
20
+ klass.__send__(:include, HoptoadNotifier::Rails::ActionControllerCatcher)
21
+ klass.class_eval(&definition) if definition
22
+ define_constant('HoptoadTestController', klass)
23
+ end
24
+ end
25
+
26
+ def assert_sent_hash(hash, xpath)
27
+ hash.each do |key, value|
28
+ element_xpath = "#{xpath}/var[@key = '#{key}']"
29
+ if value.respond_to?(:to_hash)
30
+ assert_sent_hash value.to_hash, element_xpath
31
+ else
32
+ assert_sent_element value, element_xpath
33
+ end
34
+ end
35
+ end
36
+
37
+ def assert_sent_element(value, xpath)
38
+ assert_valid_node last_sent_notice_document, xpath, stringify_array_elements(value).to_s
39
+ end
40
+
41
+ def stringify_array_elements(data)
42
+ if data.respond_to?(:to_ary)
43
+ data.collect do |value|
44
+ stringify_array_elements(value)
45
+ end
46
+ else
47
+ data.to_s
48
+ end
49
+ end
50
+
51
+ def assert_sent_request_info_for(request)
52
+ params = request.parameters.to_hash
53
+ assert_sent_hash params, '/notice/request/params'
54
+ assert_sent_element params['controller'], '/notice/request/component'
55
+ assert_sent_element params['action'], '/notice/request/action'
56
+ assert_sent_element url_from_request(request), '/notice/request/url'
57
+ assert_sent_hash request.env, '/notice/request/cgi-data'
58
+ end
59
+
60
+ def url_from_request(request)
61
+ url = "#{request.protocol}#{request.host}"
62
+
63
+ unless [80, 443].include?(request.port)
64
+ url << ":#{request.port}"
65
+ end
66
+
67
+ url << request.request_uri
68
+ url
69
+ end
70
+
71
+ def sender
72
+ HoptoadNotifier.sender
73
+ end
74
+
75
+ def last_sent_notice_xml
76
+ sender.collected.last
77
+ end
78
+
79
+ def last_sent_notice_document
80
+ assert_not_nil xml = last_sent_notice_xml, "No xml was sent"
81
+ Nokogiri::XML.parse(xml)
82
+ end
83
+
84
+ def process_action(opts = {}, &action)
85
+ opts[:request] ||= ActionController::TestRequest.new
86
+ opts[:response] ||= ActionController::TestResponse.new
87
+ klass = build_controller_class do
88
+ cattr_accessor :local
89
+ define_method(:index, &action)
90
+ def local_request?
91
+ local
92
+ end
93
+ end
94
+ if opts[:filters]
95
+ klass.filter_parameter_logging *opts[:filters]
96
+ end
97
+ if opts[:user_agent]
98
+ if opts[:request].respond_to?(:user_agent=)
99
+ opts[:request].user_agent = opts[:user_agent]
100
+ else
101
+ opts[:request].env["HTTP_USER_AGENT"] = opts[:user_agent]
102
+ end
103
+ end
104
+ if opts[:port]
105
+ opts[:request].port = opts[:port]
106
+ end
107
+ klass.consider_all_requests_local = opts[:all_local]
108
+ klass.local = opts[:local]
109
+ controller = klass.new
110
+ controller.stubs(:rescue_action_in_public_without_hoptoad)
111
+ opts[:request].query_parameters = opts[:request].query_parameters.merge(opts[:params] || {})
112
+ opts[:request].session = ActionController::TestSession.new(opts[:session] || {})
113
+ controller.process(opts[:request], opts[:response])
114
+ controller
115
+ end
116
+
117
+ def process_action_with_manual_notification(args = {})
118
+ process_action(args) do
119
+ notify_hoptoad(:error_message => 'fail')
120
+ # Rails will raise a template error if we don't render something
121
+ render :nothing => true
122
+ end
123
+ end
124
+
125
+ def process_action_with_automatic_notification(args = {})
126
+ process_action(args) { raise "Hello" }
127
+ end
128
+
129
+ should "deliver notices from exceptions raised in public requests" do
130
+ process_action_with_automatic_notification
131
+ assert_caught_and_sent
132
+ end
133
+
134
+ should "not deliver notices from exceptions in local requests" do
135
+ process_action_with_automatic_notification(:local => true)
136
+ assert_caught_and_not_sent
137
+ end
138
+
139
+ should "not deliver notices from exceptions when all requests are local" do
140
+ process_action_with_automatic_notification(:all_local => true)
141
+ assert_caught_and_not_sent
142
+ end
143
+
144
+ should "not deliver notices from actions that don't raise" do
145
+ controller = process_action { render :text => 'Hello' }
146
+ assert_caught_and_not_sent
147
+ assert_equal 'Hello', controller.response.body
148
+ end
149
+
150
+ should "not deliver ignored exceptions raised by actions" do
151
+ ignore(RuntimeError)
152
+ process_action_with_automatic_notification
153
+ assert_caught_and_not_sent
154
+ end
155
+
156
+ should "deliver ignored exception raised manually" do
157
+ ignore(RuntimeError)
158
+ process_action_with_manual_notification
159
+ assert_caught_and_sent
160
+ end
161
+
162
+ should "deliver manually sent notices in public requests" do
163
+ process_action_with_manual_notification
164
+ assert_caught_and_sent
165
+ end
166
+
167
+ should "not deliver manually sent notices in local requests" do
168
+ process_action_with_manual_notification(:local => true)
169
+ assert_caught_and_not_sent
170
+ end
171
+
172
+ should "not deliver manually sent notices when all requests are local" do
173
+ process_action_with_manual_notification(:all_local => true)
174
+ assert_caught_and_not_sent
175
+ end
176
+
177
+ should "continue with default behavior after delivering an exception" do
178
+ controller = process_action_with_automatic_notification(:public => true)
179
+ # TODO: can we test this without stubbing?
180
+ assert_received(controller, :rescue_action_in_public_without_hoptoad)
181
+ end
182
+
183
+ should "not create actions from Hoptoad methods" do
184
+ controller = build_controller_class.new
185
+ assert_equal [], HoptoadNotifier::Rails::ActionControllerCatcher.instance_methods
186
+ end
187
+
188
+ should "ignore exceptions when user agent is being ignored by regular expression" do
189
+ HoptoadNotifier.configuration.ignore_user_agent_only = [/Ignored/]
190
+ process_action_with_automatic_notification(:user_agent => 'ShouldBeIgnored')
191
+ assert_caught_and_not_sent
192
+ end
193
+
194
+ should "ignore exceptions when user agent is being ignored by string" do
195
+ HoptoadNotifier.configuration.ignore_user_agent_only = ['IgnoredUserAgent']
196
+ process_action_with_automatic_notification(:user_agent => 'IgnoredUserAgent')
197
+ assert_caught_and_not_sent
198
+ end
199
+
200
+ should "not ignore exceptions when user agent is not being ignored" do
201
+ HoptoadNotifier.configuration.ignore_user_agent_only = ['IgnoredUserAgent']
202
+ process_action_with_automatic_notification(:user_agent => 'NonIgnoredAgent')
203
+ assert_caught_and_sent
204
+ end
205
+
206
+ should "send session data for manual notifications" do
207
+ data = { 'one' => 'two' }
208
+ process_action_with_manual_notification(:session => data)
209
+ assert_sent_hash data, "/notice/request/session"
210
+ end
211
+
212
+ should "send session data for automatic notification" do
213
+ data = { 'one' => 'two' }
214
+ process_action_with_automatic_notification(:session => data)
215
+ assert_sent_hash data, "/notice/request/session"
216
+ end
217
+
218
+ should "send request data for manual notification" do
219
+ params = { 'controller' => "hoptoad_test", 'action' => "index" }
220
+ controller = process_action_with_manual_notification(:params => params)
221
+ assert_sent_request_info_for controller.request
222
+ end
223
+
224
+ should "send request data for manual notification with non-standard port" do
225
+ params = { 'controller' => "hoptoad_test", 'action' => "index" }
226
+ controller = process_action_with_manual_notification(:params => params, :port => 81)
227
+ assert_sent_request_info_for controller.request
228
+ end
229
+
230
+ should "send request data for automatic notification" do
231
+ params = { 'controller' => "hoptoad_test", 'action' => "index" }
232
+ controller = process_action_with_automatic_notification(:params => params)
233
+ assert_sent_request_info_for controller.request
234
+ end
235
+
236
+ should "send request data for automatic notification with non-standard port" do
237
+ params = { 'controller' => "hoptoad_test", 'action' => "index" }
238
+ controller = process_action_with_automatic_notification(:params => params, :port => 81)
239
+ assert_sent_request_info_for controller.request
240
+ end
241
+
242
+ should "use standard rails logging filters on params and env" do
243
+ filtered_params = { "abc" => "123",
244
+ "def" => "456",
245
+ "ghi" => "[FILTERED]" }
246
+ ENV['ghi'] = 'abc'
247
+ filtered_env = { 'ghi' => '[FILTERED]' }
248
+ filtered_cgi = { 'REQUEST_METHOD' => '[FILTERED]' }
249
+
250
+ process_action_with_automatic_notification(:filters => [:ghi, :request_method],
251
+ :params => { "abc" => "123",
252
+ "def" => "456",
253
+ "ghi" => "789" })
254
+ assert_sent_hash filtered_params, '/notice/request/params'
255
+ assert_sent_hash filtered_cgi, '/notice/request/cgi-data'
256
+ end
257
+
258
+ context "for a local error with development lookup enabled" do
259
+ setup do
260
+ HoptoadNotifier.configuration.development_lookup = true
261
+ HoptoadNotifier.stubs(:build_lookup_hash_for).returns({ :awesome => 2 })
262
+
263
+ @controller = process_action_with_automatic_notification(:local => true)
264
+ @response = @controller.response
265
+ end
266
+
267
+ should "append custom CSS and JS to response body for a local error" do
268
+ assert_match /text\/css/, @response.body
269
+ assert_match /text\/javascript/, @response.body
270
+ end
271
+
272
+ should "contain host, API key and notice JSON" do
273
+ assert_match HoptoadNotifier.configuration.host.to_json, @response.body
274
+ assert_match HoptoadNotifier.configuration.api_key.to_json, @response.body
275
+ assert_match ({ :awesome => 2 }).to_json, @response.body
276
+ end
277
+ end
278
+
279
+ context "for a local error with development lookup disabled" do
280
+ setup do
281
+ HoptoadNotifier.configuration.development_lookup = false
282
+
283
+ @controller = process_action_with_automatic_notification(:local => true)
284
+ @response = @controller.response
285
+ end
286
+
287
+ should "not append custom CSS and JS to response for a local error" do
288
+ assert_no_match /text\/css/, @response.body
289
+ assert_no_match /text\/javascript/, @response.body
290
+ end
291
+ end
292
+
293
+ should "call session.to_hash if available" do
294
+ hash_data = {:key => :value}
295
+
296
+ session = ActionController::TestSession.new
297
+ ActionController::TestSession.stubs(:new).returns(session)
298
+ session.stubs(:to_hash).returns(hash_data)
299
+
300
+ process_action_with_automatic_notification
301
+ assert_received(session, :to_hash)
302
+ assert_received(session, :data) { |expect| expect.never }
303
+ assert_caught_and_sent
304
+ end
305
+
306
+ should "call session.data if session.to_hash is undefined" do
307
+ hash_data = {:key => :value}
308
+
309
+ session = ActionController::TestSession.new
310
+ ActionController::TestSession.stubs(:new).returns(session)
311
+ session.stubs(:data).returns(hash_data)
312
+ if session.respond_to?(:to_hash)
313
+ class << session
314
+ undef to_hash
315
+ end
316
+ end
317
+
318
+ process_action_with_automatic_notification
319
+ assert_received(session, :to_hash) { |expect| expect.never }
320
+ assert_received(session, :data) { |expect| expect.at_least_once }
321
+ assert_caught_and_sent
322
+ end
323
+
324
+ end
@@ -0,0 +1,208 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class ConfigurationTest < Test::Unit::TestCase
4
+
5
+ include DefinesConstants
6
+
7
+ should "provide default values" do
8
+ assert_config_default :proxy_host, nil
9
+ assert_config_default :proxy_port, nil
10
+ assert_config_default :proxy_user, nil
11
+ assert_config_default :proxy_pass, nil
12
+ assert_config_default :project_root, nil
13
+ assert_config_default :environment_name, nil
14
+ assert_config_default :logger, nil
15
+ assert_config_default :notifier_version, HoptoadNotifier::VERSION
16
+ assert_config_default :notifier_name, 'Hoptoad Notifier'
17
+ assert_config_default :notifier_url, 'http://hoptoadapp.com'
18
+ assert_config_default :secure, false
19
+ assert_config_default :host, 'hoptoadapp.com'
20
+ assert_config_default :http_open_timeout, 2
21
+ assert_config_default :http_read_timeout, 5
22
+ assert_config_default :ignore_by_filters, []
23
+ assert_config_default :ignore_user_agent, []
24
+ assert_config_default :params_filters,
25
+ HoptoadNotifier::Configuration::DEFAULT_PARAMS_FILTERS
26
+ assert_config_default :backtrace_filters,
27
+ HoptoadNotifier::Configuration::DEFAULT_BACKTRACE_FILTERS
28
+ assert_config_default :ignore,
29
+ HoptoadNotifier::Configuration::IGNORE_DEFAULT
30
+ assert_config_default :development_lookup, true
31
+ assert_config_default :framework, 'Standalone'
32
+ end
33
+
34
+ should "provide default values for secure connections" do
35
+ config = HoptoadNotifier::Configuration.new
36
+ config.secure = true
37
+ assert_equal 443, config.port
38
+ assert_equal 'https', config.protocol
39
+ end
40
+
41
+ should "provide default values for insecure connections" do
42
+ config = HoptoadNotifier::Configuration.new
43
+ config.secure = false
44
+ assert_equal 80, config.port
45
+ assert_equal 'http', config.protocol
46
+ end
47
+
48
+ should "not cache inferred ports" do
49
+ config = HoptoadNotifier::Configuration.new
50
+ config.secure = false
51
+ config.port
52
+ config.secure = true
53
+ assert_equal 443, config.port
54
+ end
55
+
56
+ should "allow values to be overwritten" do
57
+ assert_config_overridable :proxy_host
58
+ assert_config_overridable :proxy_port
59
+ assert_config_overridable :proxy_user
60
+ assert_config_overridable :proxy_pass
61
+ assert_config_overridable :secure
62
+ assert_config_overridable :host
63
+ assert_config_overridable :port
64
+ assert_config_overridable :http_open_timeout
65
+ assert_config_overridable :http_read_timeout
66
+ assert_config_overridable :project_root
67
+ assert_config_overridable :notifier_version
68
+ assert_config_overridable :notifier_name
69
+ assert_config_overridable :notifier_url
70
+ assert_config_overridable :environment_name
71
+ assert_config_overridable :development_lookup
72
+ assert_config_overridable :logger
73
+ end
74
+
75
+ should "have an api key" do
76
+ assert_config_overridable :api_key
77
+ end
78
+
79
+ should "act like a hash" do
80
+ config = HoptoadNotifier::Configuration.new
81
+ hash = config.to_hash
82
+ [:api_key, :backtrace_filters, :development_environments,
83
+ :environment_name, :host, :http_open_timeout,
84
+ :http_read_timeout, :ignore, :ignore_by_filters, :ignore_user_agent,
85
+ :notifier_name, :notifier_url, :notifier_version, :params_filters,
86
+ :project_root, :port, :protocol, :proxy_host, :proxy_pass, :proxy_port,
87
+ :proxy_user, :secure, :development_lookup].each do |option|
88
+ assert_equal config[option], hash[option], "Wrong value for #{option}"
89
+ end
90
+ end
91
+
92
+ should "be mergable" do
93
+ config = HoptoadNotifier::Configuration.new
94
+ hash = config.to_hash
95
+ assert_equal hash.merge(:key => 'value'), config.merge(:key => 'value')
96
+ end
97
+
98
+ should "allow param filters to be appended" do
99
+ assert_appends_value :params_filters
100
+ end
101
+
102
+ should "warn when attempting to read environment filters" do
103
+ config = HoptoadNotifier::Configuration.new
104
+ config.
105
+ expects(:warn).
106
+ with(regexp_matches(/deprecated/i))
107
+ assert_equal [], config.environment_filters
108
+ end
109
+
110
+ should "allow ignored user agents to be appended" do
111
+ assert_appends_value :ignore_user_agent
112
+ end
113
+
114
+ should "allow backtrace filters to be appended" do
115
+ assert_appends_value(:backtrace_filters) do |config|
116
+ new_filter = lambda {}
117
+ config.filter_backtrace(&new_filter)
118
+ new_filter
119
+ end
120
+ end
121
+
122
+ should "allow ignore by filters to be appended" do
123
+ assert_appends_value(:ignore_by_filters) do |config|
124
+ new_filter = lambda {}
125
+ config.ignore_by_filter(&new_filter)
126
+ new_filter
127
+ end
128
+ end
129
+
130
+ should "allow ignored exceptions to be appended" do
131
+ config = HoptoadNotifier::Configuration.new
132
+ original_filters = config.ignore.dup
133
+ new_filter = 'hello'
134
+ config.ignore << new_filter
135
+ assert_same_elements original_filters + [new_filter], config.ignore
136
+ end
137
+
138
+ should "allow ignored exceptions to be replaced" do
139
+ assert_replaces(:ignore, :ignore_only=)
140
+ end
141
+
142
+ should "allow ignored user agents to be replaced" do
143
+ assert_replaces(:ignore_user_agent, :ignore_user_agent_only=)
144
+ end
145
+
146
+ should "use development and test as development environments by default" do
147
+ config = HoptoadNotifier::Configuration.new
148
+ assert_same_elements %w(development test cucumber), config.development_environments
149
+ end
150
+
151
+ should "be public in a public environment" do
152
+ config = HoptoadNotifier::Configuration.new
153
+ config.development_environments = %w(development)
154
+ config.environment_name = 'production'
155
+ assert config.public?
156
+ end
157
+
158
+ should "not be public in a development environment" do
159
+ config = HoptoadNotifier::Configuration.new
160
+ config.development_environments = %w(staging)
161
+ config.environment_name = 'staging'
162
+ assert !config.public?
163
+ end
164
+
165
+ should "be public without an environment name" do
166
+ config = HoptoadNotifier::Configuration.new
167
+ assert config.public?
168
+ end
169
+
170
+ should "use the assigned logger if set" do
171
+ config = HoptoadNotifier::Configuration.new
172
+ config.logger = "CUSTOM LOGGER"
173
+ assert_equal "CUSTOM LOGGER", config.logger
174
+ end
175
+
176
+ def assert_config_default(option, default_value, config = nil)
177
+ config ||= HoptoadNotifier::Configuration.new
178
+ assert_equal default_value, config.send(option)
179
+ end
180
+
181
+ def assert_config_overridable(option, value = 'a value')
182
+ config = HoptoadNotifier::Configuration.new
183
+ config.send(:"#{option}=", value)
184
+ assert_equal value, config.send(option)
185
+ end
186
+
187
+ def assert_appends_value(option, &block)
188
+ config = HoptoadNotifier::Configuration.new
189
+ original_values = config.send(option).dup
190
+ block ||= lambda do |config|
191
+ new_value = 'hello'
192
+ config.send(option) << new_value
193
+ new_value
194
+ end
195
+ new_value = block.call(config)
196
+ assert_same_elements original_values + [new_value], config.send(option)
197
+ end
198
+
199
+ def assert_replaces(option, setter)
200
+ config = HoptoadNotifier::Configuration.new
201
+ new_value = 'hello'
202
+ config.send(setter, [new_value])
203
+ assert_equal [new_value], config.send(option)
204
+ config.send(setter, new_value)
205
+ assert_equal [new_value], config.send(option)
206
+ end
207
+
208
+ end