101 lines
3.2 KiB
TypeScript
101 lines
3.2 KiB
TypeScript
// src/utils/authUtils.test.ts
|
|
import { describe, it, expect, vi } from 'vitest';
|
|
import zxcvbn from 'zxcvbn';
|
|
import { validatePasswordStrength } from './authUtils';
|
|
|
|
// Mock the zxcvbn library to control its output for tests
|
|
vi.mock('zxcvbn');
|
|
|
|
// Helper function to create a complete mock zxcvbn result, satisfying the type.
|
|
const createMockZxcvbnResult = (
|
|
score: 0 | 1 | 2 | 3 | 4,
|
|
suggestions: string[] = [],
|
|
): zxcvbn.ZXCVBNResult => ({
|
|
score,
|
|
feedback: {
|
|
suggestions,
|
|
warning: '',
|
|
},
|
|
// Add dummy values for the other required properties to satisfy the type.
|
|
guesses: 1,
|
|
guesses_log10: 1,
|
|
crack_times_seconds: {
|
|
online_throttling_100_per_hour: 1,
|
|
online_no_throttling_10_per_second: 1,
|
|
offline_slow_hashing_1e4_per_second: 1,
|
|
offline_fast_hashing_1e10_per_second: 1,
|
|
},
|
|
crack_times_display: {
|
|
online_throttling_100_per_hour: '1 second',
|
|
online_no_throttling_10_per_second: '1 second',
|
|
offline_slow_hashing_1e4_per_second: '1 second',
|
|
offline_fast_hashing_1e10_per_second: '1 second',
|
|
},
|
|
sequence: [],
|
|
calc_time: 1,
|
|
});
|
|
|
|
describe('validatePasswordStrength', () => {
|
|
it('should return invalid for a very weak password (score 0)', () => {
|
|
// Arrange: Mock zxcvbn to return a score of 0 and specific feedback
|
|
vi.mocked(zxcvbn).mockReturnValue(
|
|
createMockZxcvbnResult(0, ['Add more words', 'Use a longer password']),
|
|
);
|
|
|
|
// Act
|
|
const result = validatePasswordStrength('password');
|
|
|
|
// Assert
|
|
expect(result.isValid).toBe(false);
|
|
expect(result.feedback).toBe('Password is too weak. Add more words Use a longer password');
|
|
});
|
|
|
|
it('should return invalid for a weak password (score 1)', () => {
|
|
// Arrange: Mock zxcvbn to return a score of 1
|
|
vi.mocked(zxcvbn).mockReturnValue(createMockZxcvbnResult(1, ['Avoid common words']));
|
|
|
|
// Act
|
|
const result = validatePasswordStrength('password123');
|
|
|
|
// Assert
|
|
expect(result.isValid).toBe(false);
|
|
expect(result.feedback).toBe('Password is too weak. Avoid common words');
|
|
});
|
|
|
|
it('should return invalid for a medium password (score 2)', () => {
|
|
// Arrange: Mock zxcvbn to return a score of 2
|
|
vi.mocked(zxcvbn).mockReturnValue(createMockZxcvbnResult(2, ['Add another symbol or number']));
|
|
|
|
// Act
|
|
const result = validatePasswordStrength('Password123');
|
|
|
|
// Assert
|
|
expect(result.isValid).toBe(false);
|
|
expect(result.feedback).toBe('Password is too weak. Add another symbol or number');
|
|
});
|
|
|
|
it('should return valid for a good password (score 3)', () => {
|
|
// Arrange: Mock zxcvbn to return a score of 3 (the minimum required)
|
|
vi.mocked(zxcvbn).mockReturnValue(createMockZxcvbnResult(3));
|
|
|
|
// Act
|
|
const result = validatePasswordStrength('a-Strong-Password!');
|
|
|
|
// Assert
|
|
expect(result.isValid).toBe(true);
|
|
expect(result.feedback).toBe('');
|
|
});
|
|
|
|
it('should return valid for a very strong password (score 4)', () => {
|
|
// Arrange: Mock zxcvbn to return a score of 4
|
|
vi.mocked(zxcvbn).mockReturnValue(createMockZxcvbnResult(4));
|
|
|
|
// Act
|
|
const result = validatePasswordStrength('a-Very-Strong-Password-123!');
|
|
|
|
// Assert
|
|
expect(result.isValid).toBe(true);
|
|
expect(result.feedback).toBe('');
|
|
});
|
|
});
|