Files
RuoYi-Vue3-FastAPI/ruoyi-fastapi-frontend/tests/plugins/pluginConfigStatus.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

78 lines
2.5 KiB
JavaScript

import assert from 'node:assert/strict'
import { readFileSync } from 'node:fs'
import { compileScript, parse } from '@vue/compiler-sfc'
import { computed, effectScope, nextTick, reactive, ref, watch } from 'vue'
const source = readFileSync(
new URL('../../src/views/system/plugin/components/PluginConfigStatus.vue', import.meta.url),
'utf8'
)
const { descriptor } = parse(source)
const compiled = compileScript(descriptor, { id: 'config-status-test' })
const script = compiled.scriptSetupAst
.filter((statement) => statement.type !== 'ImportDeclaration')
.map((statement) => descriptor.scriptSetup.content.slice(statement.start, statement.end))
.join('\n')
const setup = new Function(
'computed',
'ref',
'watch',
'onBeforeUnmount',
'defineProps',
'getPluginConfigStatus',
`${script}\nreturn { data, loading, error, refresh, statusText }`
)
const props = reactive({ pluginId: 'first_plugin', refreshKey: 0 })
const calls = []
let unmount
const scope = effectScope()
const state = scope.run(() =>
setup(
computed,
ref,
watch,
(callback) => {
unmount = callback
},
() => props,
(pluginId, signal) =>
new Promise((resolve, reject) => {
calls.push({ pluginId, signal, resolve, reject })
})
)
)
assert.equal(calls[0].pluginId, 'first_plugin')
props.pluginId = 'second_plugin'
await nextTick()
assert.equal(calls[0].signal.aborted, true)
calls[1].resolve({ data: { state: 'restart_required', pendingWorkers: 2 } })
await nextTick()
calls[0].resolve({ data: { state: 'observed_match', matchedWorkers: 1 } })
await nextTick()
assert.match(state.statusText.value, /2 个已观测进程.*待重启/)
// 保存成功后主动重查,不用旧状态冒充最新保存版本。
props.refreshKey++
await nextTick()
assert.equal(state.data.value, null)
calls[2].resolve({ data: { state: 'observed_match', matchedWorkers: 2 } })
await nextTick()
assert.match(state.statusText.value, /已观测进程.*匹配/)
assert.equal(state.loading.value, false)
const failed = state.refresh()
calls[3].reject(new Error('unavailable'))
await failed
assert.equal(state.data.value, null)
assert.match(state.error.value, /查询失败/)
const retry = state.refresh()
calls[4].resolve({ data: { state: 'unobserved' } })
await retry
assert.match(state.statusText.value, /尚不能确认|尚未观测/)
const closing = state.refresh()
unmount()
scope.stop()
assert.equal(calls[5].signal.aborted, true)
calls[5].reject(new Error('cancelled'))
await closing
assert.equal(state.error.value, '')