120 lines
3.1 KiB
TypeScript
120 lines
3.1 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
|
|
const h = vi.hoisted(() => ({
|
|
provider: {
|
|
displayName: 'Dota 2',
|
|
start: vi.fn(),
|
|
stop: vi.fn(),
|
|
detect: vi.fn(),
|
|
install: vi.fn(),
|
|
uninstall: vi.fn(),
|
|
reconcile: vi.fn()
|
|
},
|
|
startGsiServer: vi.fn(),
|
|
stopGsiServer: vi.fn(),
|
|
onLaunchOptionsApplied: vi.fn(),
|
|
gamesEnabled: { dota2: true },
|
|
fireMatchSummary: vi.fn(),
|
|
log: { info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() }
|
|
}))
|
|
|
|
vi.mock('electron', () => ({
|
|
BrowserWindow: { getAllWindows: () => [] }
|
|
}))
|
|
|
|
vi.mock('./dota2', () => ({
|
|
Dota2Provider: vi.fn(function Dota2Provider() {
|
|
return h.provider
|
|
})
|
|
}))
|
|
|
|
vi.mock('./gsi-server', () => ({
|
|
startGsiServer: h.startGsiServer,
|
|
stopGsiServer: h.stopGsiServer
|
|
}))
|
|
|
|
vi.mock('./steam-launch-options', () => ({
|
|
onLaunchOptionsApplied: h.onLaunchOptionsApplied
|
|
}))
|
|
|
|
vi.mock('../store', () => ({
|
|
getChallenges: () => [],
|
|
getGamesEnabled: () => h.gamesEnabled
|
|
}))
|
|
|
|
vi.mock('../notifications', () => ({
|
|
fireMatchSummary: h.fireMatchSummary
|
|
}))
|
|
|
|
vi.mock('../logger', () => ({
|
|
log: h.log
|
|
}))
|
|
|
|
async function loadRegistry(): Promise<typeof import('./registry')> {
|
|
return import('./registry')
|
|
}
|
|
|
|
beforeEach(() => {
|
|
vi.resetModules()
|
|
h.provider.start.mockResolvedValue(undefined)
|
|
h.provider.stop.mockResolvedValue(undefined)
|
|
h.provider.detect.mockResolvedValue({
|
|
id: 'dota2',
|
|
name: 'Dota 2',
|
|
installed: true,
|
|
integrationActive: true,
|
|
launchOptionStatus: 'applied',
|
|
enabled: true
|
|
})
|
|
h.provider.install.mockResolvedValue(undefined)
|
|
h.provider.uninstall.mockResolvedValue(undefined)
|
|
h.provider.reconcile.mockResolvedValue(undefined)
|
|
h.startGsiServer.mockReset()
|
|
h.startGsiServer.mockResolvedValue(undefined)
|
|
h.stopGsiServer.mockReset()
|
|
h.stopGsiServer.mockResolvedValue(undefined)
|
|
h.onLaunchOptionsApplied.mockClear()
|
|
h.fireMatchSummary.mockClear()
|
|
h.log.info.mockClear()
|
|
h.log.warn.mockClear()
|
|
h.log.error.mockClear()
|
|
h.log.debug.mockClear()
|
|
})
|
|
|
|
describe('games registry lifecycle', () => {
|
|
it('сбрасывает running после ошибки старта GSI и позволяет повторный старт', async () => {
|
|
h.startGsiServer
|
|
.mockRejectedValueOnce(new Error('port busy'))
|
|
.mockResolvedValueOnce(undefined)
|
|
|
|
const { startGamesRegistry } = await loadRegistry()
|
|
await startGamesRegistry()
|
|
await startGamesRegistry()
|
|
|
|
expect(h.startGsiServer).toHaveBeenCalledTimes(2)
|
|
expect(h.provider.start).toHaveBeenCalledTimes(1)
|
|
})
|
|
|
|
it('stopGamesRegistry ждёт полного shutdown GSI-сервера', async () => {
|
|
let releaseStop!: () => void
|
|
const stopPromise = new Promise<void>((resolve) => {
|
|
releaseStop = resolve
|
|
})
|
|
h.stopGsiServer.mockReturnValue(stopPromise)
|
|
|
|
const { startGamesRegistry, stopGamesRegistry } = await loadRegistry()
|
|
await startGamesRegistry()
|
|
|
|
let resolved = false
|
|
const pending = stopGamesRegistry().then(() => {
|
|
resolved = true
|
|
})
|
|
await Promise.resolve()
|
|
|
|
expect(resolved).toBe(false)
|
|
releaseStop()
|
|
await pending
|
|
expect(resolved).toBe(true)
|
|
})
|
|
})
|