refactor: update TypeScript configuration and test utilities for improved type safety

- Modify tsconfig.json to relax strict type checking for gradual migration
- Update test files to use more flexible type checking and mocking
- Add type-safe mock and test utility functions
- Improve error handling and type inference in test suites
- Export Tool interface and tools list for better testing support
This commit is contained in:
jango-blockchained
2025-02-05 09:16:21 +01:00
parent eefbf790c3
commit 4e9ebbbc2c
21 changed files with 526 additions and 532 deletions

View File

@@ -5,7 +5,7 @@ import { EventEmitter } from 'events';
import * as HomeAssistant from '../../src/types/hass.js';
// Mock WebSocket
jest.mock('ws');
// // jest.mock('ws');
describe('WebSocket Event Handling', () => {
let client: HassWebSocketClient;
@@ -25,10 +25,10 @@ describe('WebSocket Event Handling', () => {
eventEmitter.on(event, listener);
return mockWebSocket;
}),
send: jest.fn(),
close: jest.fn(),
send: mock(),
close: mock(),
readyState: WebSocket.OPEN,
removeAllListeners: jest.fn(),
removeAllListeners: mock(),
// Add required WebSocket properties
binaryType: 'arraybuffer',
bufferedAmount: 0,
@@ -36,9 +36,9 @@ describe('WebSocket Event Handling', () => {
protocol: '',
url: 'ws://test.com',
isPaused: () => false,
ping: jest.fn(),
pong: jest.fn(),
terminate: jest.fn()
ping: mock(),
pong: mock(),
terminate: mock()
} as unknown as jest.Mocked<WebSocket>;
// Mock WebSocket constructor
@@ -53,9 +53,9 @@ describe('WebSocket Event Handling', () => {
client.disconnect();
});
it('should handle connection events', () => {
test('should handle connection events', () => {
// Simulate open event
eventEmitter.emit('open');
eventEmitter.emtest('open');
// Verify authentication message was sent
expect(mockWebSocket.send).toHaveBeenCalledWith(
@@ -63,17 +63,17 @@ describe('WebSocket Event Handling', () => {
);
});
it('should handle authentication response', () => {
test('should handle authentication response', () => {
// Simulate auth_ok message
eventEmitter.emit('message', JSON.stringify({ type: 'auth_ok' }));
eventEmitter.emtest('message', JSON.stringify({ type: 'auth_ok' }));
// Verify client is ready for commands
expect(mockWebSocket.readyState).toBe(WebSocket.OPEN);
});
it('should handle auth failure', () => {
test('should handle auth failure', () => {
// Simulate auth_invalid message
eventEmitter.emit('message', JSON.stringify({
eventEmitter.emtest('message', JSON.stringify({
type: 'auth_invalid',
message: 'Invalid token'
}));
@@ -82,34 +82,34 @@ describe('WebSocket Event Handling', () => {
expect(mockWebSocket.close).toHaveBeenCalled();
});
it('should handle connection errors', () => {
test('should handle connection errors', () => {
// Create error spy
const errorSpy = jest.fn();
const errorSpy = mock();
client.on('error', errorSpy);
// Simulate error
const testError = new Error('Test error');
eventEmitter.emit('error', testError);
eventEmitter.emtest('error', testError);
// Verify error was handled
expect(errorSpy).toHaveBeenCalledWith(testError);
});
it('should handle disconnection', () => {
test('should handle disconnection', () => {
// Create close spy
const closeSpy = jest.fn();
const closeSpy = mock();
client.on('close', closeSpy);
// Simulate close
eventEmitter.emit('close');
eventEmitter.emtest('close');
// Verify close was handled
expect(closeSpy).toHaveBeenCalled();
});
it('should handle event messages', () => {
test('should handle event messages', () => {
// Create event spy
const eventSpy = jest.fn();
const eventSpy = mock();
client.on('event', eventSpy);
// Simulate event message
@@ -123,44 +123,44 @@ describe('WebSocket Event Handling', () => {
}
}
};
eventEmitter.emit('message', JSON.stringify(eventData));
eventEmitter.emtest('message', JSON.stringify(eventData));
// Verify event was handled
expect(eventSpy).toHaveBeenCalledWith(eventData.event);
});
describe('Connection Events', () => {
it('should handle successful connection', (done) => {
test('should handle successful connection', (done) => {
client.on('open', () => {
expect(mockWebSocket.send).toHaveBeenCalled();
done();
});
eventEmitter.emit('open');
eventEmitter.emtest('open');
});
it('should handle connection errors', (done) => {
test('should handle connection errors', (done) => {
const error = new Error('Connection failed');
client.on('error', (err: Error) => {
expect(err).toBe(error);
done();
});
eventEmitter.emit('error', error);
eventEmitter.emtest('error', error);
});
it('should handle connection close', (done) => {
test('should handle connection close', (done) => {
client.on('disconnected', () => {
expect(mockWebSocket.close).toHaveBeenCalled();
done();
});
eventEmitter.emit('close');
eventEmitter.emtest('close');
});
});
describe('Authentication', () => {
it('should send authentication message on connect', () => {
test('should send authentication message on connect', () => {
const authMessage: HomeAssistant.AuthMessage = {
type: 'auth',
access_token: 'test_token'
@@ -170,27 +170,27 @@ describe('WebSocket Event Handling', () => {
expect(mockWebSocket.send).toHaveBeenCalledWith(JSON.stringify(authMessage));
});
it('should handle successful authentication', (done) => {
test('should handle successful authentication', (done) => {
client.on('auth_ok', () => {
done();
});
client.connect();
eventEmitter.emit('message', JSON.stringify({ type: 'auth_ok' }));
eventEmitter.emtest('message', JSON.stringify({ type: 'auth_ok' }));
});
it('should handle authentication failure', (done) => {
test('should handle authentication failure', (done) => {
client.on('auth_invalid', () => {
done();
});
client.connect();
eventEmitter.emit('message', JSON.stringify({ type: 'auth_invalid' }));
eventEmitter.emtest('message', JSON.stringify({ type: 'auth_invalid' }));
});
});
describe('Event Subscription', () => {
it('should handle state changed events', (done) => {
test('should handle state changed events', (done) => {
const stateEvent: HomeAssistant.StateChangedEvent = {
event_type: 'state_changed',
data: {
@@ -236,16 +236,16 @@ describe('WebSocket Event Handling', () => {
done();
});
eventEmitter.emit('message', JSON.stringify({ type: 'event', event: stateEvent }));
eventEmitter.emtest('message', JSON.stringify({ type: 'event', event: stateEvent }));
});
it('should subscribe to specific events', async () => {
test('should subscribe to specific events', async () => {
const subscriptionId = 1;
const callback = jest.fn();
const callback = mock();
// Mock successful subscription
const subscribePromise = client.subscribeEvents('state_changed', callback);
eventEmitter.emit('message', JSON.stringify({
eventEmitter.emtest('message', JSON.stringify({
id: 1,
type: 'result',
success: true
@@ -258,7 +258,7 @@ describe('WebSocket Event Handling', () => {
entity_id: 'light.living_room',
state: 'on'
};
eventEmitter.emit('message', JSON.stringify({
eventEmitter.emtest('message', JSON.stringify({
type: 'event',
event: {
event_type: 'state_changed',
@@ -269,13 +269,13 @@ describe('WebSocket Event Handling', () => {
expect(callback).toHaveBeenCalledWith(eventData);
});
it('should unsubscribe from events', async () => {
test('should unsubscribe from events', async () => {
// First subscribe
const subscriptionId = await client.subscribeEvents('state_changed', () => { });
// Then unsubscribe
const unsubscribePromise = client.unsubscribeEvents(subscriptionId);
eventEmitter.emit('message', JSON.stringify({
eventEmitter.emtest('message', JSON.stringify({
id: 2,
type: 'result',
success: true
@@ -286,16 +286,16 @@ describe('WebSocket Event Handling', () => {
});
describe('Message Handling', () => {
it('should handle malformed messages', (done) => {
test('should handle malformed messages', (done) => {
client.on('error', (error: Error) => {
expect(error.message).toContain('Unexpected token');
done();
});
eventEmitter.emit('message', 'invalid json');
eventEmitter.emtest('message', 'invalid json');
});
it('should handle unknown message types', (done) => {
test('should handle unknown message types', (done) => {
const unknownMessage = {
type: 'unknown_type',
data: {}
@@ -306,12 +306,12 @@ describe('WebSocket Event Handling', () => {
done();
});
eventEmitter.emit('message', JSON.stringify(unknownMessage));
eventEmitter.emtest('message', JSON.stringify(unknownMessage));
});
});
describe('Reconnection', () => {
it('should attempt to reconnect on connection loss', (done) => {
test('should attempt to reconnect on connection loss', (done) => {
let reconnectAttempts = 0;
client.on('disconnected', () => {
reconnectAttempts++;
@@ -321,19 +321,19 @@ describe('WebSocket Event Handling', () => {
}
});
eventEmitter.emit('close');
eventEmitter.emtest('close');
});
it('should re-authenticate after reconnection', (done) => {
test('should re-authenticate after reconnection', (done) => {
client.connect();
client.on('auth_ok', () => {
done();
});
eventEmitter.emit('close');
eventEmitter.emit('open');
eventEmitter.emit('message', JSON.stringify({ type: 'auth_ok' }));
eventEmitter.emtest('close');
eventEmitter.emtest('open');
eventEmitter.emtest('message', JSON.stringify({ type: 'auth_ok' }));
});
});
});