import { describe, it, expect } from 'vitest';
import {
  ApiError,
  AuthenticationError,
  NetworkError,
  RefreshTokenExpiredError,
} from '../errors.js';

describe('ApiError', () => {
  it('stores status code and message', () => {
    const error = new ApiError('Not found', 404);
    expect(error.message).toBe('Not found');
    expect(error.status).toBe(404);
    expect(error.name).toBe('ApiError');
  });

  it('stores optional validation errors', () => {
    const validationErrors = [{ field: 'email', message: 'Invalid email' }];
    const error = new ApiError('Validation failed', 400, undefined, validationErrors);
    expect(error.validationErrors).toEqual(validationErrors);
  });

  it('stores optional code', () => {
    const error = new ApiError('Conflict', 409, 'USERNAME_TAKEN');
    expect(error.code).toBe('USERNAME_TAKEN');
  });
});

describe('AuthenticationError', () => {
  it('defaults to 401 status', () => {
    const error = new AuthenticationError();
    expect(error.status).toBe(401);
    expect(error.name).toBe('AuthenticationError');
  });

  it('accepts custom status for 403', () => {
    const error = new AuthenticationError('Forbidden', 403);
    expect(error.status).toBe(403);
  });
});

describe('NetworkError', () => {
  it('defaults to non-timeout', () => {
    const error = new NetworkError();
    expect(error.isTimeout).toBe(false);
    expect(error.name).toBe('NetworkError');
  });

  it('flags timeout errors', () => {
    const error = new NetworkError('Request timed out', true);
    expect(error.isTimeout).toBe(true);
  });
});

describe('RefreshTokenExpiredError', () => {
  it('is an AuthenticationError with correct message', () => {
    const error = new RefreshTokenExpiredError();
    expect(error).toBeInstanceOf(AuthenticationError);
    expect(error.message).toBe('Session expired. Please log in again.');
    expect(error.name).toBe('RefreshTokenExpiredError');
  });
});
