Merge tag 'v4.3.0-rc.1'
This commit is contained in:
commit
26c9b9ba39
3459 changed files with 130932 additions and 69993 deletions
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe DisallowedHashtagsValidator, type: :validator do
|
||||
RSpec.describe DisallowedHashtagsValidator do
|
||||
let(:disallowed_tags) { [] }
|
||||
|
||||
describe '#validate' do
|
||||
|
|
|
|||
125
spec/validators/domain_validator_spec.rb
Normal file
125
spec/validators/domain_validator_spec.rb
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe DomainValidator do
|
||||
let(:record) { record_class.new }
|
||||
|
||||
context 'with no options' do
|
||||
let(:record_class) do
|
||||
Class.new do
|
||||
include ActiveModel::Validations
|
||||
|
||||
attr_accessor :domain
|
||||
|
||||
validates :domain, domain: true
|
||||
end
|
||||
end
|
||||
|
||||
describe '#validate_each' do
|
||||
context 'with a nil value' do
|
||||
it 'does not add errors' do
|
||||
record.domain = nil
|
||||
|
||||
expect(record).to be_valid
|
||||
expect(record.errors).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a valid domain' do
|
||||
it 'does not add errors' do
|
||||
record.domain = 'example.com'
|
||||
|
||||
expect(record).to be_valid
|
||||
expect(record.errors).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a domain that is too long' do
|
||||
it 'adds an error' do
|
||||
record.domain = "#{'a' * 300}.com"
|
||||
|
||||
expect(record).to_not be_valid
|
||||
expect(record.errors.where(:domain)).to_not be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a domain with an empty segment' do
|
||||
it 'adds an error' do
|
||||
record.domain = '.example.com'
|
||||
|
||||
expect(record).to_not be_valid
|
||||
expect(record.errors.where(:domain)).to_not be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a domain with an invalid character' do
|
||||
it 'adds an error' do
|
||||
record.domain = '*.example.com'
|
||||
|
||||
expect(record).to_not be_valid
|
||||
expect(record.errors.where(:domain)).to_not be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a domain that would fail parsing' do
|
||||
it 'adds an error' do
|
||||
record.domain = '/'
|
||||
|
||||
expect(record).to_not be_valid
|
||||
expect(record.errors.where(:domain)).to_not be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with acct option' do
|
||||
let(:record_class) do
|
||||
Class.new do
|
||||
include ActiveModel::Validations
|
||||
|
||||
attr_accessor :acct
|
||||
|
||||
validates :acct, domain: { acct: true }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#validate_each' do
|
||||
context 'with a nil value' do
|
||||
it 'does not add errors' do
|
||||
record.acct = nil
|
||||
|
||||
expect(record).to be_valid
|
||||
expect(record.errors).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'with no domain' do
|
||||
it 'does not add errors' do
|
||||
record.acct = 'hoge_123'
|
||||
|
||||
expect(record).to be_valid
|
||||
expect(record.errors).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a valid domain' do
|
||||
it 'does not add errors' do
|
||||
record.acct = 'hoge_123@example.com'
|
||||
|
||||
expect(record).to be_valid
|
||||
expect(record.errors).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'with an invalid domain' do
|
||||
it 'adds an error' do
|
||||
record.acct = 'hoge_123@.example.com'
|
||||
|
||||
expect(record).to_not be_valid
|
||||
expect(record.errors.where(:acct)).to_not be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -2,26 +2,21 @@
|
|||
|
||||
require 'rails_helper'
|
||||
|
||||
describe EmailMxValidator do
|
||||
RSpec.describe EmailMxValidator do
|
||||
describe '#validate' do
|
||||
let(:user) { instance_double(User, email: 'foo@example.com', sign_up_ip: '1.2.3.4', errors: instance_double(ActiveModel::Errors, add: nil)) }
|
||||
let(:resolv_dns_double) { instance_double(Resolv::DNS) }
|
||||
|
||||
context 'with an e-mail domain that is explicitly allowed' do
|
||||
around do |block|
|
||||
tmp = Rails.configuration.x.email_domains_whitelist
|
||||
Rails.configuration.x.email_domains_whitelist = 'example.com'
|
||||
tmp = Rails.configuration.x.email_domains_allowlist
|
||||
Rails.configuration.x.email_domains_allowlist = 'example.com'
|
||||
block.call
|
||||
Rails.configuration.x.email_domains_whitelist = tmp
|
||||
Rails.configuration.x.email_domains_allowlist = tmp
|
||||
end
|
||||
|
||||
it 'does not add errors if there are no DNS records' do
|
||||
resolver = instance_double(Resolv::DNS)
|
||||
|
||||
allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::MX).and_return([])
|
||||
allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::A).and_return([])
|
||||
allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::AAAA).and_return([])
|
||||
allow(resolver).to receive(:timeouts=).and_return(nil)
|
||||
allow(Resolv::DNS).to receive(:open).and_yield(resolver)
|
||||
configure_resolver('example.com')
|
||||
|
||||
subject.validate(user)
|
||||
expect(user.errors).to_not have_received(:add)
|
||||
|
|
@ -29,13 +24,7 @@ describe EmailMxValidator do
|
|||
end
|
||||
|
||||
it 'adds no error if there are DNS records for the e-mail domain' do
|
||||
resolver = instance_double(Resolv::DNS)
|
||||
|
||||
allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::MX).and_return([])
|
||||
allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::A).and_return([Resolv::DNS::Resource::IN::A.new('192.0.2.42')])
|
||||
allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::AAAA).and_return([])
|
||||
allow(resolver).to receive(:timeouts=).and_return(nil)
|
||||
allow(Resolv::DNS).to receive(:open).and_yield(resolver)
|
||||
configure_resolver('example.com', a: resolv_double_a('192.0.2.42'))
|
||||
|
||||
subject.validate(user)
|
||||
expect(user.errors).to_not have_received(:add)
|
||||
|
|
@ -58,13 +47,7 @@ describe EmailMxValidator do
|
|||
end
|
||||
|
||||
it 'adds an error if the email domain name contains empty labels' do
|
||||
resolver = instance_double(Resolv::DNS)
|
||||
|
||||
allow(resolver).to receive(:getresources).with('example..com', Resolv::DNS::Resource::IN::MX).and_return([])
|
||||
allow(resolver).to receive(:getresources).with('example..com', Resolv::DNS::Resource::IN::A).and_return([Resolv::DNS::Resource::IN::A.new('192.0.2.42')])
|
||||
allow(resolver).to receive(:getresources).with('example..com', Resolv::DNS::Resource::IN::AAAA).and_return([])
|
||||
allow(resolver).to receive(:timeouts=).and_return(nil)
|
||||
allow(Resolv::DNS).to receive(:open).and_yield(resolver)
|
||||
configure_resolver('example..com', a: resolv_double_a('192.0.2.42'))
|
||||
|
||||
user = instance_double(User, email: 'foo@example..com', sign_up_ip: '1.2.3.4', errors: instance_double(ActiveModel::Errors, add: nil))
|
||||
subject.validate(user)
|
||||
|
|
@ -72,51 +55,64 @@ describe EmailMxValidator do
|
|||
end
|
||||
|
||||
it 'adds an error if there are no DNS records for the e-mail domain' do
|
||||
resolver = instance_double(Resolv::DNS)
|
||||
|
||||
allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::MX).and_return([])
|
||||
allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::A).and_return([])
|
||||
allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::AAAA).and_return([])
|
||||
allow(resolver).to receive(:timeouts=).and_return(nil)
|
||||
allow(Resolv::DNS).to receive(:open).and_yield(resolver)
|
||||
configure_resolver('example.com')
|
||||
|
||||
subject.validate(user)
|
||||
expect(user.errors).to have_received(:add)
|
||||
end
|
||||
|
||||
it 'adds an error if a MX record does not lead to an IP' do
|
||||
resolver = instance_double(Resolv::DNS)
|
||||
|
||||
allow(resolver).to receive(:getresources)
|
||||
.with('example.com', Resolv::DNS::Resource::IN::MX)
|
||||
.and_return([instance_double(Resolv::DNS::Resource::MX, exchange: 'mail.example.com')])
|
||||
allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::A).and_return([])
|
||||
allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::AAAA).and_return([])
|
||||
allow(resolver).to receive(:getresources).with('mail.example.com', Resolv::DNS::Resource::IN::A).and_return([])
|
||||
allow(resolver).to receive(:getresources).with('mail.example.com', Resolv::DNS::Resource::IN::AAAA).and_return([])
|
||||
allow(resolver).to receive(:timeouts=).and_return(nil)
|
||||
allow(Resolv::DNS).to receive(:open).and_yield(resolver)
|
||||
configure_resolver('example.com', mx: resolv_double_mx('mail.example.com'))
|
||||
configure_resolver('mail.example.com')
|
||||
|
||||
subject.validate(user)
|
||||
expect(user.errors).to have_received(:add)
|
||||
end
|
||||
|
||||
it 'adds an error if the MX record is blacklisted' do
|
||||
it 'adds an error if the MX record has an email domain block' do
|
||||
EmailDomainBlock.create!(domain: 'mail.example.com')
|
||||
resolver = instance_double(Resolv::DNS)
|
||||
|
||||
allow(resolver).to receive(:getresources)
|
||||
.with('example.com', Resolv::DNS::Resource::IN::MX)
|
||||
.and_return([instance_double(Resolv::DNS::Resource::MX, exchange: 'mail.example.com')])
|
||||
allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::A).and_return([])
|
||||
allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::AAAA).and_return([])
|
||||
allow(resolver).to receive(:getresources).with('mail.example.com', Resolv::DNS::Resource::IN::A).and_return([instance_double(Resolv::DNS::Resource::IN::A, address: '2.3.4.5')])
|
||||
allow(resolver).to receive(:getresources).with('mail.example.com', Resolv::DNS::Resource::IN::AAAA).and_return([instance_double(Resolv::DNS::Resource::IN::A, address: 'fd00::2')])
|
||||
allow(resolver).to receive(:timeouts=).and_return(nil)
|
||||
allow(Resolv::DNS).to receive(:open).and_yield(resolver)
|
||||
configure_resolver(
|
||||
'example.com',
|
||||
mx: resolv_double_mx('mail.example.com')
|
||||
)
|
||||
configure_resolver(
|
||||
'mail.example.com',
|
||||
a: instance_double(Resolv::DNS::Resource::IN::A, address: '2.3.4.5'),
|
||||
aaaa: instance_double(Resolv::DNS::Resource::IN::AAAA, address: 'fd00::2')
|
||||
)
|
||||
|
||||
subject.validate(user)
|
||||
expect(user.errors).to have_received(:add)
|
||||
end
|
||||
end
|
||||
|
||||
def configure_resolver(domain, options = {})
|
||||
allow(resolv_dns_double)
|
||||
.to receive(:getresources)
|
||||
.with(domain, Resolv::DNS::Resource::IN::MX)
|
||||
.and_return(Array(options[:mx]))
|
||||
allow(resolv_dns_double)
|
||||
.to receive(:getresources)
|
||||
.with(domain, Resolv::DNS::Resource::IN::A)
|
||||
.and_return(Array(options[:a]))
|
||||
allow(resolv_dns_double)
|
||||
.to receive(:getresources)
|
||||
.with(domain, Resolv::DNS::Resource::IN::AAAA)
|
||||
.and_return(Array(options[:aaaa]))
|
||||
allow(resolv_dns_double)
|
||||
.to receive(:timeouts=)
|
||||
.and_return(nil)
|
||||
allow(Resolv::DNS)
|
||||
.to receive(:open)
|
||||
.and_yield(resolv_dns_double)
|
||||
end
|
||||
|
||||
def resolv_double_mx(domain)
|
||||
instance_double(Resolv::DNS::Resource::MX, exchange: domain)
|
||||
end
|
||||
|
||||
def resolv_double_a(domain)
|
||||
Resolv::DNS::Resource::IN::A.new(domain)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
83
spec/validators/existing_username_validator_spec.rb
Normal file
83
spec/validators/existing_username_validator_spec.rb
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe ExistingUsernameValidator do
|
||||
let(:record_class) do
|
||||
Class.new do
|
||||
include ActiveModel::Validations
|
||||
attr_accessor :contact, :friends
|
||||
|
||||
def self.name
|
||||
'Record'
|
||||
end
|
||||
|
||||
validates :contact, existing_username: true
|
||||
validates :friends, existing_username: { multiple: true }
|
||||
end
|
||||
end
|
||||
let(:record) { record_class.new }
|
||||
|
||||
describe '#validate_each' do
|
||||
context 'with a nil value' do
|
||||
it 'does not add errors' do
|
||||
record.contact = nil
|
||||
|
||||
expect(record).to be_valid
|
||||
expect(record.errors).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there are no accounts' do
|
||||
it 'adds errors to the record' do
|
||||
record.contact = 'user@example.com'
|
||||
|
||||
expect(record).to_not be_valid
|
||||
expect(record.errors.first.attribute).to eq(:contact)
|
||||
expect(record.errors.first.type).to eq I18n.t('existing_username_validator.not_found')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there are accounts' do
|
||||
before { Fabricate(:account, domain: 'example.com', username: 'user') }
|
||||
|
||||
context 'when the value does not match' do
|
||||
it 'adds errors to the record' do
|
||||
record.contact = 'friend@other.host'
|
||||
|
||||
expect(record).to_not be_valid
|
||||
expect(record.errors.first.attribute).to eq(:contact)
|
||||
expect(record.errors.first.type).to eq I18n.t('existing_username_validator.not_found')
|
||||
end
|
||||
|
||||
context 'when multiple is true' do
|
||||
it 'adds errors to the record' do
|
||||
record.friends = 'friend@other.host'
|
||||
|
||||
expect(record).to_not be_valid
|
||||
expect(record.errors.first.attribute).to eq(:friends)
|
||||
expect(record.errors.first.type).to eq I18n.t('existing_username_validator.not_found_multiple', usernames: 'friend@other.host')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the value does match' do
|
||||
it 'does not add errors to the record' do
|
||||
record.contact = 'user@example.com'
|
||||
|
||||
expect(record).to be_valid
|
||||
expect(record.errors).to be_empty
|
||||
end
|
||||
|
||||
context 'when multiple is true' do
|
||||
it 'does not add errors to the record' do
|
||||
record.friends = 'user@example.com'
|
||||
|
||||
expect(record).to be_valid
|
||||
expect(record.errors).to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -2,48 +2,76 @@
|
|||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe FollowLimitValidator, type: :validator do
|
||||
RSpec.describe FollowLimitValidator do
|
||||
describe '#validate' do
|
||||
before do
|
||||
allow_any_instance_of(described_class).to receive(:limit_reached?).with(account) do
|
||||
limit_reached
|
||||
end
|
||||
context 'with a nil account' do
|
||||
it 'does not add validation errors to base' do
|
||||
follow = Fabricate.build(:follow, account: nil)
|
||||
|
||||
described_class.new.validate(follow)
|
||||
end
|
||||
follow.valid?
|
||||
|
||||
let(:follow) { instance_double(Follow, account: account, errors: errors) }
|
||||
let(:errors) { instance_double(ActiveModel::Errors, add: nil) }
|
||||
let(:account) { instance_double(Account, nil?: _nil, local?: local, following_count: 0, followers_count: 0) }
|
||||
let(:_nil) { true }
|
||||
let(:local) { false }
|
||||
|
||||
context 'with follow.account.nil? || !follow.account.local?' do
|
||||
let(:_nil) { true }
|
||||
|
||||
it 'not calls errors.add' do
|
||||
expect(errors).to_not have_received(:add).with(:base, any_args)
|
||||
expect(follow.errors[:base]).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'with !(follow.account.nil? || !follow.account.local?)' do
|
||||
let(:_nil) { false }
|
||||
let(:local) { true }
|
||||
context 'with a non-local account' do
|
||||
it 'does not add validation errors to base' do
|
||||
follow = Fabricate.build(:follow, account: Account.new(domain: 'host.example'))
|
||||
|
||||
context 'when limit_reached?' do
|
||||
let(:limit_reached) { true }
|
||||
follow.valid?
|
||||
|
||||
it 'calls errors.add' do
|
||||
expect(errors).to have_received(:add)
|
||||
.with(:base, I18n.t('users.follow_limit_reached', limit: FollowLimitValidator::LIMIT))
|
||||
expect(follow.errors[:base]).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a local account' do
|
||||
let(:account) { Account.new }
|
||||
|
||||
context 'when the followers count is under the limit' do
|
||||
before do
|
||||
allow(account).to receive(:following_count).and_return(described_class::LIMIT - 100)
|
||||
end
|
||||
|
||||
it 'does not add validation errors to base' do
|
||||
follow = Fabricate.build(:follow, account: account)
|
||||
|
||||
follow.valid?
|
||||
|
||||
expect(follow.errors[:base]).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'with !limit_reached?' do
|
||||
let(:limit_reached) { false }
|
||||
context 'when the following count is over the limit' do
|
||||
before do
|
||||
allow(account).to receive(:following_count).and_return(described_class::LIMIT + 100)
|
||||
end
|
||||
|
||||
it 'not calls errors.add' do
|
||||
expect(errors).to_not have_received(:add).with(:base, any_args)
|
||||
context 'when the followers count is low' do
|
||||
before do
|
||||
allow(account).to receive(:followers_count).and_return(10)
|
||||
end
|
||||
|
||||
it 'adds validation errors to base' do
|
||||
follow = Fabricate.build(:follow, account: account)
|
||||
|
||||
follow.valid?
|
||||
|
||||
expect(follow.errors[:base]).to include(I18n.t('users.follow_limit_reached', limit: described_class::LIMIT))
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the followers count is high' do
|
||||
before do
|
||||
allow(account).to receive(:followers_count).and_return(100_000)
|
||||
end
|
||||
|
||||
it 'does not add validation errors to base' do
|
||||
follow = Fabricate.build(:follow, account: account)
|
||||
|
||||
follow.valid?
|
||||
|
||||
expect(follow.errors[:base]).to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'rails_helper'
|
||||
|
||||
describe LanguageValidator do
|
||||
RSpec.describe LanguageValidator do
|
||||
let(:record_class) do
|
||||
Class.new do
|
||||
include ActiveModel::Validations
|
||||
|
|
|
|||
46
spec/validators/lines_validator_spec.rb
Normal file
46
spec/validators/lines_validator_spec.rb
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe LinesValidator do
|
||||
let(:record_class) do
|
||||
Class.new do
|
||||
include ActiveModel::Validations
|
||||
|
||||
attr_accessor :text
|
||||
|
||||
validates :text, lines: { maximum: 5 }
|
||||
end
|
||||
end
|
||||
|
||||
let(:record) { record_class.new }
|
||||
|
||||
describe '#validate_each' do
|
||||
context 'with a nil value' do
|
||||
it 'does not add errors' do
|
||||
record.text = nil
|
||||
|
||||
expect(record).to be_valid
|
||||
expect(record.errors).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'with lines below the limit' do
|
||||
it 'does not add errors' do
|
||||
record.text = "hoge\n" * 5
|
||||
|
||||
expect(record).to be_valid
|
||||
expect(record.errors).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'with more lines than limit' do
|
||||
it 'adds an error' do
|
||||
record.text = "hoge\n" * 6
|
||||
|
||||
expect(record).to_not be_valid
|
||||
expect(record.errors.where(:text)).to_not be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
require 'rails_helper'
|
||||
|
||||
describe NoteLengthValidator do
|
||||
RSpec.describe NoteLengthValidator do
|
||||
subject { described_class.new(attributes: { note: true }, maximum: 640) }
|
||||
|
||||
describe '#validate' do
|
||||
it 'adds an error when text is over 640 characters' do
|
||||
it 'adds an error when text is over configured character limit' do
|
||||
text = 'a' * 650
|
||||
account = instance_double(Account, note: text, errors: activemodel_errors)
|
||||
|
||||
|
|
@ -14,16 +14,16 @@ describe NoteLengthValidator do
|
|||
expect(account.errors).to have_received(:add)
|
||||
end
|
||||
|
||||
it 'counts URLs as 23 characters flat' do
|
||||
text = ('a' * 476) + " http://#{'b' * 30}.com/example"
|
||||
it 'reduces calculated length of auto-linkable space-separated URLs' do
|
||||
text = [starting_string, example_link].join(' ')
|
||||
account = instance_double(Account, note: text, errors: activemodel_errors)
|
||||
|
||||
subject.validate_each(account, 'note', text)
|
||||
expect(account.errors).to_not have_received(:add)
|
||||
end
|
||||
|
||||
it 'does not count non-autolinkable URLs as 23 characters flat' do
|
||||
text = ('a' * 476) + "http://#{'b' * 30}.com/example"
|
||||
it 'does not reduce calculated length of non-autolinkable URLs' do
|
||||
text = [starting_string, example_link].join
|
||||
account = instance_double(Account, note: text, errors: activemodel_errors)
|
||||
|
||||
subject.validate_each(account, 'note', text)
|
||||
|
|
@ -32,6 +32,14 @@ describe NoteLengthValidator do
|
|||
|
||||
private
|
||||
|
||||
def starting_string
|
||||
'a' * 476
|
||||
end
|
||||
|
||||
def example_link
|
||||
"http://#{'b' * 30}.com/example"
|
||||
end
|
||||
|
||||
def activemodel_errors
|
||||
instance_double(ActiveModel::Errors, add: nil)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe PollValidator, type: :validator do
|
||||
RSpec.describe PollValidator do
|
||||
describe '#validate' do
|
||||
before do
|
||||
validator.validate(poll)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'rails_helper'
|
||||
|
||||
describe ReactionValidator do
|
||||
RSpec.describe ReactionValidator do
|
||||
let(:announcement) { Fabricate(:announcement) }
|
||||
|
||||
describe '#validate' do
|
||||
|
|
@ -19,8 +19,9 @@ describe ReactionValidator do
|
|||
expect(reaction.errors).to be_empty
|
||||
end
|
||||
|
||||
it 'adds error when 8 reactions already exist' do
|
||||
%w(🐘 ❤️ 🙉 😍 😋 😂 😞 👍).each do |name|
|
||||
it 'adds error when reaction limit count has already been reached' do
|
||||
stub_const 'ReactionValidator::LIMIT', 2
|
||||
%w(🐘 ❤️).each do |name|
|
||||
announcement.announcement_reactions.create!(name: name, account: Fabricate(:account))
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -2,64 +2,72 @@
|
|||
|
||||
require 'rails_helper'
|
||||
|
||||
describe StatusLengthValidator do
|
||||
RSpec.describe StatusLengthValidator do
|
||||
describe '#validate' do
|
||||
before { stub_const("#{described_class}::MAX_CHARS", 500) } # Example values below are relative to this baseline
|
||||
|
||||
it 'does not add errors onto remote statuses' do
|
||||
status = instance_double(Status, local?: false)
|
||||
allow(status).to receive(:errors)
|
||||
|
||||
subject.validate(status)
|
||||
expect(status).to_not receive(:errors)
|
||||
|
||||
expect(status).to_not have_received(:errors)
|
||||
end
|
||||
|
||||
it 'does not add errors onto local reblogs' do
|
||||
status = instance_double(Status, local?: false, reblog?: true)
|
||||
allow(status).to receive(:errors)
|
||||
|
||||
subject.validate(status)
|
||||
expect(status).to_not receive(:errors)
|
||||
|
||||
expect(status).to_not have_received(:errors)
|
||||
end
|
||||
|
||||
it 'adds an error when content warning is over 500 characters' do
|
||||
status = instance_double(Status, spoiler_text: 'a' * 520, text: '', errors: activemodel_errors, local?: true, reblog?: false)
|
||||
it 'adds an error when content warning is over character limit' do
|
||||
status = status_double(spoiler_text: 'a' * 520)
|
||||
subject.validate(status)
|
||||
expect(status.errors).to have_received(:add)
|
||||
end
|
||||
|
||||
it 'adds an error when text is over 500 characters' do
|
||||
status = instance_double(Status, spoiler_text: '', text: 'a' * 520, errors: activemodel_errors, local?: true, reblog?: false)
|
||||
it 'adds an error when text is over character limit' do
|
||||
status = status_double(text: 'a' * 520)
|
||||
subject.validate(status)
|
||||
expect(status.errors).to have_received(:add)
|
||||
end
|
||||
|
||||
it 'adds an error when text and content warning are over 500 characters total' do
|
||||
status = instance_double(Status, spoiler_text: 'a' * 250, text: 'b' * 251, errors: activemodel_errors, local?: true, reblog?: false)
|
||||
it 'adds an error when text and content warning are over character limit total' do
|
||||
status = status_double(spoiler_text: 'a' * 250, text: 'b' * 251)
|
||||
subject.validate(status)
|
||||
expect(status.errors).to have_received(:add)
|
||||
end
|
||||
|
||||
it 'counts URLs as 23 characters flat' do
|
||||
text = ('a' * 476) + " http://#{'b' * 30}.com/example"
|
||||
status = instance_double(Status, spoiler_text: '', text: text, errors: activemodel_errors, local?: true, reblog?: false)
|
||||
it 'reduces calculated length of auto-linkable space-separated URLs' do
|
||||
text = [starting_string, example_link].join(' ')
|
||||
status = status_double(text: text)
|
||||
|
||||
subject.validate(status)
|
||||
expect(status.errors).to_not have_received(:add)
|
||||
end
|
||||
|
||||
it 'does not count non-autolinkable URLs as 23 characters flat' do
|
||||
text = ('a' * 476) + "http://#{'b' * 30}.com/example"
|
||||
status = instance_double(Status, spoiler_text: '', text: text, errors: activemodel_errors, local?: true, reblog?: false)
|
||||
it 'does not reduce calculated length of non-autolinkable URLs' do
|
||||
text = [starting_string, example_link].join
|
||||
status = status_double(text: text)
|
||||
|
||||
subject.validate(status)
|
||||
expect(status.errors).to have_received(:add)
|
||||
end
|
||||
|
||||
it 'does not count overly long URLs as 23 characters flat' do
|
||||
it 'does not reduce calculated length of count overly long URLs' do
|
||||
text = "http://example.com/valid?#{'#foo?' * 1000}"
|
||||
status = instance_double(Status, spoiler_text: '', text: text, errors: activemodel_errors, local?: true, reblog?: false)
|
||||
status = status_double(text: text)
|
||||
subject.validate(status)
|
||||
expect(status.errors).to have_received(:add)
|
||||
end
|
||||
|
||||
it 'counts only the front part of remote usernames' do
|
||||
text = ('a' * 475) + " @alice@#{'b' * 30}.com"
|
||||
status = instance_double(Status, spoiler_text: '', text: text, errors: activemodel_errors, local?: true, reblog?: false)
|
||||
status = status_double(text: text)
|
||||
|
||||
subject.validate(status)
|
||||
expect(status.errors).to_not have_received(:add)
|
||||
|
|
@ -67,7 +75,7 @@ describe StatusLengthValidator do
|
|||
|
||||
it 'does count both parts of remote usernames for overly long domains' do
|
||||
text = "@alice@#{'b' * 500}.com"
|
||||
status = instance_double(Status, spoiler_text: '', text: text, errors: activemodel_errors, local?: true, reblog?: false)
|
||||
status = status_double(text: text)
|
||||
|
||||
subject.validate(status)
|
||||
expect(status.errors).to have_received(:add)
|
||||
|
|
@ -76,6 +84,25 @@ describe StatusLengthValidator do
|
|||
|
||||
private
|
||||
|
||||
def starting_string
|
||||
'a' * 476
|
||||
end
|
||||
|
||||
def example_link
|
||||
"http://#{'b' * 30}.com/example"
|
||||
end
|
||||
|
||||
def status_double(spoiler_text: '', text: '')
|
||||
instance_double(
|
||||
Status,
|
||||
spoiler_text: spoiler_text,
|
||||
text: text,
|
||||
errors: activemodel_errors,
|
||||
local?: true,
|
||||
reblog?: false
|
||||
)
|
||||
end
|
||||
|
||||
def activemodel_errors
|
||||
instance_double(ActiveModel::Errors, add: nil)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe StatusPinValidator, type: :validator do
|
||||
RSpec.describe StatusPinValidator do
|
||||
describe '#validate' do
|
||||
before do
|
||||
subject.validate(pin)
|
||||
|
|
@ -45,8 +45,8 @@ RSpec.describe StatusPinValidator, type: :validator do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when pin.account.status_pins.count > 4 && pin.account.local?' do
|
||||
let(:count) { 5 }
|
||||
context 'when pin account is local and has too many pins' do
|
||||
let(:count) { described_class::PIN_LIMIT + 1 }
|
||||
let(:local) { true }
|
||||
|
||||
it 'calls errors.add' do
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'rails_helper'
|
||||
|
||||
describe UniqueUsernameValidator do
|
||||
RSpec.describe UniqueUsernameValidator do
|
||||
describe '#validate' do
|
||||
context 'when local account' do
|
||||
it 'does not add errors if username is nil' do
|
||||
|
|
|
|||
|
|
@ -2,41 +2,118 @@
|
|||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe UnreservedUsernameValidator, type: :validator do
|
||||
describe '#validate' do
|
||||
before do
|
||||
allow(validator).to receive(:reserved_username?) { reserved_username }
|
||||
validator.validate(account)
|
||||
RSpec.describe UnreservedUsernameValidator do
|
||||
let(:record_class) do
|
||||
Class.new do
|
||||
include ActiveModel::Validations
|
||||
attr_accessor :username
|
||||
|
||||
validates_with UnreservedUsernameValidator
|
||||
end
|
||||
end
|
||||
let(:record) { record_class.new }
|
||||
|
||||
let(:validator) { described_class.new }
|
||||
let(:account) { instance_double(Account, username: username, errors: errors) }
|
||||
let(:errors) { instance_double(ActiveModel::Errors, add: nil) }
|
||||
describe '#validate' do
|
||||
context 'when username is nil' do
|
||||
it 'does not add errors' do
|
||||
record.username = nil
|
||||
|
||||
context 'when @username is blank?' do
|
||||
let(:username) { nil }
|
||||
|
||||
it 'not calls errors.add' do
|
||||
expect(errors).to_not have_received(:add).with(:username, any_args)
|
||||
expect(record).to be_valid
|
||||
expect(record.errors).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'when @username is not blank?' do
|
||||
let(:username) { 'f' }
|
||||
context 'when PAM is enabled' do
|
||||
before do
|
||||
allow(Devise).to receive(:pam_authentication).and_return(true)
|
||||
end
|
||||
|
||||
context 'with reserved_username?' do
|
||||
let(:reserved_username) { true }
|
||||
context 'with a pam service available' do
|
||||
let(:service) { double }
|
||||
let(:pam_class) do
|
||||
Class.new do
|
||||
def self.account(service, username); end
|
||||
end
|
||||
end
|
||||
|
||||
it 'calls errors.add' do
|
||||
expect(errors).to have_received(:add).with(:username, :reserved)
|
||||
before do
|
||||
stub_const('Rpam2', pam_class)
|
||||
allow(Devise).to receive(:pam_controlled_service).and_return(service)
|
||||
end
|
||||
|
||||
context 'when the account exists' do
|
||||
before do
|
||||
allow(Rpam2).to receive(:account).with(service, 'username').and_return(true)
|
||||
end
|
||||
|
||||
it 'adds errors to the record' do
|
||||
record.username = 'username'
|
||||
|
||||
expect(record).to_not be_valid
|
||||
expect(record.errors.first.attribute).to eq(:username)
|
||||
expect(record.errors.first.type).to eq(:reserved)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the account does not exist' do
|
||||
before do
|
||||
allow(Rpam2).to receive(:account).with(service, 'username').and_return(false)
|
||||
end
|
||||
|
||||
it 'does not add errors to the record' do
|
||||
record.username = 'username'
|
||||
|
||||
expect(record).to be_valid
|
||||
expect(record.errors).to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when username is not reserved' do
|
||||
let(:reserved_username) { false }
|
||||
context 'without a pam service' do
|
||||
before do
|
||||
allow(Devise).to receive(:pam_controlled_service).and_return(false)
|
||||
end
|
||||
|
||||
it 'not calls errors.add' do
|
||||
expect(errors).to_not have_received(:add).with(:username, any_args)
|
||||
context 'when there are not any reserved usernames' do
|
||||
before do
|
||||
stub_reserved_usernames(nil)
|
||||
end
|
||||
|
||||
it 'does not add errors to the record' do
|
||||
record.username = 'username'
|
||||
|
||||
expect(record).to be_valid
|
||||
expect(record.errors).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there are reserved usernames' do
|
||||
before do
|
||||
stub_reserved_usernames(%w(alice bob))
|
||||
end
|
||||
|
||||
context 'when the username is reserved' do
|
||||
it 'adds errors to the record' do
|
||||
record.username = 'alice'
|
||||
|
||||
expect(record).to_not be_valid
|
||||
expect(record.errors.first.attribute).to eq(:username)
|
||||
expect(record.errors.first.type).to eq(:reserved)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the username is not reserved' do
|
||||
it 'does not add errors to the record' do
|
||||
record.username = 'chris'
|
||||
|
||||
expect(record).to be_valid
|
||||
expect(record.errors).to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def stub_reserved_usernames(value)
|
||||
allow(Setting).to receive(:[]).with('reserved_usernames').and_return(value)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'rails_helper'
|
||||
|
||||
describe URLValidator do
|
||||
RSpec.describe URLValidator do
|
||||
let(:record_class) do
|
||||
Class.new do
|
||||
include ActiveModel::Validations
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe BlacklistedEmailValidator, type: :validator do
|
||||
RSpec.describe UserEmailValidator do
|
||||
describe '#validate' do
|
||||
subject { described_class.new.validate(user); errors }
|
||||
subject { described_class.new.validate(user) }
|
||||
|
||||
let(:user) { instance_double(User, email: 'info@mail.com', sign_up_ip: '1.2.3.4', errors: errors) }
|
||||
let(:errors) { instance_double(ActiveModel::Errors, add: nil) }
|
||||
|
|
@ -18,7 +18,8 @@ RSpec.describe BlacklistedEmailValidator, type: :validator do
|
|||
let(:blocked_email) { true }
|
||||
|
||||
it 'adds error' do
|
||||
described_class.new.validate(user)
|
||||
subject
|
||||
|
||||
expect(errors).to have_received(:add).with(:email, :blocked).once
|
||||
end
|
||||
end
|
||||
|
|
@ -27,7 +28,8 @@ RSpec.describe BlacklistedEmailValidator, type: :validator do
|
|||
let(:blocked_email) { false }
|
||||
|
||||
it 'does not add errors' do
|
||||
described_class.new.validate(user)
|
||||
subject
|
||||
|
||||
expect(errors).to_not have_received(:add)
|
||||
end
|
||||
|
||||
|
|
@ -39,7 +41,8 @@ RSpec.describe BlacklistedEmailValidator, type: :validator do
|
|||
end
|
||||
|
||||
it 'adds error' do
|
||||
described_class.new.validate(user)
|
||||
subject
|
||||
|
||||
expect(errors).to have_received(:add).with(:email, :taken).once
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue