discourse/spec/models/username_validator_spec.rb

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

277 lines
8.6 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
RSpec.describe UsernameValidator do
def expect_valid(*usernames, failure_reason: "")
usernames.each do |username|
validator = UsernameValidator.new(username)
message = "expected '#{username}' to be valid"
message = "#{message}, #{failure_reason}" if failure_reason.present?
aggregate_failures do
expect(validator.valid_format?).to eq(true), message
expect(validator.errors).to be_empty
end
end
end
def expect_invalid(*usernames, error_message:, failure_reason: "")
usernames.each do |username|
validator = UsernameValidator.new(username)
message = "expected '#{username}' to be invalid"
message = "#{message}, #{failure_reason}" if failure_reason.present?
aggregate_failures do
expect(validator.valid_format?).to eq(false), message
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),
failure_reason: "Should be invalid as username length > #{SiteSetting.max_username_length}",
)
end
it "is valid when the username has the maximum length" do
SiteSetting.max_username_length = 8
expect_valid(
"abcdefgh",
failure_reason: "Should be valid as username length = #{SiteSetting.max_username_length}",
)
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 "with ASCII usernames" do
include_examples "ASCII username"
end
context "with 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),
failure_reason:
"Should be invalid as username length are > #{SiteSetting.max_username_length}",
)
end
it "is valid when the username has the maximum length" do
SiteSetting.max_username_length = 9
expect_valid(
"Дровосек",
"چوب-لباسی",
"தமிழ்-தமிழ்",
failure_reason: "Should be valid as usernames are <= #{SiteSetting.max_username_length}",
)
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 invisible characters" do
expect_invalid(
"a\u{034F}b",
"a\u{115F}b",
"a\u{1160}b",
"a\u{17B4}b",
"a\u{17B5}b",
"a\u{180B}b",
"a\u{180C}b",
"a\u{180D}b",
"a\u{3164}b",
"a\u{FFA0}b",
"a\u{FE00}b",
"a\u{FE0F}b",
"a\u{E0100}b",
"a\u{E01EF}b",
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