/**
 * Tests for render.js security and correctness
 * Run with: node glass-ui/js/render.test.js
 */

// Mock minimal browser environment
const escHtml = (s) =>
  String(s ?? "")
    .replace(/&/g, "&amp;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/"/g, "&quot;")
    .replace(/'/g, "&#39;");

// Test cases for XSS prevention
// Key insight: we check that < and > are escaped, which neutralizes ALL HTML injection
const xssTestCases = [
  {
    name: "Script tag in inline code - angle brackets escaped",
    input: '<script>alert("XSS")</script>',
    mustNotContain: "<script>", // Raw < must be escaped
    mustContain: "&lt;script&gt;",
  },
  {
    name: "Image tag XSS - angle brackets escaped",
    input: '<img src=x onerror="alert(1)">',
    mustNotContain: "<img", // Raw < must be escaped
    mustContain: "&lt;img",
  },
  {
    name: "Quotes escaped to prevent attribute injection",
    input: '" onclick="alert(1)"',
    mustNotContain: null, // All content is safe inside escaped code
    mustContain: "&quot;", // Double quotes must be escaped
  },
  {
    name: "HTML entities double-escaped",
    input: "&amp; &lt; &gt;",
    mustContain: "&amp;amp;",
  },
  {
    name: "Single quotes escaped",
    input: "it's a test",
    mustContain: "&#39;",
  },
  {
    name: "Normal code unchanged semantically",
    input: "const x = 1;",
    mustContain: "const x = 1;",
  },
  {
    name: "SVG XSS vector blocked",
    input: '<svg onload="alert(1)">',
    mustNotContain: "<svg",
    mustContain: "&lt;svg",
  },
  {
    name: "Nested script blocked",
    input: "<<script>script>alert(1)<</script>/script>",
    mustNotContain: "<script",
    mustContain: "&lt;",
  },
];

// Simulate renderer.codespan behavior (fixed version)
function renderCodespan(text) {
  return `<code class="inline-code">${escHtml(text)}</code>`;
}

// Run tests
console.log("Glass UI render.js Security Tests\n" + "=".repeat(40) + "\n");

let passed = 0;
let failed = 0;

for (const tc of xssTestCases) {
  const result = renderCodespan(tc.input);
  let testPassed = true;
  const errors = [];

  if (tc.mustNotContain && result.includes(tc.mustNotContain)) {
    testPassed = false;
    errors.push(`Should NOT contain: "${tc.mustNotContain}"`);
  }

  if (tc.mustContain && !result.includes(tc.mustContain)) {
    testPassed = false;
    errors.push(`Should contain: "${tc.mustContain}"`);
  }

  if (testPassed) {
    console.log(`✓ ${tc.name}`);
    passed++;
  } else {
    console.log(`✗ ${tc.name}`);
    console.log(`  Input:  ${tc.input}`);
    console.log(`  Output: ${result}`);
    errors.forEach((e) => console.log(`  Error:  ${e}`));
    failed++;
  }
}

console.log("\n" + "=".repeat(40));
console.log(`Results: ${passed} passed, ${failed} failed`);

if (failed > 0) {
  console.log("\n❌ XSS vulnerability detected!");
  process.exit(1);
} else {
  console.log("\n✅ All XSS tests passed - inline code is properly escaped");
  process.exit(0);
}
