import { describe, it, expect } from 'vitest'; import { buildSecurityHeaders } from './middleware'; describe('buildSecurityHeaders', () => { const headers = buildSecurityHeaders(); it('sets a strict Content-Security-Policy', () => { const csp = headers['Content-Security-Policy']; expect(csp).toContain("default-src 'self'"); expect(csp).toContain("script-src 'self'"); expect(csp).toContain("frame-ancestors 'none'"); expect(csp).toContain("form-action 'none'"); expect(csp).toContain("base-uri 'self'"); expect(csp).toContain("object-src 'none'"); }); it('denies framing', () => { expect(headers['X-Frame-Options']).toBe('DENY'); }); it('disables MIME sniffing', () => { expect(headers['X-Content-Type-Options']).toBe('nosniff'); }); it('sets a strict referrer policy', () => { expect(headers['Referrer-Policy']).toBe('strict-origin-when-cross-origin'); }); it('disables sensitive browser features', () => { const pp = headers['Permissions-Policy']; expect(pp).toContain('geolocation=()'); expect(pp).toContain('microphone=()'); expect(pp).toContain('camera=()'); expect(pp).toContain('payment=()'); }); it('sets HSTS with long max-age, subdomains, and preload', () => { const hsts = headers['Strict-Transport-Security']; expect(hsts).toContain('max-age=31536000'); expect(hsts).toContain('includeSubDomains'); expect(hsts).toContain('preload'); }); it('does not allow inline scripts', () => { // Script directive must not include 'unsafe-inline' — find it explicitly and assert. const scriptDirective = headers['Content-Security-Policy'] .split(';') .map(s => s.trim()) .find(s => s.startsWith('script-src')) ?? ''; expect(scriptDirective).toContain("'self'"); expect(scriptDirective).not.toContain("'unsafe-inline'"); expect(scriptDirective).not.toContain("'unsafe-eval'"); }); });