Files
go_bt/tests/account_refund_status.test.js

107 lines
5.7 KiB
JavaScript

'use strict';
const assert = require('assert');
const fs = require('fs');
const os = require('os');
const path = require('path');
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'account-refund-status-'));
const Config = require('../src/core/config');
Config.DATA_DIR = tempDir;
Config.DB_PATH = path.join(tempDir, 'accounts.db');
const database = require('../src/core/database');
try {
database.initDB();
const columns = database.getDb().pragma('table_info(accounts)').map(row => row.name);
assert(columns.includes('account_refund_status'), '账号表应包含 account_refund_status');
assert(columns.includes('refund_process_status'), '账号表应包含独立的 refund_process_status');
database.upsertAccount({ email: 'default@example.com' });
assert.strictEqual(
database.getAccount('default@example.com').account_refund_status,
'无状态',
'新账号退款状态应默认为无状态',
);
assert.strictEqual(
database.getAccount('default@example.com').refund_process_status,
'未发起',
'新账号退款流程状态应默认为未发起',
);
assert.strictEqual(database.updateAccountRefundProcessStatus('default@example.com', '已发起'), true);
assert.strictEqual(database.getAccount('default@example.com').refund_process_status, '已发起');
assert.strictEqual(database.updateAccountRefundProcessStatus('default@example.com', '发起失败'), true);
assert.strictEqual(database.getAccount('default@example.com').refund_process_status, '发起失败');
database.upsertAccount({ email: 'refunded@example.com', account_refund_status: '已退款' });
assert.strictEqual(database.getAccount('refunded@example.com').account_refund_status, '已退款');
database.upsertAccount({ email: 'refunded@example.com', account_refund_status: '' });
assert.strictEqual(
database.getAccount('refunded@example.com').account_refund_status,
'无状态',
'空退款状态应恢复默认值',
);
assert.strictEqual(database.updateAccountRefundStatus('refunded@example.com', '未操作'), true);
assert.strictEqual(
database.getAccount('refunded@example.com').account_refund_status,
'无状态',
'未操作应统一保存为无状态',
);
assert.strictEqual(database.updateAccountRefundStatus('refunded@example.com', '已申请退款'), true);
assert.strictEqual(database.getAccount('refunded@example.com').account_refund_status, '已申请退款');
const staged = database.stageAccounts(
['refunded@example.com'],
'退款状态导出',
['email', 'account_refund_status'],
);
const stagedDetail = database.getStagingBatch(staged.batchId);
assert.deepStrictEqual(
JSON.parse(stagedDetail.batch.selected_fields),
['email', 'account_refund_status'],
'暂存箱导出应保留账号退款字段',
);
const html = fs.readFileSync(path.join(__dirname, '..', 'public', 'index.html'), 'utf8');
const customerColumn = html.indexOf('<th>客户名</th>');
const refundColumn = html.indexOf('<th>账号退款</th>');
const refundProcessColumn = html.indexOf('<th>是否已发起退款流程</th>');
const statusColumn = html.indexOf('<th>状态</th>');
assert(customerColumn >= 0
&& refundColumn > customerColumn
&& refundProcessColumn > refundColumn
&& statusColumn > refundProcessColumn,
'独立退款流程状态列应位于账号退款右侧');
assert(html.includes("account.account_refund_status || '无状态'"), '列表空退款状态应显示无状态');
assert(html.includes("account.refund_process_status || '未发起'"), '列表空退款流程状态应显示未发起');
assert(html.includes('startInlineEditAccountRefund(account.email)'), '账号退款列应支持双击编辑');
assert(html.includes('startInlineEditRefundProcess(account.email)'), '退款流程状态列应支持双击编辑');
const inlineRefundProcessSelect = html.match(/<template x-if="inlineEditRefundProcessEmail === account\.email">([\s\S]*?)<\/template>/);
assert(inlineRefundProcessSelect, '退款流程状态列应渲染原地下拉编辑器');
for (const status of ['未发起', '已发起', '发起失败']) {
assert(inlineRefundProcessSelect[1].includes(`<option value="${status}">${status}</option>`),
`退款流程状态编辑器应包含:${status}`);
}
const inlineRefundSelect = html.match(/<template x-if="inlineEditAccountRefundEmail === account\.email">([\s\S]*?)<\/template>/);
assert(inlineRefundSelect && inlineRefundSelect[1].includes('<option value="无状态">无状态</option>'),
'账号退款编辑器必须预先渲染无状态选项,避免动态选项导致初始值错误');
assert(!inlineRefundSelect[1].includes('x-for="status in accountRefundStatusOptions"'),
'账号退款编辑器不能在 select 赋值后再异步生成 option');
const appSource = fs.readFileSync(path.join(__dirname, '..', 'public', 'app.js'), 'utf8');
const routeSource = fs.readFileSync(path.join(__dirname, '..', 'src', 'routes', 'accounts.js'), 'utf8');
assert(appSource.includes('/refund-process-status'), '前端应调用退款流程状态专用保存接口');
assert(routeSource.includes("router.put('/:email/refund-process-status'"), '服务端应提供退款流程状态专用保存接口');
for (const status of [
'无状态', '已退款', '未退款', '退款失败', '已申请退款', 'google封号无法查询',
'gpt封号退款失败', 'gpt警告', '已被改密无法查询', '已被改2FA无法查询',
'需要手机号查询', '无订阅',
]) {
assert(appSource.includes(`'${status}'`), `前端应包含退款状态:${status}`);
}
console.log('account_refund_status.test.js: PASS');
} finally {
try { database.getDb().close(); } catch (_) {}
fs.rmSync(tempDir, { recursive: true, force: true });
}