Smail/test/frontend/telegram-settings.test.mjs
smail 6f79441585 修复审查发现的认证配置邮件协议及前端问题
补齐安全运行时清理、配置候选恢复、泛域名证书事务提交、邮件副本与协议边界、插件隐私和安装回滚回归,并更新修复状态及待验收清单。
2026-09-06 13:02:02 +08:00

78 lines
3.9 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, reactive, ref } from './vue.mjs'
const root = new URL('../../frontend/src/views/components/PluginSettings/', import.meta.url)
const source = readFileSync(new URL('TelegramSettings/TelegramSettings.js', root), 'utf8')
const create = compileFunction(source.replace(/^import .*$/gm, '').replace('export function ', 'function ') + '\nreturn useTelegramSettings()',
['computed', 'onMounted', 'onBeforeUnmount', 'reactive', 'ref', 'ElMessage', 'http'])
test('Telegram 原生设置保留版本、限制用户字段,不依赖插件 iframe', async () => {
const requests = []
let conflict = false
const page = create(computed, () => {}, () => {}, reactive, ref, { success() {} }, {
get: async url => ({ errorNo: 0, data: url.endsWith('/bot') ? { username: 'smail_test_bot', botLink: 'javascript:alert(1)' }
: { version: 7, settings: { chatId: '123', sendAttachments: false, secret: '不得传回' } } }),
put: async (url, body) => {
requests.push({ url, body })
return conflict ? { errorNo: 400, errorMsg: '配置已被其他操作更新,请刷新后重试' }
: { errorNo: 0, data: { version: 8, settings: body.settings } }
},
post: async (url, body) => { requests.push({ url, body }); return { errorNo: 0 } }
})
await page.load()
assert.equal(page.ready.value, true)
assert.equal(page.botLink.value, 'https://t.me/smail_test_bot')
page.settings.sendAttachments = true
await page.submit('save')
assert.equal(requests[0].body.version, 7)
assert.deepEqual(Object.keys(requests[0].body.settings).sort(), ['chatId', 'disableLinkPreview', 'sendAttachments', 'showContent', 'spoilerContent'])
assert.equal(page.version.value, 8)
await page.submit('test')
assert.equal(requests[1].url, '/api/v1/plugin/settings/telegram_push/test')
assert.equal(page.version.value, 8)
conflict = true
await page.submit('save')
assert.match(page.errorMessage.value, /刷新/)
assert.equal(page.version.value, 8)
const count = requests.length
page.settings.chatId = 'invalid'
await page.submit('test')
assert.equal(requests.length, count)
})
test('Telegram 首次读取失败禁止覆盖存量设置,机器人故障不影响停用', async () => {
let fail = true
const page = create(computed, () => {}, () => {}, reactive, ref, { success() {} }, {
get: async url => {
if (fail || url.endsWith('/bot')) throw new Error('模拟离线')
return { errorNo: 0, data: { version: 0, settings: {} } }
},
put: async () => assert.fail('读取失败后不能保存')
})
await page.load()
await page.submit('save')
assert.equal(page.ready.value, false)
fail = false
await page.load()
assert.equal(page.ready.value, true)
assert.equal(page.botLink.value, '')
})
test('Telegram 模板独立编译,其他插件继续保持 sandbox 隔离', () => {
const require = createRequire(new URL('../../frontend/package.json', import.meta.url))
const { parse, compileScript, compileStyle } = require('@vue/compiler-sfc')
const parent = readFileSync(new URL('PluginSettings.vue', root), 'utf8')
assert.match(parent, /TelegramSettings v-else-if="entry.logicalID === 'telegram_push'"/)
assert.match(parent, /sandbox="allow-scripts"/)
assert.doesNotMatch(parent, /allow-same-origin/)
const { descriptor, errors } = parse(readFileSync(new URL('TelegramSettings/TelegramSettings.vue', root), 'utf8'))
assert.deepEqual(errors, [])
assert.doesNotThrow(() => compileScript(descriptor, { id: 'telegram-settings', inlineTemplate: true }))
assert.deepEqual(compileStyle({ source: readFileSync(new URL('TelegramSettings/TelegramSettings.css', root), 'utf8'), id: 'telegram-settings', scoped: true }).errors, [])
assert.doesNotMatch(source, /window\.parent|parent\.document|postMessage|localStorage/)
})