Я нахожусь в процессе разделения функции смены пароля на своей странице на моем сайте. Весь процесс работает нормально, когда я выполняю его вручную как настоящий пользователь, но я не могу пройти тесты Cucumber, потому что при последнем обращении к контроллеру current_user таинственным образом возвращает ноль.
У меня серьезный момент WTF, потому что пользователь DEFINITELY входит в систему в начале тестов, и я выполняю все те же шаги, что и другие проходящие тесты, и, как я уже сказал, все работает нормально, когда шагая по нему рукой.
Вот тест на вопрос:
Scenario: The user should be able to change their password
Given I have a signed in user with email = "test@mycompany.com" and password = "password"
When I am on the change-password page # this hits registrations_controller#change_password
And I fill in "Current password" with "password"
And I fill in "New password" with "new_password"
And I fill in "Re-enter new password" with "new_password"
And I press "Update"
Then I should see "You updated your account successfully"
И шаг входа в систему:
Given /^I have a signed in user with email\s*=\s*"([^"]*)" and password\s*=\s*"([^"]*)"$/ do |email, password|
@user = User.new
@user.email = email
@user.password = password
@user.confirm!
@user.save!
visit '/sign_in'
fill_in("Email", :with => @user.email)
fill_in("Password", :with => @user.password)
click_button("Sign in")
end
Действия контроллера, из "registrations_controller.rb":
def change_password
# calling "current_user" here retuns the logged-in user as expected
@user = current_user
end
def update_password
# calling "current_user" here returns nil
# error occurs at call to nil.update_with_password
@user = current_user
if @user.update_with_password( params["user"] )
redirect_to after_update_path_for( @user )
else
clean_up_passwords( @user )
render_with_scope :change_password
end
end
Теперь мы используем devise (1.1.8), и я думаю, что я что-то не так сделал с маршрутами devise, которые выглядят так в "rout.rb"
devise_for :users, :controllers => {:confirmations => "confirmations", :sessions => "sessions", :registrations => "registrations"} do
# ...other routes here...
get "/change_password", :to => "registrations#change_password"
put "/update_password", :to => "registrations#update_password"
end
Наконец, для полноты, вот "change_password.html.haml"
= render :partial => "shared/stats"
#main
= form_for(resource, :as => resource_name, :url => "update_password", :html => { :method => :put, :autocomplete => "off" }) do |f|
= devise_error_messages!
.edit-account-hold
%span Your password
= f.label :current_password, "Current password"
= f.password_field :current_password
= f.label :password, "New password"
= f.password_field :password
= f.label :password_confirmation, "Re-enter new password"
= f.password_field :password_confirmation
= f.submit "Update", :class => "orange-button border-radius"
= link_to "Cancel", account_path, :id => "cancel-link"
:javascript
$(document).ready( function() {
$("#user_current_password").focus();
});