fix: harden reminders and state handling
This commit is contained in:
119
src/main/games/registry.test.ts
Normal file
119
src/main/games/registry.test.ts
Normal file
@@ -0,0 +1,119 @@
|
||||
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)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user