107 lines
4.7 KiB
JavaScript
107 lines
4.7 KiB
JavaScript
import assert from 'node:assert/strict'
|
|
import test from 'node:test'
|
|
import { readFileSync } from 'node:fs'
|
|
import { compileFunction } from 'node:vm'
|
|
import { reactive, ref, watch } from './vue.mjs'
|
|
|
|
const source = readFileSync(new URL('../../frontend/src/views/EmailDetail/EmailDetail.js', import.meta.url), 'utf8')
|
|
const createPage = compileFunction(
|
|
source.replace(/^import .*$/gm, '').replace('export function usePage', 'function usePage').replace(/export \{[^}]+\}/g, '') + '\nreturn usePage()',
|
|
['ref', 'watch', 'onBeforeUnmount', 'useRoute', 'useRouter', 'useGroupStore', 'http', 'ElMessage', 'ElMessageBox', 'lang', 'Document', 'Back', 'Delete', 'Download']
|
|
)
|
|
const settle = () => new Promise(resolve => setImmediate(resolve))
|
|
const email = id => ({errorNo: 0, data: {id, subject: `mail-${id}`, to: '[{"EmailAddress":"test@example.com"}]', cc: '[]', attachments: []}})
|
|
|
|
function fixture(post, id = '15') {
|
|
const route = reactive({params: {id}})
|
|
const requests = []
|
|
const navigations = []
|
|
let unmount
|
|
const page = createPage(ref, watch, callback => { unmount = callback }, () => route,
|
|
() => ({push: target => navigations.push(target)}), () => ({tag: ''}),
|
|
{post: async (...args) => { requests.push(args); return post(...args) }}, {}, {}, {}, {}, {}, {}, {})
|
|
return {page, route, requests, navigations, unmount: () => unmount()}
|
|
}
|
|
|
|
test('邮件业务错误不渲染空数据,允许重试后读取正文与附件', async () => {
|
|
let response = {errorNo: 500, errorMsg: '读取邮件失败', data: ''}
|
|
const {page, requests} = fixture(async () => response)
|
|
assert.equal(page.loading.value, true)
|
|
await settle()
|
|
assert.equal(page.loading.value, false)
|
|
assert.equal(page.loadError.value, '读取邮件失败')
|
|
assert.equal(page.detailData.value.id, undefined)
|
|
page.handleDelete()
|
|
assert.equal(requests.length, 1)
|
|
response = email(15)
|
|
response.data.attachments = [{Index: 0, Filename: '中文附件.txt'}]
|
|
await page.loadDetail()
|
|
assert.equal(page.loadError.value, '')
|
|
assert.equal(page.detailData.value.subject, 'mail-15')
|
|
assert.equal(page.detailData.value.attachments[0].Filename, '中文附件.txt')
|
|
assert.equal(page.tos.value[0].EmailAddress, 'test@example.com')
|
|
})
|
|
|
|
test('网络失败提供中文错误,返回操作明确进入邮件列表', async () => {
|
|
const {page, navigations} = fixture(async () => { throw new Error('Network Error') })
|
|
await settle()
|
|
assert.equal(page.loading.value, false)
|
|
assert.equal(page.loadError.value, '网络连接失败,请稍后重试')
|
|
page.backToList()
|
|
assert.equal(navigations[0].name, 'list')
|
|
})
|
|
|
|
test('无效编号不发请求,空响应或编号不匹配不当作成功', async () => {
|
|
for (const id of ['abc', '15abc', '-1', '0', '9007199254740992']) {
|
|
const {page, requests} = fixture(async () => email(15), id)
|
|
await settle()
|
|
assert.equal(requests.length, 0)
|
|
assert.equal(page.loadError.value, '邮件地址无效,请返回邮件列表')
|
|
}
|
|
for (const data of [null, '', [], {}, {id: 14}]) {
|
|
const {page} = fixture(async () => ({errorNo: 0, data}))
|
|
await settle()
|
|
assert.equal(page.loadError.value, '邮件不可用,请返回邮件列表')
|
|
assert.equal(page.detailData.value.id, undefined)
|
|
}
|
|
})
|
|
|
|
test('异常地址和附件字段不导致页面异常,切换邮件清除旧收件人', async () => {
|
|
const {page, route} = fixture(async (_, {id}) => ({errorNo: 0, data: {id, to: id === 15 ? '[{"EmailAddress":"old@example.com"}]' : 'null', cc: id === 15 ? '[{"EmailAddress":"copy@example.com"}]' : '{', attachments: 'bad'}}))
|
|
await settle()
|
|
assert.equal(page.showCC.value, true)
|
|
assert.equal(page.detailData.value.attachments.length, 0)
|
|
route.params.id = '16'
|
|
await settle()
|
|
assert.equal(page.detailData.value.id, 16)
|
|
assert.equal(page.tos.value.length, 0)
|
|
assert.equal(page.ccs.value.length, 0)
|
|
assert.equal(page.showCC.value, false)
|
|
})
|
|
|
|
test('切换邮件后旧请求成功或失败均不能覆盖新邮件', async () => {
|
|
for (const staleFailure of [false, true]) {
|
|
let finish
|
|
let fail
|
|
const {page, route} = fixture((_, {id}) => id === 15 ? new Promise((resolve, reject) => { finish = resolve; fail = reject }) : Promise.resolve(email(id)))
|
|
route.params.id = '16'
|
|
await settle()
|
|
assert.equal(page.detailData.value.id, 16)
|
|
if (staleFailure) fail(new Error('Network Error'))
|
|
else finish(email(15))
|
|
await settle()
|
|
assert.equal(page.detailData.value.id, 16)
|
|
assert.equal(page.loadError.value, '')
|
|
assert.equal(page.loading.value, false)
|
|
}
|
|
})
|
|
|
|
test('离开详情后未完成请求不再写入状态', async () => {
|
|
let finish
|
|
const {page, unmount} = fixture(() => new Promise(resolve => { finish = resolve }))
|
|
unmount()
|
|
finish(email(15))
|
|
await settle()
|
|
assert.equal(page.detailData.value.id, undefined)
|
|
})
|