I'm using rspec, cucumber and capybara and I'm looking for a way to test that a malicious user can't hack a form then post to an url he/she doesn't have permission to. I have my permissions set up in cancan such that this "should" work, however, the only way I can test it is by hacking a form myself.
我正在使用rspec,黄瓜和水豚,我正在寻找一种方法来测试恶意用户无法破解表单然后发布到他/她没有权限的网址。我已经在cancan中设置了我的权限,这样“应该”可以工作,但是,我可以测试它的唯一方法是自己黑客攻击表单。
How can I automate this sort of testing? With webrat I could do this in a unit test with rspec with something like
如何自动进行此类测试?有了webrat,我可以用rspec进行单元测试
put :update, :user_id => @user.id, :id => @user_achievement.id
response.should contain("Error, you don't have permission to access that!")
In capybara, however, visit only does get's it seems. I can't find a way to do this, I've googled everwhere.
然而,在水豚中,访问只是看起来似乎。我找不到办法做到这一点,我已经google了无处不在。
Any help would be much appreciated, Thanks
任何帮助将不胜感激,谢谢
2 个解决方案
#1
8
I think you can do this with rack-test https://github.com/brynary/rack-test
我认为你可以用机架测试https://github.com/brynary/rack-test来做到这一点
in your Gemfile:
在你的Gemfile中:
gem 'rack-test'
in your env.rb file
在你的env.rb文件中
module CapybaraApp
def app; Capybara.app; end
end
World(CapybaraApp)
World(Rack::Test::Methods)
step defintions somewhere:
步骤定义:
When /^I send a POST request to "([^"]*)"$/ do |path|
post path
end
Most of what I learned came from here: http://www.anthonyeden.com/2010/11/testing-rest-apis-with-cucumber-and-rack-test
我学到的大部分内容来自这里:http://www.anthonyeden.com/2010/11/testing-rest-apis-with-cucumber-and-rack-test
UPDATE: I think you can skip the changes to your env.rb file with newer versions of Rails and/or Cucumber (not sure which, I just don't do that part on my newer projects and it works fine)
更新:我认为你可以跳过你的env.rb文件的更改与更新版本的Rails和/或黄瓜(不知道哪些,我只是不做我的新项目的那部分,它工作正常)
#2
2
Same as @Josh Crews I've largely based this off of: http://www.anthonyeden.com/2010/11/testing-rest-apis-with-cucumber-and-rack-test/#comment-159. But there are two notable exceptions: 1) I test the actual response body, 2) I demonstrate how to test a POST request. Here's an example using Rails 3.0.9:
和@Josh Crews一样,我主要基于这个:http://www.anthonyeden.com/2010/11/testing-rest-apis-with-cucumber-and-rack-test/#comment-159。但有两个值得注意的例外:1)我测试实际的响应体,2)我演示了如何测试POST请求。这是使用Rails 3.0.9的示例:
Steps:
脚步:
# features/step_definitions/api_step.feature
When /^I send a GET request to "([^\"]*)"$/ do |url|
authorize(User.last.email, "cucumber")
header 'Accept', 'application/json'
header 'Content-Type', 'application/json'
get url
end
When /^I send a POST request to "([^\"]*)" with:$/ do |url, body|
authorize(User.last.email, "cucumber")
header 'Accept', 'application/json'
header 'Content-Type', 'application/json'
post url, body
end
Then /^the JSON response should have (\d+) "([^\"]*)" elements$/ do |number_of_children, name|
page = JSON.parse(last_response.body)
page.map { |d| d[name] }.length.should == number_of_children.to_i
end
Then /^I should receive the following JSON response:$/ do |expected_json|
expected_json = JSON.parse(expected_json)
response_json = JSON.parse(last_response.body)
response_json.should == expected_json
end
Then /^I should receive the following JSON object response:$/ do |expected_json|
expected_json = JSON.parse(expected_json)
response_json = JSON.parse(last_response.body)
if expected_json['id'] == 'RESPONSE_ID'
expected_json['id'] = response_json['id']
end
response_json.should == expected_json
end
Feature:
特征:
# features/api/some_feature.feature
Feature: Users API
Background:
Given the following users exist:
| id | name |
| 1 | Joe |
| 2 | Sue |
| 3 | Paul |
Scenario: Index action
When I send a GET request to "/users/"
Then the JSON response should have 3 "user" elements
And I should receive the following JSON response:
"""
[
{
"id":1,
"name":"Joe"
},
{
"id":2,
"name":"Sue"
},
{
"id":3,
"name":"Paul"
}
]
"""
Scenario: Create action
When I send a POST request to "/users/" with:
"""
{
"name":"Polly"
}
"""
Then I should receive the following JSON object response:
"""
{
"id":"RESPONSE_ID",
"name":"Polly"
}
"""
And I send a GET request to "/users/"
And the JSON response should have 4 "user" elements
#1
8
I think you can do this with rack-test https://github.com/brynary/rack-test
我认为你可以用机架测试https://github.com/brynary/rack-test来做到这一点
in your Gemfile:
在你的Gemfile中:
gem 'rack-test'
in your env.rb file
在你的env.rb文件中
module CapybaraApp
def app; Capybara.app; end
end
World(CapybaraApp)
World(Rack::Test::Methods)
step defintions somewhere:
步骤定义:
When /^I send a POST request to "([^"]*)"$/ do |path|
post path
end
Most of what I learned came from here: http://www.anthonyeden.com/2010/11/testing-rest-apis-with-cucumber-and-rack-test
我学到的大部分内容来自这里:http://www.anthonyeden.com/2010/11/testing-rest-apis-with-cucumber-and-rack-test
UPDATE: I think you can skip the changes to your env.rb file with newer versions of Rails and/or Cucumber (not sure which, I just don't do that part on my newer projects and it works fine)
更新:我认为你可以跳过你的env.rb文件的更改与更新版本的Rails和/或黄瓜(不知道哪些,我只是不做我的新项目的那部分,它工作正常)
#2
2
Same as @Josh Crews I've largely based this off of: http://www.anthonyeden.com/2010/11/testing-rest-apis-with-cucumber-and-rack-test/#comment-159. But there are two notable exceptions: 1) I test the actual response body, 2) I demonstrate how to test a POST request. Here's an example using Rails 3.0.9:
和@Josh Crews一样,我主要基于这个:http://www.anthonyeden.com/2010/11/testing-rest-apis-with-cucumber-and-rack-test/#comment-159。但有两个值得注意的例外:1)我测试实际的响应体,2)我演示了如何测试POST请求。这是使用Rails 3.0.9的示例:
Steps:
脚步:
# features/step_definitions/api_step.feature
When /^I send a GET request to "([^\"]*)"$/ do |url|
authorize(User.last.email, "cucumber")
header 'Accept', 'application/json'
header 'Content-Type', 'application/json'
get url
end
When /^I send a POST request to "([^\"]*)" with:$/ do |url, body|
authorize(User.last.email, "cucumber")
header 'Accept', 'application/json'
header 'Content-Type', 'application/json'
post url, body
end
Then /^the JSON response should have (\d+) "([^\"]*)" elements$/ do |number_of_children, name|
page = JSON.parse(last_response.body)
page.map { |d| d[name] }.length.should == number_of_children.to_i
end
Then /^I should receive the following JSON response:$/ do |expected_json|
expected_json = JSON.parse(expected_json)
response_json = JSON.parse(last_response.body)
response_json.should == expected_json
end
Then /^I should receive the following JSON object response:$/ do |expected_json|
expected_json = JSON.parse(expected_json)
response_json = JSON.parse(last_response.body)
if expected_json['id'] == 'RESPONSE_ID'
expected_json['id'] = response_json['id']
end
response_json.should == expected_json
end
Feature:
特征:
# features/api/some_feature.feature
Feature: Users API
Background:
Given the following users exist:
| id | name |
| 1 | Joe |
| 2 | Sue |
| 3 | Paul |
Scenario: Index action
When I send a GET request to "/users/"
Then the JSON response should have 3 "user" elements
And I should receive the following JSON response:
"""
[
{
"id":1,
"name":"Joe"
},
{
"id":2,
"name":"Sue"
},
{
"id":3,
"name":"Paul"
}
]
"""
Scenario: Create action
When I send a POST request to "/users/" with:
"""
{
"name":"Polly"
}
"""
Then I should receive the following JSON object response:
"""
{
"id":"RESPONSE_ID",
"name":"Polly"
}
"""
And I send a GET request to "/users/"
And the JSON response should have 4 "user" elements