import { describe, it, expect } from 'vitest'; import { signRequest, generateNonce, hmacSha256Sync } from '@/utils/request-signer'; describe('generateNonce', () => { it('生成 16 字符十六进制字符串', () => { const nonce = generateNonce(); expect(nonce).toHaveLength(16); expect(nonce).toMatch(/^[0-9a-f]{16}$/); }); it('连续调用生成不同值', () => { const n1 = generateNonce(); const n2 = generateNonce(); expect(n1).not.toBe(n2); }); }); describe('hmacSha256Sync', () => { it('相同输入产生相同输出', () => { const key = 'test-key'; const msg = 'hello world'; const r1 = hmacSha256Sync(key, msg); const r2 = hmacSha256Sync(key, msg); expect(r1).toBe(r2); expect(r1).toHaveLength(64); // SHA-256 = 32 bytes = 64 hex chars }); it('不同输入产生不同输出', () => { const r1 = hmacSha256Sync('key', 'msg1'); const r2 = hmacSha256Sync('key', 'msg2'); expect(r1).not.toBe(r2); }); }); describe('signRequest', () => { const signingKey = 'test-signing-key-256-bit!!!!!!!!!!!'; it('GET 请求生成正确的签名头', () => { const headers = signRequest('GET', '/health/patients', undefined, signingKey); expect(headers).toHaveProperty('X-Signature'); expect(headers).toHaveProperty('X-Timestamp'); expect(headers).toHaveProperty('X-Nonce'); expect(headers['X-Nonce']).toHaveLength(16); expect(headers['X-Signature']).toHaveLength(64); }); it('POST 请求包含 body hash', () => { const headers = signRequest('POST', '/health/vital-signs', { value: 120 }, signingKey); expect(headers).toHaveProperty('X-Signature'); expect(headers['X-Signature']).toHaveLength(64); }); it('无 body 时也能正常签名', () => { const headers = signRequest('GET', '/test', undefined, signingKey); expect(headers['X-Signature']).toBeTruthy(); }); it('相同参数不同 nonce 产生不同签名', () => { const h1 = signRequest('GET', '/test', undefined, signingKey); // 由于 nonce 不同,签名也不同 const h2 = signRequest('GET', '/test', undefined, signingKey); expect(h1['X-Signature']).not.toBe(h2['X-Signature']); }); });