From ce9944c316f0a47f1d4a3226ab82bff47ecbd935 Mon Sep 17 00:00:00 2001
From: lzt404 <2596933790@qq.com>
Date: Mon, 7 Sep 2026 18:14:51 +0800
Subject: [PATCH] fix: remove xAI availability testing
- Remove test buttons from credential and quota pages
- Delete paid probe requests, confirmations, and result feedback
- Clean up related translations and obsolete button hints
- Preserve quota queries and update tests to verify no paid probes occur
---
src/components/QuotaActionFeedback.tsx | 4 +--
src/i18n/ja.ts | 14 +----------
src/i18n/locales/en.ts | 14 +----------
src/i18n/locales/zh-CN.ts | 14 +----------
src/pages/AuthFileManagementPage.tsx | 18 +-------------
src/pages/QuotaPage.tsx | 23 +++--------------
src/services/quotaActions.ts | 11 +++------
src/services/quotaService.ts | 34 ++------------------------
tests/quotaConfirmation.test.ts | 11 +--------
tests/quotaRendering.test.tsx | 6 +++--
tests/quotaRequests.test.ts | 24 +++---------------
tests/quotaService.test.ts | 6 ++---
12 files changed, 25 insertions(+), 154 deletions(-)
diff --git a/src/components/QuotaActionFeedback.tsx b/src/components/QuotaActionFeedback.tsx
index 6f9e67e..8c55dfb 100644
--- a/src/components/QuotaActionFeedback.tsx
+++ b/src/components/QuotaActionFeedback.tsx
@@ -7,9 +7,7 @@ export function QuotaActionFeedback({ quota }: { quota: QuotaState }) {
const result = quota.actionResult;
if (!result) return null;
const successful = result.status === 'success';
- const message = result.action === 'probe'
- ? t(successful ? 'quota.probe.success' : 'quota.probe.failed', { error: result.error ?? '' })
- : t(successful ? 'quota.resetResult.submitted' : result.status === 'refresh-error'
+ const message = t(successful ? 'quota.resetResult.submitted' : result.status === 'refresh-error'
? 'quota.resetResult.refreshFailed' : 'quota.resetResult.failed', { error: result.error ?? '' });
return (
diff --git a/src/i18n/ja.ts b/src/i18n/ja.ts
index 32502bd..19dd79c 100644
--- a/src/i18n/ja.ts
+++ b/src/i18n/ja.ts
@@ -186,16 +186,8 @@ export const jaOverrides = {
'quota.empty.description': 'まず認証ファイルにクォータ照会対応の認証情報を追加してください。',
'quota.unknownProvider': '不明',
'common.confirm': '確認',
- 'quota.probe.button': '利用可否をテスト',
- 'quota.probe.title': 'xAI 有料 API のテスト',
- 'quota.probe.confirm': '「{name}」の有料 API の利用可否をテストしますか?',
- 'quota.probe.confirmButton': 'テストを実行',
- 'quota.probe.running': '利用可否をテスト中…',
- 'quota.probe.success': '利用可否のテストに成功しました。残りのクォータは取得されません。',
- 'quota.probe.failed': '利用可否のテストに失敗しました:{error}',
'quota.service.xaiPaidAccount': '有料 API アカウント',
- 'quota.service.xaiPaidQuotaUnavailable': 'このアカウントの残りクォータは提供されていません。接続の確認は「利用可否をテスト」から実行してください。',
- 'quota.service.error.xaiProbeOnly': 'この利用可否テストは xAI 認証情報のみをサポートします',
+ 'quota.service.xaiPaidQuotaUnavailable': 'このアカウントの残りクォータは提供されていません。',
'quota.confirm.button': 'リセットを実行',
'quota.confirm.applicableLabel': '現在適用可能な回数',
'quota.resetting': 'リセットを送信してクォータを更新中…',
@@ -218,11 +210,7 @@ export const jaOverrides = {
'quota.subscriptionExpiry': 'サブスクリプション期限:{time}',
'quota.resetApplicable': '現在適用可能:{count} 回',
'quota.resetCreditsWarning': 'リセット回数の詳細取得に失敗:{error}',
- 'quota.xaiProbeConfirm': '最小限の grok-4.5 リクエストを 1 回送信し、少額の料金が発生する可能性があります。利用可否のみをテストし、残りのクォータは取得しません。',
'quota.service.window.sevenDayFable': '7 日間 Fable 枠',
- 'quota.service.xaiPaidHealth': '有料 API 利用可能',
- 'quota.service.xaiPaidHealthDetail': '短い会話テストに成功。残りクォータは提供されていません',
- 'quota.service.error.xaiProbeRequired': '有料 API テストには確認が必要です。課金リクエストは送信していません',
'quota.service.error.resetCreditsInvalid': 'リセット回数 API のデータ形式を認識できません',
'quota.confirm.title': '「{name}」の Codex クォータをリセットしますか?',
'quota.confirm.cost': 'この操作では手動リセットを 1 回消費します。',
diff --git a/src/i18n/locales/en.ts b/src/i18n/locales/en.ts
index 2dc6268..f37c966 100644
--- a/src/i18n/locales/en.ts
+++ b/src/i18n/locales/en.ts
@@ -173,16 +173,8 @@ export const en: Record
= {
'quota.empty.description': 'Add a credential that supports quota queries under Auth Files first.',
'quota.unknownProvider': 'Unknown',
'common.confirm': 'Confirm',
- 'quota.probe.button': 'Test Availability',
- 'quota.probe.title': 'Test xAI Paid API',
- 'quota.probe.confirm': 'Test paid API availability for "{name}"?',
- 'quota.probe.confirmButton': 'Confirm Test',
- 'quota.probe.running': 'Testing availability…',
- 'quota.probe.success': 'Availability test passed; this test does not report remaining quota.',
- 'quota.probe.failed': 'Availability test failed: {error}',
'quota.service.xaiPaidAccount': 'Paid API account',
- 'quota.service.xaiPaidQuotaUnavailable': 'Remaining quota is not provided for this account. Use Test Availability separately to check the connection.',
- 'quota.service.error.xaiProbeOnly': 'This availability test only supports xAI credentials',
+ 'quota.service.xaiPaidQuotaUnavailable': 'Remaining quota is not provided for this account.',
'quota.confirm.button': 'Confirm Reset',
'quota.confirm.applicableLabel': 'Currently applicable resets',
'quota.resetting': 'Submitting reset and refreshing quota…',
@@ -205,11 +197,7 @@ export const en: Record = {
'quota.subscriptionExpiry': 'Subscription expires: {time}',
'quota.resetApplicable': 'Currently applicable: {count}',
'quota.resetCreditsWarning': 'Reset credit details unavailable: {error}',
- 'quota.xaiProbeConfirm': 'This sends one minimal grok-4.5 request and may incur a small charge. It only tests availability and does not report remaining quota.',
'quota.service.window.sevenDayFable': '7-day Fable window',
- 'quota.service.xaiPaidHealth': 'Paid API available',
- 'quota.service.xaiPaidHealthDetail': 'Tiny chat probe succeeded; remaining quota is not provided',
- 'quota.service.error.xaiProbeRequired': 'Paid API health probing requires confirmation; no billable request was sent',
'quota.service.error.resetCreditsInvalid': 'The reset credits endpoint returned unrecognized data',
'quota.confirm.title': 'Reset the Codex quota for “{name}”?',
'quota.confirm.cost': 'This will consume one manual reset credit.',
diff --git a/src/i18n/locales/zh-CN.ts b/src/i18n/locales/zh-CN.ts
index 0019067..0c4f5fe 100644
--- a/src/i18n/locales/zh-CN.ts
+++ b/src/i18n/locales/zh-CN.ts
@@ -172,16 +172,8 @@ export const zhCN = {
'quota.empty.description': '先在凭证文件中添加支持配额查询的凭据。',
'quota.unknownProvider': '未知',
'common.confirm': '确认',
- 'quota.probe.button': '测试可用性',
- 'quota.probe.title': '测试 xAI 付费 API',
- 'quota.probe.confirm': '确认测试“{name}”的付费 API 可用性吗?',
- 'quota.probe.confirmButton': '确认测试',
- 'quota.probe.running': '正在测试可用性…',
- 'quota.probe.success': '可用性测试通过;此操作不提供剩余额度。',
- 'quota.probe.failed': '可用性测试失败:{error}',
'quota.service.xaiPaidAccount': '付费 API 账号',
- 'quota.service.xaiPaidQuotaUnavailable': '此账号不提供剩余额度。如需检测连接,请单独点击“测试可用性”。',
- 'quota.service.error.xaiProbeOnly': '只有 xAI 凭证支持此可用性测试',
+ 'quota.service.xaiPaidQuotaUnavailable': '此账号不提供剩余额度。',
'quota.confirm.button': '确认重置',
'quota.confirm.applicableLabel': '当前适用次数',
'quota.resetting': '正在提交重置并刷新额度…',
@@ -204,11 +196,7 @@ export const zhCN = {
'quota.subscriptionExpiry': '订阅到期:{time}',
'quota.resetApplicable': '当前适用:{count} 次',
'quota.resetCreditsWarning': '重置次数详情查询失败:{error}',
- 'quota.xaiProbeConfirm': '将发送一次极短的 grok-4.5 请求,可能产生少量费用。此操作仅测试可用性,不会返回剩余额度。',
'quota.service.window.sevenDayFable': '7 天 Fable 窗口',
- 'quota.service.xaiPaidHealth': '付费 API 可用',
- 'quota.service.xaiPaidHealthDetail': '极短对话探测成功;上游未提供剩余额度',
- 'quota.service.error.xaiProbeRequired': '付费 API 可用性探测需要确认,尚未发送计费请求',
'quota.service.error.resetCreditsInvalid': '重置次数接口返回了无法识别的数据',
'quota.confirm.title': '确认重置“{name}”的 Codex 额度吗?',
'quota.confirm.cost': '本操作将消耗 1 次主动重置机会。',
diff --git a/src/pages/AuthFileManagementPage.tsx b/src/pages/AuthFileManagementPage.tsx
index 53a4713..5e97a87 100644
--- a/src/pages/AuthFileManagementPage.tsx
+++ b/src/pages/AuthFileManagementPage.tsx
@@ -1,7 +1,6 @@
import { ChangeEvent, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useConfirmation } from '../components/ConfirmationDialog';
import { QuotaActionFeedback } from '../components/QuotaActionFeedback';
-import { probeXaiWithConfirmation } from '../services/quotaActions';
import { InlineNotice, useAppNotice } from '../appNotice';
import { AuthFileModelsDialog } from '../components/AuthFileModelsDialog';
import {
@@ -121,7 +120,7 @@ function AuthFileQuotaSummary({ quota }: { quota: QuotaState }) {
return (
- {t(quota.pendingAction === 'probe' ? 'quota.probe.running' : 'authFiles.quota.loading')}
+ {t('authFiles.quota.loading')}
);
}
@@ -235,20 +234,6 @@ export function AuthFileManagementPage() {
});
};
- const probeXai = async (file: AuthFile) => {
- setError('');
- try {
- await probeXaiWithConfirmation(file, () => askConfirmation({
- title: t('quota.probe.title'),
- message: t('quota.probe.confirm', { name: fileName(file) }),
- warning: t('quota.xaiProbeConfirm'),
- confirmText: t('quota.probe.confirmButton'),
- }));
- } catch (requestError) {
- setError(String(requestError));
- }
- };
-
const closeOauthModels = () => {
if (oauthModelSaveRef.current) return;
oauthModelRequestRef.current += 1;
@@ -558,7 +543,6 @@ export function AuthFileManagementPage() {
{quotaProviderForFile(file) && !disabled ?
: null}
- {quotaProviderForFile(file) === 'xai' ?
: null}
{providerKey(file) ?
: null}
{providerKey(file) ?
: null}
diff --git a/src/pages/QuotaPage.tsx b/src/pages/QuotaPage.tsx
index 8bb5d6b..4978fd6 100644
--- a/src/pages/QuotaPage.tsx
+++ b/src/pages/QuotaPage.tsx
@@ -2,7 +2,7 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
import { AlertCircle, LoaderCircle, RefreshCw } from 'lucide-react';
import { useConfirmation } from '../components/ConfirmationDialog';
import { QuotaActionFeedback } from '../components/QuotaActionFeedback';
-import { canResetCodexQuota, probeXaiWithConfirmation, resetCodexQuotaWithConfirmation } from '../services/quotaActions';
+import { canResetCodexQuota, resetCodexQuotaWithConfirmation } from '../services/quotaActions';
import antigravityIcon from '../assets/icons/antigravity.svg';
import claudeIcon from '../assets/icons/claude.svg';
import codexIcon from '../assets/icons/codex.svg';
@@ -112,20 +112,6 @@ export function QuotaPage() {
}
}, [askConfirmation, locale, t]);
- const probeXai = useCallback(async (file: AuthFile) => {
- setError('');
- try {
- await probeXaiWithConfirmation(file, () => askConfirmation({
- title: t('quota.probe.title'),
- message: t('quota.probe.confirm', { name: fileName(file) }),
- warning: t('quota.xaiProbeConfirm'),
- confirmText: t('quota.probe.confirmButton'),
- }));
- } catch (requestError) {
- setError(String(requestError));
- }
- }, [askConfirmation, t]);
-
const refreshAll = useCallback(async () => {
if (Object.values(getQuotaCacheSnapshot()).some((quota) => quota.status === 'loading')) return;
setRefreshing(true);
@@ -192,7 +178,7 @@ export function QuotaPage() {
{grouped.map(([provider, items]) => (

{providerMeta[provider].label}
{t(items.length === 1 ? 'quota.credentials.one' : 'quota.credentials.other', { count: items.length })}
- {items.map(({ file, quota }) => void refreshOne(file)} onReset={provider === 'codex' ? () => void resetCodexQuota(file, quota) : undefined} onProbe={provider === 'xai' ? () => void probeXai(file) : undefined} />)}
+ {items.map(({ file, quota }) => void refreshOne(file)} onReset={provider === 'codex' ? () => void resetCodexQuota(file, quota) : undefined} />)}
))}
@@ -201,7 +187,7 @@ export function QuotaPage() {
);
}
-export function QuotaCard({ file, quota, onRefresh, onReset, onProbe }: { file: AuthFile; quota: QuotaState; onRefresh: () => void; onReset?: () => void; onProbe?: () => void }) {
+export function QuotaCard({ file, quota, onRefresh, onReset }: { file: AuthFile; quota: QuotaState; onRefresh: () => void; onReset?: () => void }) {
const { locale, t } = useI18n();
const now = useQuotaClock() + (quota.serverTimeOffsetMs ?? 0);
const provider = providerForFile(file);
@@ -213,13 +199,12 @@ export function QuotaCard({ file, quota, onRefresh, onReset, onProbe }: { file:
{name}{provider ? providerMeta[provider].label : t('quota.unknownProvider')}{quota.plan ? ' · ' + quota.plan : ''}
{onReset && (quota.resetCredits ?? 0) > 0 ? : null}
- {onProbe ? : null}
{quota.status === 'idle' ? {disabled ? t('quota.fileDisabled') : t('quota.notFetched')}
: null}
- {quota.status === 'loading' ? {t(quota.pendingAction === 'reset' ? 'quota.resetting' : quota.pendingAction === 'probe' ? 'quota.probe.running' : 'quota.querying')}
: null}
+ {quota.status === 'loading' ? {t(quota.pendingAction === 'reset' ? 'quota.resetting' : 'quota.querying')}
: null}
{quota.status === 'error' ? : null}
{quota.status === 'success' && provider === 'codex' ?
{t('quota.resetCredits')} {quota.resetCredits ?? '—'}
diff --git a/src/services/quotaActions.ts b/src/services/quotaActions.ts
index 4419fa0..1d9d9d4 100644
--- a/src/services/quotaActions.ts
+++ b/src/services/quotaActions.ts
@@ -6,7 +6,7 @@ import {
} from './quotaCache';
import { readBoolean } from './managementApi';
import {
- consumeCodexResetCredit, idleQuota, probeXaiAvailability, providerForFile, quotaKey,
+ consumeCodexResetCredit, idleQuota, providerForFile, quotaKey,
type AuthFile, type QuotaState,
} from './quotaService';
@@ -23,7 +23,7 @@ export const canResetCodexQuota = (file: AuthFile, quota: QuotaState): boolean =
async function runConfirmedQuotaAction(
file: AuthFile,
- action: 'reset' | 'probe',
+ action: 'reset',
confirmAction: () => Promise,
execute: (file: AuthFile) => Promise,
): Promise {
@@ -46,7 +46,7 @@ async function runConfirmedQuotaAction(
updateQuotaCache((current) => ({ ...current, [key]: pending! }));
const result = await execute(file);
if (result.status === 'error') {
- const status = action === 'reset' ? 'refresh-error' : 'error';
+ const status = 'refresh-error';
commit({ ...previous, actionResult: { action, status, error: result.error } });
return status;
}
@@ -65,8 +65,3 @@ export function resetCodexQuotaWithConfirmation(file: AuthFile, confirmReset: ()
if (!canResetCodexQuota(file, getQuotaCacheSnapshot()[quotaKey(file)] ?? idleQuota())) return Promise.resolve('cancelled');
return runConfirmedQuotaAction(file, 'reset', confirmReset, consumeCodexResetCredit);
}
-
-export function probeXaiWithConfirmation(file: AuthFile, confirmProbe: () => Promise): Promise {
- if (providerForFile(file) !== 'xai') return Promise.resolve('cancelled');
- return runConfirmedQuotaAction(file, 'probe', confirmProbe, probeXaiAvailability);
-}
diff --git a/src/services/quotaService.ts b/src/services/quotaService.ts
index 3fee422..4fbf68a 100644
--- a/src/services/quotaService.ts
+++ b/src/services/quotaService.ts
@@ -37,8 +37,8 @@ export type QuotaState = {
subscriptionActiveUntil?: string;
serverTimeOffsetMs?: number;
fetchedAt?: number;
- pendingAction?: 'reset' | 'probe';
- actionResult?: { action: 'reset' | 'probe'; status: 'success' | 'refresh-error' | 'error'; error?: string };
+ pendingAction?: 'reset';
+ actionResult?: { action: 'reset'; status: 'success' | 'refresh-error' | 'error'; error?: string };
};
export const idleQuota = (): QuotaState => ({ status: 'idle', rows: [] });
@@ -471,11 +471,6 @@ export const quotaRowsFor = (provider: QuotaProvider, payload: unknown): QuotaRo
remainingPercent: null,
detail: quotaText('quota.service.xaiPaidQuotaUnavailable'),
}];
- if (value.mode === 'paid-health') return [{
- label: quotaText('quota.service.xaiPaidHealth'),
- remainingPercent: null,
- detail: quotaText('quota.service.xaiPaidHealthDetail'),
- }];
const payloads = isRecord(value.weekly) || isRecord(value.monthly)
? [value.weekly, value.monthly]
: [value];
@@ -661,20 +656,6 @@ const requestQuotaPayload = async (
return parseBody(response.body ?? response.bodyText);
};
-const callXaiPaidHealth = async (authIndex: string): Promise => {
- const header = { Authorization: 'Bearer $TOKEN$', accept: 'application/json' };
- const [profile, chat] = await Promise.allSettled([
- requestQuotaPayload(authIndex, 'https://api.x.ai/v1/me', header, 'GET', undefined, 15_000),
- requestQuotaPayload(authIndex, 'https://api.x.ai/v1/chat/completions', {
- ...header, 'Content-Type': 'application/json',
- }, 'POST', JSON.stringify({
- model: 'grok-4.5', messages: [{ role: 'user', content: 'ping' }], max_tokens: 1, stream: false,
- }), 15_000),
- ]);
- if (chat.status === 'rejected') throw chat.reason;
- return { mode: 'paid-health', plan_type: 'Paid', profile: profile.status === 'fulfilled' ? profile.value : null };
-};
-
const callXaiQuota = async (file: AuthFile): Promise => {
const authIndex = normalizeAuthIndex(file.auth_index ?? file.authIndex);
if (!authIndex) throw new Error(quotaText('quota.service.error.missingAuthIndex'));
@@ -984,14 +965,3 @@ function runQuotaMutation(file: AuthFile, mutate: () => Promise): Pr
export function consumeCodexResetCredit(file: AuthFile): Promise {
return runQuotaMutation(file, () => consumeCodexResetCreditSnapshot(file));
}
-
-export function probeXaiAvailability(file: AuthFile): Promise {
- return runQuotaMutation(file, async () => {
- if (providerForFile(file) !== 'xai') throw new Error(quotaText('quota.service.error.xaiProbeOnly'));
- if (booleanValue(file.disabled) === true) throw new Error(quotaText('quota.fileDisabled'));
- const authIndex = normalizeAuthIndex(file.auth_index ?? file.authIndex);
- if (!authIndex) throw new Error(quotaText('quota.service.error.missingAuthIndex'));
- const payload = await callXaiPaidHealth(authIndex);
- return { status: 'success', rows: quotaRowsFor('xai', payload), plan: 'Paid', fetchedAt: Date.now() };
- });
-}
diff --git a/tests/quotaConfirmation.test.ts b/tests/quotaConfirmation.test.ts
index 15f17ca..d1e61d2 100644
--- a/tests/quotaConfirmation.test.ts
+++ b/tests/quotaConfirmation.test.ts
@@ -1,6 +1,6 @@
import { afterEach, beforeEach, describe, expect, it } from 'bun:test';
import { clearMocks, mockIPC } from '@tauri-apps/api/mocks';
-import { canResetCodexQuota, probeXaiWithConfirmation, resetCodexQuotaWithConfirmation } from '../src/services/quotaActions';
+import { canResetCodexQuota, resetCodexQuotaWithConfirmation } from '../src/services/quotaActions';
import { getQuotaCacheSnapshot, pruneQuotaCache, updateQuotaCache } from '../src/services/quotaCache';
import { quotaKey, type QuotaState } from '../src/services/quotaService';
@@ -139,15 +139,6 @@ describe('quota action confirmation with fully mocked IPC', () => {
expect(upstreamCalls.filter((request) => request.url.endsWith('/consume'))).toHaveLength(1);
});
- it('only runs a paid availability test after separate explicit confirmation', async () => {
- const xai = { name: 'xai-test.json', provider: 'xai', auth_index: 'test-xai' };
- await probeXaiWithConfirmation(xai, async () => false);
- expect(upstreamCalls).toHaveLength(0);
- expect(await probeXaiWithConfirmation(xai, async () => true)).toBe('success');
- expect(upstreamCalls.filter((request) => request.url.endsWith('/chat/completions'))).toHaveLength(1);
- expect(upstreamCalls.some((request) => request.url.endsWith('/consume'))).toBe(false);
- });
-
it('keeps application confirmations out of native and browser dialog APIs', async () => {
for (const name of ['QuotaPage', 'AuthFileManagementPage', 'ApiAccessPage', 'ThinkingAliasesPage', 'UsageRecordsPage']) {
const source = await Bun.file(new URL('../src/pages/' + name + '.tsx', import.meta.url)).text();
diff --git a/tests/quotaRendering.test.tsx b/tests/quotaRendering.test.tsx
index 2562131..649837e 100644
--- a/tests/quotaRendering.test.tsx
+++ b/tests/quotaRendering.test.tsx
@@ -20,10 +20,12 @@ describe('quota card rendering', () => {
expect(html).toContain('订阅到期');
});
- it('付费 API 健康状态不画成 0% 或 100% 的额度条', () => {
- const html = render({ status: 'success', rows: [{ label: '付费 API 可用', remainingPercent: null, detail: '上游未提供剩余额度' }] }, 'xai');
+ it('xAI 付费账号保留额度说明和刷新入口,不显示可用性测试', () => {
+ const html = render({ status: 'success', rows: [{ label: '付费 API 账号', remainingPercent: null, detail: '上游未提供剩余额度' }] }, 'xai');
expect(html).toContain('上游未提供剩余额度');
expect(html).not.toContain('real-quota-track');
+ expect(html).not.toContain('测试可用性');
+ expect(html).toContain('获取/刷新额度');
});
it('缓存中的原始重置时间提供动态提示,过期额度不伪造为已恢复', () => {
diff --git a/tests/quotaRequests.test.ts b/tests/quotaRequests.test.ts
index 4df90b4..d90414e 100644
--- a/tests/quotaRequests.test.ts
+++ b/tests/quotaRequests.test.ts
@@ -1,6 +1,6 @@
import { afterEach, beforeEach, describe, expect, it, spyOn } from 'bun:test';
import { managementApi } from '../src/services/managementApi';
-import { consumeCodexResetCredit, loadQuota, probeXaiAvailability } from '../src/services/quotaService';
+import { consumeCodexResetCredit, loadQuota } from '../src/services/quotaService';
const success = (body: unknown) => ({ status_code: 200, body });
const codexUsage = {
@@ -122,7 +122,7 @@ describe('quota API compatibility', () => {
});
});
-describe('xAI quota queries and explicit availability tests', () => {
+describe('xAI quota queries without paid probes', () => {
const file = { name: 'xai.json', provider: 'x-ai', auth_index: 'x' };
it('单个账单接口失败仍展示另一接口的数据,不触发收费探测', async () => {
@@ -140,22 +140,10 @@ describe('xAI quota queries and explicit availability tests', () => {
const result = await loadQuota({ ...file, using_api: true, prefix: 'paid' });
expect(result.status).toBe('success');
expect(result.rows[0].remainingPercent).toBeNull();
- expect(result.rows[0].detail).toContain('不提供剩余额度');
+ expect(result.rows[0].detail).toBe('此账号不提供剩余额度。');
expect(post).not.toHaveBeenCalled();
});
- it('确认后执行极短对话探测,profile 失败不影响结果,也不伪造剩余额度', async () => {
- handler = (request) => request.url.endsWith('/me') ? { status_code: 403 } : success({ choices: [] });
- const result = await probeXaiAvailability({ ...file, using_api: true, prefix: 'paid' });
- expect(result).toMatchObject({ status: 'success', plan: 'Paid', rows: [{ remainingPercent: null }] });
- expect(calls).toHaveLength(2);
- expect(calls.every((request) => request.url.startsWith('https://api.x.ai/'))).toBe(true);
- expect(JSON.parse(calls.find((request) => request.method === 'POST')!.data!)).toEqual({
- model: 'grok-4.5', messages: [{ role: 'user', content: 'ping' }], max_tokens: 1, stream: false,
- });
- post.mock.calls.forEach((call: unknown[]) => expect(call[2]).toEqual({ timeoutMs: 15000 }));
- });
-
it('两个账单均无数据时返回查询错误,不自动发起付费测试', async () => {
handler = (request) => request.url.includes('cli-chat-proxy') ? { status_code: 403, body: 'billing denied' }
: { status_code: 429, body: 'paid denied' };
@@ -164,12 +152,6 @@ describe('xAI quota queries and explicit availability tests', () => {
expect(calls).toHaveLength(2);
expect(calls.every((request) => request.method === 'GET')).toBe(true);
});
-
- it('不允许仅凭 profile 成功把对话失败的付费账户标记为可用', async () => {
- handler = (request) => request.url.endsWith('/me') ? success({ user_id: 'u' }) : { status_code: 429, body: 'chat denied' };
- await expect(probeXaiAvailability({ ...file, using_api: true, prefix: 'paid' }))
- .rejects.toThrow('chat denied');
- });
});
describe('quota request synchronization', () => {
diff --git a/tests/quotaService.test.ts b/tests/quotaService.test.ts
index 524dd10..19a65f4 100644
--- a/tests/quotaService.test.ts
+++ b/tests/quotaService.test.ts
@@ -262,11 +262,11 @@ describe('quotaRowsFor', () => {
]);
});
- it('xAI 仅返回产品用量时仍能解析,付费探测不伪造百分比', () => {
+ it('xAI 仅返回产品用量时仍能解析,付费账号不伪造剩余额度', () => {
expect(quotaRowsFor('xai', { config: { productUsage: [{ product: 'grok', usagePercent: 20 }] } })[1])
.toMatchObject({ label: 'grok', remainingPercent: 80 });
- expect(quotaRowsFor('xai', { mode: 'paid-health' })[0])
- .toMatchObject({ label: '付费 API 可用', remainingPercent: null });
+ expect(quotaRowsFor('xai', { mode: 'paid-info' })[0])
+ .toMatchObject({ label: '付费 API 账号', remainingPercent: null });
});
it('xAI 不从月账单借用周窗口的重置时间', () => {