/**
 * Changelog module — unit tests.
 */

import { describe, it, expect } from 'vitest';
import { CreateChangelogSchema, UpdateChangelogSchema } from './types.js';

describe('CreateChangelogSchema', () => {
  it('accepts valid entry', () => {
    const result = CreateChangelogSchema.parse({
      version: '1.2.0',
      title: 'New Dashboard',
      categories: ['feature'],
    });
    expect(result.version).toBe('1.2.0');
    expect(result.body).toBe('');
    expect(result.published).toBe(false);
  });

  it('accepts entry with all fields', () => {
    const result = CreateChangelogSchema.parse({
      version: '2.0.0',
      title: 'Major Release',
      body: '## Breaking Changes\n- New API format',
      categories: ['feature', 'breaking'],
      published: true,
    });
    expect(result.categories).toHaveLength(2);
    expect(result.published).toBe(true);
  });

  it('rejects empty version', () => {
    expect(() =>
      CreateChangelogSchema.parse({ version: '', title: 'Test', categories: ['fix'] })
    ).toThrow();
  });

  it('rejects empty title', () => {
    expect(() =>
      CreateChangelogSchema.parse({ version: '1.0.0', title: '', categories: ['fix'] })
    ).toThrow();
  });

  it('rejects empty categories', () => {
    expect(() =>
      CreateChangelogSchema.parse({ version: '1.0.0', title: 'Test', categories: [] })
    ).toThrow();
  });

  it('rejects invalid category', () => {
    expect(() =>
      CreateChangelogSchema.parse({ version: '1.0.0', title: 'Test', categories: ['unknown'] })
    ).toThrow();
  });

  it('rejects title over 200 chars', () => {
    expect(() =>
      CreateChangelogSchema.parse({ version: '1.0.0', title: 'x'.repeat(201), categories: ['fix'] })
    ).toThrow();
  });

  it('rejects body over 10000 chars', () => {
    expect(() =>
      CreateChangelogSchema.parse({
        version: '1.0.0',
        title: 'Test',
        body: 'x'.repeat(10001),
        categories: ['fix'],
      })
    ).toThrow();
  });
});

describe('UpdateChangelogSchema', () => {
  it('accepts partial update', () => {
    const result = UpdateChangelogSchema.parse({ title: 'Updated Title' });
    expect(result.title).toBe('Updated Title');
    expect(result.version).toBeUndefined();
  });

  it('accepts publish toggle', () => {
    const result = UpdateChangelogSchema.parse({ published: true });
    expect(result.published).toBe(true);
  });

  it('accepts category update', () => {
    const result = UpdateChangelogSchema.parse({ categories: ['fix', 'security'] });
    expect(result.categories).toEqual(['fix', 'security']);
  });

  it('rejects invalid category in update', () => {
    expect(() => UpdateChangelogSchema.parse({ categories: ['invalid'] })).toThrow();
  });

  it('rejects empty categories array in update', () => {
    expect(() => UpdateChangelogSchema.parse({ categories: [] })).toThrow();
  });
});
