Azure DevOps MCP Server
import {
AzureDevOpsError,
AzureDevOpsAuthenticationError,
AzureDevOpsValidationError,
AzureDevOpsResourceNotFoundError,
AzureDevOpsPermissionError,
AzureDevOpsRateLimitError,
isAzureDevOpsError,
formatAzureDevOpsError
} from '../../../src/api/errors';
describe('Azure DevOps Errors', () => {
describe('AzureDevOpsError', () => {
it('should create base error with message', () => {
const error = new AzureDevOpsError('Test error');
expect(error.message).toBe('Test error');
expect(error.name).toBe('AzureDevOpsError');
expect(error instanceof Error).toBe(true);
expect(error instanceof AzureDevOpsError).toBe(true);
});
});
describe('AzureDevOpsAuthenticationError', () => {
it('should create authentication error', () => {
const error = new AzureDevOpsAuthenticationError('Auth failed');
expect(error.message).toBe('Auth failed');
expect(error.name).toBe('AzureDevOpsAuthenticationError');
expect(error instanceof AzureDevOpsError).toBe(true);
expect(error instanceof AzureDevOpsAuthenticationError).toBe(true);
});
});
describe('AzureDevOpsValidationError', () => {
it('should create validation error with response', () => {
const response = { status: 400, data: { message: 'Invalid input' } };
const error = new AzureDevOpsValidationError('Validation failed', response);
expect(error.message).toBe('Validation failed');
expect(error.name).toBe('AzureDevOpsValidationError');
expect(error.response).toBe(response);
expect(error instanceof AzureDevOpsError).toBe(true);
expect(error instanceof AzureDevOpsValidationError).toBe(true);
});
it('should create validation error without response', () => {
const error = new AzureDevOpsValidationError('Validation failed', undefined);
expect(error.message).toBe('Validation failed');
expect(error.response).toBeUndefined();
});
});
describe('AzureDevOpsResourceNotFoundError', () => {
it('should create not found error', () => {
const error = new AzureDevOpsResourceNotFoundError('Resource not found');
expect(error.message).toBe('Resource not found');
expect(error.name).toBe('AzureDevOpsResourceNotFoundError');
expect(error instanceof AzureDevOpsError).toBe(true);
expect(error instanceof AzureDevOpsResourceNotFoundError).toBe(true);
});
});
describe('AzureDevOpsPermissionError', () => {
it('should create permission error', () => {
const error = new AzureDevOpsPermissionError('Permission denied');
expect(error.message).toBe('Permission denied');
expect(error.name).toBe('AzureDevOpsPermissionError');
expect(error instanceof AzureDevOpsError).toBe(true);
expect(error instanceof AzureDevOpsPermissionError).toBe(true);
});
});
describe('AzureDevOpsRateLimitError', () => {
it('should create rate limit error with reset time', () => {
const resetAt = new Date();
const error = new AzureDevOpsRateLimitError('Rate limit exceeded', resetAt);
expect(error.message).toBe('Rate limit exceeded');
expect(error.name).toBe('AzureDevOpsRateLimitError');
expect(error.resetAt).toBe(resetAt);
expect(error instanceof AzureDevOpsError).toBe(true);
expect(error instanceof AzureDevOpsRateLimitError).toBe(true);
});
it('should create rate limit error with default reset time', () => {
const error = new AzureDevOpsRateLimitError('Rate limit exceeded', new Date(0));
expect(error.message).toBe('Rate limit exceeded');
expect(error.resetAt.getTime()).toBe(0);
});
});
describe('isAzureDevOpsError', () => {
it('should return true for Azure DevOps errors', () => {
expect(isAzureDevOpsError(new AzureDevOpsError('Test'))).toBe(true);
expect(isAzureDevOpsError(new AzureDevOpsAuthenticationError('Test'))).toBe(true);
expect(isAzureDevOpsError(new AzureDevOpsValidationError('Test', undefined))).toBe(true);
expect(isAzureDevOpsError(new AzureDevOpsResourceNotFoundError('Test'))).toBe(true);
expect(isAzureDevOpsError(new AzureDevOpsPermissionError('Test'))).toBe(true);
expect(isAzureDevOpsError(new AzureDevOpsRateLimitError('Test', new Date(0)))).toBe(true);
});
it('should return false for non-Azure DevOps errors', () => {
expect(isAzureDevOpsError(new Error('Test'))).toBe(false);
expect(isAzureDevOpsError({ message: 'Test' })).toBe(false);
expect(isAzureDevOpsError(null)).toBe(false);
expect(isAzureDevOpsError(undefined)).toBe(false);
});
});
describe('formatAzureDevOpsError', () => {
it('should format Azure DevOps error with name and message', () => {
const error = new AzureDevOpsError('Test error');
expect(formatAzureDevOpsError(error)).toBe('AzureDevOpsError: Test error');
});
it('should format validation error with response', () => {
const response = { status: 400, data: { message: 'Invalid input' } };
const error = new AzureDevOpsValidationError('Validation failed', response);
expect(formatAzureDevOpsError(error)).toBe(
'AzureDevOpsValidationError: Validation failed\nResponse: {"status":400,"data":{"message":"Invalid input"}}'
);
});
it('should format validation error with null response', () => {
const error = new AzureDevOpsValidationError('Validation failed', null);
expect(formatAzureDevOpsError(error)).toBe('AzureDevOpsValidationError: Validation failed');
});
it('should format rate limit error with reset time', () => {
const resetAt = new Date('2024-01-01T00:00:00Z');
const error = new AzureDevOpsRateLimitError('Rate limit exceeded', resetAt);
expect(formatAzureDevOpsError(error)).toBe(
'AzureDevOpsRateLimitError: Rate limit exceeded\nReset at: 2024-01-01T00:00:00.000Z'
);
});
it('should format non-Azure DevOps error', () => {
const error = new Error('Regular error');
expect(formatAzureDevOpsError(error as AzureDevOpsError)).toBe('Error: Regular error');
});
it('should handle non-error objects', () => {
const objError = { name: 'TestError', message: 'Test' } as AzureDevOpsError;
const strError = 'string error' as unknown as AzureDevOpsError;
const nullError = null as unknown as AzureDevOpsError;
const undefinedError = undefined as unknown as AzureDevOpsError;
expect(formatAzureDevOpsError(objError)).toBe('TestError: Test');
expect(formatAzureDevOpsError(strError)).toBe('string error');
expect(formatAzureDevOpsError(nullError)).toBe('null');
expect(formatAzureDevOpsError(undefinedError)).toBe('undefined');
});
it('should handle objects with missing properties', () => {
const errorWithoutName = { message: 'No name' } as AzureDevOpsError;
const errorWithoutMessage = { name: 'NoMessage' } as AzureDevOpsError;
const emptyObject = {} as AzureDevOpsError;
expect(formatAzureDevOpsError(errorWithoutName)).toBe('Unknown: No name');
expect(formatAzureDevOpsError(errorWithoutMessage)).toBe('NoMessage: Unknown error');
expect(formatAzureDevOpsError(emptyObject)).toBe('Unknown: Unknown error');
});
it('should handle other primitive types', () => {
const numberError = 123 as unknown as AzureDevOpsError;
const booleanError = true as unknown as AzureDevOpsError;
expect(formatAzureDevOpsError(numberError)).toBe('Unknown: Unknown error');
expect(formatAzureDevOpsError(booleanError)).toBe('Unknown: Unknown error');
});
});
});