import test from 'node:test'; import assert from 'node:assert/strict'; import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; const adminRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); const billingPagePath = path.join( adminRoot, 'src/pages/settings/billing/index.tsx' ); const billingLocalePath = path.join( adminRoot, 'src/pages/settings/billing/locale/index.ts' ); const mainLocalePath = path.join(adminRoot, 'src/locale/index.ts'); function readPage(): string { assert.ok(fs.existsSync(billingPagePath), '订阅账单页面必须存在'); return fs.readFileSync(billingPagePath, 'utf-8'); } function readLocale(): string { assert.ok(fs.existsSync(billingLocalePath), '订阅账单语言包必须存在'); return fs.readFileSync(billingLocalePath, 'utf-8'); } function assertNoFabricatedCheckoutUrl(content: string, label: string) { assert.ok(!content.includes('cs_test_'), `${label}禁止前端自造 cs_test_`); assert.ok( !content.includes('https://checkout.stripe.com'), `${label}禁止前端自造完整 checkout URL` ); assert.ok(!content.includes('sk_live'), `${label}禁止出现 sk_live`); } function assertNoFakePayPalCheckout(content: string, label: string) { assert.ok( !/paypal\.com/i.test(content), `${label}禁止出现 paypal.com 假结账地址` ); assert.ok( !/www\.paypal\.com/i.test(content), `${label}禁止出现 www.paypal.com` ); assert.ok( !content.includes('paypal-checkout') && !content.includes('billing/paypal'), `${label}禁止伪造 PayPal 结账接口` ); } test('1. settings/billing 必须请求 billing/currentPlan', () => { const content = readPage(); assert.ok( content.includes('billing/currentPlan'), '必须请求 POST /api/admin/team/billing/currentPlan' ); assert.ok( content.includes('admin/team/billing/currentPlan'), '必须请求完整后台路径 /api/admin/team/billing/currentPlan' ); assert.ok(content.includes('axios'), '必须使用 axios 发请求'); assert.ok( content.includes('{}'), '进入页必须 POST currentPlan {}' ); assert.ok( content.includes("from '@arco-design/web-react'"), '必须从 @arco-design/web-react 引入组件' ); assert.ok( content.includes('code === 1000') || content.includes('code ===1000'), '必须按 Cool-Admin code === 1000 判断成功' ); assert.ok(content.includes('Message.error'), '失败必须使用 Arco Message.error'); assert.ok(content.includes('BillingQuota'), '必须使用 BillingQuota 类型'); assert.ok(content.includes('TenantPlanType'), '必须使用 TenantPlanType 类型'); assert.ok(content.includes("from '@/types/omni'"), '必须复用 admin/src/types/omni.ts'); assert.ok( !content.includes('Mock.js') && !content.includes("from 'mockjs'"), '禁止用 Mock.js 假数据冒充成功' ); assert.ok(!/\bany\b/.test(content), '禁止使用 any'); assertNoFabricatedCheckoutUrl(content, '页面'); assertNoFakePayPalCheckout(content, '页面'); }); test('2. settings/billing 必须使用 Card / Progress / Tag', () => { const content = readPage(); assert.ok(content.includes('Card'), '必须使用 Arco Card'); assert.ok(content.includes('Progress'), '必须使用 Arco Progress'); assert.ok(content.includes('Tag'), '必须使用 Arco Tag'); assert.ok(content.includes('Alert'), '必须使用 Arco Alert 说明后续接入'); assert.ok(content.includes('planType'), 'Card 必须展示 planType'); assert.ok(content.includes('seatsUsed'), 'Progress 必须展示 seatsUsed'); assert.ok(content.includes('seatsLimit'), 'Progress 必须展示 seatsLimit'); assert.ok(content.includes('cardsUsed'), 'Progress 必须展示 cardsUsed'); assert.ok(content.includes('cardsLimit'), 'Progress 必须展示 cardsLimit'); assert.ok(content.includes("'free'"), '必须说明 free 套餐'); assert.ok(content.includes("'pro'"), '必须说明 pro 套餐'); assert.ok(content.includes("'enterprise'"), '必须说明 enterprise 套餐'); assert.ok(content.includes('lightColors'), '颜色必须引用 lightColors token'); assert.ok(content.includes('type="primary"'), '必须有一个主 CTA 刷新配额'); assert.ok( !/#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})\b/.test(content), '禁止硬编码颜色' ); assert.ok( !content.includes('#000') && !content.includes('#000000'), '禁止纯黑' ); assert.ok( !content.includes('Mock.js') && !content.includes("from 'mockjs'"), '禁止用 Mock.js' ); assert.ok(!/\bany\b/.test(content), '禁止使用 any'); assertNoFabricatedCheckoutUrl(content, '页面'); assertNoFakePayPalCheckout(content, '页面'); }); test('3. settings/billing locale 必须包含 menu.settings.billing', () => { const content = readLocale(); assert.ok( content.includes("'menu.settings.billing'"), '页面语言包必须包含 menu.settings.billing' ); assert.ok(content.includes("'en-US'"), '必须包含英文案'); assert.ok(content.includes("'zh-CN'"), '必须包含中文案'); assert.ok(content.includes("'ar-SA'"), '必须包含阿语文案'); assert.ok( content.includes('settingsBilling.request.fail'), '必须包含失败提示文案' ); assert.ok( content.includes('settingsBilling.action.refresh'), '必须包含刷新配额主 CTA 文案' ); assert.ok( content.includes('settingsBilling.alert'), '必须包含国际卡与发票后续接入提示' ); assert.ok( content.includes('settingsBilling.checkout.stripeMissing'), '必须包含未配置 Stripe 无法打开支付的 i18n' ); assert.ok( content.includes('settingsBilling.action.upgrade'), '必须包含升级/结账文案' ); assert.ok( content.includes('settingsBilling.checkout.paypalUnavailable'), '必须包含 PayPal 暂不可用文案 key' ); assert.ok( content.includes('settingsBilling.action.paypal'), '必须包含 PayPal 按钮文案 key' ); assert.ok(!/\bany\b/.test(content), 'locale 禁止使用 any'); assert.ok( !/[\u{1F300}-\u{1F9FF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}]/u.test(content), 'locale 禁止使用 emoji' ); assertNoFabricatedCheckoutUrl(content, 'locale'); assertNoFakePayPalCheckout(content, 'locale'); const mainLocale = fs.readFileSync(mainLocalePath, 'utf-8'); assert.ok( /'en-US'[\s\S]*'menu\.settings\.billing':\s*'Billing'/.test(mainLocale), '主词典 en-US menu.settings.billing 应为 Billing' ); assert.ok( /'zh-CN'[\s\S]*'menu\.settings\.billing':\s*'订阅账单'/.test(mainLocale), '主词典 zh-CN menu.settings.billing 应为 订阅账单' ); }); test('4. settings/billing 升级结账仅信任 Stripe 结账域', () => { const content = readPage(); const locale = readLocale(); assert.ok( content.includes('stripe-checkout') || content.includes('billing/stripe-checkout'), '必须请求 POST /api/admin/team/billing/stripe-checkout' ); assert.ok(content.includes('window.open'), '成功时必须 window.open 打开结账页'); assert.ok(content.includes('Message.error'), '失败必须 Message.error'); assert.ok( content.includes('checkout.stripe.com'), '必须校验返回 url 主机为 checkout.stripe.com' ); assert.ok( content.includes("protocol === 'https:'") || content.includes('protocol === "https:"') || content.includes("protocol==='https:'"), '必须校验返回 url 协议为 https' ); assert.ok( content.includes('settingsBilling.checkout.stripeMissing'), '缺服务端文案时必须回退到 Stripe 未配置 i18n' ); assert.ok( locale.includes("'settingsBilling.checkout.stripeMissing'"), 'locale 必须声明 Stripe 未配置文案 key' ); assert.ok( /'zh-CN'[\s\S]*settingsBilling\.checkout\.stripeMissing'[\s\S]*未配置 Stripe/.test( locale ), '中文案必须含「未配置 Stripe」' ); assert.ok( /'en-US'[\s\S]*settingsBilling\.checkout\.stripeMissing'/.test(locale), '英文案必须含 Stripe missing 提示' ); assert.ok( /'ar-SA'[\s\S]*settingsBilling\.checkout\.stripeMissing'/.test(locale), '阿语文案必须含 Stripe missing 提示' ); assertNoFabricatedCheckoutUrl(content, '结账逻辑'); assertNoFakePayPalCheckout(content, '结账逻辑'); assert.ok(!/\bany\b/.test(content), '结账逻辑禁止 any'); }); test('5. settings/billing PayPal 按钮必须禁用且不可假结账', () => { const content = readPage(); const locale = readLocale(); assert.ok( content.includes('settingsBilling.action.paypal'), '页面必须渲染 PayPal 按钮文案' ); assert.ok( content.includes('settingsBilling.checkout.paypalUnavailable'), '页面必须展示 PayPal 暂不可用说明' ); assert.ok( /disabled(\s*=\s*\{?\s*true\s*\}?)?/.test(content) || content.includes('disabled={true}') || content.includes('disabled'), 'PayPal 按钮必须 disabled' ); assert.ok( !content.includes('Message.success'), 'PayPal 点击不得 Message.success' ); assert.ok( !content.includes('window.open') || content.includes('isTrustedStripeCheckoutUrl'), 'window.open 仅允许用于受信 Stripe URL' ); assert.ok( !content.includes('paypal-checkout') && !content.includes('billing/paypal'), '禁止请求不存在的 PayPal 结账接口' ); assert.ok( locale.includes("'settingsBilling.action.paypal'"), 'locale 必须声明 PayPal 按钮文案' ); assert.ok( locale.includes("'settingsBilling.checkout.paypalUnavailable'"), 'locale 必须声明 PayPal 暂不可用文案' ); assert.ok( /'zh-CN'[\s\S]*settingsBilling\.checkout\.paypalUnavailable'[\s\S]*暂不可用/.test( locale ), '中文案必须说明 PayPal 暂不可用' ); assert.ok( /'en-US'[\s\S]*settingsBilling\.checkout\.paypalUnavailable'[\s\S]*(unavailable|not available|temporarily)/i.test( locale ), '英文案必须说明 PayPal 暂不可用' ); assert.ok( /'ar-SA'[\s\S]*settingsBilling\.checkout\.paypalUnavailable'/.test(locale), '阿语文案必须含 PayPal 暂不可用提示' ); assertNoFakePayPalCheckout(content, 'PayPal 按钮'); assertNoFakePayPalCheckout(locale, 'PayPal locale'); assert.ok(!/\bany\b/.test(content), 'PayPal 逻辑禁止 any'); });