airbrake 3.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. data/.gitignore +18 -0
  2. data/.yardopts +3 -0
  3. data/CHANGELOG +441 -0
  4. data/Gemfile +3 -0
  5. data/INSTALL +25 -0
  6. data/MIT-LICENSE +22 -0
  7. data/README.md +431 -0
  8. data/README_FOR_HEROKU_ADDON.md +93 -0
  9. data/Rakefile +188 -0
  10. data/SUPPORTED_RAILS_VERSIONS +14 -0
  11. data/TESTING.md +26 -0
  12. data/airbrake.gemspec +33 -0
  13. data/features/metal.feature +23 -0
  14. data/features/rack.feature +27 -0
  15. data/features/rails.feature +254 -0
  16. data/features/rails_with_js_notifier.feature +78 -0
  17. data/features/rake.feature +23 -0
  18. data/features/sinatra.feature +33 -0
  19. data/features/step_definitions/airbrake_shim.rb.template +15 -0
  20. data/features/step_definitions/file_steps.rb +10 -0
  21. data/features/step_definitions/metal_steps.rb +23 -0
  22. data/features/step_definitions/rack_steps.rb +20 -0
  23. data/features/step_definitions/rails_application_steps.rb +401 -0
  24. data/features/step_definitions/rake_steps.rb +17 -0
  25. data/features/support/airbrake_shim.rb.template +15 -0
  26. data/features/support/env.rb +18 -0
  27. data/features/support/matchers.rb +35 -0
  28. data/features/support/rails.rb +181 -0
  29. data/features/support/rake/Rakefile +57 -0
  30. data/features/support/terminal.rb +103 -0
  31. data/features/user_informer.feature +63 -0
  32. data/generators/airbrake/airbrake_generator.rb +90 -0
  33. data/generators/airbrake/lib/insert_commands.rb +34 -0
  34. data/generators/airbrake/lib/rake_commands.rb +24 -0
  35. data/generators/airbrake/templates/airbrake_tasks.rake +25 -0
  36. data/generators/airbrake/templates/capistrano_hook.rb +6 -0
  37. data/generators/airbrake/templates/initializer.rb +6 -0
  38. data/install.rb +1 -0
  39. data/lib/airbrake.rb +150 -0
  40. data/lib/airbrake/backtrace.rb +100 -0
  41. data/lib/airbrake/capistrano.rb +21 -0
  42. data/lib/airbrake/configuration.rb +247 -0
  43. data/lib/airbrake/notice.rb +348 -0
  44. data/lib/airbrake/rack.rb +42 -0
  45. data/lib/airbrake/rails.rb +41 -0
  46. data/lib/airbrake/rails/action_controller_catcher.rb +30 -0
  47. data/lib/airbrake/rails/controller_methods.rb +68 -0
  48. data/lib/airbrake/rails/error_lookup.rb +33 -0
  49. data/lib/airbrake/rails/javascript_notifier.rb +42 -0
  50. data/lib/airbrake/rails3_tasks.rb +82 -0
  51. data/lib/airbrake/railtie.rb +33 -0
  52. data/lib/airbrake/rake_handler.rb +65 -0
  53. data/lib/airbrake/sender.rb +83 -0
  54. data/lib/airbrake/shared_tasks.rb +30 -0
  55. data/lib/airbrake/tasks.rb +83 -0
  56. data/lib/airbrake/user_informer.rb +25 -0
  57. data/lib/airbrake/version.rb +3 -0
  58. data/lib/airbrake_tasks.rb +50 -0
  59. data/lib/rails/generators/airbrake/airbrake_generator.rb +96 -0
  60. data/lib/templates/javascript_notifier.erb +13 -0
  61. data/lib/templates/rescue.erb +91 -0
  62. data/rails/init.rb +1 -0
  63. data/script/integration_test.rb +38 -0
  64. data/test/airbrake_2_2.xsd +78 -0
  65. data/test/airbrake_tasks_test.rb +163 -0
  66. data/test/backtrace_test.rb +163 -0
  67. data/test/catcher_test.rb +333 -0
  68. data/test/configuration_test.rb +216 -0
  69. data/test/helper.rb +251 -0
  70. data/test/javascript_notifier_test.rb +52 -0
  71. data/test/logger_test.rb +85 -0
  72. data/test/notice_test.rb +459 -0
  73. data/test/notifier_test.rb +235 -0
  74. data/test/rack_test.rb +58 -0
  75. data/test/rails_initializer_test.rb +36 -0
  76. data/test/recursion_test.rb +10 -0
  77. data/test/sender_test.rb +193 -0
  78. data/test/user_informer_test.rb +29 -0
  79. metadata +365 -0
@@ -0,0 +1,78 @@
1
+ Feature: Install the Gem in a Rails application and enable the JavaScript notifier
2
+
3
+ Background:
4
+ Given I have built and installed the "airbrake" gem
5
+
6
+ Scenario: Include the Javascript notifier when enabled
7
+ When I generate a new Rails application
8
+ And I configure the Airbrake shim
9
+ And I configure my application to require the "airbrake" gem
10
+ When I configure the notifier to use the following configuration lines:
11
+ """
12
+ config.api_key = "myapikey"
13
+ """
14
+ And I define a response for "TestController#index":
15
+ """
16
+ render :inline => '<html><head profile="http://example.com"><%= airbrake_javascript_notifier %></head><body></body></html>'
17
+ """
18
+ And I route "/test/index" to "test#index"
19
+ And I perform a request to "http://example.com:123/test/index"
20
+ Then I should see the notifier JavaScript for the following:
21
+ | api_key | environment | host |
22
+ | myapikey | production | airbrakeapp.com |
23
+ And the notifier JavaScript should provide the following errorDefaults:
24
+ | url | component | action |
25
+ | http://example.com:123/test/index | test | index |
26
+
27
+ Scenario: Include the Javascript notifier when enabled using custom configuration settings
28
+ When I generate a new Rails application
29
+ And I configure the Airbrake shim
30
+ And I configure my application to require the "airbrake" gem
31
+ When I configure the notifier to use the following configuration lines:
32
+ """
33
+ config.api_key = "myapikey!"
34
+ config.host = "myairbrake.com"
35
+ config.port = 3001
36
+ """
37
+ And I define a response for "TestController#index":
38
+ """
39
+ render :inline => '<html><head><%= airbrake_javascript_notifier %></head><body></body></html>'
40
+ """
41
+ And I route "/test/index" to "test#index"
42
+ And I perform a request to "http://example.com:123/test/index"
43
+ Then I should see the notifier JavaScript for the following:
44
+ | api_key | environment | host |
45
+ | myapikey! | production | myairbrake.com:3001 |
46
+
47
+ Scenario: Don't include the Javascript notifier by default
48
+ When I generate a new Rails application
49
+ And I configure the Airbrake shim
50
+ And I configure my application to require the "airbrake" gem
51
+ When I configure the notifier to use the following configuration lines:
52
+ """
53
+ config.api_key = "myapikey!"
54
+ """
55
+ And I define a response for "TestController#index":
56
+ """
57
+ render :inline => "<html><head></head><body></body></html>"
58
+ """
59
+ And I route "/test/index" to "test#index"
60
+ And I perform a request to "http://example.com:123/test/index"
61
+ Then I should not see notifier JavaScript
62
+
63
+ Scenario: Don't include the Javascript notifier when enabled in non-public environments
64
+ When I generate a new Rails application
65
+ And I configure the Airbrake shim
66
+ And I configure my application to require the "airbrake" gem
67
+ When I configure the notifier to use the following configuration lines:
68
+ """
69
+ config.api_key = "myapikey!"
70
+ config.environment_name = 'test'
71
+ """
72
+ And I define a response for "TestController#index":
73
+ """
74
+ render :inline => '<html><head><%= airbrake_javascript_notifier %></head><body></body></html>'
75
+ """
76
+ And I route "/test/index" to "test#index"
77
+ And I perform a request to "http://example.com:123/test/index" in the "test" environment
78
+ Then I should not see notifier JavaScript
@@ -0,0 +1,23 @@
1
+ Feature: Use the Gem to catch errors in a Rake application
2
+ Background:
3
+ Given I have built and installed the "airbrake" gem
4
+
5
+ Scenario: Catching exceptions in Rake
6
+ When I run rake with airbrake
7
+ Then Airbrake should catch the exception
8
+
9
+ Scenario: Disabling Rake exception catcher
10
+ When I run rake with airbrake disabled
11
+ Then Airbrake should not catch the exception
12
+
13
+ Scenario: Autodetect, running from terminal
14
+ When I run rake with airbrake autodetect from terminal
15
+ Then Airbrake should not catch the exception
16
+
17
+ Scenario: Autodetect, not running from terminal
18
+ When I run rake with airbrake autodetect not from terminal
19
+ Then Airbrake should catch the exception
20
+
21
+ Scenario: Sendind the correct component name
22
+ When I run rake with airbrake
23
+ Then Airbrake should send the rake command line as the component name
@@ -0,0 +1,33 @@
1
+ Feature: Use the notifier in a Sinatra app
2
+
3
+ Background:
4
+ Given I have built and installed the "airbrake" gem
5
+
6
+ Scenario: Rescue an exception in a Sinatra app
7
+ Given the following Rack app:
8
+ """
9
+ require 'sinatra/base'
10
+ require 'airbrake'
11
+
12
+ Airbrake.configure do |config|
13
+ config.api_key = 'my_api_key'
14
+ end
15
+
16
+ class FontaneApp < Sinatra::Base
17
+ use Airbrake::Rack
18
+ enable :raise_errors
19
+
20
+ get "/test/index" do
21
+ raise "Sinatra has left the building"
22
+ end
23
+ end
24
+
25
+ app = FontaneApp
26
+ """
27
+ When I perform a Rack request to "http://example.com:123/test/index?param=value"
28
+ Then I should receive the following Airbrake notification:
29
+ | error message | RuntimeError: Sinatra has left the building |
30
+ | error class | RuntimeError |
31
+ | parameters | param: value |
32
+ | url | http://example.com:123/test/index?param=value |
33
+
@@ -0,0 +1,15 @@
1
+ require 'sham_rack'
2
+
3
+ ShamRack.at("airbrakeapp.com") do |env|
4
+ xml = env['rack.input'].read
5
+ puts "Recieved the following exception:\n#{xml}"
6
+ response = <<-end_xml
7
+ <?xml version="1.0" encoding="UTF-8"?>
8
+ <notice>
9
+ <error-id type="integer">3799307</error-id>
10
+ <url>http://sample.airbrakeapp.com/errors/3799307/notices/643732254</url>
11
+ <id type="integer">643732254</id>
12
+ </notice>
13
+ end_xml
14
+ ["200 OK", { "Content-type" => "text/xml" }, response]
15
+ end
@@ -0,0 +1,10 @@
1
+ Then /^"([^\"]*)" should not contain text of "([^\"]*)"$/ do |target_file, contents_file|
2
+ notifier_root = File.join(File.dirname(__FILE__), '..', '..')
3
+ full_path_contents = File.join(notifier_root, contents_file)
4
+ contents_text = File.open(full_path_contents).read
5
+
6
+ full_path_target = File.join(rails_root, target_file)
7
+ target_text = File.open(full_path_target).read
8
+
9
+ target_text.should_not include(contents_text)
10
+ end
@@ -0,0 +1,23 @@
1
+ When /^I define a Metal endpoint called "([^\"]*)":$/ do |class_name, definition|
2
+ FileUtils.mkdir_p(File.join(rails_root, 'app', 'metal'))
3
+ file_name = File.join(rails_root, 'app', 'metal', "#{class_name.underscore}.rb")
4
+ File.open(file_name, "w") do |file|
5
+ file.puts "class #{class_name}"
6
+ file.puts definition
7
+ file.puts "end"
8
+ end
9
+ When %{the metal endpoint "#{class_name}" is mounted in the Rails 3 routes.rb} if rails3?
10
+ end
11
+
12
+ When /^the metal endpoint "([^\"]*)" is mounted in the Rails 3 routes.rb$/ do |class_name|
13
+ routesrb = File.join(rails_root, "config", "routes.rb")
14
+ routes = IO.readlines(routesrb)
15
+ rack_route = "match '/metal(/*other)' => #{class_name}"
16
+ routes = routes[0..-2] + [rack_route, routes[-1]]
17
+ File.open(routesrb, "w") do |f|
18
+ f.puts "require 'app/metal/#{class_name.underscore}'"
19
+ routes.each do |route_line|
20
+ f.puts route_line
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,20 @@
1
+ Given /^the following Rack app:$/ do |definition|
2
+ File.open(RACK_FILE, 'w') { |file| file.write(definition) }
3
+ end
4
+
5
+ When /^I perform a Rack request to "([^\"]*)"$/ do |url|
6
+ shim_file = File.join(PROJECT_ROOT, 'features', 'support', 'airbrake_shim.rb.template')
7
+ request_file = File.join(TEMP_DIR, 'rack_request.rb')
8
+ File.open(request_file, 'w') do |file|
9
+ file.puts "require 'rubygems'"
10
+ file.puts IO.read(shim_file)
11
+ file.puts IO.read(RACK_FILE)
12
+ file.puts "env = Rack::MockRequest.env_for(#{url.inspect})"
13
+ file.puts "status, headers, body = app.call(env)"
14
+ file.puts %{puts "HTTP \#{status}"}
15
+ file.puts %{headers.each { |key, value| puts "\#{key}: \#{value}"}}
16
+ file.puts "body.each { |part| print part }"
17
+ end
18
+ @terminal.run("ruby #{request_file}")
19
+ end
20
+
@@ -0,0 +1,401 @@
1
+ require 'uri'
2
+ require 'active_support/core_ext/string/inflections'
3
+
4
+ When /^I generate a new Rails application$/ do
5
+ @terminal.cd(TEMP_DIR)
6
+ version_string = ENV['RAILS_VERSION']
7
+
8
+ rails3 = version_string =~ /^3/
9
+
10
+ if rails3
11
+ rails_create_command = 'new'
12
+ else
13
+ rails_create_command = ''
14
+ end
15
+
16
+ load_rails = <<-RUBY
17
+ gem 'rails', '#{version_string}'; \
18
+ load Gem.bin_path('rails', 'rails', '#{version_string}')
19
+ RUBY
20
+
21
+ @terminal.run(%{ruby -rrubygems -rthread -e "#{load_rails.strip!}" #{rails_create_command} rails_root})
22
+ if rails_root_exists?
23
+ @terminal.echo("Generated a Rails #{version_string} application")
24
+ else
25
+ raise "Unable to generate a Rails application:\n#{@terminal.output}"
26
+ end
27
+ require_thread
28
+ When %{I configure my application to require the "rake" gem with version "0.8.7"}
29
+ config_gem_dependencies unless rails3
30
+ end
31
+
32
+ When /^I run the airbrake generator with "([^\"]*)"$/ do |generator_args|
33
+ if rails3?
34
+ When %{I run "script/rails generate airbrake #{generator_args}"}
35
+ else
36
+ When %{I run "script/generate airbrake #{generator_args}"}
37
+ end
38
+ end
39
+
40
+ When /^I print the console output$/ do
41
+ puts @terminal.output
42
+ end
43
+
44
+ Given /^I have installed the "([^\"]*)" gem$/ do |gem_name|
45
+ @terminal.install_gem(gem_name)
46
+ end
47
+
48
+ Given /^I have built and installed the "([^\"]*)" gem$/ do |gem_name|
49
+ @terminal.build_and_install_gem(File.join(PROJECT_ROOT, "#{gem_name}.gemspec"))
50
+ end
51
+
52
+ When /^I configure my application to require the "([^\"]*)" gem(?: with version "(.+)")?$/ do |gem_name, version|
53
+ if rails_manages_gems?
54
+ config_gem(gem_name, version)
55
+ elsif bundler_manages_gems?
56
+ bundle_gem(gem_name, version)
57
+ else
58
+ File.open(environment_path, 'a') do |file|
59
+ file.puts
60
+ file.puts("require 'airbrake'")
61
+ file.puts("require 'airbrake/rails'")
62
+ end
63
+
64
+ unless rails_finds_generators_in_gems?
65
+ FileUtils.cp_r(File.join(PROJECT_ROOT, 'generators'), File.join(rails_root, 'lib'))
66
+ end
67
+ end
68
+ end
69
+
70
+ When /^I run "([^\"]*)"$/ do |command|
71
+ @terminal.cd(rails_root)
72
+ @terminal.run(command)
73
+ end
74
+
75
+ Then /^I should receive a Airbrake notification$/ do
76
+ Then %{I should see "[Airbrake] Success: Net::HTTPOK"}
77
+ end
78
+
79
+ Then /^I should receive two Airbrake notifications$/ do
80
+ @terminal.output.scan(/\[Airbrake\] Success: Net::HTTPOK/).size.should == 2
81
+ end
82
+
83
+ When /^I configure the Airbrake shim$/ do
84
+ if bundler_manages_gems?
85
+ bundle_gem("sham_rack")
86
+ end
87
+
88
+ shim_file = File.join(PROJECT_ROOT, 'features', 'support', 'airbrake_shim.rb.template')
89
+ if rails_supports_initializers?
90
+ target = File.join(rails_root, 'config', 'initializers', 'airbrake_shim.rb')
91
+ FileUtils.cp(shim_file, target)
92
+ else
93
+ File.open(environment_path, 'a') do |file|
94
+ file.puts
95
+ file.write IO.read(shim_file)
96
+ end
97
+ end
98
+ end
99
+
100
+ When /^I configure the notifier to use "([^\"]*)" as an API key$/ do |api_key|
101
+ steps %{
102
+ When I configure the notifier to use the following configuration lines:
103
+ """
104
+ config.api_key = #{api_key.inspect}
105
+ """
106
+ }
107
+ end
108
+
109
+ When /^I configure the notifier to use the following configuration lines:$/ do |configuration_lines|
110
+ if rails_manages_gems?
111
+ requires = ''
112
+ else
113
+ requires = "require 'airbrake'"
114
+ end
115
+
116
+ initializer_code = <<-EOF
117
+ #{requires}
118
+ Airbrake.configure do |config|
119
+ #{configuration_lines}
120
+ end
121
+ EOF
122
+
123
+ if rails_supports_initializers?
124
+ File.open(rails_initializer_file, 'w') { |file| file.write(initializer_code) }
125
+ else
126
+ File.open(environment_path, 'a') do |file|
127
+ file.puts
128
+ file.puts initializer_code
129
+ end
130
+ end
131
+
132
+ end
133
+
134
+ def rails_initializer_file
135
+ File.join(rails_root, 'config', 'initializers', 'airbrake.rb')
136
+ end
137
+
138
+ def rails_non_initializer_airbrake_config_file
139
+ File.join(rails_root, 'config', 'airbrake.rb')
140
+ end
141
+
142
+ Then /^I should see "([^\"]*)"$/ do |expected_text|
143
+ unless @terminal.output.include?(expected_text)
144
+ raise("Got terminal output:\n#{@terminal.output}\n\nExpected output:\n#{expected_text}")
145
+ end
146
+ end
147
+
148
+ Then /^I should not see "([^\"]*)"$/ do |unexpected_text|
149
+ if @terminal.output.include?(unexpected_text)
150
+ raise("Got terminal output:\n#{@terminal.output}\n\nDid not expect the following output:\n#{unexpected_text}")
151
+ end
152
+ end
153
+
154
+ When /^I uninstall the "([^\"]*)" gem$/ do |gem_name|
155
+ @terminal.uninstall_gem(gem_name)
156
+ end
157
+
158
+ When /^I unpack the "([^\"]*)" gem$/ do |gem_name|
159
+ if bundler_manages_gems?
160
+ @terminal.cd(rails_root)
161
+ @terminal.run("bundle pack")
162
+ elsif rails_manages_gems?
163
+ @terminal.cd(rails_root)
164
+ @terminal.run("rake gems:unpack GEM=#{gem_name}")
165
+ else
166
+ vendor_dir = File.join(rails_root, 'vendor', 'gems')
167
+ FileUtils.mkdir_p(vendor_dir)
168
+ @terminal.cd(vendor_dir)
169
+ @terminal.run("gem unpack #{gem_name}")
170
+ gem_path =
171
+ Dir.glob(File.join(rails_root, 'vendor', 'gems', "#{gem_name}-*", 'lib')).first
172
+ File.open(environment_path, 'a') do |file|
173
+ file.puts
174
+ file.puts("$: << #{gem_path.inspect}")
175
+ end
176
+ end
177
+ end
178
+
179
+ When /^I install cached gems$/ do
180
+ if bundler_manages_gems?
181
+ When %{I run "bundle install"}
182
+ end
183
+ end
184
+
185
+ When /^I install the "([^\"]*)" plugin$/ do |plugin_name|
186
+ FileUtils.mkdir_p("#{rails_root}/vendor/plugins/#{plugin_name}")
187
+ end
188
+
189
+ When /^I define a response for "([^\"]*)":$/ do |controller_and_action, definition|
190
+ controller_class_name, action = controller_and_action.split('#')
191
+ controller_name = controller_class_name.underscore
192
+ controller_file_name = File.join(rails_root, 'app', 'controllers', "#{controller_name}.rb")
193
+ File.open(controller_file_name, "w") do |file|
194
+ file.puts "class #{controller_class_name} < ApplicationController"
195
+ file.puts "def consider_all_requests_local; false; end"
196
+ file.puts "def local_request?; false; end"
197
+ file.puts "def #{action}"
198
+ file.puts definition
199
+ file.puts "end"
200
+ file.puts "end"
201
+ end
202
+ end
203
+
204
+ When /^I perform a request to "([^\"]*)"$/ do |uri|
205
+ perform_request(uri)
206
+ end
207
+
208
+ When /^I perform a request to "([^\"]*)" in the "([^\"]*)" environment$/ do |uri, environment|
209
+ perform_request(uri, environment)
210
+ end
211
+
212
+ Given /^the response page for a "([^\"]*)" error is$/ do |error, html|
213
+ File.open(File.join(rails_root, "public", "#{error}.html"), "w") do |file|
214
+ file.write(html)
215
+ end
216
+ end
217
+
218
+ Then /^I should receive the following Airbrake notification:$/ do |table|
219
+ exceptions = @terminal.output.scan(%r{Recieved the following exception:\n([^\n]*)\n}m)
220
+ exceptions.should_not be_empty
221
+
222
+ xml = exceptions.last[0]
223
+ doc = Nokogiri::XML.parse(xml)
224
+
225
+ hash = table.transpose.hashes.first
226
+
227
+ doc.should have_content('//error/message', hash['error message'])
228
+ doc.should have_content('//error/class', hash['error class'])
229
+ doc.should have_content('//request/url', hash['url'])
230
+
231
+ doc.should have_content('//component', hash['component']) if hash['component']
232
+ doc.should have_content('//action', hash['action']) if hash['action']
233
+ doc.should have_content('//server-environment/project-root', hash['project-root']) if hash['project-root']
234
+
235
+ if hash['session']
236
+ session_key, session_value = hash['session'].split(': ')
237
+ doc.should have_content('//request/session/var/@key', session_key)
238
+ doc.should have_content('//request/session/var', session_value)
239
+ end
240
+
241
+ if hash['parameters']
242
+ param_key, param_value = hash['parameters'].split(': ')
243
+ doc.should have_content('//request/params/var/@key', param_key)
244
+ doc.should have_content('//request/params/var', param_value)
245
+ end
246
+ end
247
+
248
+ Then /^I should see the Rails version$/ do
249
+ Then %{I should see "[Rails: #{rails_version}]"}
250
+ end
251
+
252
+ Then /^I should see that "([^\"]*)" is not considered a framework gem$/ do |gem_name|
253
+ Then %{I should not see "[R] #{gem_name}"}
254
+ end
255
+
256
+ Then /^the command should have run successfully$/ do
257
+ @terminal.status.exitstatus.should == 0
258
+ end
259
+
260
+ When /^I route "([^\"]*)" to "([^\"]*)"$/ do |path, controller_action_pair|
261
+ route = if rails3?
262
+ %(match "#{path}", :to => "#{controller_action_pair}")
263
+ else
264
+ controller, action = controller_action_pair.split('#')
265
+ %(map.connect "#{path}", :controller => "#{controller}", :action => "#{action}")
266
+ end
267
+ routes_file = File.join(rails_root, "config", "routes.rb")
268
+ File.open(routes_file, "r+") do |file|
269
+ content = file.read
270
+ content.gsub!(/^end$/, " #{route}\nend")
271
+ file.rewind
272
+ file.write(content)
273
+ end
274
+ end
275
+
276
+ Then /^"([^\"]*)" should not contain "([^\"]*)"$/ do |file_path, text|
277
+ actual_text = IO.read(File.join(rails_root, file_path))
278
+ if actual_text.include?(text)
279
+ raise "Didn't expect text:\n#{actual_text}\nTo include:\n#{text}"
280
+ end
281
+ end
282
+
283
+ Then /^my Airbrake configuration should contain the following line:$/ do |line|
284
+ configuration_file = if rails_supports_initializers?
285
+ rails_initializer_file
286
+ else
287
+ rails_non_initializer_airbrake_config_file
288
+ # environment_path
289
+ end
290
+
291
+ configuration = File.read(configuration_file)
292
+ if ! configuration.include?(line.strip)
293
+ raise "Expected text:\n#{configuration}\nTo include:\n#{line}\nBut it didn't."
294
+ end
295
+ end
296
+
297
+ When /^I set the environment variable "([^\"]*)" to "([^\"]*)"$/ do |environment_variable, value|
298
+ @terminal.environment_variables[environment_variable] = value
299
+ end
300
+
301
+ When /^I configure the Heroku rake shim$/ do
302
+ @terminal.invoke_heroku_rake_tasks_locally = true
303
+ end
304
+
305
+ When /^I configure the Heroku gem shim with "([^\"]*)"( and multiple app support)?$/ do |api_key, multi_app|
306
+ heroku_script_bin = File.join(TEMP_DIR, "bin")
307
+ FileUtils.mkdir_p(heroku_script_bin)
308
+ heroku_script = File.join(heroku_script_bin, "heroku")
309
+ single_app_script = <<-SINGLE
310
+ #!/bin/bash
311
+ if [[ $1 == 'console' && $2 == 'puts ENV[%{AIRBRAKE_API_KEY}]' ]]; then
312
+ echo #{api_key}
313
+ fi
314
+ SINGLE
315
+
316
+ multi_app_script = <<-MULTI
317
+ #!/bin/bash
318
+ if [[ $1 == 'console' && $2 == '--app' && $4 == 'puts ENV[%{AIRBRAKE_API_KEY}]' ]]; then
319
+ echo #{api_key}
320
+ fi
321
+ MULTI
322
+
323
+ File.open(heroku_script, "w") do |f|
324
+ if multi_app
325
+ f.puts multi_app_script
326
+ else
327
+ f.puts single_app_script
328
+ end
329
+ end
330
+ FileUtils.chmod(0755, heroku_script)
331
+ @terminal.prepend_path(heroku_script_bin)
332
+ end
333
+
334
+ When /^I configure the application to filter parameter "([^\"]*)"$/ do |parameter|
335
+ if rails3?
336
+ application_filename = File.join(rails_root, 'config', 'application.rb')
337
+ application_lines = File.open(application_filename).readlines
338
+
339
+ application_definition_line = application_lines.detect { |line| line =~ /Application/ }
340
+ application_definition_line_index = application_lines.index(application_definition_line)
341
+
342
+ application_lines.insert(application_definition_line_index + 1,
343
+ " config.filter_parameters += [#{parameter.inspect}]")
344
+
345
+ File.open(application_filename, "w") do |file|
346
+ file.puts application_lines.join("\n")
347
+ end
348
+ else
349
+ controller_filename = application_controller_filename
350
+ controller_lines = File.open(controller_filename).readlines
351
+
352
+ controller_definition_line = controller_lines.detect { |line| line =~ /ApplicationController/ }
353
+ controller_definition_line_index = controller_lines.index(controller_definition_line)
354
+
355
+ controller_lines.insert(controller_definition_line_index + 1,
356
+ " filter_parameter_logging #{parameter.inspect}")
357
+
358
+ File.open(controller_filename, "w") do |file|
359
+ file.puts controller_lines.join("\n")
360
+ end
361
+ end
362
+ end
363
+
364
+ Then /^I should see the notifier JavaScript for the following:$/ do |table|
365
+ hash = table.hashes.first
366
+ host = hash['host'] || 'airbrakeapp.com'
367
+ secure = hash['secure'] || false
368
+ api_key = hash['api_key']
369
+ environment = hash['environment'] || 'production'
370
+
371
+ document_body = '<html>' + @terminal.output.split('<html>').last
372
+ document_body.should include("#{host}/javascripts/notifier.js")
373
+
374
+ response = Nokogiri::HTML.parse(document_body)
375
+ response.css("script[type='text/javascript']:last-child").each do |element|
376
+ content = element.content
377
+ content.should include("Airbrake.setKey('#{api_key}');")
378
+ content.should include("Airbrake.setHost('#{host}');")
379
+ content.should include("Airbrake.setEnvironment('#{environment}');")
380
+ end
381
+ end
382
+
383
+ Then "the notifier JavaScript should provide the following errorDefaults:" do |table|
384
+ hash = table.hashes.first
385
+
386
+ document_body = '<html>' + @terminal.output.split('<html>').last
387
+
388
+ response = Nokogiri::HTML.parse(document_body)
389
+ response.css("script[type='text/javascript']:last-child").each do |element|
390
+ content = element.content
391
+
392
+ hash.each do |key, value|
393
+ content.should =~ %r{Airbrake\.setErrorDefaults.*#{key}: "#{value}}m
394
+ end
395
+ end
396
+ end
397
+
398
+ Then /^I should not see notifier JavaScript$/ do
399
+ response = Nokogiri::HTML.parse('<html>' + @terminal.output.split('<html>').last)
400
+ response.at_css("script[type='text/javascript'][src$='/javascripts/notifier.js']").should be_nil
401
+ end