Files
pj_admin_cloud/tests/upload-transport.test.cjs
T
dzc 1fa2f11057
build / task (16.x, npm, macOS-latest) (push) Canceled after 0s
build / task (16.x, npm, ubuntu-latest) (push) Canceled after 0s
build / task (16.x, npm, windows-latest) (push) Canceled after 0s
build / task (16.x, pnpm, macOS-latest) (push) Canceled after 0s
build / task (16.x, pnpm, ubuntu-latest) (push) Canceled after 0s
build / task (16.x, pnpm, windows-latest) (push) Canceled after 0s
build / task (16.x, yarn, macOS-latest) (push) Canceled after 0s
build / task (16.x, yarn, ubuntu-latest) (push) Canceled after 0s
build / task (16.x, yarn, windows-latest) (push) Canceled after 0s
build / task (18.x, npm, macOS-latest) (push) Canceled after 0s
build / task (18.x, npm, ubuntu-latest) (push) Canceled after 0s
build / task (18.x, npm, windows-latest) (push) Canceled after 0s
build / task (18.x, pnpm, macOS-latest) (push) Canceled after 0s
build / task (18.x, pnpm, ubuntu-latest) (push) Canceled after 0s
build / task (18.x, pnpm, windows-latest) (push) Canceled after 0s
build / task (18.x, yarn, macOS-latest) (push) Canceled after 0s
build / task (18.x, yarn, ubuntu-latest) (push) Canceled after 0s
build / task (18.x, yarn, windows-latest) (push) Canceled after 0s
build / task (20.x, npm, macOS-latest) (push) Canceled after 0s
build / task (20.x, npm, ubuntu-latest) (push) Canceled after 0s
build / task (20.x, npm, windows-latest) (push) Canceled after 0s
build / task (20.x, pnpm, macOS-latest) (push) Canceled after 0s
build / task (20.x, pnpm, ubuntu-latest) (push) Canceled after 0s
build / task (20.x, pnpm, windows-latest) (push) Canceled after 0s
build / task (20.x, yarn, macOS-latest) (push) Canceled after 0s
build / task (20.x, yarn, ubuntu-latest) (push) Canceled after 0s
build / task (20.x, yarn, windows-latest) (push) Canceled after 0s
feat:日志敏感信息过滤
2026-10-29 15:46:24 +08:00

88 lines
5.4 KiB
JavaScript

const { test } = require('node:test')
const assert = require('node:assert/strict')
const fs = require('node:fs')
const path = require('node:path')
const vue = require('vue')
const { parse, compileScript, compileTemplate } = require('@vue/compiler-sfc')
const { compile, root, runtime } = require('./helpers/file-access-runtime.cjs')
function setup(relative, props, request, fileAccess = {}) {
const descriptor = parse(fs.readFileSync(path.join(root, relative), 'utf8')).descriptor
assert.deepEqual(compileTemplate({ source: descriptor.template.content, filename: relative, id: 'upload-transport' }).errors, [])
const errors = [], events = [], loaded = { exports: {} }
const vueHooks = { ...vue, onBeforeUnmount() {} }
const mocks = {
vue: vueHooks,
'/@/utils/request': { default: request },
'/@/utils/storage': { Session: { get: () => 'token', getTenant: () => '42' } },
'/@/hooks/message': { useMessage: () => ({ error: value => errors.push(value) }) },
'/@/utils/other': { default: { adaptationUrl: url => url, addUnit: value => value } },
'/@/utils/file-access': fileAccess,
'/@/utils/file-access-dom': { bindFileAccessDom() {} },
'vue-i18n': { useI18n: () => ({ t: key => key }) },
'@wangeditor/editor/dist/css/style.css': {},
'@wangeditor/editor-for-vue': { Toolbar: {}, Editor: {} },
}
const globals = { ref: vue.ref, computed: vue.computed, watch: vue.watch,
getCurrentInstance: () => ({ proxy: { baseURL: '/api' } }), onMounted() {}, nextTick: vue.nextTick }
new Function('module', 'exports', 'require', ...Object.keys(globals), compile(compileScript(descriptor, { id: 'upload-transport' }).content))(
loaded, loaded.exports, name => name in mocks ? mocks[name] : require(name), ...Object.values(globals))
const state = loaded.exports.default.setup(props, { expose() {}, emit: (...args) => events.push(args) })
return { state, errors, events }
}
test('generic uploads preserve multipart fields, delegate URL adaptation to the common transport, and finish a batch after one file fails', async () => {
const requests = []
const file = new File(['%PDF-1.4\n%%EOF'], 'report.PDF', { type: 'application/pdf' })
for (const type of ['default', 'simple']) {
const { state, errors, events } = setup('src/components/Upload/index.vue', {
type, modelValue: '', fileType: ['pdf'], fileSize: 100, data: {}, dir: 'reports', uploadFileUrl: '/admin/sys-file/upload',
}, async options => { requests.push(options); return { code: 0, data: { url: '/admin/sys-file/oss/file?fileName=report.pdf' } } })
assert.equal(state.handleBeforeUpload(file), true)
assert.equal(state.handleBeforeUpload(file), true)
const result = await state.handleHttpUpload({ action: '/api/admin/sys-file/upload', filename: 'file', file,
data: { dir: 'reports', groupId: 12, type: 'pdf' } })
const request = requests.at(-1)
assert.equal(request.url, '/admin/sys-file/upload')
assert.equal(request.baseURL, undefined)
assert.equal(request.data.get('file').name, 'report.PDF')
assert.equal(request.data.get('dir'), 'reports')
assert.equal(request.data.get('groupId'), '12')
assert.equal(request.data.get('type'), 'pdf')
state.handleUploadSuccess(result, { name: file.name, raw: file, size: file.size })
assert.equal(events.length, 0)
state.handleUploadError({ msg: '不支持上传此文件类型' })
assert.deepEqual(errors, ['不支持上传此文件类型'])
assert.equal(state.number.value, 0)
assert.equal(events.find(event => event[0] === 'update:modelValue')[1], '/admin/sys-file/oss/file?fileName=report.pdf')
}
})
test('rich text images and videos use the common transport, preserve raw saved references, and propagate upload failures', async () => {
const env = runtime(), requests = [], inserted = []
const raw = '/admin/sys-file/oss/file?fileName=photo.png'
let result = { code: 0, data: { url: raw } }
let transportError
try {
const { state, events } = setup('src/components/Editor/index.vue', {
getHtml: '', placeholder: '', height: '310', width: 'auto', uploadFileUrl: '/admin/sys-file/upload',
}, async options => { requests.push(options); if (transportError) throw transportError; return result }, env.api)
for (const name of ['uploadImage', 'uploadVideo']) {
const file = new File(['test content'], name === 'uploadImage' ? 'photo.png' : 'video.mp4')
await state.state.editorConfig.MENU_CONF[name].customUpload(file, value => inserted.push(value))
assert.equal(requests.at(-1).url, '/admin/sys-file/upload')
assert.equal(requests.at(-1).method, 'post')
assert.equal(requests.at(-1).data.get('file').name, file.name)
}
state.handleChange({ getHtml: () => '<img src="' + env.api.fileUrl(raw) + '">', getText: () => '' })
const saved = events.find(event => event[0] === 'update:getHtml')[1]
assert.doesNotMatch(saved, /[?&](?:sign|appId|kid|ts)=/)
assert.match(saved, /fileName=photo\.png/)
result = { code: 1, msg: '文件内容与后缀类型不符' }
await assert.rejects(state.uploadAttr.customUpload(new File(['bad'], 'bad.png'), value => inserted.push(value)), /文件内容与后缀类型不符/)
transportError = { msg: '上传身份校验失败' }
await assert.rejects(state.uploadAttr.customUpload(new File(['bad'], 'bad.png'), value => inserted.push(value)), /上传身份校验失败/)
assert.equal(inserted.length, 2)
} finally { env.close() }
})