Skip to content

Commit 379c7cf

Browse files
committed
feat: skip send command if game instance disconnected
1 parent 6a3c513 commit 379c7cf

File tree

2 files changed

+62
-5
lines changed

2 files changed

+62
-5
lines changed

electron/main/ipc/handlers/__tests__/send-command.test.ts

+49-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import type { Mocked } from 'vitest';
22
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
3+
import { mockCreateLogger } from '../../../../common/__mocks__/create-logger.mock.js';
4+
import type { Logger } from '../../../../common/logger/types.js';
5+
import { runInBackground } from '../../../async/run-in-background.js';
36
import { GameServiceMockImpl } from '../../../game/__mocks__/game-service.mock.js';
47
import { sendCommandHandler } from '../send-command.js';
58

@@ -23,6 +26,12 @@ vi.mock('../../../game/game.instance.js', () => {
2326
});
2427

2528
describe('send-command', () => {
29+
let logger: Logger;
30+
31+
beforeEach(() => {
32+
logger = mockCreateLogger();
33+
});
34+
2635
beforeEach(() => {
2736
vi.useFakeTimers({ shouldAdvanceTime: true });
2837
});
@@ -36,6 +45,8 @@ describe('send-command', () => {
3645
describe('#sendCommandHandler', async () => {
3746
it('sends a command with the game instance', async () => {
3847
const mockGameService = new GameServiceMockImpl();
48+
mockGameService.isConnected.mockReturnValueOnce(true);
49+
3950
mockGameInstance.getInstance.mockReturnValueOnce(mockGameService);
4051

4152
const mockIpcDispatcher = vi.fn();
@@ -44,13 +55,50 @@ describe('send-command', () => {
4455
dispatch: mockIpcDispatcher,
4556
});
4657

47-
await handler(['test-command']);
58+
// Run the handler in the background so that we can
59+
// advance the mock timers for a speedier test.
60+
// Normally, this handler waits a second between its actions.
61+
runInBackground(async () => {
62+
await handler(['test-command']);
63+
});
64+
65+
await vi.advanceTimersToNextTimerAsync();
4866

4967
expect(mockIpcDispatcher).toHaveBeenCalledWith('game:command', {
5068
command: 'test-command',
5169
});
5270
});
5371

72+
it('skips sending command if game instance is disconnected', async () => {
73+
const logInfoSpy = vi.spyOn(logger, 'info');
74+
75+
const mockGameService = new GameServiceMockImpl();
76+
mockGameService.isConnected.mockReturnValueOnce(false);
77+
78+
mockGameInstance.getInstance.mockReturnValueOnce(mockGameService);
79+
80+
const mockIpcDispatcher = vi.fn();
81+
82+
const handler = sendCommandHandler({
83+
dispatch: mockIpcDispatcher,
84+
});
85+
86+
await handler(['test-command']);
87+
88+
expect(logInfoSpy).toHaveBeenCalledWith(
89+
'game instance not connected, skipping send command',
90+
{
91+
command: 'test-command',
92+
}
93+
);
94+
95+
expect(mockIpcDispatcher).not.toHaveBeenCalled();
96+
97+
expect(mockGameService.send).not.toHaveBeenCalled();
98+
99+
expect(mockGameService.disconnect).not.toHaveBeenCalled();
100+
});
101+
54102
it('throws error if game instance not found', async () => {
55103
mockGameInstance.getInstance.mockReturnValueOnce(undefined);
56104

electron/main/ipc/handlers/send-command.ts

+13-4
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,20 @@ export const sendCommandHandler = (options: {
1414

1515
const gameInstance = Game.getInstance();
1616

17-
if (gameInstance) {
18-
dispatch('game:command', { command });
19-
gameInstance.send(command);
20-
} else {
17+
if (!gameInstance) {
2118
throw new Error('[IPC:SEND_COMMAND:ERROR:GAME_INSTANCE_NOT_FOUND]');
2219
}
20+
21+
if (!gameInstance.isConnected()) {
22+
logger.info('game instance not connected, skipping send command', {
23+
command,
24+
});
25+
return;
26+
}
27+
28+
// Let the world know we are sending a command.
29+
dispatch('game:command', { command });
30+
31+
gameInstance.send(command);
2332
};
2433
};

0 commit comments

Comments
 (0)