const { test, expect } = require('@playwright/test');

const PRODUCTION_URL = 'https://colinknapp.com';
const LOCAL_URL = 'http://localhost:8080';

async function getPageUrl(page) {
    try {
        // Try production first
        await page.goto(PRODUCTION_URL, { timeout: 60000 });
        return PRODUCTION_URL;
    } catch (error) {
        console.log('Production site not available, falling back to local');
        await page.goto(LOCAL_URL, { timeout: 60000 });
        return LOCAL_URL;
    }
}

test.describe('Security Headers Tests', () => {
    test('should have all required security headers', async ({ page, request }) => {
        const url = await getPageUrl(page);
        console.log(`Running security header tests against ${url}`);

        // Get headers directly from the main page
        const response = await request.get(url);
        const headers = response.headers();

        // Check Content Security Policy
        const csp = headers['content-security-policy'];
        expect(csp).toBeTruthy();
        expect(csp).toContain("default-src 'none'");
        expect(csp).toContain("script-src 'self'");
        expect(csp).toContain("style-src 'self'");
        expect(csp).toContain("img-src 'self' data:");
        expect(csp).toContain("font-src 'self' data:");
        expect(csp).toContain("connect-src 'self'");
        expect(csp).toContain("object-src 'none'");
        expect(csp).toContain("frame-ancestors 'none'");
        expect(csp).toContain("base-uri 'none'");
        expect(csp).toContain("form-action 'none'");

        // Check other security headers
        expect(headers['x-content-type-options']).toBe('nosniff');
        expect(headers['x-frame-options']).toBe('DENY');
        expect(headers['referrer-policy']).toBe('strict-origin-when-cross-origin');
    });

    test('should have correct Subresource Integrity (SRI) attributes', async ({ page }) => {
        const url = await getPageUrl(page);
        console.log(`Running SRI tests against ${url}`);
        await page.goto(url, { timeout: 60000 });
        await page.waitForLoadState('networkidle');

        // Check stylesheet
        const stylesheet = await page.locator('link[rel="stylesheet"]').first();
        const stylesheetIntegrity = await stylesheet.getAttribute('integrity');
        const stylesheetCrossorigin = await stylesheet.getAttribute('crossorigin');
        expect(stylesheetIntegrity).toBeTruthy();
        expect(stylesheetCrossorigin).toBe('anonymous');

        // Check script
        const script = await page.locator('script[src]').first();
        const scriptIntegrity = await script.getAttribute('integrity');
        const scriptCrossorigin = await script.getAttribute('crossorigin');
        expect(scriptIntegrity).toBeTruthy();
        expect(scriptCrossorigin).toBe('anonymous');
    });

    test('should have correct caching headers for static assets', async ({ request }) => {
        const url = await getPageUrl({ goto: async () => {} });
        console.log(`Running caching header tests against ${url}`);
        const baseUrl = url.replace(/\/$/, '');

        // Check styles.css
        const stylesResponse = await request.get(`${baseUrl}/styles.css`);
        const stylesCacheControl = stylesResponse.headers()['cache-control'];
        expect(stylesCacheControl).toContain('public');
        expect(stylesCacheControl).toContain('max-age=');

        // Check theme.js
        const scriptResponse = await request.get(`${baseUrl}/theme.js`);
        const scriptCacheControl = scriptResponse.headers()['cache-control'];
        expect(scriptCacheControl).toContain('public');
        expect(scriptCacheControl).toContain('max-age=');
    });
}); 