import { describe, it, expect, beforeEach, afterEach } from 'vitest' import { createMockEvent } from '../helpers/createMockEvent.js' import securityHeadersMiddleware from '../../../server/middleware/02.security-headers.js' describe('security-headers middleware', () => { const originalNodeEnv = process.env.NODE_ENV afterEach(() => { process.env.NODE_ENV = originalNodeEnv }) describe('always-present headers', () => { beforeEach(() => { process.env.NODE_ENV = 'development' }) it('sets X-Content-Type-Options to nosniff', () => { const event = createMockEvent({ path: '/' }) securityHeadersMiddleware(event) expect(event._testSetHeaders['x-content-type-options']).toBe('nosniff') }) it('sets X-Frame-Options to DENY', () => { const event = createMockEvent({ path: '/' }) securityHeadersMiddleware(event) expect(event._testSetHeaders['x-frame-options']).toBe('DENY') }) it('sets X-XSS-Protection to 0', () => { const event = createMockEvent({ path: '/' }) securityHeadersMiddleware(event) expect(event._testSetHeaders['x-xss-protection']).toBe('0') }) it('sets Referrer-Policy', () => { const event = createMockEvent({ path: '/' }) securityHeadersMiddleware(event) expect(event._testSetHeaders['referrer-policy']).toBe('strict-origin-when-cross-origin') }) it('sets Permissions-Policy', () => { const event = createMockEvent({ path: '/' }) securityHeadersMiddleware(event) expect(event._testSetHeaders['permissions-policy']).toBe('camera=(), microphone=(), geolocation=()') }) }) describe('production-only headers', () => { it('sets HSTS in production', () => { process.env.NODE_ENV = 'production' const event = createMockEvent({ path: '/' }) securityHeadersMiddleware(event) expect(event._testSetHeaders['strict-transport-security']).toBe('max-age=31536000; includeSubDomains') }) it('does not set HSTS in development', () => { process.env.NODE_ENV = 'development' const event = createMockEvent({ path: '/' }) securityHeadersMiddleware(event) expect(event._testSetHeaders['strict-transport-security']).toBeUndefined() }) it('sets CSP in production', () => { process.env.NODE_ENV = 'production' const event = createMockEvent({ path: '/' }) securityHeadersMiddleware(event) expect(event._testSetHeaders['content-security-policy']).toBeDefined() }) it('does not set CSP in development', () => { process.env.NODE_ENV = 'development' const event = createMockEvent({ path: '/' }) securityHeadersMiddleware(event) expect(event._testSetHeaders['content-security-policy']).toBeUndefined() }) }) describe('CSP directives', () => { beforeEach(() => { process.env.NODE_ENV = 'production' }) it('includes Helcim sources in CSP', () => { const event = createMockEvent({ path: '/' }) securityHeadersMiddleware(event) const csp = event._testSetHeaders['content-security-policy'] expect(csp).toContain('myposjs.helcim.com') expect(csp).toContain('api.helcim.com') expect(csp).toContain('secure.helcim.com') }) it('includes Cloudinary sources in CSP', () => { const event = createMockEvent({ path: '/' }) securityHeadersMiddleware(event) const csp = event._testSetHeaders['content-security-policy'] expect(csp).toContain('res.cloudinary.com') }) it('includes Plausible sources in CSP', () => { const event = createMockEvent({ path: '/' }) securityHeadersMiddleware(event) const csp = event._testSetHeaders['content-security-policy'] expect(csp).toContain('plausible.io') }) }) })