feat: 添加 CPA 手机号注册提示逻辑及相关测试用例

This commit is contained in:
QLHazyCoder
2026-05-05 23:33:31 +08:00
parent b58f09580d
commit 5d4e0d230a
3 changed files with 211 additions and 9 deletions
+4
View File
@@ -456,6 +456,10 @@ function syncAutoRunState() {}
function syncPasswordField() {}
function renderStepStatuses() {}
function setLocalCpaStep9Mode() {}
function normalizePanelMode(value = '') {
const normalized = String(value || '').trim().toLowerCase();
return normalized === 'sub2api' || normalized === 'codex2api' ? normalized : 'cpa';
}
function isCustomMailProvider() { return false; }
function setMail2925Mode() {}
function normalizeIcloudFetchMode(value) { return String(value || '') === 'always_new' ? 'always_new' : 'reuse_existing'; }
@@ -149,6 +149,96 @@ test('sidepanel source wires runtime signup phone field to background sync messa
assert.match(sidepanelSource, /inputSignupPhone\.addEventListener\('input'[\s\S]*signupPhoneInputDirty = true/);
});
test('sidepanel warns once before using phone signup with CPA source', async () => {
assert.match(
sidepanelSource,
/signupMethodButtons\.forEach\(\(button\) => \{[\s\S]*await confirmCpaPhoneSignupIfNeeded\(\{[\s\S]*signupMethod: nextSignupMethod,[\s\S]*panelMode: getSelectedPanelMode\(\),/
);
assert.match(
sidepanelSource,
/selectPanelMode\.addEventListener\('change', async \(\) => \{[\s\S]*await confirmCpaPhoneSignupIfNeeded\(\{[\s\S]*signupMethod: getSelectedSignupMethod\(\),[\s\S]*panelMode: nextPanelMode,/
);
const bundle = [
extractFunction('normalizeSignupMethod'),
extractFunction('normalizePanelMode'),
extractFunction('isPromptDismissed'),
extractFunction('setPromptDismissed'),
extractFunction('isCpaPhoneSignupPromptDismissed'),
extractFunction('setCpaPhoneSignupPromptDismissed'),
extractFunction('shouldWarnCpaPhoneSignup'),
extractFunction('openCpaPhoneSignupWarningModal'),
extractFunction('confirmCpaPhoneSignupIfNeeded'),
].join('\n');
const api = new Function(`
const SIGNUP_METHOD_PHONE = 'phone';
const SIGNUP_METHOD_EMAIL = 'email';
const DEFAULT_SIGNUP_METHOD = SIGNUP_METHOD_EMAIL;
const CPA_PHONE_SIGNUP_PROMPT_DISMISSED_STORAGE_KEY = 'multipage-cpa-phone-signup-prompt-dismissed';
const CPA_PHONE_SIGNUP_WARNING_MESSAGE = 'CPA 未适配手机号注册模式,认证成功后无法使用。请使用 SUB2API,或者认证成功后重新登录一遍进行解决。';
const storage = new Map();
const localStorage = {
getItem(key) {
return storage.has(key) ? storage.get(key) : null;
},
setItem(key, value) {
storage.set(key, String(value));
},
removeItem(key) {
storage.delete(key);
},
};
let selectedSignupMethod = 'phone';
let selectedPanelMode = 'cpa';
let capturedOptions = null;
let modalResult = { confirmed: true, optionChecked: false };
function getSelectedSignupMethod() {
return selectedSignupMethod;
}
function getSelectedPanelMode() {
return selectedPanelMode;
}
async function openConfirmModalWithOption(options) {
capturedOptions = options;
return modalResult;
}
${bundle}
return {
shouldWarnCpaPhoneSignup,
confirmCpaPhoneSignupIfNeeded,
getCapturedOptions() {
return capturedOptions;
},
getDismissed() {
return localStorage.getItem(CPA_PHONE_SIGNUP_PROMPT_DISMISSED_STORAGE_KEY);
},
setModalResult(result) {
modalResult = result;
},
};
`)();
assert.equal(api.shouldWarnCpaPhoneSignup('phone', 'cpa'), true);
assert.equal(api.shouldWarnCpaPhoneSignup('email', 'cpa'), false);
assert.equal(api.shouldWarnCpaPhoneSignup('phone', 'sub2api'), false);
assert.equal(api.shouldWarnCpaPhoneSignup('phone', 'codex2api'), false);
const firstResult = await api.confirmCpaPhoneSignupIfNeeded({ signupMethod: 'phone', panelMode: 'cpa' });
assert.equal(firstResult, true);
assert.equal(api.getCapturedOptions().title, 'CPA 手机号注册提醒');
assert.equal(api.getCapturedOptions().message, 'CPA 未适配手机号注册模式,认证成功后无法使用。请使用 SUB2API,或者认证成功后重新登录一遍进行解决。');
assert.equal(api.getCapturedOptions().confirmLabel, '继续');
assert.equal(api.getCapturedOptions().optionLabel, '不再提醒');
assert.equal(api.getDismissed(), null);
api.setModalResult({ confirmed: false, optionChecked: true });
const secondResult = await api.confirmCpaPhoneSignupIfNeeded({ signupMethod: 'phone', panelMode: 'cpa' });
assert.equal(secondResult, false);
assert.equal(api.getDismissed(), '1');
assert.equal(api.shouldWarnCpaPhoneSignup('phone', 'cpa'), false);
});
test('manual step 3 uses phone identity without requiring registration email', () => {
const api = new Function(`
let latestState = { signupMethod: 'phone', phoneVerificationEnabled: true, signupPhoneNumber: '+441111111111', accountIdentifierType: 'phone', accountIdentifier: '+441111111111' };
@@ -713,6 +803,8 @@ function syncHeroSmsFallbackSelectionOrderFromSelect() {
return [{ id: 52, label: 'Thailand' }, { id: 16, label: 'United Kingdom' }];
}
function getSelectedSignupMethod() { return 'phone'; }
${extractFunction('normalizePanelMode')}
${extractFunction('getSelectedPanelMode')}
function getSelectedFiveSimCountries() {
return [{ id: 'thailand', code: 'thailand', label: 'Thailand' }, { id: 'vietnam', code: 'vietnam', label: 'Vietnam' }];
}