Rails 3.0.9 + Devise + Cucumber + Capybara the infamous “No route matches /users/sign_out”

后端 未结 6 1806
我寻月下人不归
我寻月下人不归 2021-02-02 09:27

I am using devise 1.4.2 with rails 3.0.9, cucumber-rails 1.0.2, capybara 1.0.0. I got No route matches \"/users/sign_out\" error when I clicked logout. I added

6条回答
  •  青春惊慌失措
    2021-02-02 10:20

    So I have found that

    <%= link_to "Logout", destroy_user_session_path, :method => :delete %>
    

    rails helper generates following html

    Sign out
    

    and jquery_ujs.js has following method to convert the links with data-method="delete" attribute to a form and submit at runtime:

    // Handles "data-method" on links such as:
    // Delete
    handleMethod: function(link) {
    var href = link.attr('href'),
    method = link.data('method'),
    csrf_token = $('meta[name=csrf-token]').attr('content'),
    csrf_param = $('meta[name=csrf-param]').attr('content'),
    form = $('
    '), metadata_input = ''; if (csrf_param !== undefined && csrf_token !== undefined) { metadata_input += ''; } form.hide().append(metadata_input).appendTo('body'); form.submit(); }

    And Capybara helper visit('/users/sign_out') simply clicks the link and send a GET request to the server which does not have any route for this request.

    As opposed to link_to helper the button_to helper adds the required form within the html when page is rendered instead of relying on javascript:

    <%= button_to "Logout", destroy_user_session_path, :method => :delete %>
    

    generates following html

    with this I can easily use Capybara helper click_button('Logout') in my 'I sign out' step definition.

    "link_to with a method anything other than GET is actually a bad idea, as links can be right clicked and opened in a new tab/window, and because this just copies the url (and not the method) it will break for non-get links..."

    As Max Will explained right clicking and opening the link_to link with non-get data-method in new tab results in a broken link.

    Some more useful discussion on link_to helper with ':method => :delete' and capybara issue can be found on this link

    For now I would stick to simple link_to helper without :method attribute, and would prefer using button_to if I want to switch to non-get method for deleting.

    At the same time I think there should be a capybara helper equivalent to Visit to cater for data-method attribute to send post request, so that one could avoid using javascript based driver for integration testing. Or may be there already is one which I am not aware of. Correct me if I am wrong.

提交回复
热议问题