| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- 'use strict';
- const assert = require('node:assert/strict');
- const fs = require('node:fs');
- const path = require('node:path');
- const vm = require('node:vm');
- /** @param {string} source @param {string} name @returns {string} */
- function extractFunction(source, name) {
- const pattern = new RegExp('export (?:async )?function ' + name + '\\(');
- const match = pattern.exec(source);
- assert.ok(match, '缺少方法 ' + name);
- const end = source.indexOf('\n/**', match.index + match[0].length);
- return source.slice(match.index, end < 0 ? source.length : end).replace(/^export /, '');
- }
- /** @param {object} options @returns {object} */
- function createContext(options = {}) {
- const state = {
- selectedYear: 2026, selectedMonth: 8, userId: '626968159',
- userInfo: { userName: '冷志刚/Zhigang Leng', staffType: '内部', managerId: '640891109' },
- projectRows: [], ...options.state,
- };
- return {
- state,
- collectApprovalData: () => options.projectGroups || {},
- collectOtherApprovalData: () => ({
- otherRows: [{ dateStr: '20260813', activityName: 'Annual Leave', hours: 8 }],
- otherTotal: 8, ...options.otherGroup,
- }),
- getRepairMonthText: (year, month) => String(year) + String(month).padStart(2, '0'),
- fetchDeptManagerId: methods.fetchDeptManagerId,
- buildTimecardRepairRequest: methods.buildTimecardRepairRequest,
- getTexts: () => ({ repairBackendPending: '补填连接器未配置' }),
- unwrapConnectorResponse: (response) => response.data,
- };
- }
- const sourcePath = path.resolve(__dirname, '../src/timecard-repair.oyd.jsx');
- const schemaFile = process.argv[2];
- const schema = schemaFile ? JSON.parse(fs.readFileSync(schemaFile, 'utf8')).content : null;
- const compiled = process.argv[3] === 'compiled';
- const source = schema ? schema.actions.module[compiled ? 'compiled' : 'source'] : fs.readFileSync(sourcePath, 'utf8');
- const methods = vm.runInNewContext(
- (compiled ? source : ['buildTimecardRepairRequest', 'submitTimecardRepairRequest', 'fetchDeptManagerId']
- .map((name) => extractFunction(source, name)).join('\n'))
- + '\n({buildTimecardRepairRequest, submitTimecardRepairRequest, fetchDeptManagerId})',
- { exports: {}, REPAIR_DATA_SOURCES: { submit: 'startTimecardRepair' } },
- );
- /** @returns {Promise<void>} */
- async function main() {
- const cases = [
- ['内部员工缓存主管', { state: { deptManagerInfo: { managerId: '640891109', isFallback: false } } }, '640891109'],
- ['缓存缺失时从内部人员档案获取', {}, '640891109'],
- ['外部员工从有效项目获取', { state: {
- userInfo: { staffType: '外部' },
- projectRows: [{ managerId: '634735129' }, { managerId: 'project-manager' }],
- } }, 'project-manager'],
- ['内部员工未配置主管时保留业务兜底', { state: { userInfo: { staffType: '内部' } } }, '634735129'],
- ['外部员工无有效项目经理时保留业务兜底', { state: { userInfo: { staffType: '外部' } } }, '634735129'],
- ];
- for (const [name, options, expected] of cases) {
- const context = createContext(options);
- const request = await methods.buildTimecardRepairRequest.call(context);
- assert.equal(request.otherGroup.managerId, expected, name);
- assert.equal(request.otherGroup.otherTotal, 8, name);
- assert.equal(request.otherGroup.otherRows[0].hours, 8, name);
- assert.equal(request.sourceMonthText, '202608', name);
- assert.equal(request.submitterUserId, '626968159', name);
- console.log('PASS ' + name);
- }
- const projectGroups = { pm: { managerId: 'original-pm', billableTotal: 8, nonBillableTotal: 0 } };
- const projectOnly = createContext({ projectGroups, otherGroup: { otherRows: [], otherTotal: 0 } });
- projectOnly.fetchDeptManagerId = () => { throw new Error('纯项目补填无需获取其他工时主管'); };
- assert.equal((await methods.buildTimecardRepairRequest.call(projectOnly)).projectGroups, projectGroups);
- console.log('PASS 项目工时分组保持原样');
- const context = createContext();
- let submitted;
- context.getCallableDataSource = () => ({ load: async (payload) => {
- submitted = JSON.parse(payload.inputs).Body;
- return { data: { status: '审批中' } };
- } });
- const result = await methods.submitTimecardRepairRequest.call(context);
- assert.equal(submitted.otherGroup.managerId, '640891109');
- assert.equal(submitted.otherGroup.otherRows[0].activityName, 'Annual Leave');
- assert.equal(result.status, '审批中');
- console.log('PASS 连接器实际请求携带 Kevin ID');
- const failedContext = createContext();
- failedContext.fetchDeptManagerId = async () => { throw new Error('主管获取失败'); };
- failedContext.getCallableDataSource = () => ({ load: () => assert.fail('主管获取失败后不得提交') });
- await assert.rejects(methods.submitTimecardRepairRequest.call(failedContext), /主管获取失败/);
- console.log('PASS 主管获取失败阻止提交');
- }
- main().catch((error) => { console.error(error); process.exitCode = 1; });
|