From 39a89ad564707c8332102b7c3a122c9915e045da Mon Sep 17 00:00:00 2001 From: Karol Selak Date: Sun, 21 Mar 2021 14:44:59 +0100 Subject: [PATCH] password recovery refactoring and tests --- app/controllers/users_controller.rb | 7 +- app/mailers/user_mailer.rb | 6 +- .../application_controller_spec.rb | 4 +- spec/controllers/users_controller_spec.rb | 95 +++++++++++++++++-- spec/mailers/user_mailer_spec.rb | 2 +- 5 files changed, 98 insertions(+), 16 deletions(-) diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index d0c62bf..fe97096 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -11,7 +11,10 @@ class UsersController < ApplicationController def password_recovery_request @user = User.where(email: params['email']).first - UserMailer.with(user: @user).password_recovery.deliver_now + recovery_password = ('a'..'z').to_a.shuffle[0,8].join + @user.recovery_password = recovery_password + @user.save + UserMailer.with(user: @user, recovery_password: recovery_password).password_recovery.deliver_now redirect_to '/welcome', notice: "Recovery email sent to #{params['email']}" end @@ -35,7 +38,7 @@ class UsersController < ApplicationController redirect_to '/welcome', notice: 'Passwords don\'t match' end else - redirect_to '/welcome', notice: 'Recovery link expired or unvalid' + redirect_to '/welcome', notice: 'Recovery link expired or invalid' end end end diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 6c23998..7a5ef41 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -1,10 +1,8 @@ class UserMailer < ApplicationMailer def password_recovery @user = params[:user] - recovery_password = ('a'..'z').to_a.shuffle[0,8].join - @user.recovery_password = recovery_password - @user.save - @url = "http://localhost:18210/recover_password/#{@user.id}/#{recovery_password}" + @recovery_password = params[:recovery_password] + @url = "http://localhost:18210/recover_password/#{@user.id}/#{@recovery_password}" mail(to: @user.email, subject: 'Password recovery') end end diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb index 90e5974..c6b1a80 100644 --- a/spec/controllers/application_controller_spec.rb +++ b/spec/controllers/application_controller_spec.rb @@ -3,12 +3,12 @@ require 'rails_helper' RSpec.describe ApplicationController do describe 'current_user' do before(:all) do - User.create(email: 'karol.selak@gmail.com', password: 'abcde') + User.create(email: 'test2@example.com', password: 'abcde') end context 'when a user is logged in' do it 'returns the user' do # TODO - # expect(current_user.email).to eql('karol.selak@gmail.com') + # expect(current_user.email).to eql('test2@example.com') end end end diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index 8253db7..5a5c41d 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -1,26 +1,107 @@ require 'rails_helper' RSpec.describe UsersController do + before(:all) do # TODO change it to cleanup after each test + User.destroy_all + end + let(:user1) do + User.create(email: 'test1@example.com', password: 'abcde', recovery_password: 'recovery password') + end describe 'get new' do - subject { get 'new' } + subject { get :new } it 'renders the users/new template' do expect(subject).to render_template('users/new') end end describe 'get create' do - before(:all) do # TODO change it to cleanup after each test - User.destroy_all + subject do + get :create, params: {user: {email: 'test2@example.com', password: 'abcde'}} end - subject { - get :create, params: {user: {email: 'karol.selak@gmail.com', password: 'abcde'}} - } it 'creates a user' do subject - expect(User.where(email: 'karol.selak@gmail.com').size).to eql(1) + expect(User.where(email: 'test2@example.com').size).to eql(1) end it 'redirects to /welcome' do subject expect(subject).to redirect_to('/welcome') end end + describe 'get password_recovery_request_form' do + subject { get :password_recovery_request_form } + it 'renders the users/password_recovery_request_form template' do + expect(subject).to render_template('users/password_recovery_request_form') + end + end + describe 'post password_recovery_request' do + subject do + get :password_recovery_request, params: {email: user1.email} + end + it 'sends the proper recovery email' do + srand(10) + subject + email_text = ActionMailer::Base.deliveries.last.body.raw_source + expect(email_text).to match("recover_password/#{user1.id}/tfohbclx") + end + it 'sends a recovery email to the proper email' do + subject + expect(ActionMailer::Base.deliveries.last.to).to eql([user1.email]) + end + it 'flashes a notice' do + subject + expect(subject.request.flash[:notice]).to match("Recovery email sent to #{user1.email}") + end + end + describe 'get recover_password_form' do + subject do + get :recover_password_form, params: {id: user1.id, recovery_password: 'recovery password'} + end + it 'renders proper form' do + subject + expect(subject).to render_template('users/recover_password_form') + end + end + describe 'post recover_password' do + context 'when passwords match and recovery password is proper' do + subject do + post :recover_password, params: { + user_id: user1.id, + recovery_password: 'recovery password', + password: 'new password', + password_confirmation: 'new password' + } + end + it 'flashes a notice about success' do + subject + expect(subject.request.flash[:notice]).to match('Password changed') + end + end + context 'when recovery password is inproper' do + subject do + post :recover_password, params: { + user_id: user1.id, + recovery_password: 'improper recovery password', + password: 'new password', + password_confirmation: 'new password' + } + end + it 'flashes a notice about failure' do + subject + expect(subject.request.flash[:notice]).to match('Recovery link expired or invalid') + end + end + context 'when passwords match and recovery password is improper' do + subject do + post :recover_password, params: { + user_id: user1.id, + recovery_password: 'recovery password', + password: 'new password', + password_confirmation: 'bad password' + } + end + it 'flashes a notice about failure' do + subject + expect(subject.request.flash[:notice]).to match('Passwords don\'t match') + end + end + end end \ No newline at end of file diff --git a/spec/mailers/user_mailer_spec.rb b/spec/mailers/user_mailer_spec.rb index 4a78b85..6ebbdf6 100644 --- a/spec/mailers/user_mailer_spec.rb +++ b/spec/mailers/user_mailer_spec.rb @@ -1,5 +1,5 @@ require "rails_helper" RSpec.describe UserMailer, type: :mailer do - pending "add some examples to (or delete) #{__FILE__}" + # TODO end