discourse/spec/models/username_validator_spec.rb

208 lines
7.2 KiB
Ruby
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# frozen_string_literal: true
require 'rails_helper'
describe UsernameValidator do
def expect_valid(*usernames)
usernames.each do |username|
validator = UsernameValidator.new(username)
aggregate_failures do
expect(validator.valid_format?).to eq(true), "expected '#{username}' to be valid"
expect(validator.errors).to be_empty
end
end
end
def expect_invalid(*usernames, error_message:)
usernames.each do |username|
validator = UsernameValidator.new(username)
aggregate_failures do
expect(validator.valid_format?).to eq(false), "expected '#{username}' to be invalid"
expect(validator.errors).to include(error_message)
end
end
end
shared_examples 'ASCII username' do
it 'is invalid when the username is blank' do
expect_invalid('', error_message: I18n.t(:'user.username.blank'))
end
it 'is invalid when the username is too short' do
SiteSetting.min_username_length = 4
expect_invalid('a', 'ab', 'abc',
error_message: I18n.t(:'user.username.short', min: 4))
end
it 'is valid when the username has the minimum length' do
SiteSetting.min_username_length = 4
expect_valid('abcd')
end
it 'is invalid when the username is too long' do
SiteSetting.max_username_length = 8
expect_invalid('abcdefghi',
error_message: I18n.t(:'user.username.long', max: 8))
end
it 'is valid when the username has the maximum length' do
SiteSetting.max_username_length = 8
expect_valid('abcdefgh')
end
it 'is valid when the username contains alphanumeric characters, dots, underscores and dashes' do
expect_valid('ab-cd.123_ABC-xYz')
end
it 'is invalid when the username contains non-alphanumeric characters other than dots, underscores and dashes' do
expect_invalid('abc|', 'a#bc', 'abc xyz',
error_message: I18n.t(:'user.username.characters'))
end
it 'is valid when the username starts with a alphanumeric character or underscore' do
expect_valid('abcd', '1abc', '_abc')
end
it 'is invalid when the username starts with a dot or dash' do
expect_invalid('.abc', '-abc',
error_message: I18n.t(:'user.username.must_begin_with_alphanumeric_or_underscore'))
end
it 'is valid when the username ends with a alphanumeric character' do
expect_valid('abcd', 'abc9')
end
it 'is invalid when the username ends with an underscore, a dot or dash' do
expect_invalid('abc_', 'abc.', 'abc-',
error_message: I18n.t(:'user.username.must_end_with_alphanumeric'))
end
it 'is invalid when the username contains consecutive underscores, dots or dashes' do
expect_invalid('a__bc', 'a..bc', 'a--bc',
error_message: I18n.t(:'user.username.must_not_contain_two_special_chars_in_seq'))
end
it 'is invalid when the username ends with certain file extensions' do
expect_invalid('abc.json', 'abc.png',
error_message: I18n.t(:'user.username.must_not_end_with_confusing_suffix'))
end
end
context 'when Unicode usernames are disabled' do
before { SiteSetting.unicode_usernames = false }
include_examples 'ASCII username'
it 'is invalid when the username contains non-ASCII characters except dots, underscores and dashes' do
expect_invalid('abcö', 'abc象',
error_message: I18n.t(:'user.username.characters'))
end
end
context 'when Unicode usernames are enabled' do
before { SiteSetting.unicode_usernames = true }
context "ASCII usernames" do
include_examples 'ASCII username'
end
context "Unicode usernames" do
before { SiteSetting.min_username_length = 1 }
it 'is invalid when the username is too short' do
SiteSetting.min_username_length = 3
expect_invalid('鳥', 'পাখি',
error_message: I18n.t(:'user.username.short', min: 3))
end
it 'is valid when the username has the minimum length' do
SiteSetting.min_username_length = 2
expect_valid('পাখি', 'طائر')
end
it 'is invalid when the username is too long' do
SiteSetting.max_username_length = 8
expect_invalid(וטב_עצים', 'Holzfäller',
error_message: I18n.t(:'user.username.long', max: 8))
end
it 'is valid when the username has the maximum length' do
SiteSetting.max_username_length = 9
expect_valid('Дровосек', 'چوب-لباسی', 'தமிழ்-தமிழ்')
end
it 'is invalid when the username has too many Unicode codepoints' do
SiteSetting.max_username_length = 30
expect_invalid('য়ায়ায়ায়ায়ায়ায়ায়ায়ায়ায়ায়ায়ায়ায়ায়ায়ায়ায়ায়ায়ায়ায়ায়ায়া',
error_message: I18n.t(:'user.username.too_long'))
end
it 'is valid when the username contains Unicode letters' do
expect_valid('鳥', 'طائر', 'թռչուն', 'πουλί', 'পাখি', 'madár', '새',
'پرنده', 'птица', 'fågel', 'นก', 'پرندے', 'ציפור')
end
it 'is valid when the username contains numbers from the Nd or Nl Unicode category' do
expect_valid('arabic٠١٢٣٤٥٦٧٨٩', 'bengali১২৩৫৬৮৯', 'romanⅥ', 'hangzhou〺')
end
it 'is invalid when the username contains numbers from the No Unicode category' do
expect_invalid('circled㊸', 'fraction¾',
error_message: I18n.t(:'user.username.characters'))
end
it 'is invalid when the username contains symbols or emojis' do
SiteSetting.min_username_length = 1
expect_invalid('©', '⇨', '“', '±', '‿', '😃', '🚗',
error_message: I18n.t(:'user.username.characters'))
end
it 'is invalid when the username contains zero width join characters' do
expect_invalid('ണ്‍', 'র‌্যাম',
error_message: I18n.t(:'user.username.characters'))
end
it 'is valid when the username ends with a Unicode Mark' do
expect_valid('தமிழ்')
end
it 'allows all Unicode letters when the allowlist is empty' do
expect_valid('鳥')
end
context "with Unicode allowlist" do
before { SiteSetting.allowed_unicode_username_characters = "[äöüÄÖÜß]" }
it 'is invalid when username contains non-allowlisted letters' do
expect_invalid('鳥', 'francès', error_message: I18n.t(:'user.username.characters'))
end
it 'is valid when username contains only allowlisted letters' do
expect_valid('Löwe', 'Ötzi')
end
it 'is valid when username contains only ASCII letters and numbers regardless of allowlist' do
expect_valid('a-z_A-Z.0-9')
end
it 'is valid after resetting the site setting' do
SiteSetting.allowed_unicode_username_characters = ""
expect_valid('鳥')
end
end
end
end
end