Skip to content

Commit 472f068

Browse files
committed
Merge pull request discourse#1345 from salbertson/refactor-find_by_username_or_email
Improve test coverage and refactor User.find_by_username_or_email
2 parents 3b15e2e + 1dbe1fb commit 472f068

2 files changed

Lines changed: 58 additions & 23 deletions

File tree

app/models/user.rb

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -128,23 +128,18 @@ def self.find_by_temporary_key(key)
128128
end
129129

130130
def self.find_by_username_or_email(username_or_email)
131-
lower_user = username_or_email.downcase
132-
lower_email = Email.downcase(username_or_email)
131+
conditions = if username_or_email.include?('@')
132+
{ email: Email.downcase(username_or_email) }
133+
else
134+
{ username_lower: username_or_email.downcase }
135+
end
133136

134-
users =
135-
if username_or_email.include?('@')
136-
User.where(email: lower_email)
137-
else
138-
User.where(username_lower: lower_user)
139-
end
140-
.to_a
137+
users = User.where(conditions).all
141138

142-
if users.count > 1
139+
if users.size > 1
143140
raise Discourse::TooManyMatches
144-
elsif users.count == 1
145-
users[0]
146141
else
147-
nil
142+
users.first
148143
end
149144
end
150145

spec/models/user_spec.rb

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -850,19 +850,59 @@
850850
end
851851
end
852852

853-
describe '#find_by_username_or_email' do
854-
it 'works correctly' do
855-
bob = Fabricate(:user, username: 'bob', name: 'bobs', email: 'bob@bob.com')
856-
bob2 = Fabricate(:user, username: 'bob2', name: 'bobs', email: 'bob2@bob.com')
853+
describe '.find_by_username_or_email' do
854+
it 'finds user by username' do
855+
bob = Fabricate(:user, username: 'bob')
857856

858-
expect(User.find_by_username_or_email('bob22@bob.com')).to eq(nil)
859-
expect(User.find_by_username_or_email('bobs')).to eq(nil)
857+
found_user = User.find_by_username_or_email('bob')
860858

861-
expect(User.find_by_username_or_email('bob2')).to eq(bob2)
862-
expect(User.find_by_username_or_email('bob2@BOB.com')).to eq(bob2)
859+
expect(found_user).to eq bob
860+
end
861+
862+
it 'finds user by email' do
863+
bob = Fabricate(:user, email: 'bob@example.com')
864+
865+
found_user = User.find_by_username_or_email('bob@example.com')
866+
867+
expect(found_user).to eq bob
868+
end
869+
870+
context 'when user does not exist' do
871+
it 'returns nil' do
872+
found_user = User.find_by_username_or_email('doesnotexist@example.com') ||
873+
User.find_by_username_or_email('doesnotexist')
874+
875+
expect(found_user).to be_nil
876+
end
877+
end
878+
879+
context 'when username case does not match' do
880+
it 'finds user' do
881+
bob = Fabricate(:user, username: 'bob')
882+
883+
found_user = User.find_by_username_or_email('Bob')
863884

864-
expect(User.find_by_username_or_email('bob')).to eq(bob)
865-
expect(User.find_by_username_or_email('bob@BOB.com')).to eq(bob)
885+
expect(found_user).to eq bob
886+
end
887+
end
888+
889+
context 'when email domain case does not match' do
890+
it 'finds user' do
891+
bob = Fabricate(:user, email: 'bob@example.com')
892+
893+
found_user = User.find_by_username_or_email('bob@Example.com')
894+
895+
expect(found_user).to eq bob
896+
end
897+
end
898+
899+
context 'when multiple users are found' do
900+
it 'raises an exception' do
901+
user_query = stub(all: [stub, stub])
902+
User.stubs(:where).with(username_lower: 'bob').returns(user_query)
903+
904+
expect { User.find_by_username_or_email('bob') }.to raise_error(Discourse::TooManyMatches)
905+
end
866906
end
867907
end
868908
end

0 commit comments

Comments
 (0)