69 lines
2.5 KiB
TypeScript
69 lines
2.5 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|||
|
|
import { mount } from '@vue/test-utils'
|
||
|
|
import AppSessionFrame from '../AppSessionFrame.vue'
|
||
|
|
|
||
|
|
// Regression cover for the operator-reported defect: a container that is up
|
||
|
|
// but has not finished warming up (bitcoind serving RPC -28, lnd before the
|
||
|
|
// wallet unlocks) rendered the hard "App not reachable" failure copy for the
|
||
|
|
// whole warm-up window. The retry machinery already tolerated it — only the
|
||
|
|
// headline lied.
|
||
|
|
|
||
|
|
function mountFrame(props: Record<string, unknown> = {}) {
|
||
|
|
return mount(AppSessionFrame, {
|
||
|
|
props: {
|
||
|
|
appUrl: 'http://localhost:8332/',
|
||
|
|
appId: 'bitcoin-knots',
|
||
|
|
appTitle: 'Bitcoin',
|
||
|
|
appIcon: '/icons/bitcoin.png',
|
||
|
|
loading: false,
|
||
|
|
iframeBlocked: true,
|
||
|
|
mustOpenNewTab: false,
|
||
|
|
autoRetryCount: 1,
|
||
|
|
refreshKey: 0,
|
||
|
|
...props,
|
||
|
|
},
|
||
|
|
global: { stubs: { AppLoadingScreen: true, Transition: false } },
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
describe('AppSessionFrame warm-up state', () => {
|
||
|
|
it('reads as starting, not unreachable, while the container is warming up', () => {
|
||
|
|
const text = mountFrame({ warmingUp: true }).text()
|
||
|
|
expect(text).toContain('Bitcoin is starting…')
|
||
|
|
expect(text).not.toContain('App not reachable')
|
||
|
|
})
|
||
|
|
|
||
|
|
it('says the container is running so the copy does not imply it is stopped', () => {
|
||
|
|
const text = mountFrame({ warmingUp: true }).text()
|
||
|
|
expect(text).toContain("container is running but hasn't finished warming up")
|
||
|
|
expect(text).not.toContain('the container is stopped')
|
||
|
|
})
|
||
|
|
|
||
|
|
it('still surfaces the automatic re-check while warming up', () => {
|
||
|
|
expect(mountFrame({ warmingUp: true, autoRetryCount: 3 }).text()).toContain(
|
||
|
|
'Checking again automatically (3)',
|
||
|
|
)
|
||
|
|
})
|
||
|
|
|
||
|
|
it('reverts to the real failure once warm-up is over (retries exhausted)', () => {
|
||
|
|
const text = mountFrame({ warmingUp: false, autoRetryCount: 6 }).text()
|
||
|
|
expect(text).toContain('App not reachable')
|
||
|
|
expect(text).not.toContain('is starting…')
|
||
|
|
})
|
||
|
|
|
||
|
|
it('leaves the explicit blocked-reason path untouched', () => {
|
||
|
|
const text = mountFrame({
|
||
|
|
warmingUp: false,
|
||
|
|
blockedReason: 'Waiting for Bitcoin to finish syncing.',
|
||
|
|
blockedTitle: 'Waiting for Bitcoin sync',
|
||
|
|
}).text()
|
||
|
|
expect(text).toContain('Waiting for Bitcoin sync')
|
||
|
|
expect(text).not.toContain('App not reachable')
|
||
|
|
})
|
||
|
|
|
||
|
|
it('leaves the new-tab path untouched', () => {
|
||
|
|
const text = mountFrame({ warmingUp: false, mustOpenNewTab: true }).text()
|
||
|
|
expect(text).toContain('This app opens in a new tab')
|
||
|
|
})
|
||
|
|
})
|