require 'uri' require 'active_support/core_ext/string/inflections' Given /^I have built and installed the "([^\"]*)" gem$/ do |gem_name| @terminal.build_and_install_gem(File.join(PROJECT_ROOT, "#{gem_name}.gemspec")) end Given /^PENDING/ do pending end Given /^ProjectlockerErrata server is not responding$/ do bundle_gem("sham_rack") content = <<-CONTENT require 'sham_rack' ProjectlockerErrata.configuration.logger = Logger.new STDOUT ShamRack.at("api.projectlocker_errata.io") {["500", { "Content-type" => "text/xml" }, ["Internal server error"]]} CONTENT target = File.join(rails_root, 'config', 'initializers', 'projectlocker_errata_shim.rb') File.open(target,"w") { |f| f.write content } end When /^I generate a new Rails application$/ do @terminal.cd(TEMP_DIR) rails3 = version_string =~ /^3/ if rails3 rails_create_command = 'new' else rails_create_command = '' end load_rails = <<-RUBY gem 'rails', '#{version_string}'; \ load Gem.bin_path('#{version_string >= "3.2.0" ? "railties" : "rails"}', 'rails', '#{version_string}') RUBY @terminal.run(%{ruby -rrubygems -rthread -e "#{load_rails.strip!}" #{rails_create_command} rails_root}) if rails_root_exists? @terminal.echo("Generated a Rails #{version_string.strip} application") else raise "Unable to generate a Rails application:\n#{@terminal.output}" end require_thread if version_string >= "3.1.0" When %{I configure my application to require the "therubyracer" gem with version "0.10.1"} elsif version_string =~ /2.3.14/ monkeypatch_old_version end config_gem_dependencies unless rails3 end When /^I run the projectlocker_errata generator with "([^\"]*)"$/ do |generator_args| if rails3? When %{I run "./script/rails generate projectlocker_errata #{generator_args}"} else When %{I run "./script/generate projectlocker_errata #{generator_args}"} end end When /^I print the console output$/ do puts @terminal.output end Given /^I have installed the "([^\"]*)" gem$/ do |gem_name| @terminal.install_gem(gem_name) end When /^I configure my application to require the "capistrano" gem if necessary$/ do When %{I configure my application to require the "capistrano" gem} if version_string >= "3.0.0" end When /^I configure my application to require the "([^\"]*)" gem(?: with version "(.+)")?$/ do |gem_name, version| if rails_manages_gems? config_gem(gem_name, version) elsif bundler_manages_gems? bundle_gem(gem_name, version) else File.open(environment_path, 'a') do |file| file.puts file.puts("require 'projectlocker_errata'") file.puts("require 'projectlocker_errata/rails'") end unless rails_finds_generators_in_gems? FileUtils.cp_r(File.join(PROJECT_ROOT, 'generators'), File.join(rails_root, 'lib')) end end end When /^I run "([^\"]*)"$/ do |command| @terminal.cd(rails_root) @terminal.run(command) end Then /^I should( not)? receive a ProjectlockerErrata notification$/ do |or_should_not| Then %{I should#{or_should_not} see "** [ProjectlockerErrata] Response from ProjectlockerErrata:"} And %{I should#{or_should_not} see "b6817316-9c45-ed26-45eb-780dbb86aadb"} And %{I should#{or_should_not} see "http://projectlocker_errata.io/locate/b6817316-9c45-ed26-45eb-780dbb86aadb"} end Then /^I should receive two ProjectlockerErrata notifications$/ do @terminal.output.scan(/\[ProjectlockerErrata\] Response from ProjectlockerErrata:/).size.should == 2 end When /^I configure the ProjectlockerErrata shim$/ do if bundler_manages_gems? bundle_gem("sham_rack") end shim_file = File.join(PROJECT_ROOT, 'features', 'support', 'projectlocker_errata_shim.rb.template') if rails_supports_initializers? target = File.join(rails_root, 'config', 'initializers', 'projectlocker_errata_shim.rb') FileUtils.cp(shim_file, target) else File.open(environment_path, 'a') do |file| file.puts file.write IO.read(shim_file) end end target = File.join(rails_root, 'config', 'initializers', 'projectlocker_errata_shim.rb') FileUtils.cp(shim_file, target) end When /^I configure the notifier to use "([^\"]*)" as an API key$/ do |api_key| steps %{ When I configure the notifier to use the following configuration lines: """ config.api_key = #{api_key.inspect} """ } end When /^I configure the notifier to use the following configuration lines:$/ do |configuration_lines| if rails_manages_gems? requires = '' else requires = "require 'projectlocker_errata'" end initializer_code = <<-EOF #{requires} ProjectlockerErrata.configure do |config| #{configuration_lines} end EOF if rails_supports_initializers? File.open(rails_initializer_file, 'w') { |file| file.write(initializer_code) } else File.open(environment_path, 'a') do |file| file.puts file.puts initializer_code end end end def rails_initializer_file File.join(rails_root, 'config', 'initializers', 'projectlocker_errata.rb') end def rails_non_initializer_projectlocker_errata_config_file File.join(rails_root, 'config', 'projectlocker_errata.rb') end Then /^I should see "([^\"]*)"$/ do |expected_text| unless @terminal.output.include?(expected_text) raise("Got terminal output:\n#{@terminal.output}\n\nExpected output:\n#{expected_text}") end end Then /^I should not see "([^\"]*)"$/ do |unexpected_text| if @terminal.output.include?(unexpected_text) raise("Got terminal output:\n#{@terminal.output}\n\nDid not expect the following output:\n#{unexpected_text}") end end When /^I uninstall the "([^\"]*)" gem$/ do |gem_name| @terminal.uninstall_gem(gem_name) end When /^I unpack the "([^\"]*)" gem$/ do |gem_name| if bundler_manages_gems? @terminal.cd(rails_root) @terminal.run("bundle pack") elsif rails_manages_gems? @terminal.cd(rails_root) @terminal.run("rake gems:unpack GEM=#{gem_name}") else vendor_dir = File.join(rails_root, 'vendor', 'gems') FileUtils.mkdir_p(vendor_dir) @terminal.cd(vendor_dir) @terminal.run("gem unpack #{gem_name}") gem_path = Dir.glob(File.join(rails_root, 'vendor', 'gems', "#{gem_name}-*", 'lib')).first File.open(environment_path, 'a') do |file| file.puts file.puts("$: << #{gem_path.inspect}") end end end When /^I install cached gems$/ do if bundler_manages_gems? Then %{I run "bundle install"} end end When /^I install the "([^\"]*)" plugin$/ do |plugin_name| FileUtils.mkdir_p("#{rails_root}/vendor/plugins/#{plugin_name}") end When /^I define a response for "([^\"]*)":$/ do |controller_and_action, definition| controller_class_name, action = controller_and_action.split('#') controller_name = controller_class_name.underscore controller_file_name = File.join(rails_root, 'app', 'controllers', "#{controller_name}.rb") File.open(controller_file_name, "w") do |file| file.puts "class #{controller_class_name} < ApplicationController" file.puts "def consider_all_requests_local; false; end" file.puts "def local_request?; false; end" file.puts "def #{action}" file.puts definition file.puts "end" file.puts "end" end end When /^I perform a request to "([^\"]*)"$/ do |uri| perform_request(uri) end When /^I perform a request to "([^\"]*)" in the "([^\"]*)" environment$/ do |uri, environment| perform_request(uri, environment) end Given /^the response page for a "([^\"]*)" error is$/ do |error, html| File.open(File.join(rails_root, "public", "#{error}.html"), "w") do |file| file.write(html) end end Then /^I should receive the following ProjectlockerErrata notification:$/ do |table| exceptions = @terminal.output.scan(%r{Recieved the following exception:\n([^\n]*)\n}m) exceptions.should_not be_empty xml = exceptions.last[0] doc = Nokogiri::XML.parse(xml) hash = table.transpose.hashes.first doc.should have_content('//error/message', hash['error message']) doc.should have_content('//error/class', hash['error class']) doc.should have_content('//request/url', hash['url']) doc.should have_content('//component', hash['component']) if hash['component'] doc.should have_content('//action', hash['action']) if hash['action'] doc.should have_content('//server-environment/project-root', hash['project-root']) if hash['project-root'] if hash['session'] session_key, session_value = hash['session'].split(': ') doc.should have_content('//request/session/var/@key', session_key) doc.should have_content('//request/session/var', session_value) end if hash['parameters'] param_key, param_value = hash['parameters'].split(': ') doc.should have_content('//request/params/var/@key', param_key) doc.should have_content('//request/params/var', param_value) end end Then /^I should see the Rails version$/ do Then %{I should see "[Rails: #{rails_version}]"} end Then /^I should see that "([^\"]*)" is not considered a framework gem$/ do |gem_name| Then %{I should not see "[R] #{gem_name}"} end Then /^the command should have run successfully$/ do @terminal.status.exitstatus.should == 0 end When /^I route "([^\"]*)" to "([^\"]*)"$/ do |path, controller_action_pair| route = if rails3? %(match "#{path}", :to => "#{controller_action_pair}") else controller, action = controller_action_pair.split('#') %(map.connect "#{path}", :controller => "#{controller}", :action => "#{action}") end routes_file = File.join(rails_root, "config", "routes.rb") File.open(routes_file, "r+") do |file| content = file.read content.gsub!(/^end$/, " #{route}\nend") file.rewind file.write(content) end end Then /^"([^\"]*)" should not contain "([^\"]*)"$/ do |file_path, text| actual_text = IO.read(File.join(rails_root, file_path)) if actual_text.include?(text) raise "Didn't expect text:\n#{actual_text}\nTo include:\n#{text}" end end Then /^my ProjectlockerErrata configuration should contain the following line:$/ do |line| configuration_file = if rails_supports_initializers? rails_initializer_file else rails_non_initializer_projectlocker_errata_config_file # environment_path end configuration = File.read(configuration_file) if ! configuration.include?(line.strip) raise "Expected text:\n#{configuration}\nTo include:\n#{line}\nBut it didn't." end end When /^I set the environment variable "([^\"]*)" to "([^\"]*)"$/ do |environment_variable, value| @terminal.environment_variables[environment_variable] = value end When /^I configure the Heroku rake shim$/ do @terminal.invoke_heroku_rake_tasks_locally = true end When /^I configure the Heroku gem shim with "([^\"]*)"( and multiple app support)?$/ do |api_key, multi_app| heroku_script_bin = File.join(TEMP_DIR, "bin") FileUtils.mkdir_p(heroku_script_bin) heroku_script = File.join(heroku_script_bin, "heroku") heroku_env_vars = <<-VARS PROJECTLOCKER_ERRATA_API_KEY => myapikey APP_NAME => cold-moon-2929 BUNDLE_WITHOUT => development:test COMMIT_HASH => lj32j42ss9332jfa2 DATABASE_URL => postgres://fchovwjcyb:QLPVWmBBbf4hCG_YMrtV@ec3-107-28-193-23.compute-1.amazonaws.com/fhcvojwwcyb LANG => en_US.UTF-8 LAST_GIT_BY => kensa RACK_ENV => production SHARED_DATABASE_URL => postgres://fchovwjcyb:QLPVwMbbbF8Hcg_yMrtV@ec2-94-29-181-224.compute-1.amazonaws.com/fhcvojcwwyb STACK => bamboo-mri-1.9.2 URL => cold-moon-2929.heroku.com VARS single_app_script = <<-SINGLE #!/bin/bash if [ $1 == 'config' ] then echo "#{heroku_env_vars}" fi SINGLE multi_app_script = <<-MULTI #!/bin/bash if [[ $1 == 'config' && $2 == '--app' ]] then echo "#{heroku_env_vars}" fi MULTI File.open(heroku_script, "w") do |f| if multi_app f.puts multi_app_script else f.puts single_app_script end end FileUtils.chmod(0755, heroku_script) @terminal.prepend_path(heroku_script_bin) end When /^I configure the application to filter parameter "([^\"]*)"$/ do |parameter| if rails3? application_filename = File.join(rails_root, 'config', 'application.rb') application_lines = File.open(application_filename).readlines application_definition_line = application_lines.detect { |line| line =~ /Application/ } application_definition_line_index = application_lines.index(application_definition_line) application_lines.insert(application_definition_line_index + 1, " config.filter_parameters += [#{parameter.inspect}]") File.open(application_filename, "w") do |file| file.puts application_lines.join("\n") end else controller_filename = application_controller_filename controller_lines = File.open(controller_filename).readlines controller_definition_line = controller_lines.detect { |line| line =~ /ApplicationController/ } controller_definition_line_index = controller_lines.index(controller_definition_line) controller_lines.insert(controller_definition_line_index + 1, " filter_parameter_logging #{parameter.inspect}") File.open(controller_filename, "w") do |file| file.puts controller_lines.join("\n") end end end Then /^I should see the notifier JavaScript for the following:$/ do |table| hash = table.hashes.first host = hash['host'] || 'api.projectlocker_errata.io' secure = hash['secure'] || false api_key = hash['api_key'] environment = hash['environment'] || 'production' document_body = '' + @terminal.output.split('').last document_body.should include("#{host}/javascripts/notifier.js") response = Nokogiri::HTML.parse(document_body) response.css("script[type='text/javascript']:last-child").each do |element| content = element.content content.should include("ProjectlockerErrata.setKey('#{api_key}');") content.should include("ProjectlockerErrata.setHost('#{host}');") content.should include("ProjectlockerErrata.setEnvironment('#{environment}');") end end Then "the notifier JavaScript should provide the following errorDefaults:" do |table| hash = table.hashes.first document_body = '' + @terminal.output.split('').last response = Nokogiri::HTML.parse(document_body) response.css("script[type='text/javascript']:last-child").each do |element| content = element.content hash.each do |key, value| content.should =~ %r{ProjectlockerErrata\.setErrorDefaults.*#{key}: "#{value}}m end end end Then /^I should not see notifier JavaScript$/ do response = Nokogiri::HTML.parse('' + @terminal.output.split('').last) response.at_css("script[type='text/javascript'][src$='/javascripts/notifier.js']").should be_nil end When /^I configure usage of ProjectlockerErrata$/ do When %{I configure my application to require the "projectlocker_errata" gem} When %{I run the projectlocker_errata generator with "-k myapikey"} @terminal.flush! # flush the results of setting up ProjectlockerErrata (generates notification) end When /^I have set up authentication system in my app that uses "([^\"]*)"$/ do |current_user| application_controller = File.join(rails_root, 'app', 'controllers', "application_controller.rb") definition = """ class ApplicationController < ActionController::Base def consider_all_requests_local; false; end def local_request?; false; end # this is the ultimate authentication system, devise is history def #{current_user} Struct.new(:attributes).new({:id => 1,:name => 'Bender',:email => 'bender@beer.com',:username => 'b3nd0r'}) end end """ File.open(application_controller, "w") {|file| file.puts definition } end Then /^the ProjectlockerErrata notification should contain user details$/ do Then %{I should see "Bender"} And %{I should see "bender@beer.com"} And %{I should see "1"} And %{I should see "b3nd0r"} end