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