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,7 @@
1
+ Rails 3.0.20
2
+ Rails 3.1.12
3
+ Rails 3.2.13
4
+ Rails 4.0.0
5
+ Sinatra 1.3.3
6
+ Rack 1.4.3
7
+ Rake 10.0.3
@@ -0,0 +1,41 @@
1
+ require "./lib/airbrake/version"
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "airbrakeV4rails5"
5
+ s.version = Airbrake::VERSION.dup
6
+ s.summary = "Send your application errors to our hosted service and reclaim your inbox."
7
+ s.license = "MIT"
8
+
9
+ s.executables << "airbrake"
10
+ s.files = Dir["{generators/**/*,lib/**/*,rails/**/*,resources/*,script/*}"] +
11
+ %w(airbrake.gemspec CHANGELOG Gemfile Guardfile INSTALL LICENSE Rakefile README_FOR_HEROKU_ADDON.md README.md TESTED_AGAINST install.rb)
12
+ s.test_files = Dir.glob("{test,spec,features}/**/*")
13
+
14
+ s.add_runtime_dependency("builder")
15
+ s.add_runtime_dependency("multi_json")
16
+
17
+ s.add_development_dependency("bourne", "~> 1.4.0")
18
+ s.add_development_dependency("cucumber-rails","~> 1.1.1")
19
+ s.add_development_dependency("fakeweb", "~> 1.3.0")
20
+ s.add_development_dependency("nokogiri", "~> 1.5.0")
21
+ s.add_development_dependency("rspec", "~> 2.6.0")
22
+ s.add_development_dependency("sham_rack", "~> 1.3.0")
23
+ s.add_development_dependency("json-schema", "~> 1.0.12")
24
+ s.add_development_dependency("capistrano", "~> 2.0")
25
+ s.add_development_dependency("aruba")
26
+ s.add_development_dependency("appraisal")
27
+ s.add_development_dependency("rspec-rails")
28
+ s.add_development_dependency("girl_friday")
29
+ s.add_development_dependency("sucker_punch", "1.0.2")
30
+ s.add_development_dependency("shoulda-matchers")
31
+ s.add_development_dependency("shoulda-context")
32
+ s.add_development_dependency("pry")
33
+ s.add_development_dependency("coveralls")
34
+ s.add_development_dependency("minitest", ["~> 4.0"])
35
+ s.add_development_dependency("test-unit")
36
+
37
+
38
+ s.authors = ["Airbrake"]
39
+ s.email = "support@airbrake.io"
40
+ s.homepage = "http://www.airbrake.io"
41
+ end
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "airbrake"
4
+ require "airbrake/cli/runner"
5
+ require "net/http"
6
+ require "uri"
7
+
8
+ args = ARGV.dup
9
+ command = args.shift.strip rescue nil
10
+ options = ARGV[1..-1]
11
+
12
+ Runner.run!(command, options)
@@ -0,0 +1,34 @@
1
+ Feature: Rescue errors in Rails middleware
2
+ Background:
3
+ Given I successfully run `rails new rails_root -O --skip-gemfile`
4
+ And I cd to "rails_root"
5
+ And I configure the notifier to use the following configuration lines:
6
+ """
7
+ config.api_key = "myapikey"
8
+ config.logger = Logger.new STDOUT
9
+ """
10
+ And I configure the Airbrake shim
11
+ And I append to "app/metal/exploder.rb" with:
12
+ """
13
+ class Exploder
14
+ def call(env)
15
+ raise "Explode!"
16
+ end
17
+ end
18
+ """
19
+ And I remove the file "config/routes.rb"
20
+ And I append to "config/routes.rb" with:
21
+ """
22
+ RailsRoot::Application.routes.draw do
23
+ mount Exploder.new => "/"
24
+ end
25
+ """
26
+
27
+ Scenario: It should not report to Airbrake in development
28
+ When I perform a request to "http://example.com:123/metal/index?param=value"
29
+ Then I should not receive a Airbrake notification
30
+
31
+ Scenario: It should report to Airbrake in production
32
+ When I perform a request to "http://example.com:123/metal/index?param=value" in the "production" environment
33
+ Then I should receive a Airbrake notification
34
+
@@ -0,0 +1,60 @@
1
+ Feature: Use the notifier in a plain Rack app
2
+
3
+ Scenario: Rescue and exception in a Rack app
4
+
5
+ Given the following Rack app:
6
+ """
7
+ require 'logger'
8
+ require 'rack'
9
+ require 'airbrake'
10
+
11
+ Airbrake.configure do |config|
12
+ config.api_key = 'my_api_key'
13
+ config.logger = Logger.new STDOUT
14
+ end
15
+
16
+ app = Rack::Builder.app do
17
+ use Airbrake::Rack
18
+ run lambda { |env| raise "Rack down" }
19
+ end
20
+
21
+ """
22
+ When I perform a Rack request to "http://example.com:123/test/index?param=value"
23
+ Then I should receive a Airbrake notification
24
+
25
+ Scenario: Ignore user agents
26
+
27
+ Given the following Rack app:
28
+ """
29
+ require 'logger'
30
+ require 'rack'
31
+ require 'airbrake'
32
+
33
+ Airbrake.configure do |config|
34
+ config.api_key = 'my_api_key'
35
+ config.ignore_user_agent << /ignore/
36
+ config.logger = Logger.new STDOUT
37
+ end
38
+
39
+ class Mock
40
+ class AppendUserAgent
41
+ def initialize(app)
42
+ @app = app
43
+ end
44
+
45
+ def call(env)
46
+ env["HTTP_USER_AGENT"] = "ignore"
47
+ @app.call(env)
48
+ end
49
+ end
50
+ end
51
+
52
+ app = Rack::Builder.app do
53
+ use Airbrake::Rack
54
+ use Mock::AppendUserAgent
55
+ run lambda { |env| raise "Rack down" }
56
+ end
57
+
58
+ """
59
+ When I perform a Rack request to "http://example.com:123/test/index?param=value"
60
+ Then I should not receive a Airbrake notification
@@ -0,0 +1,324 @@
1
+ Feature: Install the Gem in a Rails application
2
+
3
+ Background:
4
+ Given I successfully run `rails new rails_root -O --skip-gemfile`
5
+ And I cd to "rails_root"
6
+
7
+ Scenario: Use the gem without vendoring the gem in a Rails application
8
+ When I configure the Airbrake shim
9
+ And I run `rails generate airbrake -k myapikey -t`
10
+ Then I should receive a Airbrake notification
11
+ And I should see the Rails version
12
+
13
+ Scenario: Configure the notifier by hand
14
+ When I configure the Airbrake shim
15
+ And I configure the notifier to use "myapikey" as an API key
16
+ And I run `rails generate airbrake`
17
+ Then I should receive a Airbrake notification
18
+
19
+ Scenario: Configuration within initializer isn't overridden by Railtie
20
+ When I configure the Airbrake shim
21
+ And I run `rails generate airbrake -k myapikey -t`
22
+ And I configure the notifier to use the following configuration lines:
23
+ """
24
+ config.api_key = "myapikey"
25
+ config.project_root = "argle/bargle"
26
+ """
27
+ And I define a response for "TestController#index":
28
+ """
29
+ raise RuntimeError, "some message"
30
+ """
31
+ And I route "/test/index" to "test#index"
32
+ And I perform a request to "http://example.com:123/test/index?param=value"
33
+ Then I should receive a Airbrake notification
34
+
35
+ Scenario: Try to install without an api key
36
+ When I run `rails generate airbrake`
37
+ Then I should see "Must pass --api-key or --heroku or create config/initializers/airbrake.rb"
38
+
39
+ Scenario: Generator should support the --secure option
40
+ When I run `rails generate airbrake -k myapikey --secure`
41
+ Then my Airbrake configuration should contain the following line:
42
+ """
43
+ config.secure = true
44
+ """
45
+
46
+ Scenario: Configure and deploy using only installed gem
47
+ When I run `capify .`
48
+ And I configure the Airbrake shim
49
+ And I run `rails generate airbrake -k myapikey -t`
50
+ And I run `cap -T`
51
+ Then I should see "airbrake:deploy"
52
+
53
+ Scenario: Try to install when the airbrake plugin still exists
54
+ When I install the "airbrake" plugin
55
+ And I configure the Airbrake shim
56
+ And I configure the notifier to use "myapikey" as an API key
57
+ And I run `rails generate airbrake`
58
+ Then I should see "You must first remove the airbrake plugin. Please run: script/plugin remove airbrake"
59
+
60
+ Scenario: Rescue an exception in a controller
61
+ When I configure the Airbrake shim
62
+ And I run `rails generate airbrake -k myapikey -t`
63
+ And I define a response for "TestController#index":
64
+ """
65
+ raise RuntimeError, "some message"
66
+ """
67
+ And I route "/test/index" to "test#index"
68
+ And I perform a request to "http://example.com:123/test/index?param=value"
69
+ Then I should receive a Airbrake notification
70
+
71
+ Scenario: The gem should not be considered a framework gem
72
+ When I configure the Airbrake shim
73
+ And I run `rails generate airbrake -k myapikey -t`
74
+ And I run `rake gems`
75
+ Then I should see that "airbrake" is not considered a framework gem
76
+
77
+ Scenario: The app uses Vlad instead of Capistrano
78
+ When I configure the Airbrake shim
79
+ And I run `touch config/deploy.rb`
80
+ And I run `rm Capfile`
81
+ And I run `rails generate airbrake -k myapikey`
82
+ Then "config/deploy.rb" should not contain "capistrano"
83
+
84
+ # @wip
85
+ # Scenario: Support the Heroku addon in the generator
86
+ # When I configure the Airbrake shim
87
+ # And I run `rails generate airbrake -k myapikey -t`
88
+ # And I configure the Heroku shim with "myapikey"
89
+ # And I run `rails generate airbrake --heroku`
90
+ # Then I should receive a Airbrake notification
91
+ # And I should see the Rails version
92
+ # And my Airbrake configuration should contain the following line:
93
+ # """
94
+ # config.api_key = 'myapikey'
95
+ # """
96
+
97
+ # @wip
98
+ # Scenario: Support the --app option for the Heroku addon in the generator
99
+ # When I configure the Airbrake shim
100
+ # And I configure the Heroku shim with "myapikey" and multiple app support
101
+ # And I run `rails generate airbrake --heroku -a myapp -t`
102
+ # Then I should receive a Airbrake notification
103
+ # And I should see the Rails version
104
+ # And my Airbrake configuration should contain the following line:
105
+ # """
106
+ # config.api_key = 'myapikey'
107
+ # """
108
+
109
+ Scenario: Filtering parameters in a controller
110
+ When I configure the Airbrake shim
111
+ And I run `rails generate airbrake -k myapikey -t`
112
+ When I configure the notifier to use the following configuration lines:
113
+ """
114
+ config.api_key = "myapikey"
115
+ config.params_filters << "credit_card_number"
116
+ config.params_filters << "secret"
117
+ config.logger = Logger.new STDOUT
118
+ """
119
+ And I define a response for "TestController#index":
120
+ """
121
+ session["secret"] = "blue42"
122
+ params[:credit_card_number] = "red23"
123
+ raise RuntimeError, "some message"
124
+ """
125
+ And I route "/test/index" to "test#index"
126
+ And I perform a request to "http://example.com:123/test/index?param=value" in the "production" environment
127
+ Then I should receive a Airbrake notification
128
+ And the Airbrake notification should not contain "red23"
129
+ And the Airbrake notification should not contain "blue42"
130
+ And the Airbrake notification should contain "FILTERED"
131
+
132
+ Scenario: Filtering session and params based on Rails parameter filters
133
+ When I configure the Airbrake shim
134
+ And I run `rails generate airbrake -k myapikey -t`
135
+ When I configure the notifier to use the following configuration lines:
136
+ """
137
+ config.api_key = "myapikey"
138
+ config.logger = Logger.new STDOUT
139
+ """
140
+ And I configure the application to filter parameter "secret"
141
+ And I define a response for "TestController#index":
142
+ """
143
+ params["secret"] = "red23"
144
+ session["secret"] = "blue42"
145
+ raise RuntimeError, "some message"
146
+ """
147
+ And I route "/test/index" to "test#index"
148
+ And I perform a request to "http://example.com:123/test/index" in the "production" environment
149
+ Then I should receive a Airbrake notification
150
+ And the Airbrake notification should not contain "red23"
151
+ And the Airbrake notification should not contain "blue42"
152
+ And the Airbrake notification should contain "FILTERED"
153
+
154
+ Scenario: Filtering sensitive Rack variables
155
+ When I configure the Airbrake shim
156
+ And I run `rails generate airbrake -k myapikey -t`
157
+ When I configure the notifier to use the following configuration lines:
158
+ """
159
+ config.logger = Logger.new STDOUT
160
+ """
161
+ And I define a response for "TestController#index":
162
+ """
163
+ raise RuntimeError
164
+ """
165
+ Then I should receive a Airbrake notification
166
+ And the Airbrake notification should not contain any of the sensitive Rack variables
167
+
168
+ Scenario: Filtering vs symbols
169
+ When I configure the Airbrake shim
170
+ And I run `rails generate airbrake -k myapikey -t`
171
+ When I configure the notifier to use the following configuration lines:
172
+ """
173
+ config.api_key = "myapikey"
174
+ config.logger = Logger.new STDOUT
175
+ """
176
+ And I configure the application to filter parameter "block"
177
+ And I define a response for "TestController#index":
178
+ """
179
+ request.env["foo"] = {:foo => "bar"}
180
+ raise RuntimeError, "some message"
181
+ """
182
+ And I route "/test/index" to "test#index"
183
+ And I perform a request to "http://example.com:123/test/index" in the "production" environment
184
+ Then I should receive a Airbrake notification
185
+ And the Airbrake notification should contain "some message"
186
+
187
+ Scenario: Notify airbrake within the controller
188
+ When I configure the Airbrake shim
189
+ And I run `rails generate airbrake -k myapikey -t`
190
+ And I define a response for "TestController#index":
191
+ """
192
+ session[:value] = "unicorn"
193
+ notify_airbrake(RuntimeError.new("some message"))
194
+ render :nothing => true
195
+ """
196
+ And I route "/test/index" to "test#index"
197
+ And I perform a request to "http://example.com:123/test/index?param=value" in the "production" environment
198
+ Then I should receive a Airbrake notification
199
+ And the Airbrake notification should contain "unicorn"
200
+
201
+ Scenario: Reporting 404s should be disabled by default
202
+ When I configure the Airbrake shim
203
+ And I configure the notifier to use the following configuration lines:
204
+ """
205
+ config.api_key = "myapikey"
206
+ """
207
+ And I perform a request to "http://example.com:123/this/route/does/not/exist" in the "production" environment
208
+ Then I should see "The page you were looking for doesn't exist."
209
+ And I should not receive a Airbrake notification
210
+
211
+ Scenario: Reporting 404s should work when configured properly
212
+ When I configure the Airbrake shim
213
+ And I run `rails generate airbrake -k myapikey -t`
214
+ When I configure the notifier to use the following configuration lines:
215
+ """
216
+ config.ignore_only = []
217
+ """
218
+ And I perform a request to "http://example.com:123/this/route/does/not/exist" in the "production" environment
219
+ Then I should see "The page you were looking for doesn't exist"
220
+ And I should receive a Airbrake notification
221
+
222
+ @wip
223
+ Scenario: reporting over SSL with utf8 check should work
224
+ When I configure the Airbrake shim
225
+ And I run `rails generate airbrake -k myapikey -t`
226
+ When I configure the notifier to use the following configuration lines:
227
+ """
228
+ config.secure = true
229
+ """
230
+ And I define a response for "TestController#index":
231
+ """
232
+ raise RuntimeError, "some message"
233
+ """
234
+ And I route "/test/index" to "test#index"
235
+ And I perform a request to "http://example.com:123/test/index?utf8=✓"
236
+ Then I should receive a Airbrake notification
237
+
238
+ Scenario: It should also send the user details
239
+ When I configure the Airbrake shim
240
+ And I configure the notifier to use the following configuration lines:
241
+ """
242
+ config.api_key = "myapikey"
243
+ config.logger = Logger.new STDOUT
244
+ """
245
+ And I define a response for "TestController#index":
246
+ """
247
+ raise RuntimeError, "some message"
248
+ """
249
+ And I route "/test/index" to "test#index"
250
+ And I have set up authentication system in my app that uses "current_user"
251
+ And I perform a request to "http://example.com:123/test/index" in the "production" environment
252
+ Then I should receive a Airbrake notification
253
+ And the Airbrake notification should contain user details
254
+ When I have set up authentication system in my app that uses "current_member"
255
+ And I perform a request to "http://example.com:123/test/index" in the "production" environment
256
+ Then I should receive a Airbrake notification
257
+ And the Airbrake notification should contain user details
258
+
259
+ Scenario: It should also send custom user attributes
260
+ When I configure the Airbrake shim
261
+ And I configure the notifier to use the following configuration lines:
262
+ """
263
+ config.api_key = "myapikey"
264
+ config.logger = Logger.new STDOUT
265
+ config.user_attributes = [:id, :name, :email, :username]
266
+ """
267
+ And I define a response for "TestController#index":
268
+ """
269
+ raise RuntimeError, "some message"
270
+ """
271
+ And I route "/test/index" to "test#index"
272
+ And I have set up authentication system in my app that uses "current_user"
273
+ And I perform a request to "http://example.com:123/test/index" in the "production" environment
274
+ Then I should receive a Airbrake notification
275
+ And the Airbrake notification should contain the custom user details
276
+
277
+ Scenario: It should warn the user that she's using unsupported attributes for
278
+ current user
279
+ When I configure the Airbrake shim
280
+ And I configure the notifier to use the following configuration lines:
281
+ """
282
+ config.api_key = "myapikey"
283
+ config.logger = Logger.new STDOUT
284
+ config.user_attributes = [:id, :name, :email, :username, :shoe_size]
285
+ """
286
+ And I run `rails runner config/boot.rb`
287
+ Then I should see "Unsupported user attribute: 'shoe_size'"
288
+ And I should not see "Unsupported user attribute: 'id'"
289
+
290
+ Scenario: It should log the notice when failure happens
291
+ When Airbrake server is not responding
292
+ And I configure the notifier to use the following configuration lines:
293
+ """
294
+ config.api_key = "myapikey"
295
+ config.logger = Logger.new STDOUT
296
+ """
297
+ And I define a response for "TestController#index":
298
+ """
299
+ raise RuntimeError, "some message"
300
+ """
301
+ And I route "/test/index" to "test#index"
302
+ And I perform a request to "http://example.com:123/test/index?param=value" in the "production" environment
303
+ Then I should see "Notice details:"
304
+ And I should see "some message"
305
+
306
+ Scenario: It should send the framework info
307
+ When I configure the Airbrake shim
308
+ And I configure the notifier to use the following configuration lines:
309
+ """
310
+ config.api_key = "myapikey"
311
+ config.logger = Logger.new STDOUT
312
+ """
313
+ And I define a response for "TestController#index":
314
+ """
315
+ raise RuntimeError, "some message"
316
+ """
317
+ And I route "/test/index" to "test#index"
318
+ And I perform a request to "http://example.com:123/test/index" in the "production" environment
319
+ Then I should receive a Airbrake notification
320
+ And the Airbrake notification should contain the framework information
321
+
322
+ Scenario: Middleware should be correctly placed
323
+ When I list the application's middleware and save it into a file
324
+ Then the Airbrake middleware should be placed correctly