airbrakeV4rails5 4.3.8

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 (98) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +1716 -0
  3. data/Gemfile +3 -0
  4. data/Guardfile +6 -0
  5. data/INSTALL +20 -0
  6. data/LICENSE +61 -0
  7. data/README.md +148 -0
  8. data/README_FOR_HEROKU_ADDON.md +102 -0
  9. data/Rakefile +179 -0
  10. data/TESTED_AGAINST +7 -0
  11. data/airbrake.gemspec +41 -0
  12. data/bin/airbrake +12 -0
  13. data/features/metal.feature +34 -0
  14. data/features/rack.feature +60 -0
  15. data/features/rails.feature +324 -0
  16. data/features/rake.feature +33 -0
  17. data/features/sinatra.feature +126 -0
  18. data/features/step_definitions/file_steps.rb +14 -0
  19. data/features/step_definitions/rack_steps.rb +27 -0
  20. data/features/step_definitions/rails_application_steps.rb +267 -0
  21. data/features/step_definitions/rake_steps.rb +22 -0
  22. data/features/support/airbrake_shim.rb.template +11 -0
  23. data/features/support/aruba.rb +5 -0
  24. data/features/support/env.rb +39 -0
  25. data/features/support/matchers.rb +35 -0
  26. data/features/support/rails.rb +156 -0
  27. data/features/support/rake/Rakefile +77 -0
  28. data/features/user_informer.feature +57 -0
  29. data/generators/airbrake/airbrake_generator.rb +94 -0
  30. data/generators/airbrake/lib/insert_commands.rb +34 -0
  31. data/generators/airbrake/lib/rake_commands.rb +24 -0
  32. data/generators/airbrake/templates/airbrake_tasks.rake +25 -0
  33. data/generators/airbrake/templates/capistrano_hook.rb +6 -0
  34. data/generators/airbrake/templates/initializer.rb +4 -0
  35. data/install.rb +1 -0
  36. data/lib/airbrake.rb +191 -0
  37. data/lib/airbrake/backtrace.rb +103 -0
  38. data/lib/airbrake/capistrano.rb +103 -0
  39. data/lib/airbrake/capistrano3.rb +3 -0
  40. data/lib/airbrake/cli/client.rb +76 -0
  41. data/lib/airbrake/cli/options.rb +45 -0
  42. data/lib/airbrake/cli/printer.rb +33 -0
  43. data/lib/airbrake/cli/project.rb +17 -0
  44. data/lib/airbrake/cli/project_factory.rb +33 -0
  45. data/lib/airbrake/cli/runner.rb +49 -0
  46. data/lib/airbrake/cli/validator.rb +8 -0
  47. data/lib/airbrake/configuration.rb +366 -0
  48. data/lib/airbrake/jobs/send_job.rb +7 -0
  49. data/lib/airbrake/notice.rb +411 -0
  50. data/lib/airbrake/rack.rb +64 -0
  51. data/lib/airbrake/rails.rb +45 -0
  52. data/lib/airbrake/rails/action_controller_catcher.rb +32 -0
  53. data/lib/airbrake/rails/controller_methods.rb +146 -0
  54. data/lib/airbrake/rails/error_lookup.rb +35 -0
  55. data/lib/airbrake/rails/middleware.rb +63 -0
  56. data/lib/airbrake/rails3_tasks.rb +126 -0
  57. data/lib/airbrake/railtie.rb +44 -0
  58. data/lib/airbrake/rake_handler.rb +75 -0
  59. data/lib/airbrake/response.rb +29 -0
  60. data/lib/airbrake/sender.rb +213 -0
  61. data/lib/airbrake/shared_tasks.rb +59 -0
  62. data/lib/airbrake/sidekiq.rb +8 -0
  63. data/lib/airbrake/sinatra.rb +40 -0
  64. data/lib/airbrake/tasks.rb +81 -0
  65. data/lib/airbrake/tasks/airbrake.cap +28 -0
  66. data/lib/airbrake/user_informer.rb +36 -0
  67. data/lib/airbrake/utils/params_cleaner.rb +141 -0
  68. data/lib/airbrake/utils/rack_filters.rb +45 -0
  69. data/lib/airbrake/version.rb +3 -0
  70. data/lib/airbrake_tasks.rb +62 -0
  71. data/lib/rails/generators/airbrake/airbrake_generator.rb +155 -0
  72. data/lib/templates/rescue.erb +91 -0
  73. data/rails/init.rb +1 -0
  74. data/resources/README.md +34 -0
  75. data/resources/airbrake_2_4.xsd +89 -0
  76. data/resources/airbrake_3_0.json +52 -0
  77. data/resources/ca-bundle.crt +3376 -0
  78. data/script/integration_test.rb +35 -0
  79. data/test/airbrake_tasks_test.rb +161 -0
  80. data/test/backtrace_test.rb +215 -0
  81. data/test/capistrano_test.rb +44 -0
  82. data/test/configuration_test.rb +303 -0
  83. data/test/controller_methods_test.rb +230 -0
  84. data/test/helper.rb +233 -0
  85. data/test/integration.rb +13 -0
  86. data/test/integration/catcher_test.rb +371 -0
  87. data/test/logger_test.rb +79 -0
  88. data/test/notice_test.rb +494 -0
  89. data/test/notifier_test.rb +288 -0
  90. data/test/params_cleaner_test.rb +204 -0
  91. data/test/rack_test.rb +62 -0
  92. data/test/rails_initializer_test.rb +36 -0
  93. data/test/recursion_test.rb +10 -0
  94. data/test/response_test.rb +18 -0
  95. data/test/sender_test.rb +335 -0
  96. data/test/support/response_shim.xml +4 -0
  97. data/test/user_informer_test.rb +29 -0
  98. metadata +469 -0
@@ -0,0 +1,33 @@
1
+ Feature: Use the Gem to catch errors in a Rake application
2
+
3
+ Background:
4
+ Given I've prepared the Rakefile
5
+
6
+ Scenario: Ignoring exceptions
7
+ When I run rake with airbrake ignored
8
+ Then Airbrake should not catch the exception
9
+
10
+ Scenario: Catching exceptions in Rake
11
+ When I run rake with airbrake
12
+ Then Airbrake should catch the exception
13
+
14
+ Scenario: Falling back to default handler before Airbrake is configured
15
+ When I run rake with airbrake not yet configured
16
+ Then Airbrake should not catch the exception
17
+
18
+ Scenario: Disabling Rake exception catcher
19
+ When I run rake with airbrake disabled
20
+ Then Airbrake should not catch the exception
21
+
22
+ Scenario: Autodetect, running from terminal
23
+ When I run rake with airbrake autodetect from terminal
24
+ Then Airbrake should not catch the exception
25
+
26
+ Scenario: Autodetect, not running from terminal
27
+ When I run rake with airbrake autodetect not from terminal
28
+ Then Airbrake should catch the exception
29
+
30
+ # @wip
31
+ # Scenario: Airbrake should also send the command name
32
+ # When I run `rake airbrake_autodetect_not_from_terminal`
33
+ # Then command "airbrake_autodetect_not_from_terminal" should be reported
@@ -0,0 +1,126 @@
1
+ Feature: Use the notifier in a Sinatra app
2
+
3
+ Scenario: Rescue an exception in a Sinatra app
4
+ Given the following Rack app:
5
+ """
6
+ require 'sinatra/base'
7
+ require 'airbrake'
8
+ require 'logger'
9
+
10
+ Airbrake.configure do |config|
11
+ config.api_key = 'my_api_key'
12
+ config.logger = Logger.new STDOUT
13
+ config.development_environments = []
14
+ end
15
+
16
+ class FontaneApp < Sinatra::Base
17
+ use Airbrake::Sinatra
18
+
19
+ get "/test/index" do
20
+ raise "Sinatra has left the building"
21
+ end
22
+ end
23
+
24
+ app = FontaneApp
25
+ """
26
+ When I perform a Rack request to "http://example.com:123/test/index?param=value"
27
+ Then I should receive a Airbrake notification
28
+
29
+ Scenario: Catching environment name in modular Sinatra app
30
+ Given the following Rack app:
31
+ """
32
+ require 'sinatra/base'
33
+ require 'airbrake'
34
+ require 'logger'
35
+
36
+ Airbrake.configure do |config|
37
+ config.api_key = 'my_api_key'
38
+ config.logger = Logger.new STDOUT
39
+ end
40
+
41
+ class FontaneApp < Sinatra::Base
42
+ use Airbrake::Sinatra
43
+
44
+ set :environment, :production
45
+
46
+ get "/test/index" do
47
+ raise "Sinatra has left the building"
48
+ end
49
+ end
50
+
51
+ app = FontaneApp
52
+ """
53
+ When I perform a Rack request to "http://example.com:123/test/index?param=value"
54
+ Then I should receive a Airbrake notification
55
+ And the output should contain "Env: production"
56
+
57
+ Scenario: Warnings when environment name wasn't determined automatically
58
+ Given the following Rack app:
59
+ """
60
+ require 'sinatra/base'
61
+ require 'airbrake'
62
+ require 'logger'
63
+
64
+ Airbrake.configure do |config|
65
+ config.api_key = 'my_api_key'
66
+ config.logger = Logger.new STDOUT
67
+ config.development_environments = []
68
+ end
69
+
70
+ class DummyMiddleware
71
+ def initialize(app)
72
+ @app = app
73
+ end
74
+
75
+ def call(env)
76
+ @app.call(env)
77
+ end
78
+ end
79
+
80
+ class FontaneApp < Sinatra::Base
81
+
82
+ use Airbrake::Sinatra
83
+
84
+ use DummyMiddleware
85
+
86
+ set :environment, :production
87
+
88
+ get "/test/index" do
89
+ raise "Sinatra has left the building"
90
+ end
91
+ end
92
+
93
+ app = FontaneApp
94
+ """
95
+ When I perform a Rack request to "http://example.com:123/test/index?param=value"
96
+ Then I should receive a Airbrake notification
97
+ And the output should contain "Please set your environment name manually"
98
+
99
+ Scenario: Give precendence to environment name that was first set
100
+ Given the following Rack app:
101
+ """
102
+ require 'sinatra/base'
103
+ require 'airbrake'
104
+ require 'logger'
105
+
106
+ Airbrake.configure do |config|
107
+ config.api_key = 'my_api_key'
108
+ config.logger = Logger.new STDOUT
109
+ config.environment_name = "staging"
110
+ end
111
+
112
+ class FontaneApp < Sinatra::Base
113
+ use Airbrake::Sinatra
114
+
115
+ set :environment, :production
116
+
117
+ get "/test/index" do
118
+ raise "Sinatra has left the building"
119
+ end
120
+ end
121
+
122
+ app = FontaneApp
123
+ """
124
+ When I perform a Rack request to "http://example.com:123/test/index?param=value"
125
+ Then I should receive a Airbrake notification
126
+ And the output should contain "Env: staging"
@@ -0,0 +1,14 @@
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
11
+
12
+ Then /^I append "([^\"]*)" to Gemfile$/ do |contents|
13
+ append_to_gemfile(contents)
14
+ end
@@ -0,0 +1,27 @@
1
+ Given /^the following Rack app:$/ do |definition|
2
+ File.open(RACK_FILE, 'w') { |file| file.write(definition) }
3
+ end
4
+
5
+ When /^I add "([^\"]*)" requirement(?: with "([^\"]*)" option)?$/ do |gem,option|
6
+ append_to_gemfile("gem '#{gem}'#{option ? ", #{option}":""}")
7
+ end
8
+
9
+ When /^I initialize Gemfile$/ do
10
+ step %{I run `bundle init`}
11
+ end
12
+
13
+ When /^I perform a Rack request to "([^\"]*)"$/ do |url|
14
+ shim_file = File.join(PROJECT_ROOT, 'features', 'support', 'airbrake_shim.rb.template')
15
+ request_file = File.join(TEMP_DIR, 'rack_request.rb')
16
+ File.open(request_file, 'w') do |file|
17
+ file.puts "require 'rubygems'"
18
+ file.puts IO.read(shim_file)
19
+ file.puts IO.read(RACK_FILE)
20
+ file.puts "env = Rack::MockRequest.env_for(#{url.inspect})"
21
+ file.puts "status, headers, body = app.call(env)"
22
+ file.puts %{puts "HTTP \#{status}"}
23
+ file.puts %{headers.each { |key, value| puts "\#{key}: \#{value}"}}
24
+ file.puts "body.each { |part| print part }"
25
+ end
26
+ step %{I run `bundle exec ruby #{request_file}`}
27
+ end
@@ -0,0 +1,267 @@
1
+ require 'uri'
2
+
3
+ require 'active_support/core_ext/string/inflections'
4
+
5
+ Given /^Airbrake server is not responding$/ do
6
+ content = <<-CONTENT
7
+ require 'sham_rack'
8
+
9
+ ShamRack.at("api.airbrake.io") {["500", { "Content-type" => "text/xml" }, ["Internal server error"]]}
10
+
11
+ CONTENT
12
+ target = File.join(rails_root, 'config', 'initializers', 'airbrake_shim.rb')
13
+ File.open(target,"w") { |f| f.write content }
14
+ end
15
+
16
+ Then /^I should (?:(not ))?receive a Airbrake notification$/ do |negator|
17
+ steps %{
18
+ Then the output should #{negator}contain "** [Airbrake] Response from Airbrake:"
19
+ And the output should #{negator}contain "b6817316-9c45-ed26-45eb-780dbb86aadb"
20
+ And the output should #{negator}contain "http://airbrake.io/locate/b6817316-9c45-ed26-45eb-780dbb86aadb"
21
+ }
22
+ end
23
+
24
+ Then /^I should receive two Airbrake notifications$/ do
25
+ step %{the output should match /\[Airbrake\] Response from Airbrake:/}
26
+ end
27
+
28
+ When /^I configure the Airbrake shim$/ do
29
+ shim_file = File.join(PROJECT_ROOT, 'features', 'support', 'airbrake_shim.rb.template')
30
+ target = File.join(rails_root, 'config', 'initializers', 'airbrake_shim.rb')
31
+ FileUtils.cp(shim_file, target)
32
+ end
33
+
34
+ When /^I configure the notifier to use "([^\"]*)" as an API key$/ do |api_key|
35
+ steps %{
36
+ When I configure the notifier to use the following configuration lines:
37
+ """
38
+ config.api_key = #{api_key.inspect}
39
+ """
40
+ }
41
+ end
42
+
43
+ When /^I configure the notifier to use the following configuration lines:$/ do |configuration_lines|
44
+ initializer_code = <<-EOF
45
+ Airbrake.configure do |config|
46
+ config.test_mode = true
47
+ #{configuration_lines}
48
+ end
49
+ EOF
50
+
51
+ File.open(rails_initializer_file, 'w') { |file| file.write(initializer_code) }
52
+ end
53
+
54
+ def rails_initializer_file
55
+ File.join(rails_root, 'config', 'initializers', 'airbrake.rb')
56
+ end
57
+
58
+ def rails_non_initializer_airbrake_config_file
59
+ File.join(rails_root, 'config', 'airbrake.rb')
60
+ end
61
+
62
+ Then /^I should (?:(not ))?see "([^\"]*)"$/ do |negator,expected_text|
63
+ step %{the output should #{negator}contain "#{expected_text}"}
64
+ end
65
+
66
+ When /^I install the "([^\"]*)" plugin$/ do |plugin_name|
67
+ FileUtils.mkdir_p("#{rails_root}/vendor/plugins/#{plugin_name}")
68
+ end
69
+
70
+ When /^I define a response for "([^\"]*)":$/ do |controller_and_action, definition|
71
+ controller_class_name, action = controller_and_action.split('#')
72
+ controller_name = controller_class_name.underscore
73
+ controller_file_name = File.join(rails_root, 'app', 'controllers', "#{controller_name}.rb")
74
+ File.open(controller_file_name, "w") do |file|
75
+ file.puts "class #{controller_class_name} < ApplicationController"
76
+ file.puts "def consider_all_requests_local; false; end"
77
+ file.puts "def local_request?; false; end"
78
+ file.puts "def #{action}"
79
+ file.puts definition
80
+ file.puts "end"
81
+ file.puts "end"
82
+ end
83
+ end
84
+
85
+ When /^I perform a request to "([^\"]*)"$/ do |uri|
86
+ perform_request(uri)
87
+ step %{I run `bundle exec rails runner request.rb`}
88
+ end
89
+
90
+ When /^I perform a request to "([^\"]*)" in the "([^\"]*)" environment$/ do |uri, environment|
91
+ perform_request(uri,environment)
92
+ step %{I run `bundle exec rails runner -e #{environment} request.rb`}
93
+ end
94
+
95
+ Given /^the response page for a "([^\"]*)" error is$/ do |error, html|
96
+ File.open(File.join(rails_root, "public", "#{error}.html"), "w") do |file|
97
+ file.write(html)
98
+ end
99
+ end
100
+
101
+ Then /^I should see the Rails version$/ do
102
+ step %{I should see "Rails: #{ENV["RAILS_VERSION"]}"}
103
+ end
104
+
105
+ Then /^I should see that "([^\"]*)" is not considered a framework gem$/ do |gem_name|
106
+ step %{I should not see "[R] #{gem_name}"}
107
+ end
108
+
109
+ When /^I route "([^\"]*)" to "([^\"]*)"$/ do |path, controller_action_pair|
110
+ route = %(get "#{path}", :to => "#{controller_action_pair}")
111
+ routes_file = File.join(rails_root, "config", "routes.rb")
112
+ File.open(routes_file, "r+") do |file|
113
+ content = file.read
114
+ content.gsub!(/^end$/, " #{route}\nend")
115
+ file.rewind
116
+ file.write(content)
117
+ end
118
+ end
119
+
120
+ Then /^"([^\"]*)" should not contain "([^\"]*)"$/ do |file_path, text|
121
+ actual_text = IO.read(File.join(rails_root, file_path))
122
+ if actual_text.include?(text)
123
+ raise "Didn't expect text:\n#{actual_text}\nTo include:\n#{text}"
124
+ end
125
+ end
126
+
127
+ Then /^my Airbrake configuration should contain the following line:$/ do |line|
128
+ configuration_file = rails_initializer_file
129
+
130
+ configuration = File.read(configuration_file)
131
+ if ! configuration.include?(line.strip)
132
+ raise "Expected text:\n#{configuration}\nTo include:\n#{line}\nBut it didn't."
133
+ end
134
+ end
135
+
136
+ When /^I configure the Heroku shim with "([^\"]*)"( and multiple app support)?$/ do |api_key, multi_app|
137
+ heroku_script_bin = File.join(TEMP_DIR, "bin")
138
+ FileUtils.mkdir_p(heroku_script_bin)
139
+ heroku_script = File.join(heroku_script_bin, "heroku")
140
+ heroku_env_vars = <<-VARS
141
+ AIRBRAKE_API_KEY => myapikey
142
+ APP_NAME => cold-moon-2929
143
+ BUNDLE_WITHOUT => development:test
144
+ COMMIT_HASH => lj32j42ss9332jfa2
145
+ DATABASE_URL => postgres://fchovwjcyb:QLPVWmBBbf4hCG_YMrtV@ec3-107-28-193-23.compute-1.amazonaws.com/fhcvojwwcyb
146
+ LANG => en_US.UTF-8
147
+ LAST_GIT_BY => kensa
148
+ RACK_ENV => production
149
+ SHARED_DATABASE_URL => postgres://fchovwjcyb:QLPVwMbbbF8Hcg_yMrtV@ec2-94-29-181-224.compute-1.amazonaws.com/fhcvojcwwyb
150
+ STACK => bamboo-mri-1.9.2
151
+ URL => cold-moon-2929.heroku.com
152
+ VARS
153
+ single_app_script = <<-SINGLE
154
+ #!/bin/bash
155
+ if [ $1 == 'config' ]
156
+ then
157
+ echo "#{heroku_env_vars}"
158
+ fi
159
+ SINGLE
160
+
161
+ multi_app_script = <<-MULTI
162
+ #!/bin/bash
163
+ if [[ $1 == 'config' && $2 == '--app' ]]
164
+ then
165
+ echo "#{heroku_env_vars}"
166
+ fi
167
+ MULTI
168
+
169
+ File.open(heroku_script, "w") do |f|
170
+ if multi_app
171
+ f.puts multi_app_script
172
+ else
173
+ f.puts single_app_script
174
+ end
175
+ end
176
+ FileUtils.chmod(0755, heroku_script)
177
+ prepend_path(heroku_script_bin)
178
+ end
179
+
180
+ When /^I configure the application to filter parameter "([^\"]*)"$/ do |parameter|
181
+ application_filename = File.join(rails_root, 'config', 'application.rb')
182
+ application_lines = File.open(application_filename).readlines
183
+
184
+ application_definition_line = application_lines.detect { |line| line =~ /Application/ }
185
+ application_definition_line_index = application_lines.index(application_definition_line)
186
+
187
+ parameter = (parameter == "block" ? "lambda { |x,y| x }" : parameter.inspect)
188
+ application_lines.insert(application_definition_line_index + 1, " config.filter_parameters += [#{parameter}]")
189
+
190
+ File.open(application_filename, "w") do |file|
191
+ file.puts application_lines.join("\n")
192
+ end
193
+ end
194
+
195
+ When /^I have set up authentication system in my app that uses "([^\"]*)"$/ do |current_user|
196
+ application_controller = File.join(rails_root, 'app', 'controllers', "application_controller.rb")
197
+ definition =
198
+ """
199
+ class ApplicationController < ActionController::Base
200
+ def consider_all_requests_local; false; end
201
+ def local_request?; false; end
202
+
203
+ # this is the ultimate authentication system, devise is history
204
+ def #{current_user}
205
+ Struct.new(:id, :name, :email, :username, :class_name).new(1, 'Bender', 'bender@beer.com', 'b3nd0r', 'User')
206
+ end
207
+ end
208
+ """
209
+ File.open(application_controller, "w") {|file| file.puts definition }
210
+ end
211
+
212
+ Then /^the Airbrake notification should contain "([^\"]*)"$/ do |content|
213
+ step %{the last notice sent should contain "#{content}"}
214
+ end
215
+
216
+ Then /^the Airbrake notification should not contain "([^\"]*)"$/ do |content|
217
+ step %{the last notice sent should not contain "#{content}"}
218
+ end
219
+
220
+ Then /^the Airbrake notification should contain the custom user details$/ do
221
+ step %{the last notice sent should contain "<name>Bender</name>"}
222
+ step %{the last notice sent should contain "<email>bender@beer.com</email>"}
223
+ step %{the last notice sent should contain "<username>b3nd0r</username>"}
224
+ end
225
+
226
+ Then /^the Airbrake notification should contain user details$/ do
227
+ step %{the last notice sent should contain "<id>1</id>"}
228
+ end
229
+
230
+ Then /^the Airbrake notification should not contain any of the sensitive Rack variables$/ do
231
+ sensitive_rack_data_regex = FILTERED_RACK_VARS.map do |var|
232
+ var.instance_of?(Regexp) ? var : Regexp.quote(var)
233
+ end.join("|")
234
+ step %{the last notice sent should not contain keys with "#{sensitive_rack_data_regex}"}
235
+ end
236
+
237
+ Then /^the last notice sent should contain "([^\"]*)"$/ do |data|
238
+ last_notice = File.read(LAST_NOTICE)
239
+ last_notice.should match(%r{#{data}})
240
+ end
241
+
242
+ Then /^the last notice sent should not contain "([^\"]*)"$/ do |data|
243
+ last_notice = File.read(LAST_NOTICE)
244
+ last_notice.should_not match(%r{#{data}})
245
+ end
246
+
247
+ Then /^the last notice sent should not contain keys with "([^\"]*)"$/ do |data|
248
+ last_notice = File.read(LAST_NOTICE)
249
+ last_notice.should_not match(%r{key\=\"(#{data})\"})
250
+ end
251
+
252
+ Then /^the Airbrake notification should contain the framework information$/ do
253
+ step %{the last notice sent should contain "Rails: #{ENV["RAILS_VERSION"]}"}
254
+ end
255
+
256
+ When /^I list the application's middleware and save it into a file$/ do
257
+ step %{I run `bash -c 'bundle exec rake middleware > middleware.dump'`}
258
+ end
259
+
260
+ Then /^the Airbrake middleware should be placed correctly$/ do
261
+ middleware_file = File.join(LOCAL_RAILS_ROOT, 'middleware.dump')
262
+ middleware = File.read(middleware_file).split(/\n/)
263
+ airbrake_index = middleware.rindex("use Airbrake::Rails::Middleware")
264
+ middleware_index = middleware.rindex("use ActionDispatch::DebugExceptions") ||
265
+ middleware.rindex("use ActionDispatch::ShowExceptions")
266
+ (airbrake_index > middleware_index).should be_true
267
+ end