文件
hyb-oa/server/tests/unit/routes/integrations.erp.asset.test.js
T

140 行
3.8 KiB
JavaScript

const integrationsRoutes = require('../../../src/routes/integrations');
describe('Integrations asset ERP route helpers', () => {
const { canReadAsset, enqueueAssetExportAndMaybeRun, parseRunNow } = integrationsRoutes.__testables;
function createAsset(overrides = {}) {
return {
id: 'asset-1',
asset_no: 'ZC-001',
assignee_employee_id: 'employee-1',
legal_entity_id: 'le-1',
cost_center_id: 'cc-1',
status: 'in_use',
...overrides,
};
}
it('respects asset read permission rules', () => {
const asset = createAsset();
expect(
canReadAsset(
{ employee: { id: 'employee-1', permissionCodes: ['asset.view_own'] } },
asset,
),
).toBe(true);
expect(
canReadAsset(
{ employee: { id: 'other', permissionCodes: ['asset.view_own'] } },
asset,
),
).toBe(false);
expect(
canReadAsset(
{ employee: { id: 'other', permissionCodes: ['asset.view_all'] } },
asset,
),
).toBe(true);
});
it('retries same asset payload without triggering runNow when duplicated', async () => {
const enqueueExport = vi.fn().mockResolvedValue({
id: 'outbox-1',
status: 'succeeded',
duplicated: true,
requeued: false,
eventType: 'erp.asset.export',
});
const runOutboxOnce = vi.fn();
const result = await enqueueAssetExportAndMaybeRun({
prisma: {},
config: {},
logger: {},
context: { asset: createAsset() },
actorId: 'actor-1',
runNow: true,
findExistingOutbox: vi.fn().mockResolvedValue({
id: 'outbox-1',
status: 'succeeded',
payload: {
exportType: 'asset_ledger_summary',
entityId: 'asset-1',
assetNo: 'ZC-001',
legalEntity: { id: 'le-1' },
costCenter: { id: 'cc-1' },
status: 'in_use',
},
}),
enqueueExport,
runOutboxOnce,
});
expect(enqueueExport).toHaveBeenCalledWith(
{},
{},
expect.objectContaining({
payload: expect.objectContaining({
assetNo: 'ZC-001',
status: 'in_use',
}),
requeueOnFailure: true,
}),
);
expect(runOutboxOnce).not.toHaveBeenCalled();
expect(result.duplicated).toBe(true);
});
it('resyncs current asset snapshot when financial drift exists', async () => {
const enqueueExport = vi.fn().mockResolvedValue({
id: 'outbox-1',
status: 'pending',
duplicated: false,
requeued: true,
eventType: 'erp.asset.export',
});
const runOutboxOnce = vi.fn().mockResolvedValue({ total: 1, succeeded: 1, failed: 0 });
const result = await enqueueAssetExportAndMaybeRun({
prisma: {},
config: {},
logger: {},
context: { asset: createAsset({ cost_center_id: 'cc-2', status: 'retired' }) },
actorId: 'actor-1',
runNow: true,
findExistingOutbox: vi.fn().mockResolvedValue({
id: 'outbox-1',
status: 'succeeded',
payload: {
exportType: 'asset_ledger_summary',
entityId: 'asset-1',
assetNo: 'ZC-001',
legalEntity: { id: 'le-1' },
costCenter: { id: 'cc-1' },
status: 'in_use',
},
}),
enqueueExport,
runOutboxOnce,
});
expect(enqueueExport).toHaveBeenCalledWith(
{},
{},
expect.objectContaining({
payload: undefined,
changeType: 'retired',
changedFields: expect.arrayContaining(['costCenterId', 'status']),
}),
);
expect(runOutboxOnce).toHaveBeenCalled();
expect(result.requeued).toBe(true);
});
it('parses runNow flags for asset requeue route', () => {
expect(parseRunNow({ runNow: '1' })).toBe(true);
expect(parseRunNow({ runNow: '0' })).toBe(false);
});
});