88 lines
3.5 KiB
JavaScript
88 lines
3.5 KiB
JavaScript
import assert from 'node:assert/strict'
|
|
import test from 'node:test'
|
|
import { readFileSync } from 'node:fs'
|
|
import { compileFunction } from 'node:vm'
|
|
import { createRequire } from 'node:module'
|
|
import { computed, ref } from './vue.mjs'
|
|
|
|
const root = new URL('../../frontend/src/views/components/LogSettings/', import.meta.url)
|
|
const read = name => readFileSync(new URL(name, root), 'utf8')
|
|
const create = compileFunction(
|
|
read('LogSettings.js').replace(/^import .*$/gm, '').replace('export function', 'function') + '\nreturn useLogs()',
|
|
['computed', 'onBeforeUnmount', 'onMounted', 'ref', 'watch', 'http']
|
|
)
|
|
|
|
function fixture(get) {
|
|
let dispose
|
|
const page = create(computed, callback => { dispose = callback }, () => {}, ref, () => {}, { get })
|
|
return { page, dispose: () => dispose() }
|
|
}
|
|
|
|
test('日志页面模板和样式能编译,详情不使用原始 HTML 渲染', () => {
|
|
const require = createRequire(new URL('../../frontend/package.json', import.meta.url))
|
|
const { parse, compileScript, compileStyle } = require('@vue/compiler-sfc')
|
|
const { descriptor, errors } = parse(read('LogSettings.vue'))
|
|
assert.deepEqual(errors, [])
|
|
assert.doesNotThrow(() => compileScript(descriptor, { id: 'logs', inlineTemplate: true }))
|
|
assert.deepEqual(compileStyle({ source: read('LogSettings.css'), id: 'logs', scoped: true }).errors, [])
|
|
assert.doesNotMatch(read('LogSettings.vue'), /v-html/)
|
|
})
|
|
|
|
test('日志查询传递时间与操作者筛选,并将业务失败显示为错误', async () => {
|
|
const requests = []
|
|
const { page } = fixture(async (_, options) => {
|
|
requests.push(options.params)
|
|
return requests.length === 1
|
|
? { errorNo: 0, data: { items: [{ id: 'safe' }], hasMore: false } }
|
|
: { errorNo: 500, errorMsg: '日志暂不可用' }
|
|
})
|
|
page.actorId.value = ' 42 '
|
|
page.dateRange.value = ['2026-09-01T00:00:00Z', '2026-09-08T00:00:00Z']
|
|
await page.search()
|
|
assert.equal(requests[0].actorId, '42')
|
|
assert.equal(requests[0].from, '2026-09-01T00:00:00.000Z')
|
|
assert.equal(page.items.value.length, 1)
|
|
await page.search()
|
|
assert.equal(page.error.value, '日志暂不可用')
|
|
assert.equal(page.items.value.length, 0)
|
|
assert.equal(page.displayActor({ actorId: '0' }), '系统')
|
|
})
|
|
|
|
test('压缩日志短页正确返回上一页,文件过期后重置偏移', async () => {
|
|
let filename = 'runtime-2026-08-15.log.gz'
|
|
const offsets = []
|
|
const { page } = fixture(async (_, { params }) => {
|
|
if (!params.file) return { errorNo: 0, data: { files: [{ name: filename, compressed: true }] } }
|
|
offsets.push(params.offset)
|
|
return { errorNo: 0, data: { lines: Array(params.offset === 0 ? 8 : 12).fill('日志'), hasMore: true } }
|
|
})
|
|
page.category.value = 'runtime'
|
|
await page.search()
|
|
await page.next()
|
|
await page.next()
|
|
await page.previous()
|
|
assert.deepEqual(offsets, [0, 8, 20, 8])
|
|
filename = 'runtime-2026-08-16.log.gz'
|
|
await page.next()
|
|
assert.equal(page.offset.value, 0)
|
|
assert.equal(offsets.at(-1), 0)
|
|
})
|
|
|
|
test('慢响应及卸载后的响应不得覆盖最新日志', async () => {
|
|
let complete
|
|
let count = 0
|
|
const { page, dispose } = fixture(async () => {
|
|
if (++count === 1) return new Promise(resolve => { complete = resolve })
|
|
return { errorNo: 0, data: { items: [{ id: 'new' }] } }
|
|
})
|
|
const first = page.search()
|
|
await page.search()
|
|
complete({ errorNo: 0, data: { items: [{ id: 'old' }] } })
|
|
await first
|
|
assert.equal(page.items.value[0].id, 'new')
|
|
const last = page.search()
|
|
dispose()
|
|
await last
|
|
assert.equal(page.items.value[0].id, 'new')
|
|
})
|