import { describe, it, expect } from 'vitest';
import type { Principal } from '@platform-modules/auth';
import {
  guestAuthorFromForm,
  moderatorActorFromPrincipal,
  safeAuthorUrl,
  userAuthorFromPrincipal,
} from './comments.js';

describe('safeAuthorUrl', () => {
  const pass = [
    ['http://example.com', 'http://example.com'],
    ['https://example.com/path', 'https://example.com/path'],
    ['HTTPS://EXAMPLE.COM', 'HTTPS://EXAMPLE.COM'],
  ] as const;

  const fail = [
    '',
    '   ',
    'javascript:alert(1)',
    'data:text/html,<script>alert(1)</script>',
    'vbscript:msgbox(1)',
    '//evil.com',
    '/relative/path',
    'not-a-url',
    null,
    undefined,
  ] as const;

  it.each(pass)('allows %s', (input, expected) => {
    expect(safeAuthorUrl(input)).toBe(expected);
  });

  it.each(fail)('rejects %j → null', (input) => {
    expect(safeAuthorUrl(input)).toBeNull();
  });
});

describe('moderatorActorFromPrincipal', () => {
  const base: Principal = { userId: 'u1', sessionId: 's1', roles: [] };

  it('sets canModerate for admin role', () => {
    expect(moderatorActorFromPrincipal({ ...base, roles: ['admin'] })).toEqual({
      id: 'u1',
      canModerate: true,
    });
  });

  it('denies canModerate for editor and viewer', () => {
    expect(moderatorActorFromPrincipal({ ...base, roles: ['editor'] })).toEqual({
      id: 'u1',
      canModerate: false,
    });
    expect(moderatorActorFromPrincipal({ ...base, roles: ['viewer'] })).toEqual({
      id: 'u1',
      canModerate: false,
    });
  });
});

describe('guestAuthorFromForm', () => {
  it('builds a guest author with optional email and url', () => {
    expect(guestAuthorFromForm({ name: 'Ada', email: 'a@b.test', url: 'https://a.test' })).toEqual({
      kind: 'guest',
      name: 'Ada',
      email: 'a@b.test',
      url: 'https://a.test',
    });
  });

  it('omits empty optional fields', () => {
    expect(guestAuthorFromForm({ name: 'Bob' })).toEqual({ kind: 'guest', name: 'Bob' });
  });
});

describe('userAuthorFromPrincipal', () => {
  it('maps principal to user author', () => {
    expect(
      userAuthorFromPrincipal({ userId: 'u9', sessionId: 's1', roles: ['editor'] }),
    ).toEqual({ kind: 'user', userId: 'u9' });
  });
});
