From 40f92f3af8058d7bf7b98b344bf6d8b4e2f5ab28 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 19 Feb 2026 07:50:09 -0500 Subject: [PATCH] Use validation matchers for `UnreservedUsernameValidator` spec (#37910) --- .../unreserved_username_validator_spec.rb | 142 ++++++------------ 1 file changed, 48 insertions(+), 94 deletions(-) diff --git a/spec/validators/unreserved_username_validator_spec.rb b/spec/validators/unreserved_username_validator_spec.rb index 55dca7db84..aa90ecb0f8 100644 --- a/spec/validators/unreserved_username_validator_spec.rb +++ b/spec/validators/unreserved_username_validator_spec.rb @@ -3,6 +3,8 @@ require 'rails_helper' RSpec.describe UnreservedUsernameValidator do + subject { record_class.new } + let(:record_class) do Class.new do include ActiveModel::Validations @@ -11,115 +13,67 @@ RSpec.describe UnreservedUsernameValidator do validates_with UnreservedUsernameValidator - def self.name - 'Foo' - end + def self.name = 'Record' end end - let(:record) { record_class.new } + context 'when username is nil' do + it { is_expected.to allow_value(nil).for(:username) } + end - describe '#validate' do - context 'when username is nil' do - it 'does not add errors' do - record.username = nil + context 'when PAM is enabled' do + before do + allow(Devise).to receive(:pam_authentication).and_return(true) + end - expect(record).to be_valid - expect(record.errors).to be_empty + 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 + + 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 { is_expected.to_not allow_value('username').for(:username).with_message(:reserved) } + end + + context 'when the account does not exist' do + before do + allow(Rpam2).to receive(:account).with(service, 'username').and_return(false) + end + + it { is_expected.to allow_value('username').for(:username) } end end - context 'when PAM is enabled' do + context 'without a pam service' do before do - allow(Devise).to receive(:pam_authentication).and_return(true) + allow(Devise).to receive(:pam_controlled_service).and_return(false) end - 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 - - 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 + context 'when there are not any reserved usernames' do + it { is_expected.to allow_value('username').for(:username) } end - context 'without a pam service' do - before do - allow(Devise).to receive(:pam_controlled_service).and_return(false) + context 'when there are reserved usernames' do + before { %w(alice bob).each { |username| Fabricate(:username_block, exact: true, username:) } } + + context 'when the username is reserved' do + it { is_expected.to_not allow_values('alice', 'bob').for(:username).with_message(:reserved) } end - 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) - value&.each { |str| Fabricate(:username_block, username: str, exact: true) } + context 'when the username is not reserved' do + it { is_expected.to allow_value('chris').for(:username) } end end end