lundi 5 juin 2017

How to fix this devise authenticated controller #create method failure?

I am trying to test the Quotes#create contrloller action but am having trouble understanding a Failure. I am using Devise and FactoryGirl. The rspec failure message is No route matches {:action=>"show", :controller=>"quotes", :id=>nil} missing required keys: [:id] is I believe telling me that Quote#create has no saved object to redirect_to, but I cannot see that anything is wrong.

My best guess is that the user passed to the quote object isnot getting through; let(:quote) { FactoryGirl.create(:quote, user: user) } thus the quote is not being saved.

Any guidance appreciated.

quotes_controller.rb

before_action :authenticate_user! 

  def create
    @quote = Quote.new(quote_params)
    if @quote.save
        redirect_to quote_url(@quote), notice: 'Quote request created'
    else
      render :new
    end
  end

quote.rb model:

class Quote < ApplicationRecord
    belongs_to :user

    enum industry:          [ :financial_services, :architect, :business_consultancy ]
    enum payment_frequency: [ :annually, :monthly ]
end

users.rb:

FactoryGirl.define do
  factory :user do
    sequence(:email) { |n| "test#{}@tes.com" }
    password "12345678"

    factory :user2 do
    end
  end
end

quotes.rb

FactoryGirl.define do
  factory :quote do
    prev_cover true
    sequence(:co_name) { |n| "Acme Co #{n}" }
    co_number 9999
    postcode "al1 1aa"
    industry :financial_services
    lives_overseas true
    scheme_start_date "2018-01-01"
    payment_frequency :monthly
    commission_level 12
    gla 1

    factory :quote2 do
    end
  end
end

quote_controller_spec.rb

RSpec.describe QuotesController, type: :controller do
    describe "signed in user" do

        let(:user) { FactoryGirl.create(:user) }
        let(:quote) { FactoryGirl.create(:quote, user: user) }

        before do
            sign_in(user)
        end

        describe "POST create" do

            context "valid data" do
                let(:valid_data) { FactoryGirl.attributes_for(:quote) }
                it "redirects to quote#show" do
                    post :create, params: { quote: valid_data }
                    expect(response).to redirect_to(quote_path(assigns[:quote]))
                end

                it " creates a new quote in the database" do
                    expect {
                        post :create, params: { quote: valid_data }
                    }.to change(Quote, :count).by(1)
                end
            end
        end
    end
end

rspec output:

 1) QuotesController signed in user POST create valid data redirects to quote#show
     Failure/Error: expect(response).to redirect_to(quote_path(assigns[:quote]))

     ActionController::UrlGenerationError:
       No route matches {:action=>"show", :controller=>"quotes", :id=>nil} missing required keys: [:id]
     # ./spec/controllers/quotes_controller_spec.rb:46:in `block (5 levels) in <top (required)>'

  2) QuotesController signed in user POST create valid data  creates a new quote in the database
     Failure/Error:
       expect {
        post :create, params: { quote: valid_data }
       }.to change(Quote, :count).by(1)

       expected #count to have changed by 1, but was changed by 0
     # ./spec/controllers/quotes_controller_spec.rb:50:in `block (5 levels) in <top (required)>'

Aucun commentaire:

Enregistrer un commentaire