auth-password-policy.test.ts43 lines · main
1import { describe, expect, test } from 'bun:test';
2
3import { ValidationError } from '@briven/shared';
4
5import {
6 DEFAULT_PASSWORD_POLICY,
7 passwordHistoryDigest,
8 validatePassword,
9} from './auth-password-policy.js';
10
11describe('validatePassword', () => {
12 test('accepts default min length 8', () => {
13 expect(() => validatePassword('abcdefgh', DEFAULT_PASSWORD_POLICY)).not.toThrow();
14 });
15
16 test('rejects short passwords', () => {
17 expect(() => validatePassword('short', DEFAULT_PASSWORD_POLICY)).toThrow(ValidationError);
18 });
19
20 test('requires uppercase when configured', () => {
21 const policy = { ...DEFAULT_PASSWORD_POLICY, requireUppercase: true };
22 expect(() => validatePassword('abcdefgh', policy)).toThrow(/uppercase/i);
23 expect(() => validatePassword('Abcdefgh', policy)).not.toThrow();
24 });
25
26 test('requires number + special when configured', () => {
27 const policy = {
28 ...DEFAULT_PASSWORD_POLICY,
29 requireNumber: true,
30 requireSpecial: true,
31 };
32 expect(() => validatePassword('Abcdefgh', policy)).toThrow(/number/i);
33 expect(() => validatePassword('Abcdefg1', policy)).toThrow(/special/i);
34 expect(() => validatePassword('Abcdefg1!', policy)).not.toThrow();
35 });
36});
37
38describe('passwordHistoryDigest', () => {
39 test('is stable and different for different passwords', () => {
40 expect(passwordHistoryDigest('same')).toBe(passwordHistoryDigest('same'));
41 expect(passwordHistoryDigest('a')).not.toBe(passwordHistoryDigest('b'));
42 });
43});