Reputation: 5480
I know there are a ton of questions with this same problem but none of the solutions seem to be working for my situation.
I've defined my own sessions, registrations, and users controllers since I'm using an API with token authentication, but I can't seem to get my routes/scoping working.
I get the following error message upon trying to run an Spec test on my sessions controller (which inherits from DeviseController)
Failure/Error: post :create, credentials
AbstractController::ActionNotFound:
Could not find devise mapping for path "/api/v1/sessions/create?user_login%5Bemail%5D=rosina%40russel.name&user_login%5Bpassword%5D=12345678".
This may happen for two reasons:
1) You forgot to wrap your route inside the scope block. For example:
devise_scope :user do
get "/some/route" => "some_devise_controller"
end
2) You are testing a Devise controller bypassing the router.
If so, you can explicitly tell Devise which mapping to use:
@request.env["devise.mapping"] = Devise.mappings[:user]
I've actually done both of these things based on other answers that I've read, but I don't think its done correctly for my specific situation.
Here is the spec test I'm trying to run
describe "POST #create" do
before(:each) do
@user = FactoryGirl.create :user
@user.skip_confirmation!
@request.env['devise.mapping'] = Devise.mappings[:user]
end
context "when the credentials are correct" do
before(:each) do
credentials = { user_login: { :email => @user.email, :password => "12345678"} }
post :create, credentials
end
it "returns the user record corresponding to the given credentials" do
@user.reload
user_response = JSON.parse(response.body, symbolize_names: true)
expect(user_response[:auth_token]).to eql @user.auth_token
end
it { should respond_with :created }
end
end
As you can see, I'm specifying what it's saying that I haven't specified.
Here is the snippet from my routes.rb before the definition of my API in it's namespace:
namespace :api, defaults: { format: :json } do
namespace :v1 do
devise_for :users, skip: [:sessions, :registrations]
devise_scope :user do
post 'sessions', to: 'sessions#create'
delete 'sessions', to: 'sessions#destroy'
end
If anyone sees anything from with this please let me know, I'd love to test my controller...
And yes, my sessions_controller is located in app/controllers/api/v1/sessions_controller.rb
and it is properly defined as class API::V1::SessionsController < DeviseController
I noticed that devise_for is supposed to SET Devise.mapping but that seems to not be happening at all!
Upvotes: 1
Views: 875
Reputation: 5480
I should've done this right away. I sent Devise.mappings.inspect to the logger and it read that the mapping was stored in :api_v1_user
so the key in the mapping hash corresponds to the namespace that you wrote devise_for in... hopefully this will help others
Upvotes: 1
Reputation: 4649
Based on your routes, API is in json
format. So you need to specify that when sending post
method. Which is why I think rspec is complaining about that route not existing because it doesn't know to use json. Try changing this
post :create, credentials
to this
post :create, credentials, format: :json
Upvotes: 0