enum protocol: [:ostatus, :activitypub]
validates :username, presence: true
+ validates_with UniqueUsernameValidator, if: -> { will_save_change_to_username? }
# Remote user validations
- validates :username, uniqueness: { scope: :domain, case_sensitive: true }, if: -> { !local? && will_save_change_to_username? }
validates :username, format: { with: /\A#{USERNAME_RE}\z/i }, if: -> { !local? && will_save_change_to_username? }
# Local user validations
validates :username, format: { with: /\A[a-z0-9_]+\z/i }, length: { maximum: 30 }, if: -> { local? && will_save_change_to_username? && actor_type != 'Application' }
- validates_with UniqueUsernameValidator, if: -> { local? && will_save_change_to_username? }
validates_with UnreservedUsernameValidator, if: -> { local? && will_save_change_to_username? }
validates :display_name, length: { maximum: 30 }, if: -> { local? && will_save_change_to_display_name? }
validates :note, note_length: { maximum: 500 }, if: -> { local? && will_save_change_to_note? }
end
context 'when is remote' do
- it 'is invalid if the username is not unique in case-sensitive comparison among accounts in the same normalized domain' do
+ it 'is invalid if the username is same among accounts in the same normalized domain' do
Fabricate(:account, domain: 'にゃん', username: 'username')
account = Fabricate.build(:account, domain: 'xn--r9j5b5b', username: 'username')
account.valid?
expect(account).to model_have_error_on_field(:username)
end
- it 'is valid even if the username is unique only in case-sensitive comparison among accounts in the same normalized domain' do
+ it 'is invalid if the username is not unique in case-insensitive comparison among accounts in the same normalized domain' do
Fabricate(:account, domain: 'にゃん', username: 'username')
account = Fabricate.build(:account, domain: 'xn--r9j5b5b', username: 'Username')
account.valid?
- expect(account).not_to model_have_error_on_field(:username)
+ expect(account).to model_have_error_on_field(:username)
end
it 'is valid even if the username contains hyphens' do
describe UniqueUsernameValidator do
describe '#validate' do
+ context 'when local account' do
+ it 'does not add errors if username is nil' do
+ account = double(username: nil, domain: nil, persisted?: false, errors: double(add: nil))
+ subject.validate(account)
+ expect(account.errors).to_not have_received(:add)
+ end
+
+ it 'does not add errors when existing one is subject itself' do
+ account = Fabricate(:account, username: 'abcdef')
+ expect(account).to be_valid
+ end
+
+ it 'adds an error when the username is already used with ignoring cases' do
+ Fabricate(:account, username: 'ABCdef')
+ account = double(username: 'abcDEF', domain: nil, persisted?: false, errors: double(add: nil))
+ subject.validate(account)
+ expect(account.errors).to have_received(:add)
+ end
+
+ it 'does not add errors when same username remote account exists' do
+ Fabricate(:account, username: 'abcdef', domain: 'example.com')
+ account = double(username: 'abcdef', domain: nil, persisted?: false, errors: double(add: nil))
+ subject.validate(account)
+ expect(account.errors).to_not have_received(:add)
+ end
+ end
+ end
+
+ context 'when remote account' do
it 'does not add errors if username is nil' do
- account = double(username: nil, persisted?: false, errors: double(add: nil))
+ account = double(username: nil, domain: 'example.com', persisted?: false, errors: double(add: nil))
subject.validate(account)
expect(account.errors).to_not have_received(:add)
end
it 'does not add errors when existing one is subject itself' do
- account = Fabricate(:account, username: 'abcdef')
+ account = Fabricate(:account, username: 'abcdef', domain: 'example.com')
expect(account).to be_valid
end
it 'adds an error when the username is already used with ignoring cases' do
- Fabricate(:account, username: 'ABCdef')
- account = double(username: 'abcDEF', persisted?: false, errors: double(add: nil))
+ Fabricate(:account, username: 'ABCdef', domain: 'example.com')
+ account = double(username: 'abcDEF', domain: 'example.com', persisted?: false, errors: double(add: nil))
+ subject.validate(account)
+ expect(account.errors).to have_received(:add)
+ end
+
+ it 'adds an error when the domain is already used with ignoring cases' do
+ Fabricate(:account, username: 'ABCdef', domain: 'example.com')
+ account = double(username: 'ABCdef', domain: 'EXAMPLE.COM', persisted?: false, errors: double(add: nil))
subject.validate(account)
expect(account.errors).to have_received(:add)
end
+
+ it 'does not add errors when account with the same username and another domain exists' do
+ Fabricate(:account, username: 'abcdef', domain: 'example.com')
+ account = double(username: 'abcdef', domain: 'example2.com', persisted?: false, errors: double(add: nil))
+ subject.validate(account)
+ expect(account.errors).to_not have_received(:add)
+ end
end
end