2

I'm setting up devise for use in a rails 4 app with single table inheritance on the user model. We have 7 different classes of user, each with their own ActiveRecord model that inherits from a base User model.

I've worked through what I could find on the web, but I'm having a lot of weird problems around getting my tests set up correctly. I wrote a custom sessions_controller to figure out which type of user is trying to log in and signs in the correct resource class, and I wrote a little spec to verify it's working while I get the rest of the feature up and running. I can't seem to get the correct methods stubbed to get devise to work with rspec. I first kept running into the error:

Failure/Error: post :create, user: { email: 'fake@address.com' }
NoMethodError:
   undefined method `authenticate?' for nil:NilClass

which is weird because I include both devise and warden test helpers in my spec helper file (pasted below). When I also include Devise::TestHelpers in the SessionsController spec directly I get a different error however:

1) SessionsController POST create works
   Failure/Error: post :create, user: { email: 'fake@address.com' }
   ArgumentError:
     uncaught throw :warden
   # ./app/controllers/sessions_controller.rb:5:in 'create'
   # ./spec/controllers/sessions_controller_spec.rb:17:in 'block (3 levels) in <top (required)>'

I've done a ton of googling and only found suggestions around adding the devise and warden test helpers to the spec files or setting the "devise.mapping" on @request.env (both of which i've already done). Any and all help will be appreciated, especially a pointer to a tutorial on the web that I haven't seen ;). I've looked at these pages:

here is my sessions_controller.rb:

class SessionsController < Devise::SessionsController
  class UnrecognizedUserTypeError < StandardError; end

  def create
    created = super do
      sign_in(type, user_class.try(:find, resource.id))
    end

    created
  end

  private

  def type
    unless User::TYPES.include(type = resource.type.try(:underscore))
      raise UnrecognizedUserTypeError
    end

    type
  end

  def user_class
    type.try(:constantize)
  end
end

here is my sessions_controller_spec.rb:

require 'rails_helper'

describe SessionsController do
  # This line should not be needed since it has been included in spec_helper.rb
  # but this spec file doesn't seem to work without it (bl 2014-08-11).
  include Devise::TestHelpers

  before do
    setup_controller_for_warden
    # Since we're bypassing the router in this test, we need to explicitly
    # tell devise which mapping to use.
    @request.env["devise.mapping"] = Devise.mappings[:user]
  end

  describe "POST create" do
    it "works" do
      post :create
      expect(response.code).to eq(200)
    end
  end
end

and here are the relevant lines from my spec_helper.rb (which rails_helper requires)

RSpec.configure do |config|

  config.include FactoryGirl::Syntax::Methods
  config.include Devise::TestHelpers, type: :controller
  config.include Warden::Test::Helpers

  config.before(:suite) do
    begin
      DatabaseCleaner.start
      FactoryGirl.lint
      Warden.test_mode!
    ensure
      DatabaseCleaner.clean
    end
  end

  config.after(:suite) do
    Warden.test_reset!
  end
...
end

Here are the relevant lines from config/routes.rb:

Rails.application.routes.draw do
  devise_for :users, controllers: { sessions: 'sessions' }
  devise_for :administrator_users, skip: :sessions
  devise_for :manager_users, skip: :sessions
  devise_for :adjuster_users, skip: :sessions
  devise_for :nurse_case_manager_users, skip: :sessions
  devise_for :technical_assistant_users, skip: :sessions
  devise_for :provider_users, skip: :sessions
  devise_for :super_administrator_users, skip: :sessions
...
end
Community
  • 1
  • 1
732
  • 661
  • 5
  • 12

0 Answers0