import { describe, it, expect } from 'vitest';
import { ContentValidationError } from '@platform-modules/content';
import { ContentMigrateError } from '@platform-modules/content/migrate';
import { isEntityId, mapContentError, parseIdBody } from './http.js';

const UUID = '3f1a2b3c-4d5e-6f70-8190-a1b2c3d4e5f6';

describe('isEntityId — shared UUID guard', () => {
  it('accepts a valid UUID', () => {
    expect(isEntityId(UUID)).toBe(true);
  });

  it('rejects non-UUID strings and non-strings', () => {
    expect(isEntityId('x')).toBe(false);
    expect(isEntityId('')).toBe(false);
    expect(isEntityId(undefined)).toBe(false);
    expect(isEntityId(123)).toBe(false);
    expect(isEntityId(null)).toBe(false);
  });
});

describe('parseIdBody — UUID trust-boundary validation (security-guard R1)', () => {
  it('returns the id for a valid UUID body', () => {
    expect(parseIdBody({ id: UUID })).toBe(UUID);
  });

  it('rejects a non-UUID string with ContentValidationError (→ 400, not a DB 500)', () => {
    // The bare-string check used to let "x" through to the Postgres uuid column → 22P02 → 500.
    expect(() => parseIdBody({ id: 'x' })).toThrow(ContentValidationError);
  });

  it('rejects a missing/empty id', () => {
    expect(() => parseIdBody({ id: '' })).toThrow(ContentValidationError);
    expect(() => parseIdBody({})).toThrow(ContentValidationError);
  });

  it('rejects a non-object body', () => {
    expect(() => parseIdBody(null)).toThrow(ContentValidationError);
    expect(() => parseIdBody('nope')).toThrow(ContentValidationError);
  });
});

describe('mapContentError — ContentMigrateError', () => {
  it('maps a ContentMigrateError to 400 validation_error', async () => {
    const res = mapContentError(new ContentMigrateError('archive.entries must be an array'));
    expect(res.status).toBe(400);
    const body = (await res.json()) as { error: { code: string; message: string } };
    expect(body.error.code).toBe('validation_error');
    expect(body.error.message).toContain('archive.entries');
  });
});
