import { describe, it, expect, beforeAll } from 'vitest';
import { createPgliteClient } from '@platform-modules/db/pglite';
import {
  commentsSchema,
  list,
  post,
  type CommentsSchema,
} from '@platform-modules/comments';
import type { Querier } from '@platform-modules/db';
import { applyCommentsSchema } from './install.js';
import { guestAuthorParts, escapeHtml } from './comments-render.js';
import { sanitizeContentBody } from './sanitize.js';

const TARGET = { type: 'content_entry', id: '11111111-1111-4111-8111-111111111111' };
const moderator = { id: 'mod', canModerate: true };

describe('host security e2e (U5 §7 trust boundary)', () => {
  let db: Querier<CommentsSchema>;

  beforeAll(async () => {
    db = createPgliteClient({ schema: commentsSchema });
    await applyCommentsSchema(db);
  });

  it('(a) stored javascript: author_url is never an active link at render', async () => {
    await post(
      db,
      {
        target: TARGET,
        author: { kind: 'guest', name: 'Phish', url: 'javascript:alert(1)' },
        body: 'stored bad url',
        initialStatus: 'published',
      },
      moderator,
      sanitizeContentBody,
    );
    const page = await list(db, TARGET, {}, undefined);
    const comment = page.items[0]!;
    expect(comment.author.kind).toBe('guest');
    if (comment.author.kind === 'guest') {
      const parts = guestAuthorParts(comment.author);
      expect(parts.href).toBeNull();
    }
  });

  it('(b) script in author_name renders escaped', () => {
    const escaped = escapeHtml('<script>alert(1)</script>');
    expect(escaped).not.toContain('<script>');
    expect(escaped).toContain('&lt;script&gt;');
  });

  it('(d) anon comment is not in public list until approved', async () => {
    const target = { type: 'content_entry', id: '22222222-2222-4222-8222-222222222222' };
    await post(
      db,
      { target, author: { kind: 'guest', name: 'Anon' }, body: 'hold for mod' },
      null,
      sanitizeContentBody,
    );
    const publicPage = await list(db, target, {}, undefined);
    expect(publicPage.items).toHaveLength(0);
    const modPage = await list(db, target, { status: 'pending' }, moderator);
    expect(modPage.items).toHaveLength(1);
  });
});
