Files
integrations/test/denon/test.denon.client.node.ts
T

62 lines
2.4 KiB
TypeScript

import { createServer, type Socket } from 'node:net';
import { expect, tap } from '@git.zone/tstest/tapbundle';
import { DenonClient } from '../../ts/integrations/denon/index.js';
tap.test('reads Denon telnet state and sends control commands', async () => {
const commands: string[] = [];
const server = createServer((socketArg) => {
let buffer = '';
socketArg.setEncoding('ascii');
socketArg.on('data', (chunkArg) => {
buffer += String(chunkArg);
const parts = buffer.split('\r');
buffer = parts.pop() || '';
for (const part of parts) {
handleCommand(part.trim(), socketArg, commands);
}
});
});
await new Promise<void>((resolve) => server.listen(0, '127.0.0.1', resolve));
try {
const address = server.address();
const port = typeof address === 'object' && address ? address.port : 0;
const client = new DenonClient({ host: '127.0.0.1', port, timeoutMs: 500, responseIdleMs: 50 });
const snapshot = await client.getSnapshot();
await client.execute({ command: 'set_volume', volumeLevel: 0.5 });
await client.execute({ command: 'select_source', source: 'TV' });
expect(snapshot.online).toBeTrue();
expect(snapshot.receiverInfo.name).toEqual('Living Room Denon');
expect(snapshot.state.state).toEqual('playing');
expect(snapshot.state.volume).toEqual(27);
expect(snapshot.state.volumeLevel).toEqual(0.45);
expect(snapshot.state.muted).toBeFalse();
expect(snapshot.state.sourceName).toEqual('Media server');
expect(snapshot.state.mediaTitle).toContain('Track One');
expect(commands.includes('MV30')).toBeTrue();
expect(commands.includes('SITV')).toBeTrue();
} finally {
await new Promise<void>((resolve, reject) => server.close((errorArg) => errorArg ? reject(errorArg) : resolve()));
}
});
const handleCommand = (commandArg: string, socketArg: Socket, commandsArg: string[]): void => {
commandsArg.push(commandArg);
const responses: Record<string, string[]> = {
'NSFRN ?': ['NSFRN Living Room Denon'],
'SSFUN ?': ['SSFUNCD CD', 'SSFUNSERVER Media server', 'SSFUNTV TV'],
'SSSOD ?': ['SSSODV.AUX DEL'],
'PW?': ['PWON'],
'MV?': ['MVMAX 60', 'MV27'],
'MU?': ['MUOFF'],
'SI?': ['SISERVER'],
NSE: ['NSE0Track One', 'NSE1XArtist One', 'NSE2XAlbum One'],
};
for (const response of responses[commandArg] || []) {
socketArg.write(`${response}\r`, 'ascii');
}
};
export default tap.start();