| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- import assert from 'node:assert/strict'
- import test from 'node:test'
- import { readFile } from 'node:fs/promises'
- import ts from 'typescript'
- const root = new URL('../../', import.meta.url)
- const read = (path) => readFile(new URL(path, root), 'utf8')
- test('危化品证上传位于运输管理并复用现有 WebView 壳', async () => {
- const source = await read('miniprogram/config/workbench-menus.js')
- const { WORKBENCH_MODULES } = await import(`data:text/javascript,${encodeURIComponent(source)}`)
- const transport = WORKBENCH_MODULES.find((m) => m.key === 'pl')
- const entry = transport.menus.find((m) => m.code === 'pl-plan-cert-webview')
- assert.ok(entry, '运输管理缺少危化品证上传入口')
- assert.equal(entry.name, '危化品证上传')
- assert.equal(entry.perms, 'mini:pl:plan-cert:list')
- assert.equal(entry.enabled, true)
- const api = await read('miniprogram/config/api.js')
- const ast = ts.createSourceFile('api.js', api, ts.ScriptTarget.Latest, true)
- let expression
- function visit(node) {
- if (ts.isPropertyAssignment(node) && node.name.getText(ast) === "'pl-plan-cert-webview'")
- expression = node.initializer.getText(ast)
- ts.forEachChild(node, visit)
- }
- visit(ast)
- assert.ok(expression, '缺少工作台路由映射')
- const path = new Function('PAGE_PATHS', `return ${expression}`)({
- mpWebview: '/pages/common/mp-webview'
- })
- assert.equal(path, '/pages/common/mp-webview?path=%2Fm%2Fpl%2Fplan-cert')
- })
- test('H5 列表与详情均使用独立移动路由并隐藏桌面工作标签', async () => {
- const source = await read('web-admin/src/router/routes/staticRoutes.ts')
- const ast = ts.createSourceFile('routes.ts', source, ts.ScriptTarget.Latest, true)
- const routes = new Map()
- function visit(node) {
- if (ts.isObjectLiteralExpression(node)) {
- const pathProp = node.properties.find(
- (prop) => ts.isPropertyAssignment(prop) && prop.name.getText(ast) === 'path'
- )
- if (pathProp && ts.isPropertyAssignment(pathProp) && ts.isStringLiteral(pathProp.initializer))
- routes.set(pathProp.initializer.text, node)
- }
- ts.forEachChild(node, visit)
- }
- visit(ast)
- const listRoute = routes.get('/m/pl/plan-cert')
- const detailRoute = routes.get('/m/pl/plan-cert/:id')
- assert.ok(listRoute, '缺少 /m/pl/plan-cert 路由')
- assert.match(listRoute.getText(ast), /views\/m\/pl\/plan-cert\/index\.vue/)
- assert.ok(detailRoute, '缺少 /m/pl/plan-cert/:id 独立详情路由')
- assert.match(detailRoute.getText(ast), /views\/m\/pl\/plan-cert\/detail\.vue/)
- for (const route of [listRoute, detailRoute]) {
- assert.match(route.getText(ast), /isMpWebview:\s*true/)
- assert.match(route.getText(ast), /isHideTab:\s*true/)
- }
- })
- test('菜单 SQL 仅补移动入口与已有授权角色的完整祖先链', async () => {
- const sql = await read('docs/sql/migrations/2026-10-17-mini-pl-plan-cert-webview-menus.sql')
- assert.match(sql, /START TRANSACTION/i)
- assert.match(sql, /COMMIT/i)
- assert.match(sql, /mini:pl:plan-cert:list/)
- assert.match(sql, /MINI_PL_ROOT/)
- assert.match(sql, /parent_id\s*=\s*'1'/)
- assert.match(sql, /EXISTS\s*\([\s\S]*m\.perms\s*=\s*'pl:plan-cert:list'[\s\S]*\)/)
- assert.match(sql, /r\.tenant_no\s*=\s*'shanxia2.0'/)
- assert.match(sql, /ON DUPLICATE KEY UPDATE/i)
- assert.doesNotMatch(sql, /\b(?:DELETE|DROP|ALTER|TRUNCATE)\s/i)
- assert.doesNotMatch(sql, /pl:plan-cert:(?:upload|ready)/)
- })
|