import { unstable_getResponseFromNextConfig } from 'next/experimental/testing/server';
import { describe, expect, it } from 'vitest';
import { securityHeaders } from '../../next.config';

/** Response headers Next's own matcher produces for `path` with the given header rules. */
async function headersFor(path: string, production = true): Promise<Headers> {
  const response = await unstable_getResponseFromNextConfig({
    url: `https://pintrush.com${path}`,
    nextConfig: { headers: async () => securityHeaders(production) },
  });
  return response.headers;
}

describe('security headers (next.config.ts)', () => {
  it('hardens every route', async () => {
    for (const path of ['/', '/pricing', '/pilot', '/host', '/host/events/abc', '/admin/leads', '/api/a', '/tv/room', '/join/HARBOR', '/play/room']) {
      const h = await headersFor(path);
      expect(h.get('x-content-type-options')).toBe('nosniff');
      expect(h.get('permissions-policy')).toBe('camera=(), microphone=(), geolocation=(), payment=(), usb=()');
      expect(h.get('strict-transport-security')).toBe('max-age=63072000; includeSubDomains');
      expect(h.get('content-security-policy')).toContain("object-src 'none'");
      expect(h.get('content-security-policy')).toContain("base-uri 'self'");
    }
  });

  it('forbids framing everywhere except the routes /demo embeds', async () => {
    for (const path of ['/', '/demo', '/host', '/host/login', '/admin', '/admin/venues/x', '/pilot', '/tvguide', '/player']) {
      const h = await headersFor(path);
      expect(h.get('x-frame-options'), path).toBe('DENY');
      expect(h.get('content-security-policy'), path).toContain("frame-ancestors 'none'");
      expect(h.get('referrer-policy'), path).toBe('strict-origin-when-cross-origin');
    }
    for (const path of ['/tv/room-1', '/join/HARBOR', '/play/room-1']) {
      const h = await headersFor(path);
      expect(h.get('x-frame-options'), path).toBe('SAMEORIGIN');
      expect(h.get('content-security-policy'), path).toContain("frame-ancestors 'self'");
      expect(h.get('content-security-policy'), path).not.toContain("'none';");
    }
  });

  it('never sends a Referer from the TV (its URL carries the display token)', async () => {
    expect((await headersFor('/tv/room-1')).get('referrer-policy')).toBe('no-referrer');
    expect((await headersFor('/join/HARBOR')).get('referrer-policy')).toBe('strict-origin-when-cross-origin');
  });

  it('sends HSTS only in production', async () => {
    expect((await headersFor('/', false)).get('strict-transport-security')).toBeNull();
  });
});
