@ritas-inc/hanaqueryapi-client
Version:
TypeScript client for HANA Query API with full type safety and error handling
173 lines (155 loc) • 5.52 kB
text/typescript
/**
* Tests for type guard functions
*/
import { describe, it } from 'node:test';
import assert from 'node:assert/strict';
// Import type guards and error checking functions (values)
import {
isSuccessResponse,
isErrorResponse,
isHanaQueryClientError,
isNetworkError,
isTimeoutError,
isValidationError,
isAuthorizationError,
isNotFoundError,
isServerError,
NetworkError,
TimeoutError,
ValidationError,
AuthorizationError,
NotFoundError,
ServerError,
UnknownError
} from './index.ts';
// Import types separately
import type {
SuccessResponse,
ErrorResponse,
APIResponse
} from './index.ts';
describe('Type Guards', () => {
describe('Response Type Guards', () => {
it('should identify success responses', () => {
const successResponse: SuccessResponse = {
success: true,
data: { test: 'data' },
metadata: { count: 1 }
};
assert.equal(isSuccessResponse(successResponse), true);
assert.equal(isErrorResponse(successResponse), false);
});
it('should identify error responses', () => {
const errorResponse: ErrorResponse = {
success: false,
problem: {
status: 404,
type: 'not-found',
title: 'Not Found',
detail: 'Resource not found',
instance: '/api/test',
context: {
request: 'GET /api/test',
responseText: 'Not found'
},
issues: []
}
};
assert.equal(isErrorResponse(errorResponse), true);
assert.equal(isSuccessResponse(errorResponse), false);
});
it('should handle type narrowing for API responses', () => {
const response: APIResponse = {
success: true,
data: { items: [] },
metadata: { count: 0 }
};
if (isSuccessResponse(response)) {
// TypeScript should know response.data exists here
assert.equal(Array.isArray(response.data.items), true);
assert.equal(response.metadata.count, 0);
} else {
// This branch should not execute
assert.fail('Should be a success response');
}
});
});
describe('Error Type Guards', () => {
it('should identify HanaQueryClientError base type', () => {
const error = new NetworkError('Network failed');
assert.equal(isHanaQueryClientError(error), true);
assert.equal(isHanaQueryClientError(new Error('Regular error')), false);
assert.equal(isHanaQueryClientError('not an error'), false);
});
it('should identify NetworkError', () => {
const error = new NetworkError('Connection refused');
assert.equal(isNetworkError(error), true);
assert.equal(isTimeoutError(error), false);
assert.equal(error.type, 'network_error');
});
it('should identify TimeoutError', () => {
const error = new TimeoutError(5000);
assert.equal(isTimeoutError(error), true);
assert.equal(isNetworkError(error), false);
assert.equal(error.type, 'timeout_error');
assert.equal(error.message, 'Request timed out after 5000ms');
});
it('should identify ValidationError', () => {
const error = new ValidationError('Invalid data', ['field1', 'field2']);
assert.equal(isValidationError(error), true);
assert.equal(error.type, 'validation_error');
assert.equal(error.message, 'Validation error: Invalid data: field1, field2');
});
it('should identify AuthorizationError', () => {
const error = new AuthorizationError('Unauthorized', 401);
assert.equal(isAuthorizationError(error), true);
assert.equal(error.type, 'authorization_error');
assert.equal(error.statusCode, 401);
});
it('should identify NotFoundError', () => {
const error = new NotFoundError('/api/test');
assert.equal(isNotFoundError(error), true);
assert.equal(error.type, 'not_found_error');
assert.equal(error.statusCode, 404);
assert.equal(error.message, 'Resource not found: /api/test');
});
it('should identify ServerError', () => {
const error = new ServerError('Internal server error', 500);
assert.equal(isServerError(error), true);
assert.equal(error.type, 'server_error');
assert.equal(error.statusCode, 500);
});
it('should handle unknown errors', () => {
const error = new UnknownError('Something went wrong', new Error('Original'));
assert.equal(isHanaQueryClientError(error), true);
assert.equal(error.type, 'unknown_error');
assert.equal(error.message, 'Unknown error: Something went wrong');
});
});
describe('Error Handling in Catch Blocks', () => {
it('should handle unknown errors in catch blocks', () => {
try {
throw new Error('Test error');
} catch (error: unknown) {
// This is the pattern we want to enforce
if (error instanceof Error) {
assert.equal(error.message, 'Test error');
} else {
assert.fail('Should be an Error instance');
}
}
});
it('should handle HanaQueryClientError in catch blocks', () => {
try {
throw new NetworkError('Network issue');
} catch (error: unknown) {
if (isHanaQueryClientError(error)) {
assert.equal(error.type, 'network_error');
assert.equal(error.message, 'Network error: Network issue');
} else {
assert.fail('Should be a HanaQueryClientError');
}
}
});
});
});