后端迁移测试文件
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
import test from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
|
||||
import {
|
||||
formatLogEntry,
|
||||
formatLogTimestamp,
|
||||
normalizeLogLevel,
|
||||
resolveExpiredLogFilenames,
|
||||
resolveLogFilePath,
|
||||
shouldWriteLog,
|
||||
} from './logger.js'
|
||||
|
||||
test('normalizeLogLevel falls back to info for unsupported values', () => {
|
||||
assert.equal(normalizeLogLevel('debug'), 'debug')
|
||||
assert.equal(normalizeLogLevel('WARN'), 'warn')
|
||||
assert.equal(normalizeLogLevel('verbose'), 'info')
|
||||
assert.equal(normalizeLogLevel(''), 'info')
|
||||
})
|
||||
|
||||
test('shouldWriteLog respects configured minimum log level', () => {
|
||||
assert.equal(shouldWriteLog('debug', 'debug'), true)
|
||||
assert.equal(shouldWriteLog('info', 'debug'), true)
|
||||
assert.equal(shouldWriteLog('debug', 'info'), false)
|
||||
assert.equal(shouldWriteLog('info', 'warn'), false)
|
||||
assert.equal(shouldWriteLog('warn', 'warn'), true)
|
||||
assert.equal(shouldWriteLog('error', 'warn'), true)
|
||||
})
|
||||
|
||||
test('resolveLogFilePath uses daily log file names by channel', () => {
|
||||
assert.match(resolveLogFilePath('app', '2026-04-14T10:00:00.000Z'), /app-2026-04-14\.log$/)
|
||||
assert.match(resolveLogFilePath('webhook', '2026-04-14T10:00:00.000Z'), /webhook-2026-04-14\.log$/)
|
||||
})
|
||||
|
||||
test('resolveExpiredLogFilenames keeps latest seven days and ignores unknown files', () => {
|
||||
const expired = resolveExpiredLogFilenames([
|
||||
'app-2026-04-14.log',
|
||||
'app-2026-04-13.log',
|
||||
'app-2026-04-08.log',
|
||||
'app-2026-04-07.log',
|
||||
'webhook-2026-04-06.log',
|
||||
'app.log',
|
||||
'webhook.log',
|
||||
'random.txt',
|
||||
], '2026-04-14T12:00:00.000Z', 7)
|
||||
|
||||
assert.deepEqual(expired, [
|
||||
'app-2026-04-07.log',
|
||||
'webhook-2026-04-06.log',
|
||||
'app.log',
|
||||
'webhook.log',
|
||||
])
|
||||
})
|
||||
|
||||
test('formatLogTimestamp renders readable local timestamp with timezone offset', () => {
|
||||
const rendered = formatLogTimestamp('2026-04-14T10:36:24.974Z')
|
||||
assert.match(rendered, /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3} [+-]\d{2}:\d{2}$/)
|
||||
})
|
||||
|
||||
test('formatLogEntry prints readable one-line output for flat details', () => {
|
||||
const text = formatLogEntry({
|
||||
time: '2026-04-14T10:36:24.974Z',
|
||||
level: 'info',
|
||||
scope: '[http/access]',
|
||||
message: 'request completed',
|
||||
pid: 4671,
|
||||
detail: {
|
||||
requestId: 'req-123',
|
||||
method: 'GET',
|
||||
statusCode: 401,
|
||||
},
|
||||
}, { color: false })
|
||||
|
||||
assert.match(text, /INFO\s+\[http\/access\] request completed/)
|
||||
assert.match(text, /pid=4671/)
|
||||
assert.match(text, /requestId=req-123/)
|
||||
assert.match(text, /method=GET/)
|
||||
assert.match(text, /statusCode=401/)
|
||||
assert.doesNotMatch(text, /^\{/)
|
||||
})
|
||||
|
||||
test('formatLogEntry prints nested detail blocks without ansi colors in file mode', () => {
|
||||
const text = formatLogEntry({
|
||||
time: '2026-04-14T10:36:24.974Z',
|
||||
level: 'warn',
|
||||
scope: '[admin/auth]',
|
||||
message: '后台鉴权失败',
|
||||
pid: 4671,
|
||||
detail: {
|
||||
statusCode: 401,
|
||||
errorCode: 'admin_auth_required',
|
||||
error: {
|
||||
message: '未登录或登录已失效',
|
||||
stack: 'Error: test',
|
||||
},
|
||||
},
|
||||
}, { color: false })
|
||||
|
||||
assert.match(text, /WARN\s+\[admin\/auth\] 后台鉴权失败/)
|
||||
assert.match(text, /statusCode=401/)
|
||||
assert.match(text, /errorCode=admin_auth_required/)
|
||||
assert.match(text, /\n \{/)
|
||||
assert.match(text, /未登录或登录已失效/)
|
||||
assert.doesNotMatch(text, /\u001B\[/)
|
||||
})
|
||||
Reference in New Issue
Block a user