Refactor User.find_by_username_or_email

* Improve test coverage
This commit is contained in:
Scott Albertson 2013-08-16 11:40:30 -07:00
parent 0f27232711
commit 1dbe1fb1bc
2 changed files with 61 additions and 26 deletions

View File

@ -127,23 +127,18 @@ class User < ActiveRecord::Base
end end
def self.find_by_username_or_email(username_or_email) def self.find_by_username_or_email(username_or_email)
lower_user = username_or_email.downcase conditions = if username_or_email.include?('@')
lower_email = Email.downcase(username_or_email) { email: Email.downcase(username_or_email) }
users =
if username_or_email.include?('@')
User.where(email: lower_email)
else else
User.where(username_lower: lower_user) { username_lower: username_or_email.downcase }
end end
.to_a
if users.count > 1 users = User.where(conditions).all
if users.size > 1
raise Discourse::TooManyMatches raise Discourse::TooManyMatches
elsif users.count == 1
users[0]
else else
nil users.first
end end
end end

View File

@ -850,19 +850,59 @@ describe User do
end end
end end
describe '#find_by_username_or_email' do describe '.find_by_username_or_email' do
it 'works correctly' do it 'finds user by username' do
bob = Fabricate(:user, username: 'bob', name: 'bobs', email: 'bob@bob.com') bob = Fabricate(:user, username: 'bob')
bob2 = Fabricate(:user, username: 'bob2', name: 'bobs', email: 'bob2@bob.com')
expect(User.find_by_username_or_email('bob22@bob.com')).to eq(nil) found_user = User.find_by_username_or_email('bob')
expect(User.find_by_username_or_email('bobs')).to eq(nil)
expect(User.find_by_username_or_email('bob2')).to eq(bob2) expect(found_user).to eq bob
expect(User.find_by_username_or_email('bob2@BOB.com')).to eq(bob2) end
expect(User.find_by_username_or_email('bob')).to eq(bob) it 'finds user by email' do
expect(User.find_by_username_or_email('bob@BOB.com')).to eq(bob) bob = Fabricate(:user, email: 'bob@example.com')
found_user = User.find_by_username_or_email('bob@example.com')
expect(found_user).to eq bob
end
context 'when user does not exist' do
it 'returns nil' do
found_user = User.find_by_username_or_email('doesnotexist@example.com') ||
User.find_by_username_or_email('doesnotexist')
expect(found_user).to be_nil
end
end
context 'when username case does not match' do
it 'finds user' do
bob = Fabricate(:user, username: 'bob')
found_user = User.find_by_username_or_email('Bob')
expect(found_user).to eq bob
end
end
context 'when email domain case does not match' do
it 'finds user' do
bob = Fabricate(:user, email: 'bob@example.com')
found_user = User.find_by_username_or_email('bob@Example.com')
expect(found_user).to eq bob
end
end
context 'when multiple users are found' do
it 'raises an exception' do
user_query = stub(all: [stub, stub])
User.stubs(:where).with(username_lower: 'bob').returns(user_query)
expect { User.find_by_username_or_email('bob') }.to raise_error(Discourse::TooManyMatches)
end
end end
end end
end end