Files
Starlight_Lancher/apps/app-frontend/src/helpers/instance-player.test.ts
T
Disy 51fb0c30f7
Axolotl desktop CI / guardrails (push) Has been cancelled
Repository checks / typos (push) Has been cancelled
Repository checks / tombi (push) Has been cancelled
Rust checks / shear (push) Has been cancelled
Sync source to CNB / Sync Git ref (push) Has been cancelled
Axolotl desktop CI / desktop (macos-latest) (push) Has been cancelled
Axolotl desktop CI / desktop (ubuntu-latest) (push) Has been cancelled
Axolotl desktop CI / desktop (windows-latest) (push) Has been cancelled
Axolotl desktop CI / website (push) Has been cancelled
Sync LobeHub models / sync (push) Has been cancelled
fix: 完善整合包同步与启动器交互
2026-09-16 17:01:22 +08:00

165 lines
5.5 KiB
TypeScript

import assert from 'node:assert/strict'
import test from 'node:test'
import { useNetworkStatus } from '../composables/useNetworkStatus.ts'
import {
setSkinSiteFrame,
resetSkinSiteSession,
receiveSkinSiteMessage,
SKIN_SITE_ORIGIN,
} from '../composables/skin-site-session.ts'
import {
prepareInstancePlayer,
registerInstancePlayerPicker,
saveInstancePlayer,
onInstancePlayerChanged,
type InstancePlayer,
} from './instance-player.ts'
test('instance player selection persists independently from the globally selected account', async () => {
const previousNavigator = Object.getOwnPropertyDescriptor(globalThis, 'navigator')
Object.defineProperty(globalThis, 'navigator', { configurable: true, value: { onLine: true } })
useNetworkStatus().refreshBrowserOffline()
const saved: InstancePlayer = { id: 'saved', name: 'Saved', account_type: 'microsoft' }
let binding: InstancePlayer | null = saved
let accounts = [
{ profile: { id: 'other', name: 'Other' }, account_type: 'microsoft' },
{ profile: { id: 'saved', name: 'Saved' }, account_type: 'microsoft' },
]
const previous = Object.getOwnPropertyDescriptor(globalThis, 'window')
Object.defineProperty(globalThis, 'window', {
configurable: true,
value: {
__TAURI_INTERNALS__: {
invoke: async (command: string) => {
if (command === 'plugin:auth|get_instance_player') return binding
if (command === 'plugin:auth|get_users') return accounts
throw new Error(`Unexpected command ${command}`)
},
},
},
})
const requests: Array<InstancePlayer | null> = []
const unregister = registerInstancePlayerPicker(async (_id, locked) => {
requests.push(locked)
binding = saved
return saved
})
try {
setSkinSiteFrame({ postMessage() {} } as unknown as Window)
await prepareInstancePlayer('instance')
assert.equal(requests.length, 0)
setSkinSiteFrame(null)
binding = null
await Promise.all([prepareInstancePlayer('instance'), prepareInstancePlayer('instance')])
assert.deepEqual(requests, [null])
await prepareInstancePlayer('instance')
assert.equal(requests.length, 1)
accounts = accounts.filter((account) => account.profile.id !== saved.id)
await prepareInstancePlayer('instance')
assert.equal(
requests[1],
saved,
'Missing saved player must remain locked, not fall back to the other account',
)
} finally {
unregister()
if (previousNavigator) Object.defineProperty(globalThis, 'navigator', previousNavigator)
else Reflect.deleteProperty(globalThis, 'navigator')
if (previous) Object.defineProperty(globalThis, 'window', previous)
else Reflect.deleteProperty(globalThis, 'window')
}
})
test('signed-in skin site renews the saved player without prompting and only notifies after saving', async () => {
const previous = Object.getOwnPropertyDescriptor(globalThis, 'window')
const previousNavigator = Object.getOwnPropertyDescriptor(globalThis, 'navigator')
Object.defineProperty(globalThis, 'navigator', { configurable: true, value: { onLine: true } })
useNetworkStatus().refreshBrowserOffline()
const player: InstancePlayer = {
id: '12345678-1234-1234-1234-123456789abc',
name: 'Skin',
account_type: 'yggdrasil',
skin_site_user: 'owner',
}
const calls: string[] = []
let failSave = false
const frame = {
postMessage(data: { type: string; requestId: string }) {
if (data.type === 'starlight-pack-token-request')
receiveSkinSiteMessage(
{
origin: SKIN_SITE_ORIGIN,
source: frame,
data: {
type: 'starlight-pack-token-result',
requestId: data.requestId,
token: 'fixture.jwt',
},
} as unknown as MessageEvent,
frame,
)
},
} as unknown as Window
Object.defineProperty(globalThis, 'window', {
configurable: true,
value: {
__TAURI_INTERNALS__: {
async invoke(command: string, args: Record<string, unknown>) {
calls.push(command)
if (command.endsWith('get_instance_player')) return player
if (command.endsWith('login_skin_site_player')) {
assert.equal(args.playerId, player.id)
assert.equal(args.userId, 'owner')
assert.equal(args.token, 'fixture.jwt')
} else if (command.endsWith('set_instance_player') && failSave)
throw new Error('Save failed')
},
},
},
})
let prompts = 0
const unregister = registerInstancePlayerPicker(async (_id, locked) => {
prompts++
assert.equal(locked, player)
return player
})
const changes: string[] = []
const stop = onInstancePlayerChanged((id) => changes.push(id))
try {
resetSkinSiteSession()
setSkinSiteFrame(frame)
receiveSkinSiteMessage(
{
origin: SKIN_SITE_ORIGIN,
source: frame,
data: {
type: 'starlight-skin-session',
status: 'signed-in',
user: { uuid: 'owner', username: 'Owner' },
},
} as unknown as MessageEvent,
frame,
)
await prepareInstancePlayer('one')
assert.equal(prompts, 0)
assert.ok(calls.includes('plugin:auth|login_skin_site_player'))
await saveInstancePlayer('one', player)
assert.deepEqual(changes, ['one'])
failSave = true
await assert.rejects(saveInstancePlayer('two', player), /Save failed/)
assert.deepEqual(changes, ['one'])
resetSkinSiteSession()
await prepareInstancePlayer('one')
assert.equal(prompts, 1)
} finally {
stop()
unregister()
resetSkinSiteSession()
setSkinSiteFrame(null)
if (previous) Object.defineProperty(globalThis, 'window', previous)
else Reflect.deleteProperty(globalThis, 'window')
if (previousNavigator) Object.defineProperty(globalThis, 'navigator', previousNavigator)
else Reflect.deleteProperty(globalThis, 'navigator')
}
})