Browse files

Merge branch 'bug-emulate-javascript-csrf' of https://github.com/Jona…

…thonMA/cucumber-rails into JonathonMA-bug-emulate-javascript-csrf
  • Loading branch information...
2 parents cdf5223 + 6f9c533 commit 93e28e15e58a2ff743836d5a473b8a79517ea670 @aslakhellesoy aslakhellesoy committed Sep 11, 2011
Showing with 84 additions and 0 deletions.
  1. +54 −0 features/emulate_javascript.feature
  2. +30 −0 lib/cucumber/rails/capybara/javascript_emulation.rb
View
54 features/emulate_javascript.feature
@@ -32,3 +32,57 @@ Feature: Emulate Javascript
3 steps (3 passed)
"""
+ Scenario: Pass on the CSRF token
+ Given I have created a new Rails 3 app "widgets" with cucumber-rails support
+ And I successfully run `rails generate scaffold widget name:string`
+ And I successfully run `sed -i -e 's/forgery_protection *= false/forgery_protection = true/' config/environments/test.rb`
+ And I successfully run `rails generate controller session establish`
+ And I write to "app/controllers/session_controller.rb" with:
+ """
+ class SessionController < ApplicationController
+ def establish
+ session[:verified] = true
+ end
+ end
+ """
+ And I write to "app/controllers/application_controller.rb" with:
+ """
+ class ApplicationController < ActionController::Base
+ protect_from_forgery
+ before_filter :except => :establish do
+ render :text => "denied", :status => :forbidden and return false unless session[:verified]
+ end
+ end
+ """
+ And I write to "features/f.feature" with:
+ """
+ Feature: Widget inventory
+ Scenario: Delete a widget
+ Given there is a widget named "wrench"
+ When I go to the session establish page
+ And I go to the widgets page
+ Then I should see "wrench"
+ When I follow "Destroy"
+ Then I should not see "denied"
+ And I should be on the widgets page
+ And I should not see "wrench"
+ """
+ And I write to "features/step_definitions/s.rb" with:
+ """
+ Given /^there is a widget named "([^"]*)"$/ do |name|
+ Factory(:widget, :name => name)
+ end
+ """
+ And I write to "features/support/factories.rb" with:
+ """
+ Factory.define :widget do |f|
+ f.name 'testwidget'
+ end
+ """
+ When I run `bundle exec rake db:migrate`
+ And I run `bundle exec rake cucumber`
+ Then it should pass with:
+ """
+ 1 scenario (1 passed)
+ 8 steps (8 passed)
+ """
View
30 lib/cucumber/rails/capybara/javascript_emulation.rb
@@ -19,6 +19,26 @@ def click_with_javascript_emulation
private
+ def csrf?
+ csrf_param_node && csrf_token_node
+ end
+
+ def csrf_param_node
+ element_node.document.at_xpath("//meta[@name='csrf-param']")
+ end
+
+ def csrf_param
+ csrf_param_node['content']
+ end
+
+ def csrf_token_node
+ element_node.document.at_xpath("//meta[@name='csrf-token']")
+ end
+
+ def csrf_token
+ csrf_token_node['content']
+ end
+
def js_form(document, action, emulated_method, method = 'POST')
js_form = document.create_element('form')
js_form['action'] = action
@@ -31,6 +51,16 @@ def js_form(document, action, emulated_method, method = 'POST')
input['value'] = emulated_method
js_form.add_child(input)
end
+
+ # rails will wipe the session if the CSRF token is not sent
+ # with non-GET requests
+ if csrf? && emulated_method.downcase != "get"
+ input = document.create_element('input')
+ input['type'] = 'hidden'
+ input['name'] = csrf_param
+ input['value'] = csrf_token
+ js_form.add_child(input)
+ end
js_form
end

0 comments on commit 93e28e1

Please sign in to comment.