cloudtrapper 0.0.2.pre

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