Fix email confirmation link not updating email (#6187)
A change introduced in #6125 prevents `Devise::Models::Confirmable#confirm` from being called for existing users, which in turn leads to `email` not being set to `unconfirmed_email`, breaking email updates. This also adds a test that would've caught this issue.
This commit is contained in:
		
				
					committed by
					
						 Eugen Rochko
						Eugen Rochko
					
				
			
			
				
	
			
			
			
						parent
						
							49e296e1b0
						
					
				
				
					commit
					5ec25ff3e1
				
			| @@ -126,18 +126,18 @@ class User < ApplicationRecord | ||||
|   end | ||||
|  | ||||
|   def confirm | ||||
|     return if confirmed? | ||||
|     new_user = !confirmed? | ||||
|  | ||||
|     super | ||||
|     update_statistics! | ||||
|     update_statistics! if new_user | ||||
|   end | ||||
|  | ||||
|   def confirm! | ||||
|     return if confirmed? | ||||
|     new_user = !confirmed? | ||||
|  | ||||
|     skip_confirmation! | ||||
|     save! | ||||
|     update_statistics! | ||||
|     update_statistics! if new_user | ||||
|   end | ||||
|  | ||||
|   def promote! | ||||
|   | ||||
| @@ -12,20 +12,40 @@ describe Auth::ConfirmationsController, type: :controller do | ||||
|   end | ||||
|  | ||||
|   describe 'GET #show' do | ||||
|     let!(:user) { Fabricate(:user, confirmation_token: 'foobar', confirmed_at: nil) } | ||||
|     context 'when user is unconfirmed' do | ||||
|       let!(:user) { Fabricate(:user, confirmation_token: 'foobar', confirmed_at: nil) } | ||||
|  | ||||
|     before do | ||||
|       allow(BootstrapTimelineWorker).to receive(:perform_async) | ||||
|       @request.env['devise.mapping'] = Devise.mappings[:user] | ||||
|       get :show, params: { confirmation_token: 'foobar' } | ||||
|       before do | ||||
|         allow(BootstrapTimelineWorker).to receive(:perform_async) | ||||
|         @request.env['devise.mapping'] = Devise.mappings[:user] | ||||
|         get :show, params: { confirmation_token: 'foobar' } | ||||
|       end | ||||
|  | ||||
|       it 'redirects to login' do | ||||
|         expect(response).to redirect_to(new_user_session_path) | ||||
|       end | ||||
|  | ||||
|       it 'queues up bootstrapping of home timeline' do | ||||
|         expect(BootstrapTimelineWorker).to have_received(:perform_async).with(user.account_id) | ||||
|       end | ||||
|     end | ||||
|  | ||||
|     it 'redirects to login' do | ||||
|       expect(response).to redirect_to(new_user_session_path) | ||||
|     end | ||||
|     context 'when user is updating email' do | ||||
|       let!(:user) { Fabricate(:user, confirmation_token: 'foobar', unconfirmed_email: 'new-email@example.com') } | ||||
|  | ||||
|     it 'queues up bootstrapping of home timeline' do | ||||
|       expect(BootstrapTimelineWorker).to have_received(:perform_async).with(user.account_id) | ||||
|       before do | ||||
|         allow(BootstrapTimelineWorker).to receive(:perform_async) | ||||
|         @request.env['devise.mapping'] = Devise.mappings[:user] | ||||
|         get :show, params: { confirmation_token: 'foobar' } | ||||
|       end | ||||
|  | ||||
|       it 'redirects to login' do | ||||
|         expect(response).to redirect_to(new_user_session_path) | ||||
|       end | ||||
|  | ||||
|       it 'does not queue up bootstrapping of home timeline' do | ||||
|         expect(BootstrapTimelineWorker).to_not have_received(:perform_async) | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| end | ||||
|   | ||||
| @@ -148,6 +148,14 @@ RSpec.describe User, type: :model do | ||||
|     end | ||||
|   end | ||||
|  | ||||
|   describe '#confirm' do | ||||
|     it 'sets email to unconfirmed_email' do | ||||
|       user = Fabricate.build(:user, confirmed_at: Time.now.utc, unconfirmed_email: 'new-email@example.com') | ||||
|       user.confirm | ||||
|       expect(user.email).to eq 'new-email@example.com' | ||||
|     end | ||||
|   end | ||||
|  | ||||
|   describe '#disable_two_factor!' do | ||||
|     it 'saves false for otp_required_for_login' do | ||||
|       user = Fabricate.build(:user, otp_required_for_login: true) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user