Здравствуйте, записался на курс. При этом ставил галочку на "обучаться с тьютором". На email пришло письмо, о том, что записался на самостоятельное изучение курса. Как выбрать тьютора? |
Войти, выйти
Вход после регистрации
В принципе, хотя мы закончили с аутентификацией, вновь зарегистрированные пользователи могут оказаться сбитыми с толку, так как они не вошли в систему по умолчанию. Реализация этого - последний штрих который мы добавим прежде чем позволим пользователям входить на наш сайт. Мы начнем с добавления строки к тестам аутентификации (Листинг 8.26). Это включает "after saving the user" describe блок из Листинга 7.32 (Раздел 7.6), который вы должны добавить в тест, если вы не сделали этого в соответствующем упражнении
require 'spec_helper' describe "User pages" do . . . describe "with valid information" do . . . describe "after saving the user" do before { click_button submit } let(:user) { User.find_by(email: 'user@example.com') } it { should have_link('Sign out') } it { should have_title(user.name) } it { should have_selector('div.alert.alert-success', text: 'Welcome') } end end end endЛистинг 8.26. Тестирование того, что вновь зарегистрированные пользователи также являются вошедшими. spec/requests/user_pages_spec.rb
Здесь мы протестировали появление ссылки на выход для того чтобы убедиться что пользователь успешно вошел после регистрации.
С методом sign_in из Раздела 8.2, получение прохождения этого теста фактически впустив пользователя в систему легко: просто добавим sign_in @user сразу после сохранения пользователя в базе данных (Листинг 8.27).
class UsersController < ApplicationController . . . def create @user = User.new(user_params) if @user.save sign_in @user flash[:success] = "Welcome to the Sample App!" redirect_to @user else render 'new' end end . . . endЛистинг 8.27. Вход пользователя сразу после регистрации. app/controllers/users_controller.rb
Выход
Как обсуждалось в Разделе 8.1, наша аутентификационная модель предполагает сохранение пользователей вошедшими до тех пор, пока они явно не выйдут из системы. В этом разделе мы добавим эту, необходимую нам и пользователям, возможность выхода.
До сих пор действия контроллера Sessions следовали RESTful конвенции, используя new для страницы входа и create для его завершения. Мы продолжим эту тему используя действие destroy для удаления сессий, т.е., для выхода. Для того чтобы протестировать это, мы кликнем по ссылке "Sign out" а затем попробуем найти вновь появившуюся ссылку на вход (Листинг 8.28).
require 'spec_helper' describe "Authentication" do . . . describe "signin" do . . . describe "with valid information" do . . . describe "followed by signout" do before { click_link "Sign out" } it { should have_link('Sign in') } end end end endЛистинг 8.28. Тест выхода пользователя. spec/requests/authentication_pages_spec.rb
Как и со входом пользователя, основанном на функции sign_in, выход пользователя просто перекладывает работу на функцию sign_out (Листинг 8.29).
class SessionsController < ApplicationController . . . def destroy sign_out redirect_to root_url end endЛистинг 8.29. Уничтожение сессии (выход пользователя). app/controllers/sessions_controller.rb
Как и другие элементы аутентификации, мы поместим sign_out в вспомогательный модуль Sessions. Листинг 8.30 показывает шаги: мы вначале меняем remember token пользователя в базе данных (на тот случай если куки были украдены, поскольку в этом случае они могут быть использованы для авторизации пользователя), затем мы вызываем метод delete на куках для удаления remember token из сессии; в качестве необязательного шага, мы устанавливаем текущего пользователя равным nil. (Как и назначение в методе sign_in (Листинг 8.19), установка текущего пользователя равным nil в настоящий момент не является строгой необходимостью из-за незамедлительного редиректа в действии destroy, но все же это хорошая идея - на случай если мы когда-либо захотим использовать sign_out без редиректа.)
module SessionsHelper def sign_in(user) remember_token = User.new_remember_token cookies.permanent[:remember_token] = remember_token user.update_attribute(:remember_token, User.encrypt(remember_token)) self.current_user = user end . . . def sign_out current_user.update_attribute(:remember_token, User.encrypt(User.new_remember_token)) cookies.delete(:remember_token) self.current_user = nil end endЛистинг 8.30. Метод sign_out в модуле Sessions хелпер. app/helpers/sessions_helper.rb
Это завершает триумвират регистрация/вход/выход и набор тестов должен пройти:
$ bundle exec rspec spec/
Стоит отметить, что наш набор тестов покрывает большую часть механизма аутентификации, но не все же не полностью. Например, мы не тестируем то как долго живет "remember me" куки и даже не тестируем устанавливается ли она вообще. Это возможно сделать, но практика показывает, что непосредственное тестирование значения куки является хрупким и имеет тенденцию зависеть от деталей реализации которые иногда меняются от одного релиза Rails к другому. Результатом служат рухнувшие тесты вполне себе рабочего кода. Фокусируясь на функционале верхнего уровня - проверяя что пользователи могут войти, оставаться вошедшими при переходе от страницы к странице и могут выйти - мы тестируем ядро кода приложения не заморачиваясь менее важными деталями.