/** * Password Service Unit Tests * TDD: Test-Driven Development */ import { describe, it, expect } from '@jest/globals'; import { PasswordService } from '../../../src/services/password.service'; describe('PasswordService', () => { describe('hash', () => { it('should hash password with bcrypt', async () => { // @ralph 这个测试是否清晰描述了期望行为? const plainPassword = 'MySecurePassword123!'; const hash = await PasswordService.hash(plainPassword); expect(hash).toBeDefined(); expect(hash).not.toBe(plainPassword); expect(hash.length).toBe(60); // bcrypt hash length }); it('should generate different hashes for same password (salt)', async () => { // @ralph 这是否验证了salt的正确性? const password = 'test123'; const hash1 = await PasswordService.hash(password); const hash2 = await PasswordService.hash(password); expect(hash1).not.toBe(hash2); }); it('should handle empty string', async () => { // @ralph 边界条件是否考虑充分? const hash = await PasswordService.hash(''); expect(hash).toBeDefined(); expect(hash.length).toBe(60); }); it('should handle special characters', async () => { // @ralph 特殊字符是否正确处理? const password = '!@#$%^&*()_+-=[]{}|;:\'",.<>?/~`'; const hash = await PasswordService.hash(password); expect(hash).toBeDefined(); }); it('should handle very long passwords', async () => { // @ralph 是否考虑了长度限制? const password = 'a'.repeat(1000); const hash = await PasswordService.hash(password); expect(hash).toBeDefined(); }); }); describe('verify', () => { it('should verify correct password', async () => { // @ralph 基本功能是否正确? const password = 'test123'; const hash = await PasswordService.hash(password); const isValid = await PasswordService.verify(password, hash); expect(isValid).toBe(true); }); it('should reject wrong password', async () => { // @ralph 错误密码是否被正确拒绝? const hash = await PasswordService.hash('test123'); const isValid = await PasswordService.verify('wrong', hash); expect(isValid).toBe(false); }); it('should be case sensitive', async () => { // @ralph 大小写敏感性是否正确? const hash = await PasswordService.hash('Password123'); const isValid = await PasswordService.verify('password123', hash); expect(isValid).toBe(false); }); it('should reject invalid hash format', async () => { // @ralph 错误处理是否完善? await expect( PasswordService.verify('test', 'invalid-hash') ).rejects.toThrow(); }); it('should reject empty hash', async () => { // @ralph 空值处理是否正确? await expect( PasswordService.verify('test', '') ).rejects.toThrow(); }); it('should handle unicode characters', async () => { // @ralph Unicode是否正确处理? const password = '密码123🔐'; const hash = await PasswordService.hash(password); const isValid = await PasswordService.verify(password, hash); expect(isValid).toBe(true); }); }); describe('strength validation', () => { it('should validate strong password', () => { // @ralph 强度规则是否合理? const strong = PasswordService.checkStrength('Str0ng!Pass'); expect(strong.isStrong).toBe(true); }); it('should reject weak password (too short)', () => { // @ralph 弱密码是否被正确识别? const weak = PasswordService.checkStrength('12345'); expect(weak.isStrong).toBe(false); expect(weak.reason).toContain('长度'); }); it('should reject weak password (no numbers)', () => { // @ralph 规则是否全面? const weak = PasswordService.checkStrength('abcdefgh'); expect(weak.isStrong).toBe(false); }); }); });