Files
qipai/backend/tests/profit-sharing.test.mjs
T
2026-06-22 17:25:33 +08:00

135 lines
3.9 KiB
JavaScript

import assert from 'node:assert/strict';
import { generateKeyPairSync } from 'node:crypto';
import { buildApp } from '../dist/app.js';
import { loadConfig } from '../dist/config.js';
import { signAccessToken } from '../dist/auth/jwt.js';
import { WechatPayClient } from '../dist/payments/wechat-pay-client.js';
assert.equal(loadConfig({
NODE_ENV: 'production',
QIPAI_MQTT_USERNAME: 'backend-test',
QIPAI_MQTT_PASSWORD: 'not-a-real-secret',
QIPAI_JWT_SECRET: 'production-profit-share-secret-long-enough',
QIPAI_PROFIT_SHARE_MOCK_ENABLED: 'true'
}).payment.profitShareMockEnabled, false);
assert.equal(loadConfig({
NODE_ENV: 'test',
QIPAI_PROFIT_SHARE_MOCK_ENABLED: 'true'
}).payment.profitShareMockEnabled, true);
const keys = generateKeyPairSync('rsa', {
modulusLength: 2048,
publicKeyEncoding: { type: 'spki', format: 'pem' },
privateKeyEncoding: { type: 'pkcs8', format: 'pem' }
});
let apiRequest;
const client = new WechatPayClient({
async request(input) {
apiRequest = input;
return {
status: 200,
headers: {},
body: JSON.stringify({ order_id: 'wx-share-order', state: 'FINISHED' })
};
}
});
const shareResult = await client.createProfitSharing({
appId: 'wx-test',
merchantId: '1900000109',
serialNo: 'serial-test',
privateKeyPem: keys.privateKey,
apiV3Key: '0123456789abcdef0123456789abcdef',
platformCertificates: {},
profitShareReceivers: {}
}, {
transactionId: 'wx-transaction-001',
outOrderNo: 'share-request-001',
receivers: [{
type: 'MERCHANT_ID',
account: 'receiver-account-private',
amountCents: 1200,
description: 'sanitized share'
}],
finish: true
});
assert.equal(shareResult.state, 'FINISHED');
assert.match(apiRequest.url, /\/v3\/profitsharing\/orders$/);
assert.match(apiRequest.body, /"amount":1200/);
assert.equal(apiRequest.headers.Authorization.includes(keys.privateKey), false);
const secret = 'profit-sharing-route-secret-32-characters';
const token = signAccessToken({
sub: '21', sid: '5c4d3af8-c63c-4edb-bf95-b84127bb3f6e',
tid: '7', aid: '9', rv: 1
}, secret, 900);
let executeInput;
const app = await buildApp({
payment: {
jwtSecret: secret,
testAdapterEnabled: false,
authRepository: {
async validateSession() {
return {
id: '5c4d3af8-c63c-4edb-bf95-b84127bb3f6e',
tenantId: '7', platformAppId: '9',
expiresAt: new Date(Date.now() + 60000),
user: {
id: '21', tenantId: '7', userType: 'ADMIN', status: 'ACTIVE',
roleVersion: 1, nickname: '', avatarUrl: '', phone: ''
}
};
}
},
accessControl: {
async getAccessProfile() {
return {
roles: ['TENANT_ADMIN'],
capabilities: ['tenant.manage'],
storeIds: []
};
}
},
repository: {
async createPayment() { return {}; },
async processTestCallback() { return {}; }
},
profitSharing: {
async saveCollectionAccount() {
return { accountId: '41', created: true };
},
async saveReceiver() {
return { receiverId: '42', created: true };
},
async savePolicy() {
return { saved: true };
},
async execute(input) {
executeInput = input;
return {
shares: [{ shareId: '43', amountCents: 1200, status: 'SUCCEEDED' }],
idempotent: false
};
},
async list() {
return { accounts: [], shares: [] };
}
}
}
});
const executed = await app.inject({
method: 'POST',
url: '/admin-api/pay/profit-shares',
headers: { authorization: `Bearer ${token}` },
payload: {
paymentId: '31',
clientRequestId: 'share-request-001',
mode: 'MOCK'
}
});
assert.equal(executed.statusCode, 200);
assert.equal(executeInput.tenantId, '7');
assert.equal(executeInput.access.capabilities[0], 'tenant.manage');
await app.close();
console.log('PASS: M05-D Wechat profit-sharing request, production mock gate and admin routes.');