mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-04-27 07:48:01 -07:00
66 lines
2.2 KiB
TypeScript
66 lines
2.2 KiB
TypeScript
// KeepAliveService timing scenarios — ping loop, pong correlation, timeout.
|
|
|
|
import { describe, expect, it } from 'vitest';
|
|
|
|
import { Data } from '@app/types';
|
|
import { store } from '@app/store';
|
|
import { WebsocketTypes } from '@app/websocket/types';
|
|
|
|
import { connectRaw, getMockWebSocket } from '../helpers/setup';
|
|
import {
|
|
buildResponse,
|
|
buildResponseMessage,
|
|
deliverMessage,
|
|
} from '../helpers/protobuf-builders';
|
|
import { findLastSessionCommand } from '../helpers/command-capture';
|
|
|
|
describe('keep-alive', () => {
|
|
it('sends a Command_Ping on every keepalive interval tick', () => {
|
|
connectRaw();
|
|
|
|
expect(() => findLastSessionCommand(Data.Command_Ping_ext)).toThrow();
|
|
|
|
vi.advanceTimersByTime(5000);
|
|
const first = findLastSessionCommand(Data.Command_Ping_ext);
|
|
expect(first.cmdId).toBeGreaterThan(0);
|
|
|
|
deliverMessage(buildResponseMessage(buildResponse({
|
|
cmdId: first.cmdId,
|
|
responseCode: Data.Response_ResponseCode.RespOk,
|
|
})));
|
|
|
|
vi.advanceTimersByTime(5000);
|
|
const second = findLastSessionCommand(Data.Command_Ping_ext);
|
|
expect(second.cmdId).toBeGreaterThan(first.cmdId);
|
|
expect(store.getState().server.status.state).toBe(WebsocketTypes.StatusEnum.CONNECTED);
|
|
});
|
|
|
|
it('stays CONNECTED while pongs arrive before the next tick', () => {
|
|
connectRaw();
|
|
|
|
for (let i = 0; i < 3; i++) {
|
|
vi.advanceTimersByTime(5000);
|
|
const ping = findLastSessionCommand(Data.Command_Ping_ext);
|
|
deliverMessage(buildResponseMessage(buildResponse({
|
|
cmdId: ping.cmdId,
|
|
responseCode: Data.Response_ResponseCode.RespOk,
|
|
})));
|
|
}
|
|
|
|
expect(store.getState().server.status.state).toBe(WebsocketTypes.StatusEnum.CONNECTED);
|
|
expect(getMockWebSocket().close).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('disconnects with a timeout status when a ping goes unanswered', () => {
|
|
connectRaw();
|
|
|
|
vi.advanceTimersByTime(5000);
|
|
expect(() => findLastSessionCommand(Data.Command_Ping_ext)).not.toThrow();
|
|
expect(store.getState().server.status.state).toBe(WebsocketTypes.StatusEnum.CONNECTED);
|
|
|
|
vi.advanceTimersByTime(5000);
|
|
|
|
expect(getMockWebSocket().close).toHaveBeenCalled();
|
|
expect(store.getState().server.status.state).toBe(WebsocketTypes.StatusEnum.DISCONNECTED);
|
|
});
|
|
});
|