| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- import assert from 'node:assert/strict'
- import { readFileSync } from 'node:fs'
- import test from 'node:test'
- import { parse } from '@vue/compiler-sfc'
- import { computed, ref } from 'vue'
- import ts from 'typescript'
- function component(path: string) {
- return parse(readFileSync(new URL(`../src/views/m/${path}.vue`, import.meta.url), 'utf8'))
- .descriptor
- }
- function evaluate(path: string, name: string, bindings: Record<string, any>) {
- const ast = ts.createSourceFile(
- 'page.ts',
- component(path).scriptSetup!.content,
- ts.ScriptTarget.Latest,
- true
- )
- const statement = ast.statements.find((node) =>
- ts.isVariableStatement(node)
- ? node.declarationList.declarations.some((d) => d.name.getText(ast) === name)
- : ts.isFunctionDeclaration(node) && node.name?.text === name
- )!
- assert.ok(statement)
- return new Function(
- ...Object.keys(bindings),
- ts.transpile(statement.getText(ast)) + `; return ${name}`
- )(...Object.values(bindings))
- }
- test('main record list/detail templates have no delete buttons or delete event bindings', () => {
- for (const path of [
- 'crm/customer/index',
- 'crm/customer/detail',
- 'crm/product/index',
- 'crm/product/detail',
- 'crm/quote/MpQuoteList',
- 'crm/quote/detail',
- 'crm/quote/index',
- 'crm/quote/approval',
- 'crm/contract/MpContractList',
- 'crm/contract/detail',
- 'crm/contract/index',
- 'crm/contract/approval',
- 'pl/plan/index',
- 'pl/plan/detail',
- 'pl/plan-cert/index',
- 'pl/plan-cert/PlanCard',
- 'pl/plan-cert/detail',
- 'pl/plan-cert/CertDetail'
- ]) {
- const template = component(path).template!.content
- assert.doesNotMatch(template, /删除|@click="(?:onDelete|deleteCard|remove)\b/, path)
- }
- })
- test('quote and contract management/approval actions never offer main record deletion across statuses', () => {
- for (const domain of ['quote', 'contract']) {
- for (const approve of [false, true]) {
- for (const status of [
- 'draft',
- 'submitted',
- 'approving',
- 'accepted',
- 'rejected',
- 'approved',
- 'executing',
- 'completed',
- 'invalid'
- ]) {
- const actions = evaluate(`crm/${domain}/detail`, 'fabActions', {
- computed,
- quote: ref({ status }),
- contract: ref({ status }),
- props: { embedded: false },
- isApproveEntry: ref(approve),
- pendingApproval: ref({ id: 'approval' }),
- canApproveNow: ref(true),
- canInvalid: ref(true),
- canDelete: ref(true),
- CREATOR_DELETE_TIP: '',
- isQuoteEditableStatus: () => true,
- isContractEditableStatus: () => true
- }).value
- assert.ok(actions.length > 0)
- assert.ok(
- actions.every((action: any) => action.key !== 'delete' && action.label !== '删除')
- )
- const cardActions = evaluate(
- `crm/${domain}/Mp${domain === 'quote' ? 'Quote' : 'Contract'}List`,
- 'cardActions',
- {
- props: { mode: approve ? 'approve' : 'manage' },
- view: ref('submitted')
- }
- )({ status, canApprove: true })
- assert.ok(
- cardActions.every((action: any) => action.key !== 'delete' && action.label !== '删除')
- )
- }
- }
- }
- })
|