| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- 'use strict';
- const assert = require('node:assert/strict');
- const { queryBilling } = require('../mcp/src/core/billing-client');
- const { requestPaymentQr } = require('../mcp/src/core/recharge-client');
- async function main() {
- const originalFetch = global.fetch;
- let billingCalls = 0;
- global.fetch = async (url, options) => {
- if (/\/api\/fmode\/billing\/query$/.test(String(url))) {
- billingCalls += 1;
- assert.equal(options.method, 'POST');
- assert.match(options.headers.Authorization, /^Bearer sk-test$/);
- return new Response(JSON.stringify({
- code: 200,
- data: {
- balance: { availableQuota: 1000 },
- // NewAPI-key authentication intentionally omits this Session-bound
- // link. The client must build it locally from the current Session.
- balanceUrl: null,
- estimate: {
- quota: 2000,
- amountCny: 1,
- shortfallQuota: 1000,
- suggestedRechargeCny: 1.1,
- sufficient: false,
- operations: []
- },
- catalog: []
- }
- }), { status: 200, headers: { 'content-type': 'application/json' } });
- }
- if (/\/api\/fmode\/recharge\/order$/.test(String(url))) {
- assert.equal(options.method, 'POST');
- assert.match(String(options.body || ''), /sessionToken/);
- return new Response(JSON.stringify({ code: 200, data: { tradeNo: 'trade-query' } }), { status: 200 });
- }
- assert.match(String(url), /\/parse\/functions\/pay_code2$/);
- assert.equal(options.method, 'POST');
- assert.match(options.headers['X-Parse-Session-Token'], /^r:/);
- return new Response(JSON.stringify({ result: { code_url: ['weixin://pay/query-test'], nonce_str: 'nonce-query' } }), { status: 200 });
- };
- const result = await queryBilling({
- newapiToken: 'sk-test',
- baseUrl: 'https://billing.example.test',
- operations: [{ model: 'voc-social', count: 1 }]
- });
- assert.equal(result.status, 'ok');
- if (result.recharge) {
- assert.equal(result.recharge.paymentMode, 'balance_url_and_payment_request');
- assert.equal(Object.prototype.hasOwnProperty.call(result.recharge.paymentRequest, 'headers'), false);
- assert.doesNotMatch(JSON.stringify(result), /r:[A-Za-z0-9_-]{8,}/);
- }
- const fallbackResult = await queryBilling({
- newapiToken: 'sk-test',
- sessionToken: 'r:session-test',
- baseUrl: 'https://billing.example.test',
- operations: [{ model: 'voc-social', count: 1 }]
- });
- assert.equal(fallbackResult.status, 'ok');
- assert.equal(fallbackResult.recharge.paymentMode, 'balance_url_and_payment_request');
- assert.match(fallbackResult.recharge.balanceUrl, /balance\/\?token=r%3Asession-test/);
- assert.match(fallbackResult.assistantMessage, /免登录余额页:https:\/\/app\.fmode\.cn\/dev\/studio\/balance/);
- assert.doesNotMatch(JSON.stringify(fallbackResult.recharge.paymentRequest), /r:[A-Za-z0-9_-]{8,}/);
- const qrResult = await queryBilling({
- newapiToken: 'sk-test',
- sessionToken: 'r:session-test',
- baseUrl: 'https://billing.example.test',
- createPaymentQr: true,
- operations: [{ model: 'voc-social', count: 1 }]
- });
- assert.equal(qrResult.status, 'ok');
- assert.equal(qrResult.recharge.paymentMode, 'qr_and_balance_url');
- assert.equal(qrResult.recharge.qrCodeUrl, 'weixin://pay/query-test');
- assert.equal(qrResult.recharge.paymentRequest.nonceStr, 'nonce-query');
- assert.doesNotMatch(JSON.stringify(qrResult.recharge.paymentRequest), /r:[A-Za-z0-9_-]{8,}/);
- const qr = await requestPaymentQr({
- amount: 2,
- sessionToken: 'r:session-test',
- fetchImpl: async (_url, options) => {
- if (String(_url).endsWith('/api/fmode/recharge/order')) {
- assert.equal(options.method, 'POST');
- return new Response(JSON.stringify({ code: 200, data: { tradeNo: 'trade-qr' } }), { status: 200 });
- }
- assert.match(options.headers['X-Parse-Session-Token'], /^r:/);
- assert.equal(options.headers['X-Parse-Application-Id'], 'ncloudmaster');
- return new Response(JSON.stringify({ result: { code_url: ['weixin://pay/test'], nonce_str: 'nonce' } }), { status: 200 });
- }
- });
- assert.equal(qr.qrCodeUrl, 'weixin://pay/test');
- assert.equal(qr.amountCny, 2);
- global.fetch = originalFetch;
- console.log('billing-client smoke passed');
- }
- main().catch(error => {
- console.error(error);
- process.exitCode = 1;
- });
|