DEV: Move spec/components to spec/lib (#15987)

Lib specs were inexplicably split into two directories (`lib` and `components`)

This moves them all into `lib`.
This commit is contained in:
Jarek Radosz
2022-02-18 19:41:54 +01:00
committed by GitHub
parent cf545be338
commit 45cc16098d
199 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
# frozen_string_literal: true
require 'rails_helper'
describe AllowedIpAddressValidator do
let(:record) { Fabricate.build(:user, trust_level: TrustLevel[0], ip_address: '99.232.23.123') }
let(:validator) { described_class.new(attributes: :ip_address) }
subject(:validate) { validator.validate_each(record, :ip_address, record.ip_address) }
context "ip address should be blocked" do
it 'should add an error' do
ScreenedIpAddress.stubs(:should_block?).returns(true)
validate
expect(record.errors[:ip_address]).to be_present
expect(record.errors[:ip_address][0]).to eq(I18n.t('user.ip_address.blocked'))
end
end
context "ip address isn't allowed for registration" do
it 'should add an error' do
SpamHandler.stubs(:should_prevent_registration_from_ip?).returns(true)
validate
expect(record.errors[:ip_address]).to be_present
expect(record.errors[:ip_address][0]).to eq(I18n.t('user.ip_address.max_new_accounts_per_registration_ip'))
end
end
context "ip address should not be blocked" do
it "shouldn't add an error" do
ScreenedIpAddress.stubs(:should_block?).returns(false)
validate
expect(record.errors[:ip_address]).not_to be_present
end
end
context 'ip_address is nil' do
it "shouldn't add an error" do
ScreenedIpAddress.expects(:should_block?).never
record.ip_address = nil
validate
expect(record.errors[:ip_address]).not_to be_present
end
end
end

View File

@@ -0,0 +1,20 @@
# frozen_string_literal: true
require 'rails_helper'
require 'validators/category_search_priority_weights_validator'
RSpec.describe CategorySearchPriorityWeightsValidator do
it "should validate the results correctly" do
[1, 1.1].each do |value|
expect do
SiteSetting.category_search_priority_low_weight = value
end.to raise_error(Discourse::InvalidParameters)
end
[1, "0.9"].each do |value|
expect do
SiteSetting.category_search_priority_high_weight = value
end.to raise_error(Discourse::InvalidParameters)
end
end
end

View File

@@ -0,0 +1,23 @@
# frozen_string_literal: true
require 'rails_helper'
describe CssColorValidator do
subject { described_class.new }
it "validates hex colors" do
expect(subject.valid_value?('#0')).to eq(false)
expect(subject.valid_value?('#00')).to eq(false)
expect(subject.valid_value?('#000')).to eq(true)
expect(subject.valid_value?('#0000')).to eq(false)
expect(subject.valid_value?('#00000')).to eq(false)
expect(subject.valid_value?('#000000')).to eq(true)
end
it "validates css colors" do
expect(subject.valid_value?('red')).to eq(true)
expect(subject.valid_value?('green')).to eq(true)
expect(subject.valid_value?('blue')).to eq(true)
expect(subject.valid_value?('hello')).to eq(false)
end
end

View File

@@ -0,0 +1,17 @@
# frozen_string_literal: true
require 'rails_helper'
describe EmailAddressValidator do
it 'should match valid emails' do
['test@discourse.org', 'good_user@discourse.org', 'incoming+%{reply_key}@discourse.org'].each do |email|
expect(EmailAddressValidator.valid_value?(email)).to eq(true)
end
end
it 'should not match invalid emails' do
['testdiscourse.org', 'frank@invalid_host.contoso.com', 'frank@invalid_host.com', 'test@discourse.org; a@discourse.org', 'random', ''].each do |email|
expect(EmailAddressValidator.valid_value?(email)).to eq(false)
end
end
end

View File

@@ -0,0 +1,22 @@
# frozen_string_literal: true
require 'rails_helper'
describe EmailSettingValidator do
describe '#valid_value?' do
subject(:validator) { described_class.new }
it "returns true for blank values" do
expect(validator.valid_value?('')).to eq(true)
expect(validator.valid_value?(nil)).to eq(true)
end
it "returns true if value is a valid email address" do
expect(validator.valid_value?('vader@example.com')).to eq(true)
end
it "returns false if value is not a valid email address" do
expect(validator.valid_value?('my house')).to eq(false)
end
end
end

View File

@@ -0,0 +1,60 @@
# frozen_string_literal: true
require 'rails_helper'
describe EmailValidator do
def blocks?(email)
user = Fabricate.build(:user, email: email)
validator = EmailValidator.new(attributes: :email)
validator.validate_each(user, :email, user.email)
user.errors[:email].present?
end
context "blocked email" do
it "doesn't add an error when email doesn't match a blocked email" do
expect(blocks?('sam@sam.com')).to eq(false)
end
it "adds an error when email matches a blocked email" do
ScreenedEmail.create!(email: 'sam@sam.com', action_type: ScreenedEmail.actions[:block])
expect(blocks?('sam@sam.com')).to eq(true)
expect(blocks?('SAM@sam.com')).to eq(true)
end
it "blocks based on blocked_email_domains" do
SiteSetting.blocked_email_domains = "email.com|mail.com|e-mail.com"
expect(blocks?('sam@email.com')).to eq(true)
expect(blocks?('sam@EMAIL.com')).to eq(true)
expect(blocks?('sam@bob.email.com')).to eq(true)
expect(blocks?('sam@e-mail.com')).to eq(true)
expect(blocks?('sam@googlemail.com')).to eq(false)
end
it "blocks based on allowed_email_domains" do
SiteSetting.allowed_email_domains = "googlemail.com|email.com"
expect(blocks?('sam@email.com')).to eq(false)
expect(blocks?('sam@EMAIL.com')).to eq(false)
expect(blocks?('sam@bob.email.com')).to eq(false)
expect(blocks?('sam@e-mail.com')).to eq(true)
expect(blocks?('sam@googlemail.com')).to eq(false)
expect(blocks?('sam@email.computers.are.evil.com')).to eq(true)
end
end
context "auto approve email domains" do
it "works as expected" do
SiteSetting.auto_approve_email_domains = "example.com"
expect(EmailValidator.can_auto_approve_user?("foobar@example.com.fr")).to eq(false)
expect(EmailValidator.can_auto_approve_user?("foobar@example.com")).to eq(true)
end
it "returns false if domain not present in allowed_email_domains" do
SiteSetting.allowed_email_domains = "googlemail.com"
SiteSetting.auto_approve_email_domains = "example.com|googlemail.com"
expect(EmailValidator.can_auto_approve_user?("foobar@example.com")).to eq(false)
expect(EmailValidator.can_auto_approve_user?("foobar@googlemail.com")).to eq(true)
end
end
end

View File

@@ -0,0 +1,33 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe EnableInviteOnlyValidator do
subject { described_class.new }
context "when sso is enabled" do
before do
SiteSetting.discourse_connect_url = "https://example.com/sso"
SiteSetting.enable_discourse_connect = true
end
it "is valid when false" do
expect(subject.valid_value?('f')).to eq(true)
end
it "is isn't value for true" do
expect(subject.valid_value?('t')).to eq(false)
expect(subject.error_message).to eq(I18n.t(
'site_settings.errors.discourse_connect_invite_only'
))
end
end
context "when sso isn't enabled" do
it "is valid when true or false" do
expect(subject.valid_value?('f')).to eq(true)
expect(subject.valid_value?('t')).to eq(true)
end
end
end

View File

@@ -0,0 +1,49 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe EnableLocalLoginsViaEmailValidator do
subject { described_class.new }
describe '#valid_value?' do
describe "when 'enable_local_logins' is false" do
before do
SiteSetting.enable_local_logins = false
end
describe 'when val is false' do
it 'should be valid' do
expect(subject.valid_value?('f')).to eq(true)
end
end
describe 'when value is true' do
it 'should not be valid' do
expect(subject.valid_value?('t')).to eq(false)
expect(subject.error_message).to eq(I18n.t(
'site_settings.errors.enable_local_logins_disabled'
))
end
end
end
describe "when 'enable_local_logins' is true" do
before do
SiteSetting.enable_local_logins = true
end
describe 'when val is false' do
it 'should be valid' do
expect(subject.valid_value?('f')).to eq(true)
end
end
describe 'when value is true' do
it 'should be valid' do
expect(subject.valid_value?('t')).to eq(true)
end
end
end
end
end

View File

@@ -0,0 +1,68 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe EnableSsoValidator do
subject { described_class.new }
describe '#valid_value?' do
describe "when 'sso url' is empty" do
before do
SiteSetting.discourse_connect_url = ""
end
describe 'when val is false' do
it 'should be valid' do
expect(subject.valid_value?('f')).to eq(true)
end
end
describe 'when value is true' do
it 'should not be valid' do
expect(subject.valid_value?('t')).to eq(false)
expect(subject.error_message).to eq(I18n.t(
'site_settings.errors.discourse_connect_url_is_empty'
))
end
end
end
describe "when invite_only is set" do
before do
SiteSetting.invite_only = true
SiteSetting.discourse_connect_url = 'https://example.com/sso'
end
it 'allows a false value' do
expect(subject.valid_value?('f')).to eq(true)
end
it "doesn't allow true" do
expect(subject.valid_value?('t')).to eq(false)
expect(subject.error_message).to eq(I18n.t(
'site_settings.errors.discourse_connect_invite_only'
))
end
end
describe "when 'sso url' is present" do
before do
SiteSetting.discourse_connect_url = "https://www.example.com/sso"
end
describe 'when value is false' do
it 'should be valid' do
expect(subject.valid_value?('f')).to eq(true)
end
end
describe 'when value is true' do
it 'should be valid' do
expect(subject.valid_value?('t')).to eq(true)
end
end
end
end
end

View File

@@ -0,0 +1,27 @@
# frozen_string_literal: true
require 'rails_helper'
describe ExternalSystemAvatarsValidator do
subject { described_class.new }
it "disallows disabling external system avatars when Unicode usernames are enabled" do
SiteSetting.unicode_usernames = true
expect(subject.valid_value?("f")).to eq(false)
expect(subject.error_message).to eq(I18n.t("site_settings.errors.unicode_usernames_avatars"))
expect(subject.valid_value?("t")).to eq(true)
expect(subject.error_message).to be_blank
end
it "allows disabling external system avatars when Unicode usernames are disabled" do
SiteSetting.unicode_usernames = false
expect(subject.valid_value?("t")).to eq(true)
expect(subject.error_message).to be_blank
expect(subject.valid_value?("f")).to eq(true)
expect(subject.error_message).to be_blank
end
end

View File

@@ -0,0 +1,23 @@
# frozen_string_literal: true
require 'rails_helper'
describe GroupSettingValidator do
describe '#valid_value?' do
subject(:validator) { described_class.new }
it "returns true for blank values" do
expect(validator.valid_value?('')).to eq(true)
expect(validator.valid_value?(nil)).to eq(true)
end
it "returns true if value matches an existing group" do
Fabricate(:group, name: "hello")
expect(validator.valid_value?('hello')).to eq(true)
end
it "returns false if value does not match a group" do
expect(validator.valid_value?('notagroup')).to eq(false)
end
end
end

View File

@@ -0,0 +1,31 @@
# frozen_string_literal: true
require 'rails_helper'
describe HostListSettingValidator do
subject(:validator) { described_class.new() }
describe '#valid_value?' do
describe "returns false for values containing *" do
it { expect(validator.valid_value?("*")).to eq false }
it { expect(validator.valid_value?("**")).to eq false }
it { expect(validator.valid_value?(".*")).to eq false }
it { expect(validator.valid_value?("a")).to eq true }
end
describe "returns false for values containing ?" do
it { expect(validator.valid_value?("?")).to eq false }
it { expect(validator.valid_value?("??")).to eq false }
it { expect(validator.valid_value?(".?")).to eq false }
it { expect(validator.valid_value?("a")).to eq true }
end
end
describe "#error_message" do
it "returns invalid domain hostname error" do
expect(validator.error_message).to eq(I18n.t(
'site_settings.errors.invalid_domain_hostname'
))
end
end
end

View File

@@ -0,0 +1,112 @@
# frozen_string_literal: true
require 'rails_helper'
describe IntegerSettingValidator do
describe '#valid_value?' do
shared_examples "for all IntegerSettingValidator opts" do
it "returns false for blank values" do
expect(validator.valid_value?('')).to eq(false)
expect(validator.valid_value?(nil)).to eq(false)
end
it "returns false if value is not a valid integer" do
expect(validator.valid_value?('two')).to eq(false)
end
end
context "without min and max" do
subject(:validator) { described_class.new }
include_examples "for all IntegerSettingValidator opts"
it "returns true if value is a valid integer" do
expect(validator.valid_value?(1)).to eq(true)
expect(validator.valid_value?('1')).to eq(true)
end
it "defaults min to 0" do
expect(validator.valid_value?(-1)).to eq(false)
expect(validator.valid_value?('-1')).to eq(false)
expect(validator.valid_value?(0)).to eq(true)
expect(validator.valid_value?('0')).to eq(true)
end
it "defaults max to 2_000_000_000" do
expect(validator.valid_value?(2_000_000_001)).to eq(false)
expect(validator.valid_value?('2000000001')).to eq(false)
expect(validator.valid_value?(2_000_000_000)).to eq(true)
expect(validator.valid_value?('2000000000')).to eq(true)
end
end
context "with min" do
subject(:validator) { described_class.new(min: 2) }
include_examples "for all IntegerSettingValidator opts"
it "returns true if value is equal to min" do
expect(validator.valid_value?(2)).to eq(true)
expect(validator.valid_value?('2')).to eq(true)
end
it "returns true if value is greater than min" do
expect(validator.valid_value?(3)).to eq(true)
expect(validator.valid_value?('3')).to eq(true)
end
it "returns false if value is less than min" do
expect(validator.valid_value?(1)).to eq(false)
expect(validator.valid_value?('1')).to eq(false)
end
end
context "with max" do
subject(:validator) { described_class.new(max: 3) }
include_examples "for all IntegerSettingValidator opts"
it "returns true if value is equal to max" do
expect(validator.valid_value?(3)).to eq(true)
expect(validator.valid_value?('3')).to eq(true)
end
it "returns true if value is less than max" do
expect(validator.valid_value?(2)).to eq(true)
expect(validator.valid_value?('2')).to eq(true)
end
it "returns false if value is greater than min" do
expect(validator.valid_value?(4)).to eq(false)
expect(validator.valid_value?('4')).to eq(false)
end
end
context "with min and max" do
subject(:validator) { described_class.new(min: -1, max: 3) }
include_examples "for all IntegerSettingValidator opts"
it "returns true if value is in range" do
expect(validator.valid_value?(-1)).to eq(true)
expect(validator.valid_value?(0)).to eq(true)
expect(validator.valid_value?(3)).to eq(true)
end
it "returns false if value is out of range" do
expect(validator.valid_value?(4)).to eq(false)
expect(validator.valid_value?(-2)).to eq(false)
end
end
context "when setting is hidden" do
subject(:validator) { described_class.new(hidden: true) }
it "does not impose default validations" do
expect(validator.valid_value?(-1)).to eq(true)
expect(validator.valid_value?(20001)).to eq(true)
end
end
end
end

View File

@@ -0,0 +1,30 @@
# frozen_string_literal: true
require 'rails_helper'
describe IpAddressFormatValidator do
let(:record) { Fabricate.build(:screened_ip_address, ip_address: '99.232.23.123') }
let(:validator) { described_class.new(attributes: :ip_address) }
subject(:validate) { validator.validate_each(record, :ip_address, record.ip_address) }
['99.232.23.123', '99.232.0.0/16', 'fd12:db8::ff00:42:8329', 'fc00::/7'].each do |arg|
it "should not add an error for #{arg}" do
record.ip_address = arg
validate
expect(record.errors[:ip_address]).not_to be_present
end
end
it 'should add an error for nil IP address' do
record.ip_address = nil
validate
expect(record.errors[:ip_address]).to be_present
end
it 'should add an error for invalid IP address' do
record.ip_address = '99.99.99'
validate
expect(record.errors[:ip_address]).to be_present
end
end

View File

@@ -0,0 +1,57 @@
# encoding: UTF-8
# frozen_string_literal: true
require 'rails_helper'
require 'validators/max_emojis_validator'
describe MaxEmojisValidator do
# simulate Rails behavior (singleton)
def validate
@validator ||= MaxEmojisValidator.new(attributes: :title)
@validator.validate_each(record, :title, record.title)
end
shared_examples "validating any topic title" do
it 'adds an error when emoji count is greater than SiteSetting.max_emojis_in_title' do
SiteSetting.max_emojis_in_title = 3
CustomEmoji.create!(name: 'trout', upload: Fabricate(:upload))
Emoji.clear_cache
record.title = '🧐 Lots of emojis here 🎃 :trout: :)'
validate
expect(record.errors[:title][0]).to eq(I18n.t("errors.messages.max_emojis", max_emojis_count: 3))
record.title = ':joy: :blush: :smile: is not only about emojis: Happiness::start()'
validate
expect(record.valid?).to be true
end
end
describe 'topic' do
let(:record) { Fabricate.build(:topic) }
it 'does not add an error when emoji count is good' do
SiteSetting.max_emojis_in_title = 2
record.title = 'To Infinity and beyond! 🚀 :woman:t5:'
validate
expect(record.errors[:title]).to_not be_present
end
include_examples "validating any topic title"
end
describe 'private message' do
let(:record) { Fabricate.build(:private_message_topic) }
it 'does not add an error when emoji count is good' do
SiteSetting.max_emojis_in_title = 1
record.title = 'To Infinity and beyond! 🚀'
validate
expect(record.errors[:title]).to_not be_present
end
include_examples "validating any topic title"
end
end

View File

@@ -0,0 +1,28 @@
# frozen_string_literal: true
require 'rails_helper'
describe MaxUsernameLengthValidator do
it "checks for minimum range" do
SiteSetting.min_username_length = 6
validator = described_class.new
expect(validator.valid_value?(5)).to eq(false)
expect(validator.error_message).to eq(I18n.t("site_settings.errors.max_username_length_range"))
end
it "checks for users with short usernames" do
user = Fabricate(:user, username: 'jackjackjack')
validator = described_class.new
expect(validator.valid_value?(12)).to eq(true)
validator = described_class.new
expect(validator.valid_value?(11)).to eq(false)
expect(validator.error_message).to eq(I18n.t(
"site_settings.errors.max_username_length_exists",
username: 'jackjackjack'
))
end
end

View File

@@ -0,0 +1,28 @@
# frozen_string_literal: true
require 'rails_helper'
describe MinUsernameLengthValidator do
it "checks for maximum range" do
SiteSetting.max_username_length = 10
validator = described_class.new
expect(validator.valid_value?(11)).to eq(false)
expect(validator.error_message).to eq(I18n.t("site_settings.errors.min_username_length_range"))
end
it "checks for users with short usernames" do
user = Fabricate(:user, username: 'jack')
validator = described_class.new
expect(validator.valid_value?(4)).to eq(true)
validator = described_class.new
expect(validator.valid_value?(5)).to eq(false)
expect(validator.error_message).to eq(I18n.t(
"site_settings.errors.min_username_length_exists",
username: 'jack'
))
end
end

View File

@@ -0,0 +1,181 @@
# frozen_string_literal: true
require 'rails_helper'
describe PasswordValidator do
def password_error_message(key)
I18n.t("activerecord.errors.models.user.attributes.password.#{key.to_s}")
end
let(:validator) { described_class.new(attributes: :password) }
subject(:validate) { validator.validate_each(record, :password, @password) }
context "password required" do
let(:record) { u = Fabricate.build(:user, password: @password); u.password_required!; u }
context "password is not common" do
before do
CommonPasswords.stubs(:common_password?).returns(false)
end
context "min password length is 8" do
before { SiteSetting.min_password_length = 8 }
it "doesn't add an error when password is good" do
@password = "weron235alsfn234"
validate
expect(record.errors[:password]).not_to be_present
end
it "adds an error when password is too short" do
@password = "p"
validate
expect(record.errors[:password]).to be_present
end
it "adds an error when password is blank" do
@password = ''
validate
expect(record.errors[:password]).to be_present
end
it "adds an error when password is nil" do
@password = nil
validate
expect(record.errors[:password]).to be_present
end
it "adds an error when user is admin and password is less than 15 chars" do
SiteSetting.min_admin_password_length = 15
@password = "12345678912"
record.admin = true
validate
expect(record.errors[:password]).to be_present
end
end
context "min password length is 12" do
before { SiteSetting.min_password_length = 12 }
it "adds an error when password length is 11" do
@password = "gt38sdt92bv"
validate
expect(record.errors[:password]).to be_present
end
end
end
context "password is commonly used" do
before do
SiteSetting.min_password_length = 8
CommonPasswords.stubs(:common_password?).returns(true)
end
it "adds an error when block_common_passwords is enabled" do
SiteSetting.block_common_passwords = true
@password = "password"
validate
expect(record.errors[:password]).to include(password_error_message(:common))
end
it "doesn't add an error when block_common_passwords is disabled" do
SiteSetting.block_common_passwords = false
@password = "password"
validate
expect(record.errors[:password]).not_to be_present
end
end
context "password_unique_characters is 5" do
before do
SiteSetting.password_unique_characters = 5
end
it "adds an error when there are too few unique characters" do
SiteSetting.password_unique_characters = 6
@password = "aaaaaa5432"
validate
expect(record.errors[:password]).to include(password_error_message(:unique_characters))
end
it "doesn't add an error when there are enough unique characters" do
@password = "aaaaa12345"
validate
expect(record.errors[:password]).not_to be_present
end
it "counts capital letters as different" do
@password = "aaaAaa1234"
validate
expect(record.errors[:password]).not_to be_present
end
end
it "adds an error when password is the same as the username" do
@password = "porkchops1234"
record.username = @password
validate
expect(record.errors[:password]).to include(password_error_message(:same_as_username))
end
it "adds an error when password is the same as the name" do
@password = "myawesomepassword"
record.name = @password
validate
expect(record.errors[:password]).to include(password_error_message(:same_as_name))
end
it "adds an error when password is the same as the email" do
@password = "pork@chops.com"
record.email = @password
validate
expect(record.errors[:password]).to include(password_error_message(:same_as_email))
end
it "adds an error when new password is same as current password" do
@password = "mypetsname"
record.save!
record.reload
record.password = @password
validate
expect(record.errors[:password]).to include(password_error_message(:same_as_current))
end
it "validation required if password is required" do
expect(record.password_validation_required?).to eq(true)
end
it "validation not required after save until a new password is set" do
@password = "myoldpassword"
record.save!
record.reload
expect(record.password_validation_required?).to eq(false)
record.password = "mynewpassword"
expect(record.password_validation_required?).to eq(true)
end
end
context "password not required" do
let(:record) { Fabricate.build(:user, password: @password) }
it "doesn't add an error if password is not required" do
@password = nil
validate
expect(record.errors[:password]).not_to be_present
end
it "validation required if a password is set" do
@password = "mygameshow"
expect(record.password_validation_required?).to eq(true)
end
it "adds an error even password not required" do
@password = "p"
validate
expect(record.errors[:password]).to be_present
end
end
end

View File

@@ -0,0 +1,361 @@
# frozen_string_literal: true
require 'rails_helper'
describe PostValidator do
fab!(:topic) { Fabricate(:topic) }
let(:post) { build(:post, topic: topic) }
let(:validator) { PostValidator.new({}) }
context "#post_body_validator" do
it 'should not allow a post with an empty raw' do
post.raw = ""
validator.post_body_validator(post)
expect(post.errors).to_not be_empty
end
context "when empty raw can bypass validation" do
let(:validator) { PostValidator.new(skip_post_body: true) }
it "should be allowed for empty raw based on site setting" do
post.raw = ""
validator.post_body_validator(post)
expect(post.errors).to be_empty
end
end
describe "when post's topic is a PM between a human and a non human user" do
fab!(:robot) { Fabricate(:user, id: -3) }
fab!(:user) { Fabricate(:user) }
let(:topic) do
Fabricate(:private_message_topic, topic_allowed_users: [
Fabricate.build(:topic_allowed_user, user: robot),
Fabricate.build(:topic_allowed_user, user: user)
])
end
it 'should allow a post with an empty raw' do
post = Fabricate.build(:post, topic: topic)
post.raw = ""
validator.post_body_validator(post)
expect(post.errors).to be_empty
end
end
end
context "stripped_length" do
it "adds an error for short raw" do
post.raw = "abc"
validator.stripped_length(post)
expect(post.errors.count).to eq(1)
end
it "counts emoji as a single character" do
post.raw = ":smiling_face_with_three_hearts:" * (SiteSetting.min_post_length - 1)
validator.stripped_length(post)
expect(post.errors.count).to eq(1)
post = build(:post, topic: topic)
post.raw = ":smiling_face_with_three_hearts:" * SiteSetting.min_post_length
validator.stripped_length(post)
expect(post.errors.count).to eq(0)
end
it "counts multiple characters as a single character" do
post.raw = "." * SiteSetting.min_post_length
validator.stripped_length(post)
expect(post.errors.count).to eq(1)
post = build(:post, topic: topic)
post.raw = "," * SiteSetting.min_post_length
validator.stripped_length(post)
expect(post.errors.count).to eq(1)
post = build(:post, topic: topic)
post.raw = "<!-- #{'very long comment' * SiteSetting.min_post_length} -->"
validator.stripped_length(post)
expect(post.errors.count).to eq(1)
end
it "adds no error for long raw" do
post.raw = "this is a long topic body testing 123"
validator.stripped_length(post)
expect(post.errors.count).to eq(0)
end
it "ignores an html comment" do
post.raw = "<!-- an html comment -->abc"
validator.stripped_length(post)
expect(post.errors.count).to eq(1)
end
it "ignores multiple html comments" do
post.raw = "<!-- an html comment -->\n abc \n<!-- a comment -->"
validator.stripped_length(post)
expect(post.errors.count).to eq(1)
end
it "ignores nested html comments" do
post.raw = "<!-- <!-- an html comment --> -->"
validator.stripped_length(post)
expect(post.errors.count).to eq(1)
end
end
context "too_many_posts" do
it "should be invalid when the user has posted too much" do
post.user.expects(:posted_too_much_in_topic?).returns(true)
validator.max_posts_validator(post)
expect(post.errors.count).to be > 0
end
it "should be allowed to edit when the user has posted too much" do
post.user.stubs(:posted_too_much_in_topic?).returns(true)
post.expects(:new_record?).returns(false)
validator.max_posts_validator(post)
expect(post.errors.count).to be(0)
end
it "should be valid when the user hasn't posted too much" do
post.user.expects(:posted_too_much_in_topic?).returns(false)
validator.max_posts_validator(post)
expect(post.errors.count).to be(0)
end
end
context "too_many_mentions" do
before do
SiteSetting.newuser_max_mentions_per_post = 2
SiteSetting.max_mentions_per_post = 3
end
it "should be invalid when new user exceeds max mentions limit" do
post.acting_user = build(:newuser)
post.expects(:raw_mentions).returns(['jake', 'finn', 'jake_old'])
validator.max_mention_validator(post)
expect(post.errors.count).to be > 0
end
it "should be invalid when leader user exceeds max mentions limit" do
post.acting_user = build(:trust_level_4)
post.expects(:raw_mentions).returns(['jake', 'finn', 'jake_old', 'jake_new'])
validator.max_mention_validator(post)
expect(post.errors.count).to be > 0
end
it "should be valid when new user does not exceed max mentions limit" do
post.acting_user = build(:newuser)
post.expects(:raw_mentions).returns(['jake', 'finn'])
validator.max_mention_validator(post)
expect(post.errors.count).to be(0)
end
it "should be valid when new user exceeds max mentions limit in PM" do
post.acting_user = build(:newuser)
post.topic.expects(:private_message?).returns(true)
post.expects(:raw_mentions).returns(['jake', 'finn', 'jake_old'])
validator.max_mention_validator(post)
expect(post.errors.count).to be(0)
end
it "should be valid when leader user does not exceed max mentions limit" do
post.acting_user = build(:trust_level_4)
post.expects(:raw_mentions).returns(['jake', 'finn', 'jake_old'])
validator.max_mention_validator(post)
expect(post.errors.count).to be(0)
end
it "should be valid for moderator in all cases" do
post.acting_user = build(:moderator)
post.expects(:raw_mentions).never
validator.max_mention_validator(post)
expect(post.errors.count).to be(0)
end
it "should be valid for admin in all cases" do
post.acting_user = build(:admin)
post.expects(:raw_mentions).never
validator.max_mention_validator(post)
expect(post.errors.count).to be(0)
end
end
context "too_many_embedded_media" do
before do
SiteSetting.min_trust_to_post_embedded_media = 0
SiteSetting.newuser_max_embedded_media = 2
end
it "should be invalid when new user exceeds max mentions limit" do
post.acting_user = build(:newuser)
post.expects(:embedded_media_count).returns(3)
validator.max_embedded_media_validator(post)
expect(post.errors.count).to be > 0
end
it "should be valid when new user does not exceed max mentions limit" do
post.acting_user = build(:newuser)
post.expects(:embedded_media_count).returns(2)
validator.max_embedded_media_validator(post)
expect(post.errors.count).to be(0)
end
it "should be invalid when user trust level is not sufficient" do
SiteSetting.min_trust_to_post_embedded_media = 4
post.acting_user = build(:leader)
post.expects(:embedded_media_count).returns(2)
validator.max_embedded_media_validator(post)
expect(post.errors.count).to be > 0
end
it "should be valid for moderator in all cases" do
post.acting_user = build(:moderator)
post.expects(:embedded_media_count).never
validator.max_embedded_media_validator(post)
expect(post.errors.count).to be(0)
end
it "should be valid for admin in all cases" do
post.acting_user = build(:admin)
post.expects(:embedded_media_count).never
validator.max_embedded_media_validator(post)
expect(post.errors.count).to be(0)
end
end
context "invalid post" do
it "should be invalid" do
validator.validate(post)
expect(post.errors.count).to be > 0
end
end
describe "unique_post_validator" do
fab!(:user) { Fabricate(:user, id: 999) }
fab!(:post) { Fabricate(:post, user: user, topic: topic) }
before do
SiteSetting.unique_posts_mins = 5
post.store_unique_post_key
@key = post.unique_post_key
end
after do
Discourse.redis.del(@key)
end
context "post is unique" do
let(:new_post) do
Fabricate.build(:post, user: user, raw: "unique content", topic: topic)
end
it "should not add an error" do
validator.unique_post_validator(new_post)
expect(new_post.errors.count).to eq(0)
end
it 'should not add an error when changing an existing post' do
post.raw = "changing raw"
validator.unique_post_validator(post)
expect(post.errors.count).to eq(0)
end
end
context "post is not unique" do
let(:new_post) do
Fabricate.build(:post, user: user, raw: post.raw, topic: topic)
end
it "should add an error" do
validator.unique_post_validator(new_post)
expect(new_post.errors.to_hash.keys).to contain_exactly(:raw)
end
it "should not add an error if post.skip_unique_check is true" do
new_post.skip_unique_check = true
validator.unique_post_validator(new_post)
expect(new_post.errors.count).to eq(0)
end
end
end
context "force_edit_last_validator" do
fab!(:user) { Fabricate(:user) }
fab!(:other_user) { Fabricate(:user) }
fab!(:topic) { Fabricate(:topic) }
before do
SiteSetting.max_consecutive_replies = 2
end
it "should always allow original poster to post" do
[user, user, user, other_user, user, user, user].each_with_index do |u, i|
post = Post.new(user: u, topic: topic, raw: "post number #{i}")
validator.force_edit_last_validator(post)
expect(post.errors.count).to eq(0)
post.save!
end
end
it "should not allow posting more than 2 consecutive replies" do
Post.create!(user: user, topic: topic, raw: "post number 2", post_number: 2)
Post.create!(user: user, topic: topic, raw: "post number 3", post_number: 3)
Post.create!(user: other_user, topic: topic, raw: "post number 1", post_number: 1)
post = Post.new(user: user, topic: topic, raw: "post number 4", post_number: 4)
validator.force_edit_last_validator(post)
expect(post.errors.count).to eq(1)
end
it "should always allow editing" do
post = Fabricate(:post, user: user, topic: topic)
post = Fabricate(:post, user: user, topic: topic)
revisor = PostRevisor.new(post)
revisor.revise!(post.user, raw: 'hello world123456789')
end
it "should allow posting more than 2 replies" do
3.times do
post = Fabricate(:post, user: user, topic: topic)
Fabricate(:post, user: other_user, topic: topic)
validator.force_edit_last_validator(post)
expect(post.errors.count).to eq(0)
end
end
end
shared_examples "almost no validations" do
it "skips most validations" do
validator.expects(:stripped_length).never
validator.expects(:raw_quality).never
validator.expects(:max_posts_validator).never
validator.expects(:max_mention_validator).never
validator.expects(:max_embedded_media_validator).never
validator.expects(:max_attachments_validator).never
validator.expects(:newuser_links_validator).never
validator.expects(:unique_post_validator).never
validator.expects(:force_edit_last_validator).never
validator.validate(post)
end
end
context "admin editing a static page" do
before do
post.acting_user = build(:admin)
SiteSetting.tos_topic_id = post.topic_id
end
include_examples "almost no validations"
end
context "staged user" do
before { post.acting_user = build(:user, staged: true) }
include_examples "almost no validations"
end
end

View File

@@ -0,0 +1,91 @@
# encoding: UTF-8
# frozen_string_literal: true
require 'rails_helper'
require 'validators/quality_title_validator'
require 'ostruct'
module QualityTitleValidatorSpec
class Validatable < OpenStruct
include ActiveModel::Validations
validates :title, quality_title: { unless: :private_message? }
end
end
describe "A record validated with QualityTitleValidator" do
let(:valid_title) { "hello this is my cool topic! welcome: all;" }
let(:short_title) { valid_title.slice(0, SiteSetting.min_topic_title_length - 1) }
let(:long_title) { valid_title.center(SiteSetting.max_topic_title_length + 1, 'x') }
let(:xxxxx_title) { valid_title.gsub(/./, 'x') }
let(:meaningless_title) { "asdf asdf asdf" }
let(:loud_title) { "ALL CAPS INVALID TITLE" }
let(:pretentious_title) { "superverylongwordintitlefornoparticularreason" }
subject(:topic) { QualityTitleValidatorSpec::Validatable.new }
before(:each) do
topic.stubs(private_message?: false)
end
it "allows a regular title with a few ascii characters" do
topic.title = valid_title
expect(topic).to be_valid
end
it "allows non ascii" do
topic.title = "Iñtërnâtiônàlizætiøn"
expect(topic).to be_valid
end
it 'allows Chinese characters' do
topic.title = '现在发现使用中文标题没法发帖子了'
expect(topic).to be_valid
end
it "allows anything in a private message" do
topic.stubs(private_message?: true)
[short_title, long_title, xxxxx_title].each do |bad_title|
topic.title = bad_title
expect(topic).to be_valid
end
end
it "strips a title when identifying length" do
topic.title = short_title.center(SiteSetting.min_topic_title_length + 1, ' ')
expect(topic).not_to be_valid
end
it "doesn't allow a long title" do
topic.title = long_title
expect(topic).not_to be_valid
end
it "doesn't allow a short title" do
topic.title = short_title
expect(topic).not_to be_valid
end
it "doesn't allow a title of one repeated character" do
topic.title = xxxxx_title
expect(topic).not_to be_valid
end
it "doesn't allow a meaningless title" do
topic.title = meaningless_title
expect(topic).not_to be_valid
expect(topic.errors.full_messages.first).to include(I18n.t("errors.messages.is_invalid_meaningful"))
end
it "doesn't allow a pretentious title" do
topic.title = pretentious_title
expect(topic).not_to be_valid
expect(topic.errors.full_messages.first).to include(I18n.t("errors.messages.is_invalid_unpretentious"))
end
it "doesn't allow a loud title" do
topic.title = loud_title
expect(topic).not_to be_valid
expect(topic.errors.full_messages.first).to include(I18n.t("errors.messages.is_invalid_quiet"))
end
end

View File

@@ -0,0 +1,33 @@
# frozen_string_literal: true
require "rails_helper"
RSpec.describe RegexPresenceValidator do
subject { described_class.new(regex: 'latest', regex_error: 'site_settings.errors.must_include_latest') }
describe "#valid_value?" do
describe "when value is present" do
it "without regex match" do
expect(subject.valid_value?("categories|new")).to eq(false)
expect(subject.error_message).to eq(I18n.t(
"site_settings.errors.must_include_latest"
))
end
it "with regex match" do
expect(subject.valid_value?("latest|categories")).to eq(true)
end
end
describe "when value is empty" do
it "should not be valid" do
expect(subject.valid_value?("")).to eq(false)
expect(subject.error_message).to eq(I18n.t(
"site_settings.errors.must_include_latest"
))
end
end
end
end

View File

@@ -0,0 +1,26 @@
# frozen_string_literal: true
require 'rails_helper'
describe RegexSettingValidator do
describe '#valid_value?' do
subject(:validator) { described_class.new }
it "returns true for blank values" do
expect(validator.valid_value?('')).to eq(true)
expect(validator.valid_value?(nil)).to eq(true)
end
it "return false for invalid regex" do
expect(validator.valid_value?('(()')).to eq(false)
end
it "returns false for regex with dangerous matches" do
expect(validator.valid_value?('(.)*')).to eq(false)
end
it "returns true for safe regex" do
expect(validator.valid_value?('\d{3}-\d{4}')).to eq(true)
end
end
end

View File

@@ -0,0 +1,41 @@
# frozen_string_literal: true
require 'rails_helper'
describe ReplyByEmailAddressValidator do
describe '#valid_value?' do
subject(:validator) { described_class.new }
it "returns true for blank values" do
expect(validator.valid_value?('')).to eq(true)
expect(validator.valid_value?(nil)).to eq(true)
end
it "returns false if value is not an email address" do
expect(validator.valid_value?('WAT%{reply_key}.com')).to eq(false)
expect(validator.valid_value?('word +%{reply_key}@example.com')).to eq(false)
end
it "returns false if value does not contain '%{reply_key}'" do
expect(validator.valid_value?('foo@bar.com')).to eq(false)
end
it "returns true if value does not contain '%{reply_key}' but 'find_related_post_with_key' is also disabled" do
SiteSetting.find_related_post_with_key = false
expect(validator.valid_value?('foo@bar.com')).to eq(true)
end
it "returns false if value is the same as SiteSetting.notification_email" do
SiteSetting.expects(:notification_email).returns("foo@bar.com")
expect(validator.valid_value?('foo+%{reply_key}@bar.com')).to eq(false)
end
it "returns true when value is OK" do
SiteSetting.expects(:notification_email).returns("foo@bar.com")
expect(validator.valid_value?('bar%{reply_key}@foo.com')).to eq(true)
end
end
end

View File

@@ -0,0 +1,33 @@
# frozen_string_literal: true
require 'rails_helper'
describe ReplyByEmailEnabledValidator do
describe '#valid_value?' do
subject(:validator) { described_class.new }
it "only validates when enabling the setting" do
expect(validator.valid_value?("f")).to eq(true)
end
it "returns false if reply_by_email_address is missing" do
SiteSetting.expects(:reply_by_email_address).returns("")
expect(validator.valid_value?("t")).to eq(false)
end
it "returns false if email polling is disabled" do
SiteSetting.expects(:reply_by_email_address).returns("foo.%{reply_key}+42@bar.com")
SiteSetting.expects(:email_polling_enabled?).returns(false)
expect(validator.valid_value?("t")).to eq(false)
end
it "returns true when email polling is enabled and the reply_by_email_address is configured" do
SiteSetting.expects(:reply_by_email_address).returns("foo.%{reply_key}+42@bar.com")
SiteSetting.expects(:email_polling_enabled?).returns(true)
expect(validator.valid_value?("t")).to eq(true)
end
end
end

View File

@@ -0,0 +1,11 @@
# frozen_string_literal: true
require 'rails_helper'
describe SearchTokenizeChineseValidator do
it 'does not allow search_tokenize_chinese to be enabled when search_tokenize_japanese is enabled' do
SiteSetting.search_tokenize_japanese = true
expect { SiteSetting.search_tokenize_chinese = true }.to raise_error(Discourse::InvalidParameters)
end
end

View File

@@ -0,0 +1,11 @@
# frozen_string_literal: true
require 'rails_helper'
describe SearchTokenizeJapaneseValidator do
it 'does not allow search_tokenize_japanese to be enabled when search_tokenize_chinese is enabled' do
SiteSetting.search_tokenize_chinese = true
expect { SiteSetting.search_tokenize_japanese = true }.to raise_error(Discourse::InvalidParameters)
end
end

View File

@@ -0,0 +1,30 @@
# frozen_string_literal: true
require 'rails_helper'
describe SelectableAvatarsEnabledValidator do
describe '#valid_value?' do
subject(:validator) { described_class.new }
it "returns true when disabling" do
SiteSetting.selectable_avatars = ""
expect(validator.valid_value?("f")).to eq(true)
SiteSetting.selectable_avatars = [Fabricate(:image_upload), Fabricate(:image_upload)]
expect(validator.valid_value?("f")).to eq(true)
end
it "returns true when there are at least two selectable avatars" do
SiteSetting.selectable_avatars = [Fabricate(:image_upload), Fabricate(:image_upload)]
expect(validator.valid_value?("t")).to eq(true)
end
it "returns false when selectable avatars is blank or has one avatar" do
SiteSetting.selectable_avatars = ""
expect(validator.valid_value?("t")).to eq(false)
SiteSetting.selectable_avatars = [Fabricate(:image_upload)]
expect(validator.valid_value?("t")).to eq(false)
end
end
end

View File

@@ -0,0 +1,53 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe SsoOverridesEmailValidator do
subject { described_class.new }
describe '#valid_value?' do
describe "when 'email editable' is true" do
before do
SiteSetting.discourse_connect_url = "https://www.example.com/sso"
SiteSetting.enable_discourse_connect = true
SiteSetting.email_editable = true
end
describe 'when val is false' do
it 'should be valid' do
expect(subject.valid_value?('f')).to eq(true)
end
end
describe 'when value is true' do
it 'should not be valid' do
expect(subject.valid_value?('t')).to eq(false)
expect(subject.error_message).to eq(I18n.t(
'site_settings.errors.email_editable_enabled'
))
end
end
end
describe "when 'email editable' is false" do
before do
SiteSetting.discourse_connect_url = "https://www.example.com/sso"
SiteSetting.enable_discourse_connect = true
SiteSetting.email_editable = false
end
describe 'when value is false' do
it 'should be valid' do
expect(subject.valid_value?('f')).to eq(true)
end
end
describe 'when value is true' do
it 'should be valid' do
expect(subject.valid_value?('t')).to eq(true)
end
end
end
end
end

View File

@@ -0,0 +1,102 @@
# frozen_string_literal: true
require 'rails_helper'
describe StringSettingValidator do
describe '#valid_value?' do
shared_examples "for all StringSettingValidator opts" do
it "returns true for blank values" do
expect(validator.valid_value?('')).to eq(true)
expect(validator.valid_value?(nil)).to eq(true)
end
end
context 'with a regex' do
subject(:validator) { described_class.new(regex: 'bacon') }
include_examples "for all StringSettingValidator opts"
it "returns true if value matches the regex" do
expect(validator.valid_value?('The bacon is delicious')).to eq(true)
end
it "returns false if the value doesn't match the regex" do
expect(validator.valid_value?('The vegetables are delicious')).to eq(false)
end
it "test some other regexes" do
v = described_class.new(regex: '^(chocolate|banana)$')
expect(v.valid_value?('chocolate')).to eq(true)
expect(v.valid_value?('chocolates')).to eq(false)
v = described_class.new(regex: '^[\w]+$')
expect(v.valid_value?('the_file')).to eq(true)
expect(v.valid_value?('the_file.bat')).to eq(false)
end
end
context 'with min' do
subject(:validator) { described_class.new(min: 2) }
include_examples "for all StringSettingValidator opts"
it "returns true if length is ok" do
expect(validator.valid_value?('ok')).to eq(true)
expect(validator.valid_value?('yep long enough')).to eq(true)
end
it "returns false if too short" do
expect(validator.valid_value?('x')).to eq(false)
end
end
context 'with max' do
subject(:validator) { described_class.new(max: 5) }
include_examples "for all StringSettingValidator opts"
it "returns true if length is ok" do
expect(validator.valid_value?('Z')).to eq(true)
expect(validator.valid_value?('abcde')).to eq(true)
end
it "returns false if too long" do
expect(validator.valid_value?('banana')).to eq(false)
end
end
context 'combinations of options' do
it "min and regex" do
v = described_class.new(regex: '^[\w]+$', min: 3)
expect(v.valid_value?('chocolate')).to eq(true)
expect(v.valid_value?('hi')).to eq(false)
expect(v.valid_value?('game.exe')).to eq(false)
end
it "max and regex" do
v = described_class.new(regex: '^[\w]+$', max: 5)
expect(v.valid_value?('chocolate')).to eq(false)
expect(v.valid_value?('a_b_c')).to eq(true)
expect(v.valid_value?('a b c')).to eq(false)
end
it "min and max" do
v = described_class.new(min: 3, max: 5)
expect(v.valid_value?('chocolate')).to eq(false)
expect(v.valid_value?('a')).to eq(false)
expect(v.valid_value?('a b c')).to eq(true)
expect(v.valid_value?('a b')).to eq(true)
end
it "min, max, and regex" do
v = described_class.new(min: 3, max: 12, regex: 'bacon')
expect(v.valid_value?('go bacon!')).to eq(true)
expect(v.valid_value?('sprinkle bacon on your cereal')).to eq(false)
expect(v.valid_value?('ba')).to eq(false)
end
end
end
end

View File

@@ -0,0 +1,71 @@
# encoding: UTF-8
# frozen_string_literal: true
require 'rails_helper'
require 'validators/topic_title_length_validator'
describe TopicTitleLengthValidator do
# simulate Rails behavior (singleton)
def validate
@validator ||= TopicTitleLengthValidator.new(attributes: :title)
@validator.validate_each(record, :title, record.title)
end
shared_examples "validating any topic title" do
it 'adds an error when topic title is greater than SiteSetting.max_topic_title_length' do
record.title = 'a' * (SiteSetting.max_topic_title_length + 1)
validate
expect(record.errors[:title]).to be_present
end
end
describe 'topic' do
let(:record) { Fabricate.build(:topic) }
it 'adds an error when topic title is shorter than SiteSetting.min_topic_title_length' do
record.title = 'a' * (SiteSetting.min_topic_title_length - 1)
validate
expect(record.errors[:title]).to be_present
end
it 'does not add an error when length is good' do
record.title = 'a' * (SiteSetting.min_topic_title_length)
validate
expect(record.errors[:title]).to_not be_present
end
it 'is up to date' do
record.title = 'a' * (SiteSetting.min_topic_title_length)
validate
expect(record.errors[:title]).to_not be_present
SiteSetting.min_topic_title_length = 2
record.title = 'aaa'
validate
expect(record.errors[:title]).to_not be_present
end
include_examples "validating any topic title"
end
describe 'private message' do
let(:record) { Fabricate.build(:private_message_topic) }
it 'adds an error when topic title is shorter than SiteSetting.min_personal_message_title_length' do
record.title = 'a' * (SiteSetting.min_personal_message_title_length - 1)
validate
expect(record.errors[:title]).to be_present
end
it 'does not add an error when topic title is shorter than SiteSetting.min_topic_title_length' do
record.title = 'a' * (SiteSetting.min_personal_message_title_length)
validate
expect(record.errors[:title]).to_not be_present
end
include_examples "validating any topic title"
end
end

View File

@@ -0,0 +1,38 @@
# frozen_string_literal: true
require 'rails_helper'
describe UnicodeUsernameAllowlistValidator do
subject { described_class.new }
it "allows an empty allowlist" do
expect(subject.valid_value?("")).to eq(true)
expect(subject.error_message).to be_blank
end
it "disallows leading and trailing slashes" do
expected_error = I18n.t("site_settings.errors.allowed_unicode_usernames.leading_trailing_slash")
expect(subject.valid_value?("/foo/")).to eq(false)
expect(subject.error_message).to eq(expected_error)
expect(subject.valid_value?("foo/")).to eq(true)
expect(subject.error_message).to be_blank
expect(subject.valid_value?("/foo")).to eq(true)
expect(subject.error_message).to be_blank
expect(subject.valid_value?("f/o/o")).to eq(true)
expect(subject.error_message).to be_blank
expect(subject.valid_value?("/foo/i")).to eq(false)
expect(subject.error_message).to eq(expected_error)
end
it "detects invalid regular expressions" do
expected_error = I18n.t("site_settings.errors.allowed_unicode_usernames.regex_invalid", error: "")
expect(subject.valid_value?("\\p{Foo}")).to eq(false)
expect(subject.error_message).to start_with(expected_error)
end
end

View File

@@ -0,0 +1,27 @@
# frozen_string_literal: true
require 'rails_helper'
describe UnicodeUsernameValidator do
subject { described_class.new }
it "disallows Unicode usernames when external system avatars are disabled" do
SiteSetting.external_system_avatars_enabled = false
expect(subject.valid_value?("t")).to eq(false)
expect(subject.error_message).to eq(I18n.t("site_settings.errors.unicode_usernames_avatars"))
expect(subject.valid_value?("f")).to eq(true)
expect(subject.error_message).to be_blank
end
it "allows Unicode usernames when external system avatars are enabled" do
SiteSetting.external_system_avatars_enabled = true
expect(subject.valid_value?("t")).to eq(true)
expect(subject.error_message).to be_blank
expect(subject.valid_value?("f")).to eq(true)
expect(subject.error_message).to be_blank
end
end

View File

@@ -0,0 +1,110 @@
# frozen_string_literal: true
require 'rails_helper'
describe UploadValidator do
subject(:validator) { described_class.new }
describe 'validate' do
fab!(:user) { Fabricate(:user) }
let(:filename) { "discourse.csv" }
let(:csv_file) { file_from_fixtures(filename, "csv") }
it "should create an invalid upload when the filename is blank" do
SiteSetting.authorized_extensions = "*"
created_upload = UploadCreator.new(csv_file, nil).create_for(user.id)
validator.validate(created_upload)
expect(created_upload).to_not be_valid
expect(created_upload.errors.full_messages.first).to include(I18n.t("activerecord.errors.messages.blank"))
end
it "allows 'gz' as extension when uploading export file" do
SiteSetting.authorized_extensions = ""
expect(UploadCreator.new(csv_file, "#{filename}.zip", for_export: true).create_for(user.id)).to be_valid
end
it "allows uses max_export_file_size_kb when uploading export file" do
SiteSetting.max_attachment_size_kb = "0"
SiteSetting.authorized_extensions = "zip"
expect(UploadCreator.new(csv_file, "#{filename}.zip", for_export: true).create_for(user.id)).to be_valid
end
describe "size validation" do
it "does not allow images that are too large" do
SiteSetting.max_image_size_kb = 1536
upload = Fabricate.build(:upload,
user: Fabricate(:admin),
original_filename: "test.png",
filesize: 2097152
)
subject.validate(upload)
expect(upload.errors.full_messages.first).to eq(
"Filesize #{I18n.t("upload.images.too_large_humanized", max_size: "1.5 MB")}"
)
end
end
describe 'when allow_staff_to_upload_any_file_in_pm is true' do
it 'should allow uploads for pm' do
upload = Fabricate.build(:upload,
user: Fabricate(:admin),
original_filename: 'test.ico',
for_private_message: true
)
expect(subject.validate(upload)).to eq(true)
end
describe 'for a normal user' do
it 'should not allow uploads for pm' do
upload = Fabricate.build(:upload,
user: Fabricate(:user),
original_filename: 'test.ico',
for_private_message: true
)
expect(subject.validate(upload)).to eq(nil)
end
end
end
describe 'upload for site settings' do
fab!(:user) { Fabricate(:admin) }
let(:upload) do
Fabricate.build(:upload,
user: user,
original_filename: 'test.ico',
for_site_setting: true
)
end
before do
SiteSetting.authorized_extensions = 'png'
end
describe 'for admin user' do
it 'should allow the upload' do
expect(subject.validate(upload)).to eq(true)
end
describe 'when filename is invalid' do
it 'should not allow the upload' do
upload.original_filename = 'test.txt'
expect(subject.validate(upload)).to eq(nil)
end
end
end
describe 'for normal user' do
fab!(:user) { Fabricate(:user) }
it 'should not allow the upload' do
expect(subject.validate(upload)).to eq(nil)
end
end
end
end
end

View File

@@ -0,0 +1,37 @@
# frozen_string_literal: true
require 'rails_helper'
require 'validators/topic_title_length_validator'
RSpec.describe UrlValidator do
let(:record) { Fabricate.build(:user_profile, user: Fabricate.build(:user)) }
let(:validator) { described_class.new(attributes: :website) }
subject(:validate) { validator.validate_each(record, :website, record.website) }
[
"http://https://google.com",
"http://google/",
"ftp://ftp.google.com",
"http:///what.is.this",
'http://meta.discourse.org TEST'
].each do |invalid_url|
it "#{invalid_url} should not be valid" do
record.website = invalid_url
validate
expect(record.errors[:website]).to be_present
end
end
[
"http://discourse.productions",
"https://google.com",
'http://xn--nw2a.xn--j6w193g/',
"http://見.香港/",
].each do |valid_url|
it "#{valid_url} should be valid" do
record.website = valid_url
validate
expect(record.errors[:website]).to_not be_present
end
end
end

View File

@@ -0,0 +1,47 @@
# frozen_string_literal: true
require "rails_helper"
describe UserFullNameValidator do
let(:validator) { described_class.new(attributes: :name) }
subject(:validate) { validator.validate_each(record, :name, @name) }
let(:record) { Fabricate.build(:user, name: @name) }
context "name not required" do
before { SiteSetting.full_name_required = false }
it "allows no name" do
@name = nil
validate
expect(record.errors[:name]).not_to be_present
end
it "allows name being set" do
@name = "Bigfoot"
validate
expect(record.errors[:name]).not_to be_present
end
end
context "name required" do
before { SiteSetting.full_name_required = true }
it "adds error for nil name" do
@name = nil
validate
expect(record.errors[:name]).to be_present
end
it "adds error for empty string name" do
@name = ""
validate
expect(record.errors[:name]).to be_present
end
it "allows name being set" do
@name = "Bigfoot"
validate
expect(record.errors[:name]).not_to be_present
end
end
end

View File

@@ -0,0 +1,44 @@
# frozen_string_literal: true
require 'rails_helper'
describe UsernameSettingValidator do
describe '#valid_value?' do
subject(:validator) { described_class.new }
it "returns true for blank values" do
expect(validator.valid_value?('')).to eq(true)
expect(validator.valid_value?(nil)).to eq(true)
end
it "returns true if value matches an existing user's username" do
Fabricate(:user, username: 'vader')
expect(validator.valid_value?('vader')).to eq(true)
end
it "returns false if value does not match a user's username" do
expect(validator.valid_value?('no way')).to eq(false)
end
context "regex support" do
fab!(:darthvader) { Fabricate(:user, username: 'darthvader') }
fab!(:luke) { Fabricate(:user, username: 'luke') }
it "returns false if regex doesn't match" do
v = described_class.new(regex: 'darth')
expect(v.valid_value?('luke')).to eq(false)
expect(v.valid_value?('vader')).to eq(false)
end
it "returns true if regex matches" do
v = described_class.new(regex: 'darth')
expect(v.valid_value?('darthvader')).to eq(true)
end
it "returns false if regex matches but username doesn't match a user" do
v = described_class.new(regex: 'darth')
expect(v.valid_value?('darthmaul')).to eq(false)
end
end
end
end