115 lines
5.4 KiB
JavaScript
115 lines
5.4 KiB
JavaScript
import assert from 'node:assert/strict'
|
|
import test from 'node:test'
|
|
|
|
import {
|
|
buildApiContext,
|
|
buildInventoryCheck,
|
|
classifyCommit,
|
|
makeFeatureCatalogKey,
|
|
makeIdempotencyKey,
|
|
normalizeRepoName,
|
|
selectUniqueProject,
|
|
validateStatusEvidence,
|
|
} from '../../scripts/kaifa-progress-sync.mjs'
|
|
|
|
test('builds the complete inventory check from the freshly fetched catalog state', () => {
|
|
const context = {
|
|
currentState: {
|
|
featureInventoryPolicy: { catalogFeatureCount: 1 },
|
|
modules: [{
|
|
moduleId: 'module-1',
|
|
name: '生产发布与团队协作',
|
|
features: [{
|
|
featureId: 'feature-1',
|
|
name: '钉钉账号登录与绑定',
|
|
description: '让现有财务账号通过钉钉完成绑定和登录。',
|
|
status: 'done',
|
|
progressPercent: 100,
|
|
}],
|
|
}],
|
|
},
|
|
}
|
|
assert.deepEqual(buildInventoryCheck(context, '2026-09-03T10:00:00.000Z'), {
|
|
reviewed_at: '2026-09-03T10:00:00.000Z',
|
|
source_inventory_complete: true,
|
|
source_feature_count: 1,
|
|
catalog_feature_count: 1,
|
|
items: [{
|
|
module_id: 'module-1',
|
|
module_name: '生产发布与团队协作',
|
|
feature_id: 'feature-1',
|
|
feature_name: '钉钉账号登录与绑定',
|
|
feature_description: '让现有财务账号通过钉钉完成绑定和登录。',
|
|
status: 'done',
|
|
progress_percent: 100,
|
|
}],
|
|
})
|
|
assert.throws(() => buildInventoryCheck({ currentState: { featureInventoryPolicy: { catalogFeatureCount: 1 }, modules: [] } }), /COUNT_MISMATCH/)
|
|
})
|
|
|
|
test('keeps Git author filtering separate from the board developer identity', () => {
|
|
assert.deepEqual(buildApiContext({
|
|
OWNER_EMAIL: '549727955@qq.com',
|
|
DEVELOPER_CONTEXT: '魔礼红',
|
|
PROJECT_DESCRIPTION: '真实项目介绍',
|
|
DEPARTMENT: '财务中心',
|
|
PROJECT: '财务系统',
|
|
}), {
|
|
department: '财务中心',
|
|
project: '财务系统',
|
|
developer: '魔礼红',
|
|
project_description: '真实项目介绍',
|
|
})
|
|
})
|
|
|
|
test('feature catalog idempotency changes with the exact requested definitions', () => {
|
|
const first = makeFeatureCatalogKey('CaiWuXiTong', [{ moduleName: '快递与审批', featureName: 'E 签宝状态轮询' }])
|
|
const same = makeFeatureCatalogKey('CaiWuXiTong', [{ featureName: 'E 签宝状态轮询', moduleName: '快递与审批' }])
|
|
const second = makeFeatureCatalogKey('CaiWuXiTong', [{ moduleName: '快递与审批', featureName: '钉钉应付流程' }])
|
|
assert.equal(first, same)
|
|
assert.notEqual(first, second)
|
|
})
|
|
|
|
test('normalizes repository names and builds a stable idempotency key', () => {
|
|
assert.equal(normalizeRepoName('http://git.example.com/team/CaiWuXiTong.git'), 'CaiWuXiTong')
|
|
assert.equal(makeIdempotencyKey('CaiWuXiTong', 'abc123', 'testing'), 'CaiWuXiTong:abc123:testing')
|
|
})
|
|
|
|
test('matches exactly one project and rejects ambiguous matches', () => {
|
|
const project = {
|
|
projectId: 'p1', projectName: '财务系统', department: '财务中心', repoName: 'CaiWuXiTong',
|
|
productionUrl: 'https://218.93.190.75:8442', deploymentName: 'caiwuxitong',
|
|
}
|
|
const identity = {
|
|
projectName: '财务系统', repoName: 'CaiWuXiTong', productionUrl: 'https://218.93.190.75:8442',
|
|
deploymentName: 'caiwuxitong',
|
|
}
|
|
assert.equal(selectUniqueProject([project], identity).projectId, 'p1')
|
|
assert.throws(() => selectUniqueProject([project, { ...project, projectId: 'p2' }], identity), /AMBIGUOUS/)
|
|
})
|
|
|
|
test('assigns one primary feature and stops on ambiguous feature matches', () => {
|
|
assert.equal(classifyCommit('财务经营报表增加安装明细', ['app/Models/Business/InstallationDetail.php']).rule.key, 'installation-details')
|
|
assert.equal(classifyCommit('修复云数据库管理不支持 PostgreSQL 连接', ['app/Http/Controllers/SystemSettings/Databases.php']).rule.key, 'upstream-connections')
|
|
const esign = classifyCommit('feat: add callback-free eSign status polling', ['app/Console/Commands/PollEsignSignatures.php']).rule
|
|
assert.equal(esign.key, 'courier-esign')
|
|
assert.equal(esign.featureName, 'E 签宝无回调状态轮询与归档')
|
|
const dingtalkLogin = classifyCommit('feat: add DingTalk account login', ['app/Http/Controllers/Auth/DingTalkLogin.php']).rule
|
|
assert.equal(dingtalkLogin.key, 'dingtalk-login')
|
|
assert.equal(dingtalkLogin.featureName, '钉钉账号登录与绑定')
|
|
assert.match(dingtalkLogin.featureDescription, /OAuth/)
|
|
assert.equal(
|
|
classifyCommit('feat: align taobao reconciliation headers', ['resources/views/store_receivables/zhongcai_reconciliations/partials/embedded-table.blade.php']).rule.key,
|
|
'zhongcai-reconciliation',
|
|
)
|
|
assert.throws(
|
|
() => classifyCommit('chore: shared update', ['app/Utilities/SystemDatabaseConfiguration.php', 'modules/EcommerceFinance/Services/UpstreamOdbcConnection.php']),
|
|
/FEATURE_MATCH_AMBIGUOUS/,
|
|
)
|
|
})
|
|
|
|
test('done requires passed tests and explicit acceptance evidence', () => {
|
|
assert.throws(() => validateStatusEvidence('done', { testStatus: 'passed', acceptanceEvidence: '' }), /DONE_REQUIRES/)
|
|
assert.doesNotThrow(() => validateStatusEvidence('done', { testStatus: 'passed', acceptanceEvidence: 'production SHA verified' }))
|
|
})
|