const assert = require('node:assert/strict') const fs = require('node:fs') const path = require('node:path') ;(async () => { const source = fs.readFileSync(path.join(__dirname, '../../ruoyi-ui/src/utils/operationAudit.js'), 'utf8') const { parseOperationAudit: parse } = await import('data:text/javascript;base64,' + Buffer.from(source).toString('base64')) const payload = { auditVersion: 1, action: '修改', target: { id: 18, name: '测试用户' }, state: 'changed', changes: [ { label: '账户余额', before: '100', after: '200' }, { label: '账户积分', before: '50', after: '80' } ], truncated: false } const result = parse(JSON.stringify(payload)) assert.equal(result.changes.length, 2) assert.equal(result.changes[0].before, '100') assert.match(result.target, /18/) for (const state of ['failed', 'unavailable', 'unchanged']) { const p = parse(JSON.stringify({ ...payload, state })) assert.equal(p.changes.length, 0) assert.ok(p.notice) } assert.match(parse(JSON.stringify({ ...payload, truncated: true })).notice, /上限/) assert.equal(parse('点击【修改】|余额\t100\t200').changes.length, 1) assert.equal(parse('点击【修改】').changes.length, 0) assert.equal(parse('{"password":"secret"}').action, '历史记录') assert.equal(parse('{malformed').action, '历史记录') const dangerous = '汉字|\t\n;→' assert.equal(parse(JSON.stringify({ ...payload, changes: [{ label: '昵称', before: '', after: dangerous }] })).changes[0].after, dangerous) const vue = fs.readFileSync(path.join(__dirname, '../../ruoyi-ui/src/views/monitor/operlog/index.vue'), 'utf8') assert.ok(!vue.includes('v-html')) const compiler = require('../../ruoyi-ui/node_modules/vue-template-compiler') const template = compiler.parseComponent(vue).template.content assert.deepEqual(compiler.compile(template).errors, []) console.log('operation-audit parser and Vue template PASSED') })().catch(e => { console.error(e); process.exit(1) })