179 lines
6.1 KiB
TypeScript
179 lines
6.1 KiB
TypeScript
import assert from 'node:assert/strict'
|
|
import test from 'node:test'
|
|
|
|
import {
|
|
normalizeFulfillmentRoutingConfig,
|
|
resolveFulfillmentRoute,
|
|
} from './routing-config-service.js'
|
|
|
|
test('normalizeFulfillmentRoutingConfig drops retired executors and keeps affiliate_dash default', () => {
|
|
const config = normalizeFulfillmentRoutingConfig({
|
|
defaultExecutorPriority: ['kuaishou_ct_assisted', 'kuaishou_feifei'],
|
|
})
|
|
|
|
assert.deepEqual(config.defaultExecutorPriority, ['affiliate_dash'])
|
|
assert.deepEqual(Object.keys(config.executors).sort(), ['affiliate_dash', 'manual_dispatch'])
|
|
assert.equal(config.unmatchedExecutorKey, 'manual_dispatch')
|
|
})
|
|
|
|
test('resolveFulfillmentRoute 总开关关闭后不再回退默认配置,返回未选中', () => {
|
|
const result = resolveFulfillmentRoute({
|
|
productName: '测试商品',
|
|
candidates: [{ executorKey: 'affiliate_dash', available: true }],
|
|
config: normalizeFulfillmentRoutingConfig({
|
|
enabled: false,
|
|
}),
|
|
})
|
|
|
|
assert.equal(result.selectedExecutorKey, '')
|
|
assert.equal(result.reason, '履约路由未启用,自动发货已停止')
|
|
})
|
|
|
|
test('resolveFulfillmentRoute 默认选择 affiliate_dash', () => {
|
|
const result = resolveFulfillmentRoute({
|
|
productName: '测试商品',
|
|
candidates: [{ executorKey: 'affiliate_dash', available: true }],
|
|
config: normalizeFulfillmentRoutingConfig({}),
|
|
})
|
|
|
|
assert.equal(result.selectedExecutorKey, 'affiliate_dash')
|
|
assert.equal(result.reason, '按全局优先级命中')
|
|
})
|
|
|
|
test('resolveFulfillmentRoute affiliate 不可用时回退人工', () => {
|
|
const result = resolveFulfillmentRoute({
|
|
productName: '测试商品',
|
|
candidates: [
|
|
{ executorKey: 'affiliate_dash', available: false, reason: '未命中 affiliate-dash sku 映射' },
|
|
],
|
|
config: normalizeFulfillmentRoutingConfig({}),
|
|
})
|
|
|
|
assert.equal(result.selectedExecutorKey, 'manual_dispatch')
|
|
assert.equal(result.reason, '未命中自动履约通道,进入人工履约')
|
|
assert.deepEqual(result.skipped[0], {
|
|
executorKey: 'affiliate_dash',
|
|
reason: '未命中 affiliate-dash sku 映射',
|
|
})
|
|
})
|
|
|
|
test('resolveFulfillmentRoute 商品规则可以强制走 affiliate_dash', () => {
|
|
const result = resolveFulfillmentRoute({
|
|
productName: '荣耀套装',
|
|
candidates: [{ executorKey: 'affiliate_dash', available: true }],
|
|
config: normalizeFulfillmentRoutingConfig({
|
|
rules: [
|
|
{
|
|
enabled: true,
|
|
productName: '荣耀套装',
|
|
executorKey: 'affiliate_dash',
|
|
priority: 200,
|
|
},
|
|
],
|
|
}),
|
|
})
|
|
|
|
assert.equal(result.selectedExecutorKey, 'affiliate_dash')
|
|
assert.equal(result.selectedRuleId, '荣耀套装:affiliate_dash')
|
|
assert.equal(result.reason, '命中商品路由规则')
|
|
})
|
|
|
|
test('resolveFulfillmentRoute 商品规则目标不可用时不再静默改通道', () => {
|
|
const result = resolveFulfillmentRoute({
|
|
productName: '套装-糯粉咩咩',
|
|
candidates: [
|
|
{ executorKey: 'affiliate_dash', available: false, reason: '未命中 affiliate-dash sku 映射' },
|
|
],
|
|
config: normalizeFulfillmentRoutingConfig({
|
|
rules: [
|
|
{
|
|
enabled: true,
|
|
productName: '套装-糯粉咩咩',
|
|
executorKey: 'affiliate_dash',
|
|
priority: 200,
|
|
},
|
|
],
|
|
}),
|
|
})
|
|
|
|
assert.equal(result.selectedExecutorKey, '')
|
|
assert.equal(result.reason, '商品路由规则目标通道不可用,且未命中其他履约通道')
|
|
assert.deepEqual(result.skipped[0], {
|
|
executorKey: 'affiliate_dash',
|
|
reason: '未命中 affiliate-dash sku 映射',
|
|
})
|
|
})
|
|
|
|
test('resolveFulfillmentRoute 商品规则可以强制转人工', () => {
|
|
const result = resolveFulfillmentRoute({
|
|
productName: '临时停用商品',
|
|
candidates: [{ executorKey: 'affiliate_dash', available: true }],
|
|
config: normalizeFulfillmentRoutingConfig({
|
|
rules: [
|
|
{
|
|
enabled: true,
|
|
productName: '临时停用',
|
|
matchType: 'contains',
|
|
executorKey: 'manual_dispatch',
|
|
priority: 300,
|
|
},
|
|
],
|
|
}),
|
|
})
|
|
|
|
assert.equal(result.selectedExecutorKey, 'manual_dispatch')
|
|
assert.equal(result.reason, '命中商品路由规则')
|
|
})
|
|
|
|
test('resolveFulfillmentRoute 指定匹配(显式映射)最高优先', () => {
|
|
const result = resolveFulfillmentRoute({
|
|
productName: '幸运币90个',
|
|
preferredExecutorKey: 'affiliate_dash',
|
|
candidates: [{ executorKey: 'affiliate_dash', available: true }],
|
|
config: normalizeFulfillmentRoutingConfig({}),
|
|
})
|
|
|
|
assert.equal(result.selectedExecutorKey, 'affiliate_dash')
|
|
assert.equal(result.reason, '命中指定匹配(显式映射),优先选择')
|
|
})
|
|
|
|
test('resolveFulfillmentRoute 指定匹配命中但通道停用时回退人工', () => {
|
|
const result = resolveFulfillmentRoute({
|
|
productName: '幸运币90个',
|
|
preferredExecutorKey: 'affiliate_dash',
|
|
candidates: [{ executorKey: 'affiliate_dash', available: true }],
|
|
config: normalizeFulfillmentRoutingConfig({
|
|
executors: {
|
|
affiliate_dash: { enabled: false },
|
|
},
|
|
}),
|
|
})
|
|
|
|
assert.equal(result.selectedExecutorKey, 'manual_dispatch')
|
|
assert.ok(result.skipped.some((item) => item.executorKey === 'affiliate_dash'))
|
|
})
|
|
|
|
test('resolveFulfillmentRoute 指定匹配命中但商品不可用时回退人工', () => {
|
|
const result = resolveFulfillmentRoute({
|
|
productName: '幸运币90个',
|
|
preferredExecutorKey: 'affiliate_dash',
|
|
candidates: [{ executorKey: 'affiliate_dash', available: false, reason: '未命中 sku 映射' }],
|
|
config: normalizeFulfillmentRoutingConfig({}),
|
|
})
|
|
|
|
assert.equal(result.selectedExecutorKey, 'manual_dispatch')
|
|
assert.ok(result.skipped.some((item) => item.executorKey === 'affiliate_dash'))
|
|
})
|
|
|
|
test('resolveFulfillmentRoute 无指定匹配时按全局优先级选择', () => {
|
|
const result = resolveFulfillmentRoute({
|
|
productName: '幸运币90个',
|
|
preferredExecutorKey: '',
|
|
candidates: [{ executorKey: 'affiliate_dash', available: true }],
|
|
config: normalizeFulfillmentRoutingConfig({}),
|
|
})
|
|
|
|
assert.equal(result.selectedExecutorKey, 'affiliate_dash')
|
|
assert.equal(result.reason, '按全局优先级命中')
|
|
})
|