157 lines
5.6 KiB
JavaScript
157 lines
5.6 KiB
JavaScript
/**
|
||
* 删除规则配置工具(module-management/ruleUtils):
|
||
* 关系业务键拼串/还原、predicate 三态推断、识别文案、新增行构造、条件面板 items 构造。
|
||
*/
|
||
import { describe, expect, it } from 'vitest'
|
||
import {
|
||
REF_RULE_HINT,
|
||
buildRuleQueryItems,
|
||
createRefRuleRow,
|
||
createRuleRow,
|
||
isCompleteRelationKey,
|
||
itemMapOf,
|
||
parseRelationScopeId,
|
||
parseRulePredicate,
|
||
relationScopeId,
|
||
ruleLabel,
|
||
ruleSummary,
|
||
ruleTypeText,
|
||
} from '@/views/module/module-management/ruleUtils'
|
||
|
||
const relation = {
|
||
b_source_module_id: 'order',
|
||
b_source_field: 'b_id',
|
||
b_target_module_id: 'order_item',
|
||
b_target_field: 'b_order_id',
|
||
}
|
||
|
||
const fields = [
|
||
{ b_field: 'b_status', b_name: '状态', b_type: 'select', b_canuse: 1 },
|
||
{ b_field: 'b_amount', b_name: '金额', b_type: 'money', b_canuse: 1 },
|
||
{ b_field: 'b_off', b_name: '停用字段', b_type: 'input', b_canuse: 0 },
|
||
]
|
||
|
||
describe('删除规则工具', () => {
|
||
it('关系业务键与四列互逆', () => {
|
||
expect(relationScopeId(relation)).toBe('order|b_id|order_item|b_order_id')
|
||
expect(parseRelationScopeId('order|b_id|order_item|b_order_id')).toEqual({
|
||
sourceModuleId: 'order',
|
||
sourceField: 'b_id',
|
||
targetModuleId: 'order_item',
|
||
targetField: 'b_order_id',
|
||
})
|
||
expect(isCompleteRelationKey(relation)).toBe(true)
|
||
expect(isCompleteRelationKey({ ...relation, b_target_field: null })).toBe(false)
|
||
})
|
||
|
||
it('predicate 三态:空=引用、JSON=勾条件、其余=SQL(非法 JSON 降级为 SQL)', () => {
|
||
expect(parseRulePredicate({ b_predicate: null }).kind).toBe('reference')
|
||
expect(parseRulePredicate({ b_predicate: ' ' }).kind).toBe('reference')
|
||
|
||
const dsl = parseRulePredicate({
|
||
b_predicate: JSON.stringify({
|
||
kind: 'dsl',
|
||
expr: { type: 'group', children: [{ type: 'condition', field: 'b_status' }] },
|
||
}),
|
||
})
|
||
expect(dsl.kind).toBe('dsl')
|
||
expect(dsl.expr.children).toHaveLength(1)
|
||
|
||
expect(parseRulePredicate({ b_predicate: 'select 1 where b_id in (:ids)' })).toMatchObject({
|
||
kind: 'sql',
|
||
})
|
||
expect(parseRulePredicate({ b_predicate: '{不是合法 JSON' })).toMatchObject({ kind: 'sql' })
|
||
// JSON 合法但不是 dsl 形状:按 SQL 文本处理,内容不丢
|
||
expect(parseRulePredicate({ b_predicate: '{"foo":1}' })).toMatchObject({ kind: 'sql' })
|
||
})
|
||
|
||
it('类型文案与摘要:条件走中文描述、SQL 单行截断、引用固定说明', () => {
|
||
const itemByField = itemMapOf(buildRuleQueryItems(fields, {}))
|
||
|
||
const dslRow = {
|
||
b_predicate: JSON.stringify({
|
||
kind: 'dsl',
|
||
expr: {
|
||
type: 'group',
|
||
children: [{ type: 'condition', field: 'b_amount', operator: 'gt', value: 0 }],
|
||
},
|
||
}),
|
||
}
|
||
expect(ruleTypeText(dslRow)).toBe('条件')
|
||
expect(ruleSummary(dslRow, itemByField)).toBe('金额 大于 0')
|
||
|
||
const sqlRow = { b_predicate: 'select\n b_id\nfrom bill where b_settled = 1' }
|
||
expect(ruleTypeText(sqlRow)).toBe('SQL')
|
||
expect(ruleSummary(sqlRow, itemByField)).toBe('select b_id from bill where b_settled = 1')
|
||
|
||
const refRow = { b_predicate: null }
|
||
expect(ruleTypeText(refRow)).toBe('引用')
|
||
expect(ruleSummary(refRow, itemByField)).toBe(REF_RULE_HINT)
|
||
})
|
||
|
||
it('识别文案:勾条件显示条件摘要,写 SQL 显示提示文案(缺文案退回 SQL 片段)', () => {
|
||
const itemByField = itemMapOf(buildRuleQueryItems(fields, {}))
|
||
|
||
const dslRow = {
|
||
b_predicate: JSON.stringify({
|
||
kind: 'dsl',
|
||
expr: {
|
||
type: 'group',
|
||
children: [{ type: 'condition', field: 'b_status', operator: 'eq', value: 'audit' }],
|
||
},
|
||
}),
|
||
}
|
||
expect(ruleLabel(dslRow, itemByField)).toBe('状态 等于 audit')
|
||
|
||
const sqlRow = { b_predicate: 'select 1 as b_id', b_message: '单据已销账,不能删除' }
|
||
expect(ruleLabel(sqlRow, itemByField)).toBe('单据已销账,不能删除')
|
||
expect(ruleLabel({ ...sqlRow, b_message: null }, itemByField)).toBe('select 1 as b_id')
|
||
|
||
expect(ruleLabel({ b_predicate: null }, itemByField)).toBe(REF_RULE_HINT)
|
||
})
|
||
|
||
it('新增行:主键由调用方取号传入,无名称/编码字段', () => {
|
||
const rule = createRuleRow('order', { id: '1900000000000000001', xh: 30 })
|
||
expect(rule).toMatchObject({
|
||
b_id: '1900000000000000001',
|
||
b_scope_type: 'module',
|
||
b_scope_id: 'order',
|
||
b_hook: 'delete.pre',
|
||
b_predicate: null,
|
||
b_canuse: 1,
|
||
b_xh: 30,
|
||
})
|
||
expect(rule.b_code).toBeUndefined()
|
||
expect(rule.b_name).toBeUndefined()
|
||
|
||
const ref = createRefRuleRow('order|b_id|order_item|b_order_id', '1900000000000000002')
|
||
expect(ref).toMatchObject({
|
||
b_id: '1900000000000000002',
|
||
b_scope_type: 'relation',
|
||
b_scope_id: 'order|b_id|order_item|b_order_id',
|
||
b_predicate: null,
|
||
b_hook: 'delete.pre',
|
||
})
|
||
})
|
||
|
||
it('items 构造:只列启用字段,类型映射控件,select 缺选项时降级为输入', () => {
|
||
const items = buildRuleQueryItems(fields, {
|
||
groups: [
|
||
{
|
||
conditions: [
|
||
{ field: 'b_status', operator: 'in', component: 'select', options: [{ value: 'a' }] },
|
||
],
|
||
},
|
||
],
|
||
})
|
||
|
||
expect(items.map((item) => item.field.b_field)).toEqual(['b_status', 'b_amount'])
|
||
// 查询配置里定义过:沿用其操作符/控件/选项
|
||
expect(items[0].config).toMatchObject({ b_operator: 'in', b_component: 'select' })
|
||
expect(items[0].options).toEqual([{ value: 'a', label: 'a' }])
|
||
// 未定义过:按字段类型推导(金额 → 数字输入)
|
||
expect(items[1].config.b_component).toBe('number')
|
||
expect(items[1].config.b_operator).toBe('eq')
|
||
})
|
||
})
|