mirror of
https://github.com/insistence/RuoYi-Vue3-FastAPI.git
synced 2026-10-14 21:07:36 +00:00
* feat: 支持 v2 插件、原生扩展与签名发布 * fix: 修复测试 * feat: 增强宿主 SDK、运行观测与制品维护能力 * feat: 增强文件传输、配置观测与本地开发能力 * feat: 支持 SSE 实时事件流并完善开发脚手架 * feat: 完善长连接鉴权复核与关闭回收 * feat: 增强生命周期与任务关闭可靠性 * feat: 收紧健康检查契约并补齐前端与真实网络验收 * feat: 增加SDK溯源与离线更新工具并验证跨版本兼容 * feat: 增加持久化业务示例与受控 Python 交付 * feat: 增加统一运行诊断与多worker状态观测 * feat: 增加固定目标发布等待与自动验收 * fix: 修复多环境插件部署前缀与代理配置不一致 * fix: 修复测试
71 lines
2.1 KiB
JavaScript
71 lines
2.1 KiB
JavaScript
import assert from 'node:assert/strict'
|
|
import { readFileSync } from 'node:fs'
|
|
import { effectScope, nextTick, reactive, ref, watch } from 'vue'
|
|
import { compileScript, parse } from '@vue/compiler-sfc'
|
|
|
|
// 使用 Vue 调度器执行组件的真实会话监听逻辑。
|
|
// 仅查询参数变化导致 router.meta 重建时,不应重新打开已有页面。
|
|
const source = readFileSync(
|
|
new URL('../../src/components/PluginFrame/index.vue', import.meta.url),
|
|
'utf8'
|
|
)
|
|
const { descriptor } = parse(source)
|
|
const compiled = compileScript(descriptor, { id: 'plugin-frame-watch-test' })
|
|
const sessionWatch = compiled.scriptSetupAst.find(
|
|
(statement) =>
|
|
statement.type === 'ExpressionStatement' &&
|
|
statement.expression.type === 'CallExpression' &&
|
|
statement.expression.callee.name === 'watch'
|
|
).expression
|
|
const installWatcher = new Function(
|
|
'watch',
|
|
'route',
|
|
'userStore',
|
|
'cleanup',
|
|
'error',
|
|
'active',
|
|
'openPlugin',
|
|
`return ${descriptor.scriptSetup.content.slice(sessionWatch.start, sessionWatch.end)}`
|
|
)
|
|
const route = reactive({ meta: { pluginId: 'demo' }, query: { pluginRoute: '/' } })
|
|
const userStore = reactive({ token: 'host-session' })
|
|
const error = ref('')
|
|
const cleanupCalls = []
|
|
let reopened = 0
|
|
const scope = effectScope()
|
|
scope.run(() =>
|
|
installWatcher(
|
|
watch,
|
|
route,
|
|
userStore,
|
|
(logout) => cleanupCalls.push(logout),
|
|
error,
|
|
true,
|
|
() => {
|
|
reopened += 1
|
|
}
|
|
)
|
|
)
|
|
|
|
route.meta = { pluginId: 'demo' }
|
|
route.query = { pluginRoute: '/details' }
|
|
await nextTick()
|
|
assert.equal(
|
|
reopened,
|
|
0,
|
|
'same plugin + same token must preserve the frame across query navigation'
|
|
)
|
|
assert.deepEqual(cleanupCalls, [])
|
|
|
|
route.meta = { pluginId: 'another_demo' }
|
|
await nextTick()
|
|
assert.equal(reopened, 1, 'switching plugin must open a new session')
|
|
userStore.token = 'new-host-session'
|
|
await nextTick()
|
|
assert.equal(reopened, 2, 'a changed host login must not reuse the previous plugin session')
|
|
userStore.token = ''
|
|
await nextTick()
|
|
assert.deepEqual(cleanupCalls, [true], 'logout must destroy the bridge and notify the frame')
|
|
assert.match(error.value, /登录状态已失效/)
|
|
scope.stop()
|