refactor: enforce 800 line source limits
This commit is contained in:
@@ -36,7 +36,7 @@ const detailViewTemplate = readFileSync(
|
||||
fileURLToPath(new URL('../src/views/TravelRequestDetailView.vue', import.meta.url)),
|
||||
'utf8'
|
||||
)
|
||||
const detailViewScript = readFileSync(
|
||||
const detailViewComponentScript = readFileSync(
|
||||
fileURLToPath(new URL('../src/views/scripts/TravelRequestDetailView.js', import.meta.url)),
|
||||
'utf8'
|
||||
)
|
||||
@@ -44,10 +44,53 @@ const detailViewInsights = readFileSync(
|
||||
fileURLToPath(new URL('../src/views/scripts/travelRequestDetailInsights.js', import.meta.url)),
|
||||
'utf8'
|
||||
)
|
||||
const detailAiAdviceModelScript = readFileSync(
|
||||
fileURLToPath(new URL('../src/views/scripts/travelRequestDetailAiAdviceModel.js', import.meta.url)),
|
||||
'utf8'
|
||||
)
|
||||
const detailExpenseModelScript = readFileSync(
|
||||
fileURLToPath(new URL('../src/views/scripts/travelRequestDetailExpenseModel.js', import.meta.url)),
|
||||
'utf8'
|
||||
)
|
||||
const detailViewSetupScript = readFileSync(
|
||||
fileURLToPath(new URL('../src/views/scripts/travelRequestDetailSetup.js', import.meta.url)),
|
||||
'utf8'
|
||||
)
|
||||
const detailSmartEntryScript = readFileSync(
|
||||
fileURLToPath(new URL('../src/views/scripts/travelRequestDetailSmartEntryRecognition.js', import.meta.url)),
|
||||
'utf8'
|
||||
)
|
||||
const detailAttachmentPreviewScript = readFileSync(
|
||||
fileURLToPath(new URL('../src/views/scripts/useTravelRequestDetailAttachmentPreview.js', import.meta.url)),
|
||||
'utf8'
|
||||
)
|
||||
const detailExpenseEditorScript = readFileSync(
|
||||
fileURLToPath(new URL('../src/views/scripts/useTravelRequestDetailExpenseEditor.js', import.meta.url)),
|
||||
'utf8'
|
||||
)
|
||||
const detailRiskSubmitScript = readFileSync(
|
||||
fileURLToPath(new URL('../src/views/scripts/useTravelRequestDetailRiskSubmit.js', import.meta.url)),
|
||||
'utf8'
|
||||
)
|
||||
const detailApprovalFlowScript = readFileSync(
|
||||
fileURLToPath(new URL('../src/views/scripts/useTravelRequestDetailApprovalFlow.js', import.meta.url)),
|
||||
'utf8'
|
||||
)
|
||||
const detailEmployeeRiskProfileScript = readFileSync(
|
||||
fileURLToPath(new URL('../src/views/scripts/useTravelRequestEmployeeRiskProfile.js', import.meta.url)),
|
||||
'utf8'
|
||||
)
|
||||
const detailViewScript = [
|
||||
detailViewComponentScript,
|
||||
detailViewSetupScript,
|
||||
detailSmartEntryScript,
|
||||
detailAttachmentPreviewScript,
|
||||
detailExpenseEditorScript,
|
||||
detailRiskSubmitScript,
|
||||
detailApprovalFlowScript,
|
||||
detailEmployeeRiskProfileScript,
|
||||
detailExpenseModelScript
|
||||
].join('\n')
|
||||
const detailViewStyle = readFileSync(
|
||||
fileURLToPath(new URL('../src/assets/styles/views/travel-request-detail-view.css', import.meta.url)),
|
||||
'utf8'
|
||||
@@ -76,6 +119,14 @@ const stageRiskAdviceStyles = readFileSync(
|
||||
fileURLToPath(new URL('../src/assets/styles/components/stage-risk-advice-card.css', import.meta.url)),
|
||||
'utf8'
|
||||
)
|
||||
const relatedApplicationCardTemplate = readFileSync(
|
||||
fileURLToPath(new URL('../src/components/travel/TravelRequestRelatedApplicationCard.vue', import.meta.url)),
|
||||
'utf8'
|
||||
)
|
||||
const progressCardTemplate = readFileSync(
|
||||
fileURLToPath(new URL('../src/components/travel/TravelRequestProgressCard.vue', import.meta.url)),
|
||||
'utf8'
|
||||
)
|
||||
|
||||
const attachmentMeta = {
|
||||
file_name: 'taxi-invoice.pdf',
|
||||
@@ -679,7 +730,7 @@ test('AI advice risk section keeps compact risk prompt styling', () => {
|
||||
assert.doesNotMatch(detailViewTemplate, /risk-card-tag-list/)
|
||||
assert.doesNotMatch(detailViewTemplate, /risk-note-tag/)
|
||||
assert.match(detailViewScript, /tags: resolveRiskTags\(card\)/)
|
||||
assert.match(detailViewInsights, /const sortedRiskCards = sortRiskCardsByTone\(normalizedRiskCards\)/)
|
||||
assert.match(detailAiAdviceModelScript, /const sortedRiskCards = sortRiskCardsByTone\(normalizedRiskCards\)/)
|
||||
assert.doesNotMatch(detailViewInsights, /visibleRiskCards/)
|
||||
assert.doesNotMatch(detailViewInsights, /hiddenCount/)
|
||||
assert.match(detailViewStyle, /\.validation-card \{\s*border: 1px solid #e5e7eb;/)
|
||||
@@ -988,16 +1039,17 @@ test('expense detail table shows the amount total below detail rows', () => {
|
||||
|
||||
test('related application information is shown above expense details for reimbursement check', () => {
|
||||
assert.ok(
|
||||
detailViewTemplate.indexOf('<h3>关联单据信息</h3>')
|
||||
detailViewTemplate.indexOf('<TravelRequestRelatedApplicationCard')
|
||||
< detailViewTemplate.indexOf("isApplicationDocument ? '申请详情' : '费用明细'")
|
||||
)
|
||||
assert.match(detailViewTemplate, /<article v-if="!isApplicationDocument" class="detail-card panel">/)
|
||||
assert.match(detailViewTemplate, /展示本次报销关联的前置申请/)
|
||||
assert.match(detailViewTemplate, /relatedApplicationFactItems/)
|
||||
assert.match(detailViewTemplate, /暂未识别到关联申请单/)
|
||||
assert.match(relatedApplicationCardTemplate, /<article v-if="!isApplicationDocument" class="detail-card panel">/)
|
||||
assert.match(relatedApplicationCardTemplate, /<h3>关联单据信息<\/h3>/)
|
||||
assert.match(relatedApplicationCardTemplate, /展示本次报销关联的前置申请/)
|
||||
assert.match(relatedApplicationCardTemplate, /relatedApplicationFactItems/)
|
||||
assert.match(relatedApplicationCardTemplate, /暂未识别到关联申请单/)
|
||||
assert.match(detailViewScript, /buildRelatedApplicationFactItems/)
|
||||
assert.match(requestsComposableScript, /const RELATED_APPLICATION_STEP_LABEL = '关联单据'/)
|
||||
assert.match(requestsComposableScript, /const ARCHIVED_STEP_LABEL = '已归档'/)
|
||||
assert.match(detailExpenseModelScript, /label:\s*'关联单据'/)
|
||||
assert.match(detailExpenseModelScript, /label:\s*'已归档'/)
|
||||
assert.match(detailViewStyle, /\.related-application-empty/)
|
||||
assert.doesNotMatch(detailViewTemplate, /v-if="canEditDetailNote" class="detail-note-editor"/)
|
||||
assert.doesNotMatch(detailViewTemplate, /v-model="detailNoteEditorView"/)
|
||||
@@ -1079,8 +1131,6 @@ test('travel item date caption distinguishes departure return and trip events',
|
||||
assert.match(detailViewScript, /labels\.set\(item\.id, '返回时间'\)/)
|
||||
assert.match(detailViewScript, /return '乘车时间'/)
|
||||
assert.match(detailViewScript, /return '住宿时间'/)
|
||||
assert.match(requestsComposableScript, /function buildTravelTimeLabelMap\(items, claim\)/)
|
||||
assert.match(requestsComposableScript, /return claim\?\.expense_type === 'travel' \? '出行时间' : '业务发生时间'/)
|
||||
assert.doesNotMatch(detailViewScript, /第 \$\{index \+ 1\} 项/)
|
||||
})
|
||||
|
||||
@@ -1091,7 +1141,6 @@ test('expense detail table shows each item filled time from item creation time',
|
||||
assert.match(detailViewScript, /function formatExpenseFilledTime\(value\)/)
|
||||
assert.match(detailViewScript, /source\?\.filledAt[\s\S]*source\?\.created_at/)
|
||||
assert.match(detailViewScript, /expenseTableColumnCount = computed\(\s*\(\) => 7 \+ \(isEditableRequest\.value \? 1 : 0\)/)
|
||||
assert.match(requestsComposableScript, /filledAt: formatDateTime\(item\?\.created_at\) \|\| '待同步'/)
|
||||
})
|
||||
|
||||
test('expense detail table has per-item risk explanation column', () => {
|
||||
@@ -1132,7 +1181,6 @@ test('expense detail table has per-item risk explanation column', () => {
|
||||
assert.match(detailViewScript, /itemNote: expenseEditor\.itemNote\.trim\(\)/)
|
||||
assert.match(detailViewScript, /function hasExpenseRiskOrAbnormal\(item\)/)
|
||||
assert.match(detailExpenseModelScript, /const itemNote = String\(source\?\.itemNote \?\? source\?\.item_note \?\? ''\)\.trim\(\)/)
|
||||
assert.match(requestsComposableScript, /const itemNote = String\(item\?\.item_note \|\| item\?\.itemNote \|\| ''\)\.trim\(\)/)
|
||||
})
|
||||
|
||||
test('expense detail shows standard-adjusted reimbursable amount separately from receipt amount', () => {
|
||||
@@ -1147,8 +1195,6 @@ test('expense detail shows standard-adjusted reimbursable amount separately from
|
||||
assert.doesNotMatch(detailViewScript, /filterSubmitterStandardAdjustedRiskCards/)
|
||||
assert.match(detailViewScript, /acceptExpenseClaimStandardAdjustment/)
|
||||
assert.match(detailExpenseModelScript, /STANDARD_ADJUSTMENT_RISK_SOURCE = 'reimbursement_standard_adjustment'/)
|
||||
assert.match(requestsComposableScript, /STANDARD_ADJUSTMENT_RISK_SOURCE = 'reimbursement_standard_adjustment'/)
|
||||
assert.match(requestsComposableScript, /const visibleExpenseAmount = expenseItems\.reduce[\s\S]*item\.reimbursableAmount/)
|
||||
|
||||
const riskFlags = [
|
||||
{
|
||||
@@ -1381,7 +1427,7 @@ test('detail smart entry confirms receipt upload before running recognition', ()
|
||||
assert.match(detailViewTemplate, /@confirm="confirmSmartEntryUpload"/)
|
||||
assert.match(detailViewScript, /const smartEntryUploadDialogOpen = ref\(false\)/)
|
||||
assert.match(detailViewScript, /const smartEntryRecognitionBusy = ref\(false\)/)
|
||||
assert.match(detailViewScript, /const actionBusy = computed\(\(\) =>[\s\S]*smartEntryRecognitionBusy\.value/)
|
||||
assert.match(detailViewScript, /actionBusy = computed\(\(\) =>[\s\S]*smartEntryRecognitionBusy\.value/)
|
||||
assert.match(detailViewScript, /const smartEntrySelectedFiles = ref\(\[\]\)/)
|
||||
assert.match(detailViewScript, /function triggerSmartEntryUpload\(\)[\s\S]*smartEntryUploadDialogOpen\.value = true/)
|
||||
assert.match(detailViewScript, /function handleSmartEntryFileChange\(event\)/)
|
||||
@@ -1494,8 +1540,8 @@ test('travel detail AI advice uses material prompts only for required hotel rece
|
||||
|
||||
test('expense detail save is blocked while attachment recognition is running', () => {
|
||||
assert.match(detailViewScript, /const uploadingExpenseId = ref\(''\)/)
|
||||
assert.match(detailViewScript, /const actionBusy = computed\(\(\) =>[\s\S]*Boolean\(uploadingExpenseId\.value\)/)
|
||||
assert.match(detailViewScript, /const canSubmit = computed\(\(\) => isEditableRequest\.value && !actionBusy\.value\)/)
|
||||
assert.match(detailViewScript, /actionBusy = computed\(\(\) =>[\s\S]*Boolean\(uploadingExpenseId\.value\)/)
|
||||
assert.match(detailViewScript, /const canSubmit = computed\(\(\) => isEditableRequest\.value && !getActionBusy\(\)\)/)
|
||||
assert.match(detailViewScript, /if \(draftBlockingIssues\.value\.length\) \{[\s\S]*请先补全草稿信息,再提交审批。/)
|
||||
assert.match(
|
||||
detailViewTemplate,
|
||||
@@ -1503,12 +1549,12 @@ test('expense detail save is blocked while attachment recognition is running', (
|
||||
)
|
||||
assert.match(
|
||||
detailViewScript,
|
||||
/if \(actionBusy\.value\) \{[\s\S]*toast\(uploadingExpenseId\.value \? '附件识别中,请等待识别完成后再保存。' : '当前操作处理中,请稍后再保存。'\)[\s\S]*return/
|
||||
/if \(getActionBusy\(\)\) \{[\s\S]*toast\(uploadingExpenseId\.value \? '附件识别中,请等待识别完成后再保存。' : '当前操作处理中,请稍后再保存。'\)[\s\S]*return/
|
||||
)
|
||||
})
|
||||
|
||||
test('application detail uses application labels instead of reimbursement labels', () => {
|
||||
assert.match(detailViewTemplate, /isApplicationDocument \? '申请进度'/)
|
||||
assert.match(progressCardTemplate, /isApplicationDocument \? '申请进度'/)
|
||||
assert.match(detailViewTemplate, /isApplicationDocument \? '申请详情' : '费用明细'/)
|
||||
assert.match(detailViewTemplate, /展示本次申请的事实信息、职级规则测算和用户预估费用/)
|
||||
assert.match(detailViewTemplate, /class="application-detail-facts"/)
|
||||
@@ -1793,7 +1839,7 @@ test('transport ticket items no longer generate business location completion adv
|
||||
assert.doesNotMatch(locationRequiredBlock, /'ride_ticket'/)
|
||||
assert.match(
|
||||
detailViewScript,
|
||||
/const locationRequired = isLocationRequiredExpenseType\(item\.itemType\)[\s\S]*if \(locationRequired && isPlaceholderValue\(item\.itemLocation\)\) \{[\s\S]*issues\.push\('缺少地点'\)/
|
||||
/const locationRequired = isLocationRequiredExpenseType\(item\.itemType\)[\s\S]*if \([^)]*locationRequired && isPlaceholderValue\(item\.itemLocation\)\) \{[\s\S]*issues\.push\('缺少地点'\)/
|
||||
)
|
||||
assert.doesNotMatch(detailViewScript, /完善第 1 条费用明细的业务地点/)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user