0

I'm getting no route matches with rspec for testing a method in my controller.

Below is the test code:

let(:csv_file){ fixture_file_upload('files/sample_employee_data.csv', 'text/csv') }
    describe "#process_csv" do
      it "should output a valid csv file" do
        post '/payslips/process_csv', :csv => csv_file, :header => 1
        puts response
      end
    end

Below is my routes.rb file code:

PayCalculator::Application.routes.draw do
  resources :payslips do
    collection { post :process_csv }
  end

  root 'payslips#index'
end

Below is the method

def process_csv(uploaded_file = params[:files][:csv], headers = params[:files][:headers])
    begin
      rows = CSV_Manager.extract_csv(uploaded_file, headers)
      rows.each do |row|
        payslip = Payslip.create(
            :first_name => row[0],
            :last_name => row[1],
            :annual_salary => row[2],
            :superannuation => row[3].to_i,
            :payment_start_date => row[4]
            )

        redirect_to root_url, notice: payslip.errors.full_messages and return unless payslip.valid?
        prepare_output(row)
      end

      @rows = self.pay_data
      csv_file = CSV_Manager.prepare_csv(@rows, ["Name", "Pay Period", "Gross Income", "Income Tax", "Net Income", "Superannuation"])
      send_data csv_file, :type => 'text/csv; charset=iso-8859-1; header=present', 
                          :disposition => "attachment;filename=Payslip #{Date.today.to_s}.csv"

    rescue 
      redirect_to root_url, notice: "CSV not supplied or invalid format"
    end
  end

When I run rspec spec/ I get below error:

Failure/Error: post '/payslips/process_csv', :csv => csv_file, :header => 1

ActionController::UrlGeneratorError:
No route matches...

What could be wrong in here that is causing this error?

Passionate Engineer
  • 10,034
  • 26
  • 96
  • 168

2 Answers2

0

Try this:

post :process_csv, :files => {:csv => csv_file, :header => 1}
Marek Lipka
  • 50,622
  • 7
  • 87
  • 91
  • I get `NoMethodError: undefined method '[]' for nil:NilClass` – Passionate Engineer Oct 02 '13 at 12:33
  • @PassionateDeveloper so your controller (or your sample data) is probably broken. It's not related with question. – Marek Lipka Oct 02 '13 at 12:36
  • how can it be broken given all my other tests pass including `index` action in the same controller? – Passionate Engineer Oct 02 '13 at 12:40
  • @PassionateDeveloper your `process_csv` action can be broken while `index` action is fine. And it's probably the case. The error you are talking about points to `PayslipsController#process_csv` action, isn't it? – Marek Lipka Oct 02 '13 at 12:42
  • ok. But I have posted the entire `process_csv` function but the application still works fine using that method. It's just that routes initially isn't working properly or returning a NilClass somehow in RSpec – Passionate Engineer Oct 02 '13 at 12:44
  • @PassionateDeveloper Paste your error backtrace. BTW There is no functions in Ruby, there are methods. – Marek Lipka Oct 02 '13 at 12:46
  • params[:files][:headers] where you are passing :header => 1. Key is different. This will not cause no route found but just for correction. BTW you should really change the method definition of process_csv() . Please have a look in this question : http://stackoverflow.com/questions/9710303/rails-optional-argument – Anand Soni Oct 02 '13 at 12:47
  • @AnandSoni thanks, I didn't notice that the params passed into controller in test was also broken. Thanks again. – Marek Lipka Oct 02 '13 at 12:49
  • @AnandSoni thanks. you were right. I wish I could pick yours as an answer but you've posted as a comment instead...lol...I'll also look at the function to fix code smells on that aswell. Thanks! – Passionate Engineer Oct 02 '13 at 12:56
  • @MarekLipka that was the only problem with that test – Passionate Engineer Oct 02 '13 at 12:57
  • If my comment has resolve your problem then let me add in answer so that others can also get solution. – Anand Soni Oct 02 '13 at 12:58
  • @PassionateDeveloper You mean the only problem was the test. And I know now - I didn't notice - like I wrote - that params passed into controller in test are wrong. – Marek Lipka Oct 02 '13 at 12:59
  • @MarekLipka then should I take out the params from that function instead? – Passionate Engineer Oct 02 '13 at 13:02
  • @PassionateDeveloper nevertheless it was my answer that resolved No route matches error. Problem with params was separate. – Marek Lipka Oct 02 '13 at 13:03
  • @PassionateDeveloper yes, you should. Controller actions in rails don't receive arguments conventionally. You should use `params[:files][:csv]` and `params[:files][:header]` in your action body instead. – Marek Lipka Oct 02 '13 at 13:05
  • 2
    @MarekLipka thanks man. I love the Ruby community! I really need to get away from PHP! – Passionate Engineer Oct 02 '13 at 13:07
0

params[:files][:headers] where you are passing :header => 1. Key is different. This will not cause no route found probably but just for correction. As per rails convention action doesn't has parameters

If you are going to pass optional params in any methods: Please have a look at : http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_methods.html

Following is the example of method defination:

def foo(arg1="Miles", arg2="Coltrane", arg3="Roach")
  "#{arg1}, #{arg2}, #{arg3}."
end
Anand Soni
  • 5,070
  • 11
  • 50
  • 101