feat: 增强 OAuth 认证流程,优化回调状态处理与错误解释
This commit is contained in:
@@ -81,6 +81,16 @@ test('isRecoverableStep9AuthFailure matches timeout and CPA auth failure statuse
|
||||
true
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
isRecoverableStep9AuthFailure('提交回调失败:请更新CLI Proxy API或检查连接'),
|
||||
true
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
isRecoverableStep9AuthFailure('认证失败:Bad Request'),
|
||||
true
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
isRecoverableStep9AuthFailure('认证成功!'),
|
||||
false
|
||||
|
||||
@@ -58,23 +58,32 @@ const bundle = [
|
||||
extractFunction('summarizeStatusBadgeEntries'),
|
||||
extractFunction('normalizeStep9StatusText'),
|
||||
extractFunction('isOAuthCallbackTimeoutFailure'),
|
||||
extractFunction('isStep10CallbackSubmittedStatus'),
|
||||
extractFunction('isStep10CallbackFailureText'),
|
||||
extractFunction('isStep10MainWaitingStatus'),
|
||||
extractFunction('isStep10MainFailureText'),
|
||||
extractFunction('isStep9FailureText'),
|
||||
extractFunction('isStep9SuccessStatus'),
|
||||
extractFunction('isStep9SuccessLikeStatus'),
|
||||
extractFunction('formatStep10StatusSummaryValue'),
|
||||
extractFunction('buildStep9StatusDiagnostics'),
|
||||
extractFunction('extractStep10FailureDetail'),
|
||||
extractFunction('explainStep10Failure'),
|
||||
].join('\n');
|
||||
|
||||
function createApi() {
|
||||
return new Function(`
|
||||
function isRecoverableStep9AuthFailure(text) {
|
||||
return /(?:认证失败|回调 URL 提交失败):\\s*/i.test(String(text || '').trim())
|
||||
|| /oauth flow is not pending/i.test(String(text || '').trim());
|
||||
const normalized = String(text || '').trim();
|
||||
return /(?:认证失败|回调\\s*url\\s*提交失败|回调url提交失败|提交回调失败)\\s*[::]?/i.test(normalized)
|
||||
|| /oauth flow is not pending|请更新\\s*cli\\s*proxy\\s*api\\s*或检查连接|bad request|state code error|failed to exchange authorization code for tokens|failed to save authentication tokens|unknown or expired state|invalid state|state is required|code or error is required|invalid redirect_url|provider does not match state|failed to persist oauth callback|timeout waiting for oauth callback|oauth flow timed out/i.test(normalized);
|
||||
}
|
||||
|
||||
${bundle}
|
||||
|
||||
return {
|
||||
buildStep9StatusDiagnostics,
|
||||
explainStep10Failure,
|
||||
};
|
||||
`)();
|
||||
}
|
||||
@@ -86,6 +95,7 @@ test('step 9 does not treat red success badges as exact success', () => {
|
||||
visible: true,
|
||||
text: '认证成功!',
|
||||
className: 'status-badge text-danger',
|
||||
location: 'main',
|
||||
hasErrorVisualSignal: true,
|
||||
errorVisualSummary: 'color=rgb(220, 38, 38)',
|
||||
},
|
||||
@@ -104,23 +114,89 @@ test('step 9 keeps failure state dominant when success badge and error banner co
|
||||
visible: true,
|
||||
text: '认证成功!',
|
||||
className: 'status-badge',
|
||||
location: 'main',
|
||||
hasErrorVisualSignal: false,
|
||||
errorVisualSummary: '',
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
visible: true,
|
||||
text: '回调 URL 提交失败: oauth flow is not pending',
|
||||
className: 'alert alert-danger',
|
||||
className: 'status-badge error',
|
||||
location: 'callback',
|
||||
hasErrorVisualSignal: true,
|
||||
errorVisualSummary: 'color=rgb(220, 38, 38)',
|
||||
},
|
||||
],
|
||||
[],
|
||||
'page'
|
||||
);
|
||||
|
||||
assert.equal(diagnostics.hasExactSuccessVisibleBadge, true);
|
||||
assert.equal(diagnostics.hasFailureVisibleBadge, true);
|
||||
assert.equal(diagnostics.failureText, '回调 URL 提交失败: oauth flow is not pending');
|
||||
assert.equal(diagnostics.failureSource, 'callback');
|
||||
});
|
||||
|
||||
test('step 10 treats plain 认证成功 as success when no failure is visible', () => {
|
||||
const api = createApi();
|
||||
const diagnostics = api.buildStep9StatusDiagnostics(
|
||||
[
|
||||
{
|
||||
visible: true,
|
||||
text: '认证成功',
|
||||
className: 'status-badge',
|
||||
location: 'main',
|
||||
hasErrorVisualSignal: false,
|
||||
errorVisualSummary: '',
|
||||
},
|
||||
],
|
||||
[],
|
||||
'page'
|
||||
);
|
||||
|
||||
assert.equal(diagnostics.hasExactSuccessVisibleBadge, true);
|
||||
assert.equal(diagnostics.exactSuccessText, '认证成功');
|
||||
});
|
||||
|
||||
test('step 10 recognizes callback accepted badge as in-progress signal', () => {
|
||||
const api = createApi();
|
||||
const diagnostics = api.buildStep9StatusDiagnostics(
|
||||
[
|
||||
{
|
||||
visible: true,
|
||||
text: '回调 URL 已提交,等待认证中...',
|
||||
className: 'status-badge success',
|
||||
location: 'callback',
|
||||
hasErrorVisualSignal: false,
|
||||
errorVisualSummary: '',
|
||||
},
|
||||
{
|
||||
visible: true,
|
||||
text: '等待认证中...',
|
||||
className: 'status-badge',
|
||||
location: 'main',
|
||||
hasErrorVisualSignal: false,
|
||||
errorVisualSummary: '',
|
||||
},
|
||||
],
|
||||
[],
|
||||
'page'
|
||||
);
|
||||
|
||||
assert.equal(diagnostics.hasCallbackSubmittedBadge, true);
|
||||
assert.equal(diagnostics.callbackSubmittedText, '回调 URL 已提交,等待认证中...');
|
||||
assert.equal(diagnostics.mainWaitingText, '等待认证中...');
|
||||
assert.equal(diagnostics.hasExactSuccessVisibleBadge, false);
|
||||
});
|
||||
|
||||
test('step 10 explains callback upgrade hint with user-friendly reason', () => {
|
||||
const api = createApi();
|
||||
const explanation = api.explainStep10Failure(
|
||||
'回调 URL 提交失败: 请更新CLI Proxy API或检查连接',
|
||||
'callback'
|
||||
);
|
||||
|
||||
assert.equal(explanation.code, 'callback_submit_api_unavailable');
|
||||
assert.match(explanation.userMessage, /CLI Proxy API 版本过旧|管理接口未启动|连接异常/);
|
||||
assert.match(explanation.userMessage, /回调提交阶段/);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user