fix: 完善整合包同步与启动器交互
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
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
This commit is contained in:
1 parent
bd09fed0ed
commit
51fb0c30f7
45 files changed
+1804
-219
No files matched your search
@@ -0,0 +1,164 @@
|
||||
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')
|
||||
}
|
||||
})
|
||||
Reference in new issue
Block a user