Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RSpec Test of Custom Devise Session Controller Fails with AbstractController::ActionNotFound

I am currently trying to test a custom Devise session controller with rspec. My controller looks like this:

class SessionsController < Devise::SessionsController

  def create 
    #valid email?
    if !(params[:email] =~ /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/)
      set_flash_message :notice, "Please enter a valid e-mail address!"
    end

    super
  end
end

My RSpec Controller Test is this:

require 'spec_helper'
require 'devise/test_helpers'

describe SessionsController do  

  it "should put a warning on invalid mail address login attempt" do
    post :create, :user => {:email => 'invalidEmailAddress'}
    response.should contain "Please enter a valid e-mail address!"
  end

  it "should put no warning on valid mail address login attempt" do
    pending
  end
end

If I execute the RSpec Test it fails with the following line:

Failure/Error: post :new, :user => {:email => 'invalidEmailAddress'}
     AbstractController::ActionNotFound
     # ./spec/controllers/sessions_controller_spec.rb:7

Tips from the plataformatec Devise Wiki as well as this post did not solve this issue. Thanks for your help.

Addition

I investigated further. I was actually able to "remove" the error with the following addition to the controller spec:

before(:each) do
  request.env['devise.mapping'] = Devise.mappings[:user]
end

But now a new error appears:

Failure/Error: post :create  #currently fails with multiple render warning
Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like "redirect_to(...) and return".

Even with the create method left out in the inheriting controller the error appears. The error does not appear on get :new for example. It seems to be post :create only. I am out of ideas? Any help? Thanks!

like image 973
kaihowl Avatar asked Nov 27 '10 12:11

kaihowl


1 Answers

I finally fixed my problem by doing including the devise test helpers, calling the method setup_controller_for_warden in my test AND doing request.env["devise.mapping"] = Devise.mappings[:user]. Like so:

require 'test_helper'

class SessionsControllerTest < ActionController::TestCase
    include Devise::TestHelpers

    test "should reject invalid captcha" do
       setup_controller_for_warden
       request.env["devise.mapping"] = Devise.mappings[:user]

       get :new

       assert_response :success
   end
end

Not sure about your double render problem though, are you sure your supposed to call post :create then render? i'm not sure how rspec is supposed to work.

like image 128
Paul Johnson Avatar answered Oct 18 '22 23:10

Paul Johnson