How to test posts in Rails / Capybara / Cucumber or Rspec

后端 未结 2 590
[愿得一人]
[愿得一人] 2021-01-04 11:07

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.

相关标签:
2条回答
  • 2021-01-04 11:29

    I think you can do this with rack-test https://github.com/brynary/rack-test

    in your Gemfile:

    gem 'rack-test'
    

    in your env.rb file

    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

    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)

    0 讨论(0)
  • 2021-01-04 11:52

    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:

    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
    
    0 讨论(0)
提交回复
热议问题