Concierge-Auth
view release on metacpan or search on metacpan
t/02-validation.t view on Meta::CPAN
#!/usr/bin/env perl
use v5.36;
use strict;
use warnings;
use Test2::V0;
use File::Temp qw/tempfile tempdir/;
use Concierge::Auth;
my $dir = tempdir( CLEANUP => 1 );
my $file = "$dir/auth.pwd";
my $auth = Concierge::Auth->new( backend_class => 'Concierge::Auth::Pwd', file => $file );
# ========== validatePwd ==========
# This is the one format-check kept as a shared method on
# Concierge::Auth::Pwd (both enroll and change_credentials need it).
# It now uses the { success, message } hashref convention.
subtest 'validatePwd - valid passwords' => sub {
for my $pwd ( 'password', 'x' x 8, 'x' x 72, 'P@ssw0rd!123' ) {
my $result = $auth->validatePwd($pwd);
ok( $result->{success}, "valid password (length " . length($pwd) . ")" );
}
};
subtest 'validatePwd - empty' => sub {
my $result = $auth->validatePwd('');
ok( !$result->{success}, 'empty password rejected' );
like( $result->{message}, qr/empty/i, 'message mentions empty' );
$result = $auth->validatePwd(undef);
ok( !$result->{success}, 'undef password rejected' );
};
subtest 'validatePwd - too short' => sub {
my $result = $auth->validatePwd('short');
ok( !$result->{success}, '5-char password rejected' );
like( $result->{message}, qr/between/i, 'message mentions length requirement' );
};
subtest 'validatePwd - too long' => sub {
my $result = $auth->validatePwd('x' x 73);
ok( !$result->{success}, '73-char password rejected' );
like( $result->{message}, qr/between/i, 'message mentions length requirement' );
};
# ========== ID format policy ==========
# The old validateID method no longer exists as a standalone method --
# ID format policy (length, character set) is only enforced inside
# enroll(), since that's the only contract method establishing a *new*
# ID. Exercise it there instead.
subtest 'enroll - empty ID rejected' => sub {
my $result = $auth->enroll('', 'password123');
ok( !$result->{success}, 'empty ID rejected' );
like( $result->{message}, qr/empty/i, 'message mentions empty' );
};
subtest 'enroll - too-short ID rejected' => sub {
my $result = $auth->enroll('a', 'password123');
ok( !$result->{success}, 'single-char ID rejected' );
like( $result->{message}, qr/between/i, 'message mentions length requirement' );
};
subtest 'enroll - too-long ID rejected' => sub {
my $result = $auth->enroll('x' x 33, 'password123');
ok( !$result->{success}, '33-char ID rejected' );
like( $result->{message}, qr/between/i, 'message mentions length requirement' );
};
subtest 'enroll - invalid chars rejected' => sub {
for my $id ( 'user name', 'user!name', 'user#name', 'user$name' ) {
my $result = $auth->enroll($id, 'password123');
ok( !$result->{success}, "invalid ID: '$id'" );
like( $result->{message}, qr/invalid/i, 'message mentions invalid characters' );
}
};
subtest 'enroll - valid ID formats accepted' => sub {
for my $id ( 'ab', 'alice-fmt', 'user_name-fmt', 'user.name-fmt',
'user@host-fmt.com', 'A1-fmt', 'z' x 32 ) {
my $result = $auth->enroll($id, 'password123');
ok( $result->{success}, "valid ID accepted: '$id'" );
}
};
# ========== File-related error conditions ==========
# The old validateFile method no longer exists as a standalone method
# either -- file readiness is now checked inline by each contract
# method that needs it (is_id_known, authenticate, change_credentials,
# revoke). Exercise a couple of them with no file configured.
subtest 'is_id_known - no file configured is simply "not known"' => sub {
my $nofile_auth;
my $w = warnings {
$nofile_auth = Concierge::Auth->new( backend_class => 'Concierge::Auth::Pwd', no_file => 1 );
};
my $result = $nofile_auth->is_id_known('alice');
ok( $result->{success}, 'is_id_known still succeeds (no I/O error)' );
ok( !$result->{known}, 'ID reported as not known when no file is configured' );
};
subtest 'change_credentials - no file configured fails' => sub {
my $nofile_auth;
my $w = warnings {
$nofile_auth = Concierge::Auth->new( backend_class => 'Concierge::Auth::Pwd', no_file => 1 );
};
my $result = $nofile_auth->change_credentials('alice', 'password123');
ok( !$result->{success}, 'change_credentials fails when no file is set' );
like( $result->{message}, qr/not OK/i, 'message indicates file not OK' );
};
done_testing;
( run in 0.616 second using v1.01-cache-2.11-cpan-ff9377addf4 )