cloudtrapper 0.0.2.pre

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 (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