| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 |
- import assert from 'node:assert/strict'
- import test from 'node:test'
- import * as navigation from '../src/utils/mp-webview'
- const api = navigation as any
- test('客户进入合同后继续查看报价,返回合同仍保留最外层客户来源', () => {
- assert.equal(typeof api.mpContractRelatedLocation, 'function')
- const location = api.mpContractRelatedLocation('quote', { id: 'K-1', quoteId: 'Q1' }, { from: 'customer', customerId: 'C1' })
- assert.equal(location.path, '/m/crm/quote/Q1')
- assert.deepEqual(api.mpRelatedContractReturnLocation(location.query), {
- path: '/m/crm/contract/K-1', query: { from: 'customer', customerId: 'C1' }
- })
- })
- test('关联客户和商机复用现有客户详情,不需要商机列表命中', () => {
- assert.equal(typeof api.mpContractRelatedLocation, 'function')
- const row = { id: 'K1', customerId: 'C1', opportunityId: 'O999' }
- assert.equal(api.mpContractRelatedLocation('customer', row, {}).path, '/m/crm/customer/C1')
- const location = api.mpContractRelatedLocation('opportunity', row, {})
- assert.equal(location.path, '/m/crm/customer/C1')
- assert.equal(location.query.tab, 'opportunity')
- assert.equal(location.query.opportunityId, 'O999')
- })
- test('非法目标与返回ID不能形成任意站外或相对路径', () => {
- assert.equal(typeof api.mpContractRelatedLocation, 'function')
- for (const value of ['../x', '//evil.test', 'x?foo=1', ['K1'], '']) {
- assert.equal(api.mpContractRelatedLocation('quote', { id: 'K1', quoteId: value }, {}), null)
- assert.equal(api.mpRelatedContractReturnLocation({ from: 'contract', returnContractId: value }), null)
- }
- })
- test('商机跟进展示使用Web crm_follow_type,未知值保留原值', async () => {
- const { readFileSync } = await import('node:fs')
- const { compile } = await import('vue')
- const { resolveOpportunityDictLabel } = await import('../src/utils/crm-opportunity-labels')
- const source = readFileSync(new URL('../src/views/m/crm/customer/RelatedPanel.vue', import.meta.url), 'utf8')
- const expression = source.match(/{{\s*([^{}]*row\.followType[^{}]*)\s*}}/)?.[1]
- assert.ok(expression)
- const dict = { dictMap: { crm_follow_type: [{ value: 'phone', label: '客户电话' }], crm_opportunity_follow_type: [{ value: 'phone', label: '商机电话' }] }, getLabel: (type: string) => type === 'crm_follow_type' ? '客户电话' : '商机电话' }
- const render = compile(`<span>{{ ${expression} }}</span>`)
- assert.equal(render({ row: { followType: 'phone' }, dict, resolveOpportunityDictLabel }, []).children, '客户电话')
- assert.equal(render({ row: { followType: 'legacy' }, dict, resolveOpportunityDictLabel }, []).children, 'legacy')
- })
- test('关闭旧商机不能清除新目标query,关闭当前只移除目标并保留返回链', async () => {
- const { readFileSync } = await import('node:fs')
- const { parse } = await import('@vue/compiler-sfc')
- const ts = (await import('typescript')).default
- const source = parse(readFileSync(new URL('../src/views/m/crm/customer/detail.vue', import.meta.url), 'utf8')).descriptor.scriptSetup!.content
- const ast = ts.createSourceFile('detail.ts', source, ts.ScriptTarget.Latest, true)
- const method = ast.statements.find((node) => ts.isFunctionDeclaration(node) && node.name?.text === 'clearTargetOpportunity')!
- const calls: any[] = []
- const route = { path: '/m/crm/customer/C1', query: { opportunityId: 'O2', from: 'contract', returnContractId: 'K1', originCustomerId: 'C0', tab: 'opportunity' } }
- const clear = new Function('route', 'router', 'targetOpportunityId', 'isCurrentCustomerRoute', `${ts.transpile(method.getText(ast))};return clearTargetOpportunity`)(route, { replace: (v: any) => calls.push(v) }, { value: 'O2' }, () => true)
- clear('O1')
- assert.equal(calls.length, 0)
- clear('O2')
- assert.deepEqual(calls, [{ path: route.path, query: { from: 'contract', returnContractId: 'K1', originCustomerId: 'C0', tab: 'opportunity' } }])
- })
- test('历史数值ID仅接受安全整数,合同和关联对象一致规范化', () => {
- for (const id of [1, 123, Number.MAX_SAFE_INTEGER]) {
- assert.equal(api.mpCrmRecordId(id), String(id))
- const location = api.mpContractRelatedLocation('customer', { id, customerId: id }, {})
- assert.equal(location.path, `/m/crm/customer/${id}`)
- assert.equal(api.mpRelatedContractReturnLocation(location.query).path, `/m/crm/contract/${id}`)
- }
- for (const id of [NaN, Infinity, -Infinity, 1.5, Number.MAX_SAFE_INTEGER + 1]) {
- assert.equal(api.mpCrmRecordId(id), '')
- assert.equal(api.mpContractRelatedLocation('customer', { id, customerId: 'C1' }, {}), null)
- assert.equal(api.mpContractRelatedLocation('customer', { id: 'K1', customerId: id }, {}), null)
- }
- })
|