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:
@@ -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' }));
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user