diff --git a/app/validators/unique_username_validator.rb b/app/validators/unique_username_validator.rb index fb67105dd..4e24e3f5f 100644 --- a/app/validators/unique_username_validator.rb +++ b/app/validators/unique_username_validator.rb @@ -1,10 +1,12 @@ # frozen_string_literal: true +# See also: USERNAME_RE in the Account class + class UniqueUsernameValidator < ActiveModel::Validator def validate(account) return if account.username.nil? - normalized_username = account.username.downcase.delete('.') + normalized_username = account.username.downcase scope = Account.where(domain: nil).where('lower(username) = ?', normalized_username) scope = scope.where.not(id: account.id) if account.persisted? diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb index 6495a6193..3a17d540a 100644 --- a/spec/models/account_spec.rb +++ b/spec/models/account_spec.rb @@ -583,12 +583,29 @@ RSpec.describe Account, type: :model do expect(account.valid?).to be true end + it 'is valid if we are creating an instance actor account with a period' do + account = Fabricate.build(:account, id: -99, actor_type: 'Application', locked: true, username: 'example.com') + expect(account.valid?).to be true + end + + it 'is valid if we are creating a possibly-conflicting instance actor account' do + account_1 = Fabricate(:account, username: 'examplecom') + account_2 = Fabricate.build(:account, id: -99, actor_type: 'Application', locked: true, username: 'example.com') + expect(account_2.valid?).to be true + end + it 'is invalid if the username doesn\'t only contains letters, numbers and underscores' do account = Fabricate.build(:account, username: 'the-doctor') account.valid? expect(account).to model_have_error_on_field(:username) end + it 'is invalid if the username contains a period' do + account = Fabricate.build(:account, username: 'the.doctor') + account.valid? + expect(account).to model_have_error_on_field(:username) + end + it 'is invalid if the username is longer then 30 characters' do account = Fabricate.build(:account, username: Faker::Lorem.characters(31)) account.valid?