ruby-on-railsrspecintegration-testinghttp-verbsrack-test

Rails 5, RSpec with RackTest - deletion of a record feature test


I created a very simple Rails 5 demo application that has a bunch of categories (Category model). There is a _category.html.erb partial with a link to remove a category:

<%= link_to 'Remove', category_path(category), data: {method: :delete, confirm: 'Are you sure?'} %>

The corresponding destroy action:

@category.destroy
respond_to do |format|
  format.js
  format.html {redirect_to root_path, notice: 'Category destroyed!'}
end

Absolutely nothing fancy. Then I write an RSpec feature test that creates a category with FactoryGirl, visits the categories page and clicks the Remove link. After that the Category.count should equal to 0 (I also added other checks like "expect flash message to contain "Category destroyed!", but that doesn't really matter).

require 'rails_helper'

RSpec.feature 'Category deletion' do
  let!(:category) { create(:category) }

  scenario 'should be successful' do
    visit categories_path
    click_link 'Remove'
    page.save_and_open_page
    expect(Category.count).to eq(0)
  end
end

So my problem is that this ACTUALLY WORKS and I don't really understand why. The problem is that the Remove link has the method: :delete part which is processed by the jquery_ujs library that basically sends a request with the proper HTTP DELETE verb. If JavaScript is disabled on the page and I try to remove the category manually, it doesn't work - a simple GET request is sent.

I use the default RackTest driver with Capybara and it does not support JavaScript. But when I check the page's screenshot generated by the page.save_and_open_page it really does have the proper flash message.

Therefore the question is - why and how exactly is this working?


Solution

  • So, that's Capybara's doing. They have an option respect_data_method https://github.com/teamcapybara/capybara/blob/99a0372aeeb0f3cc2b8962e1753371de58b288c7/lib/capybara/rack_test/node.rb#L58 that basically checks for the data-method attribute and sends the proper HTTP request.

    Also, special thanks to Jamis Buck for noticing that.