J. Doe
J. Doe

Reputation: 75

rspec to test respond_to format and csv

I want to test if top_users eq User.top_users in my rspec controller. How do i access the format.csv? I need something like:

it "format csv" do
  get :index, format: :csv
  # expect(something)……
end

Later want to test the csv: if file format is correct, without saving/downloading it.

Controller:

def index
  respond_to do |format|  
    format.csv do
      top_users = User.top_users

      send_data(
        top_users.to_csv,
        filename: "top-users-#{Time.zone.today}.csv"
      )
    end
  end
end

Model:

def self.to_csv
  CSV.generate(headers: true) do |csv|
    csv << [‘one’, ‘two’]

    all.each do |user|
      csv << user.csv_data
    end
  end
end

csv_data is: [user.name, user.email] or so…

Upvotes: 6

Views: 10308

Answers (3)

hrdwdmrbl
hrdwdmrbl

Reputation: 5279

At least with Rails 7, there are a few things going on here:

  1. What kind of test is being written? There is a subtle difference between the deprecated ActionController::TestCase and the new ActionDispatch::IntegrationTest. Both support the as argument but only the deprecated ActionController::TestCase supports the format argument.
  2. The as argument will not accept csv out of the box. This is because content types need to be recognized by ActionDispatch::RequestEncoder, and at least for me, it only knows about :json, :identity, and :turbo_stream. YMMV.

To get Rails to recognize CSV format, you must register it like so:

register_encoder :csv, param_encoder: -> params { params.to_s }

Source:

Upvotes: 0

Thomas Van Holder
Thomas Van Holder

Reputation: 1507

If you run into the error unknown keyword: :format, try this:

describe "GET/index generate CSV" do    
  it "generate CSV" do
    get :index, params: {format: :csv}
    expect(response.header['Content-Type']).to include 'text/csv'
    expect(response.body).to include('what you expect the file to have')
  end
end

Upvotes: 5

Somar Melkhem
Somar Melkhem

Reputation: 238

It doesn't matter CSV, PDF or something else, it's all about the response that you get from the get request with format csv. This is way i do test my the csv generator:

describe "GET/index generate CSV" do
  before :each do
    get :index, format: :csv
  end

  it "generate CSV" do
    expect(response.header['Content-Type']).to include 'text/csv'
    expect(response.body).to include('what you expect the file to have')
  end
end

And that's it.

For each user that you have you can do something like this:

 User.top_users.each do |user|
   expect(response.body).to include(user.name) # or the attr you want to check if it's in the file
 end

you can also add 'pry' gem, put binding.pry before expect and see the response and what elements would be helpful for you to check if the method works correctly as you expect.

Upvotes: 15

Related Questions