Files
RuoYi-Vue3-FastAPI/ruoyi-fastapi-frontend/tests/plugins/pluginFrame.test.js
T
insistence 4bd83bc7cd feat: 支持 v2 插件、独立前端和签名制品发布 (#130)
* feat: 支持 v2 插件、原生扩展与签名发布

* fix: 修复测试

* feat: 增强宿主 SDK、运行观测与制品维护能力

* feat: 增强文件传输、配置观测与本地开发能力

* feat: 支持 SSE 实时事件流并完善开发脚手架

* feat: 完善长连接鉴权复核与关闭回收

* feat: 增强生命周期与任务关闭可靠性

* feat: 收紧健康检查契约并补齐前端与真实网络验收

* feat: 增加SDK溯源与离线更新工具并验证跨版本兼容

* feat: 增加持久化业务示例与受控 Python 交付

* feat: 增加统一运行诊断与多worker状态观测

* feat: 增加固定目标发布等待与自动验收

* fix: 修复多环境插件部署前缀与代理配置不一致

* fix: 修复测试
2026-10-09 23:49:45 +08:00

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()