Files
yunhaifinance/backend/test-finance-complete.spec.js
T

339 lines
11 KiB
JavaScript

const request = require('supertest');
const fs = require('fs');
const path = require('path');
// 测试基础URL
const BASE_URL = 'http://localhost:3005';
// 测试文件路径
const TEST_IMAGE_PATH = path.join(__dirname, 'uploads', 'test-image.png');
// 测试数据
const testUser = {
username: 'admin',
password: 'admin123'
};
let authToken = '';
// 测试套件
describe('财务流程完整测试', () => {
// 登录获取token
beforeAll(async () => {
const response = await request(BASE_URL)
.post('/api/auth/login')
.send(testUser);
expect(response.status).toBe(200);
expect(response.body.success).toBe(true);
authToken = response.body.token;
});
// 测试预支申请流程
describe('预支申请流程', () => {
let advanceId = '';
let advanceCode = '';
test('1. 创建预支申请', async () => {
const response = await request(BASE_URL)
.post('/api/advances')
.set('Authorization', `Bearer ${authToken}`)
.field('advance_date', '2026-03-24')
.field('amount', 5000)
.field('currency', 'CNY')
.field('reason', '项目差旅预支')
.field('expense_type', 'project')
.field('project_id', '1')
.field('applicant', '测试用户')
.attach('attachments', TEST_IMAGE_PATH);
expect(response.status).toBe(200);
expect(response.body.success).toBe(true);
advanceId = response.body.data.id;
advanceCode = response.body.data.advance_code;
});
test('2. 提交预支申请到审批', async () => {
const response = await request(BASE_URL)
.put(`/api/advances/${advanceId}/submit`)
.set('Authorization', `Bearer ${authToken}`);
expect(response.status).toBe(200);
expect(response.body.success).toBe(true);
});
test('3. 审批预支申请', async () => {
const response = await request(BASE_URL)
.put(`/api/advances/${advanceId}/approve`)
.set('Authorization', `Bearer ${authToken}`)
.send({ approver: '系统管理员' });
expect(response.status).toBe(200);
expect(response.body.success).toBe(true);
});
test('4. 执行预支付款', async () => {
const response = await request(BASE_URL)
.post('/api/executions')
.set('Authorization', `Bearer ${authToken}`)
.send({
apply_id: advanceId,
apply_type: 'advance',
action: 'execute',
execute_method: '银行转账',
voucher_no: 'VCH' + Date.now(),
remark: '测试执行'
});
expect(response.status).toBe(200);
expect(response.body.success).toBe(true);
});
test('5. 验证预支执行状态', async () => {
const response = await request(BASE_URL)
.get(`/api/advances/${advanceId}`)
.set('Authorization', `Bearer ${authToken}`);
expect(response.status).toBe(200);
expect(response.body.success).toBe(true);
expect(response.body.data.status).toBe('executed');
});
});
// 测试报销申请流程
describe('报销申请流程', () => {
let reimbursementId = '';
test('1. 创建报销申请', async () => {
const response = await request(BASE_URL)
.post('/api/reimbursements')
.set('Authorization', `Bearer ${authToken}`)
.field('reimbursement_date', '2026-03-24')
.field('amount', 3500)
.field('currency', 'CNY')
.field('reason', '项目差旅报销')
.field('expense_type', 'project')
.field('project_id', '1')
.field('applicant', '测试用户')
.field('detail_items', JSON.stringify([
{
description: '住宿费',
amount: 2000,
category: 'accommodation',
attachments: []
},
{
description: '餐饮费',
amount: 1500,
category: 'food',
attachments: []
}
]))
.attach('attachments', TEST_IMAGE_PATH);
expect(response.status).toBe(200);
expect(response.body.success).toBe(true);
reimbursementId = response.body.data.id;
});
test('2. 提交报销申请到审批', async () => {
const response = await request(BASE_URL)
.put(`/api/reimbursements/${reimbursementId}/submit`)
.set('Authorization', `Bearer ${authToken}`);
expect(response.status).toBe(200);
expect(response.body.success).toBe(true);
});
test('3. 审批报销申请', async () => {
const response = await request(BASE_URL)
.put(`/api/reimbursements/${reimbursementId}/approve`)
.set('Authorization', `Bearer ${authToken}`)
.send({ approver: '系统管理员' });
expect(response.status).toBe(200);
expect(response.body.success).toBe(true);
});
test('4. 执行报销付款', async () => {
const response = await request(BASE_URL)
.post('/api/executions')
.set('Authorization', `Bearer ${authToken}`)
.send({
apply_id: reimbursementId,
apply_type: 'reimbursement',
action: 'execute',
execute_method: '银行转账',
voucher_no: 'VCH' + Date.now(),
remark: '测试执行'
});
expect(response.status).toBe(200);
expect(response.body.success).toBe(true);
});
});
// 测试付款申请流程
describe('付款申请流程', () => {
let paymentId = '';
test('1. 创建付款申请', async () => {
const response = await request(BASE_URL)
.post('/api/payments')
.set('Authorization', `Bearer ${authToken}`)
.field('payment_date', '2026-03-24')
.field('amount', 50000)
.field('currency', 'CNY')
.field('reason', '设备采购款')
.field('expense_type', 'company')
.field('payee', '测试供应商')
.field('applicant', '测试用户')
.attach('attachments', TEST_IMAGE_PATH);
expect(response.status).toBe(200);
expect(response.body.success).toBe(true);
paymentId = response.body.data.id;
});
test('2. 提交付款申请到审批', async () => {
const response = await request(BASE_URL)
.put(`/api/payments/${paymentId}/submit`)
.set('Authorization', `Bearer ${authToken}`);
expect(response.status).toBe(200);
expect(response.body.success).toBe(true);
});
test('3. 审批付款申请', async () => {
const response = await request(BASE_URL)
.put(`/api/payments/${paymentId}/approve`)
.set('Authorization', `Bearer ${authToken}`)
.send({ approver: '系统管理员' });
expect(response.status).toBe(200);
expect(response.body.success).toBe(true);
});
test('4. 执行付款', async () => {
const response = await request(BASE_URL)
.post('/api/executions')
.set('Authorization', `Bearer ${authToken}`)
.send({
apply_id: paymentId,
apply_type: 'payment',
action: 'execute',
execute_method: '银行转账',
voucher_no: 'VCH' + Date.now(),
remark: '测试执行'
});
expect(response.status).toBe(200);
expect(response.body.success).toBe(true);
});
});
// 测试核销申请流程
describe('核销申请流程', () => {
let verificationId = '';
test('1. 创建核销申请', async () => {
const response = await request(BASE_URL)
.post('/api/verifications')
.set('Authorization', `Bearer ${authToken}`)
.field('verification_date', '2026-03-24')
.field('advance_id', '1')
.field('actual_amount', 4500)
.field('balance', 500)
.field('reason', '项目差旅核销')
.field('applicant', '测试用户')
.field('detail_items', JSON.stringify([
{
description: '住宿费',
amount: 2500,
category: 'accommodation',
attachments: []
},
{
description: '餐饮费',
amount: 2000,
category: 'food',
attachments: []
}
]))
.attach('attachments', TEST_IMAGE_PATH);
expect(response.status).toBe(200);
expect(response.body.success).toBe(true);
verificationId = response.body.data.id;
});
test('2. 提交核销申请到审批', async () => {
const response = await request(BASE_URL)
.put(`/api/verifications/${verificationId}/submit`)
.set('Authorization', `Bearer ${authToken}`);
expect(response.status).toBe(200);
expect(response.body.success).toBe(true);
});
test('3. 审批核销申请', async () => {
const response = await request(BASE_URL)
.put(`/api/verifications/${verificationId}/approve`)
.set('Authorization', `Bearer ${authToken}`)
.send({ approver: '系统管理员' });
expect(response.status).toBe(200);
expect(response.body.success).toBe(true);
});
test('4. 执行核销', async () => {
const response = await request(BASE_URL)
.post('/api/executions')
.set('Authorization', `Bearer ${authToken}`)
.send({
apply_id: verificationId,
apply_type: 'verification',
action: 'execute',
execute_method: '银行转账',
voucher_no: 'VCH' + Date.now(),
remark: '测试执行'
});
expect(response.status).toBe(200);
expect(response.body.success).toBe(true);
});
});
// 测试执行记录查询
describe('执行记录查询', () => {
test('查询执行记录列表', async () => {
const response = await request(BASE_URL)
.get('/api/executions')
.set('Authorization', `Bearer ${authToken}`);
expect(response.status).toBe(200);
expect(response.body.success).toBe(true);
expect(Array.isArray(response.body.data)).toBe(true);
});
test('查询待执行列表', async () => {
const response = await request(BASE_URL)
.get('/api/executions/pending')
.set('Authorization', `Bearer ${authToken}`);
expect(response.status).toBe(200);
expect(response.body.success).toBe(true);
expect(Array.isArray(response.body.data)).toBe(true);
});
test('查询已执行列表', async () => {
const response = await request(BASE_URL)
.get('/api/executions/executed')
.set('Authorization', `Bearer ${authToken}`);
expect(response.status).toBe(200);
expect(response.body.success).toBe(true);
expect(Array.isArray(response.body.data)).toBe(true);
});
});
});