I'm trying to add a custom action to Devise's registration controller which allows users to change their passwords (I cannot use default registrations#edit
since I need a form for changing only password, not email/username). The implementation I wrote below works in development mode but I get this error when I test controller.
Failure/Error: get 'password'
ActionController::RoutingError:
No route matches {:controller=>"registrations", :action=>"password"}
There is my code (I tried to skip unrelated parts)
spec/controllers/registrations_controller_spec.rb
describe RegistrationsController do
include Devise::TestHelpers
before :each do
request.env["devise.mapping"] = Devise.mappings[:users]
end
describe "GET 'password'" do
it "..." do
# The problem is here,
get 'password' # it raises ActionController::RoutingError
end
end
end
app/controllers/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
# ...
def password
end
end
config/routes.rb
devise_for :users, path: 'account',
controllers: { registrations: 'registartions' },
skip: [:registartions, :sessions]
devise_scope :user do
# ...
scope '/account' do
get 'password' => 'devise/registartions#password', as: "change_password
do
end
spec_helper.rb
# ...
RSpec.configure do |config|
# ...
config.include Devise::TestHelpers, :type => :controller
end
I would usually add a comment for this, but I'm including a code block and it gets messy in comments.
It seems like you're trying to preform a GET
on /password
instead of on /account/password
.
From what I'm reading, you've got a mapping for /account/password
:
devise_scope :user do # used to remove /users/ part from devise URLs
# ...
scope '/account' do # adds /account to URLs
get 'password' => 'devise/registartions#password', as: "change_password"
# this will match /account/passwordAnswer
do
end
So you should either remove the scope, or replace your get request in test with this:
get "/account/password", :user => @user
or this
get change_password_path(@user)
Where @user
is a User
's mock.
Run rake routes
to confirm.