fix
This commit is contained in:
@@ -392,6 +392,7 @@ app
|
|||||||
)
|
)
|
||||||
await online.initialize()
|
await online.initialize()
|
||||||
if (quitting || startupWindow.isDestroyed()) return
|
if (quitting || startupWindow.isDestroyed()) return
|
||||||
|
void online.restoreGames()
|
||||||
let previousConnection = online.state.connection
|
let previousConnection = online.state.connection
|
||||||
const logConnection = () => {
|
const logConnection = () => {
|
||||||
const status = online!.state.connection
|
const status = online!.state.connection
|
||||||
|
|||||||
@@ -938,6 +938,97 @@ test('вход, подготовка и зашифрованные секрет
|
|||||||
assert.equal(c.state.channels.main.desired, 'playing')
|
assert.equal(c.state.channels.main.desired, 'playing')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('без сохранённого входа запуск не запрашивает список игр', async (t) => {
|
||||||
|
const f = await fixture(t)
|
||||||
|
await f.online.restoreGames()
|
||||||
|
assert.equal(f.requests.length, 0)
|
||||||
|
})
|
||||||
|
|
||||||
|
for (const expired of [false, true]) {
|
||||||
|
test(`после восстановления входа список игр загружается без кнопки; токен просрочен: ${expired}`, async (t) => {
|
||||||
|
const f = await fixture(t)
|
||||||
|
await f.login()
|
||||||
|
await f.online.close()
|
||||||
|
f.requests.length = 0
|
||||||
|
f.model.accessExpired = expired
|
||||||
|
const restored = new Online(
|
||||||
|
join(f.directory, 'connection'), f.store, new Controller(() => {}), f.secrets, f.fetchAPI,
|
||||||
|
)
|
||||||
|
t.after(() => restored.close())
|
||||||
|
await restored.initialize()
|
||||||
|
await restored.restoreGames()
|
||||||
|
assert.deepEqual(restored.snapshot().games, [{ id: 7, name: 'Дело', status: 'finish' }])
|
||||||
|
assert.equal(restored.snapshot().error, '')
|
||||||
|
assert.equal(restored.snapshot().busy, false)
|
||||||
|
assert.equal(restored.snapshot().screenId, null)
|
||||||
|
assert.equal(f.model.refreshCalls, expired ? 1 : 0)
|
||||||
|
assert.ok(f.requests.every(r => ['/api/games', '/api/auth/refresh'].includes(r.path)))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
test('запуск без сети сохраняет доступ к локальной игре; список можно обновить позже', async (t) => {
|
||||||
|
const f = await fixture(t)
|
||||||
|
await f.login()
|
||||||
|
await f.online.act({ action: 'select-game', gameId: 7 })
|
||||||
|
await f.online.close()
|
||||||
|
f.model.offline = true
|
||||||
|
const controller = new Controller(() => {})
|
||||||
|
const restored = new Online(
|
||||||
|
join(f.directory, 'connection'), f.store, controller, f.secrets, f.fetchAPI,
|
||||||
|
)
|
||||||
|
t.after(() => restored.close())
|
||||||
|
await restored.initialize()
|
||||||
|
const selected = controller.state.catalog.key
|
||||||
|
assert.ok(selected)
|
||||||
|
await restored.restoreGames()
|
||||||
|
assert.match(restored.snapshot().error, /Сервер недоступен/)
|
||||||
|
assert.equal(restored.snapshot().busy, false)
|
||||||
|
controller.output(true)
|
||||||
|
assert.equal(controller.state.outputOpen, true)
|
||||||
|
assert.equal(controller.state.catalog.key, selected)
|
||||||
|
f.model.offline = false
|
||||||
|
await restored.act({ action: 'games' })
|
||||||
|
assert.equal(restored.snapshot().games.length, 1)
|
||||||
|
assert.equal(restored.snapshot().error, '')
|
||||||
|
})
|
||||||
|
|
||||||
|
for (const fails of [false, true]) {
|
||||||
|
test(`ответ фоновой загрузки после выхода игнорируется; ошибка: ${fails}`, async (t) => {
|
||||||
|
const f = await fixture(t)
|
||||||
|
await f.login()
|
||||||
|
await f.online.close()
|
||||||
|
let release!: () => void
|
||||||
|
let started!: () => void
|
||||||
|
const gate = new Promise<void>(resolve => { release = resolve })
|
||||||
|
const requestStarted = new Promise<void>(resolve => { started = resolve })
|
||||||
|
const fetchAPI: typeof fetch = async (input, init) => {
|
||||||
|
const response = await f.fetchAPI(input, init)
|
||||||
|
const read = response.json.bind(response)
|
||||||
|
response.json = async () => {
|
||||||
|
started()
|
||||||
|
await gate
|
||||||
|
if (fails) throw new Error('network failure')
|
||||||
|
return read()
|
||||||
|
}
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
const restored = new Online(
|
||||||
|
join(f.directory, 'connection'), f.store, new Controller(() => {}), f.secrets, fetchAPI,
|
||||||
|
)
|
||||||
|
t.after(() => restored.close())
|
||||||
|
await restored.initialize()
|
||||||
|
const pending = restored.restoreGames()
|
||||||
|
await requestStarted
|
||||||
|
assert.equal(restored.snapshot().busy, false)
|
||||||
|
await restored.act({ action: 'logout' })
|
||||||
|
release()
|
||||||
|
await pending
|
||||||
|
assert.equal(restored.snapshot().authenticated, false)
|
||||||
|
assert.deepEqual(restored.snapshot().games, [])
|
||||||
|
assert.equal(restored.snapshot().error, '')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
test('без хранилища ОС вход только в памяти; выход не останавливает показ', async (t) => {
|
test('без хранилища ОС вход только в памяти; выход не останавливает показ', async (t) => {
|
||||||
const f = await fixture(t, false)
|
const f = await fixture(t, false)
|
||||||
await f.prepare()
|
await f.prepare()
|
||||||
|
|||||||
@@ -1668,8 +1668,20 @@ export class Online {
|
|||||||
await this.refreshMaterials()
|
await this.refreshMaterials()
|
||||||
await this.poll()
|
await this.poll()
|
||||||
}
|
}
|
||||||
|
async restoreGames() {
|
||||||
|
if (!this.credentials) return
|
||||||
|
const generation = this.generation
|
||||||
|
try {
|
||||||
|
await this.loadGames()
|
||||||
|
} catch (error) {
|
||||||
|
if (generation === this.generation && !this.state.error)
|
||||||
|
this.state.error = error instanceof Error ? error.message : 'Не удалось загрузить список игр'
|
||||||
|
}
|
||||||
|
}
|
||||||
private async loadGames() {
|
private async loadGames() {
|
||||||
|
const generation = this.generation
|
||||||
const result = await this.client().GetGames({})
|
const result = await this.client().GetGames({})
|
||||||
|
if (generation !== this.generation) throw new SessionChangedError()
|
||||||
if (!Array.isArray(result.games ?? [])) throw new Error('Некорректный список игр')
|
if (!Array.isArray(result.games ?? [])) throw new Error('Некорректный список игр')
|
||||||
this.state.games = ((result.games ?? []) as unknown[]).map((value) => {
|
this.state.games = ((result.games ?? []) as unknown[]).map((value) => {
|
||||||
const g = object(value)
|
const g = object(value)
|
||||||
|
|||||||
Reference in New Issue
Block a user