feat(flow): unify sms multi-provider fallback and stabilize proxy/auth retries
This commit is contained in:
@@ -59,6 +59,13 @@ test('sidepanel html exposes phone verification toggle and dedicated HeroSMS row
|
||||
assert.match(html, /id="btn-toggle-phone-verification-section"/);
|
||||
assert.match(html, /id="row-phone-verification-fold"/);
|
||||
assert.match(html, /id="input-phone-verification-enabled"/);
|
||||
assert.match(html, /id="row-phone-sms-provider"/);
|
||||
assert.match(html, /id="select-phone-sms-provider"/);
|
||||
assert.match(html, /id="row-phone-sms-provider-order"/);
|
||||
assert.match(html, /id="select-phone-sms-provider-order"[^>]*multiple/);
|
||||
assert.match(html, /id="btn-phone-sms-provider-order-menu"/);
|
||||
assert.match(html, /id="row-phone-sms-provider-order-actions"/);
|
||||
assert.match(html, /id="btn-phone-sms-provider-order-reset"/);
|
||||
assert.match(html, /id="row-hero-sms-platform"/);
|
||||
assert.match(html, /id="row-hero-sms-country"/);
|
||||
assert.match(html, /id="row-hero-sms-country-fallback"/);
|
||||
@@ -69,32 +76,83 @@ test('sidepanel html exposes phone verification toggle and dedicated HeroSMS row
|
||||
assert.match(html, /id="row-hero-sms-api-key"/);
|
||||
assert.match(html, /id="row-hero-sms-max-price"/);
|
||||
assert.match(html, /id="row-hero-sms-current-number"/);
|
||||
assert.match(html, /id="row-hero-sms-current-countdown"/);
|
||||
assert.match(html, /id="row-hero-sms-price-tiers"/);
|
||||
assert.match(html, /id="row-hero-sms-current-code"/);
|
||||
assert.match(html, /id="row-hero-sms-preferred-activation"/);
|
||||
assert.match(html, /id="select-hero-sms-preferred-activation"/);
|
||||
assert.match(html, /id="row-phone-replacement-limit"/);
|
||||
assert.match(html, /id="row-phone-verification-resend-count"/);
|
||||
assert.match(html, /id="row-phone-code-wait-seconds"/);
|
||||
assert.match(html, /id="row-phone-code-timeout-windows"/);
|
||||
assert.match(html, /id="row-phone-code-poll-interval-seconds"/);
|
||||
assert.match(html, /id="row-phone-code-poll-max-rounds"/);
|
||||
assert.match(html, /id="row-oauth-flow-timeout"/);
|
||||
assert.match(html, /id="input-oauth-flow-timeout-enabled"/);
|
||||
assert.match(html, /只取消 Step 7 后链总预算/);
|
||||
assert.match(html, /id="row-five-sim-api-key"/);
|
||||
assert.match(html, /id="input-five-sim-api-key"/);
|
||||
assert.match(html, /id="row-five-sim-country"/);
|
||||
assert.match(html, /id="select-five-sim-country"[^>]*multiple/);
|
||||
assert.match(html, /id="row-five-sim-country-fallback"/);
|
||||
assert.match(html, /id="row-five-sim-operator"/);
|
||||
assert.match(html, /id="input-five-sim-operator"/);
|
||||
assert.match(html, /id="row-five-sim-product"/);
|
||||
assert.match(html, /id="input-five-sim-product"/);
|
||||
assert.match(html, /<option value="nexsms">/);
|
||||
assert.match(html, /id="row-nex-sms-api-key"/);
|
||||
assert.match(html, /id="input-nex-sms-api-key"/);
|
||||
assert.match(html, /id="row-nex-sms-country"/);
|
||||
assert.match(html, /id="select-nex-sms-country"[^>]*multiple/);
|
||||
assert.match(html, /id="row-nex-sms-country-fallback"/);
|
||||
assert.match(html, /id="row-nex-sms-service-code"/);
|
||||
assert.match(html, /id="input-nex-sms-service-code"/);
|
||||
assert.doesNotMatch(html, /id="input-account-run-history-text-enabled"/);
|
||||
});
|
||||
|
||||
test('updatePhoneVerificationSettingsUI toggles HeroSMS rows from the sms switch', () => {
|
||||
const api = new Function(`
|
||||
const phoneVerificationSectionExpanded = true;
|
||||
let latestState = {};
|
||||
const inputPhoneVerificationEnabled = { checked: false };
|
||||
const rowPhoneVerificationEnabled = { style: { display: 'none' } };
|
||||
const rowPhoneVerificationFold = { style: { display: 'none' } };
|
||||
const rowPhoneSmsProvider = { style: { display: 'none' } };
|
||||
const rowPhoneSmsProviderOrder = { style: { display: 'none' } };
|
||||
const rowPhoneSmsProviderOrderActions = { style: { display: 'none' } };
|
||||
const selectPhoneSmsProvider = { value: 'hero-sms' };
|
||||
const btnTogglePhoneVerificationSection = {
|
||||
disabled: false,
|
||||
textContent: '',
|
||||
title: '',
|
||||
setAttribute: () => {},
|
||||
};
|
||||
const DEFAULT_PHONE_SMS_PROVIDER_ORDER = ['hero-sms', '5sim', 'nexsms'];
|
||||
const phoneSmsProviderOrderSelection = [];
|
||||
function normalizePhoneSmsProviderOrderValue(value = [], fallbackOrder = DEFAULT_PHONE_SMS_PROVIDER_ORDER) {
|
||||
const source = Array.isArray(value) ? value : [];
|
||||
const normalized = [...source];
|
||||
if (normalized.length) {
|
||||
return normalized.slice(0, 3);
|
||||
}
|
||||
if (!Array.isArray(fallbackOrder) || !fallbackOrder.length) {
|
||||
return [];
|
||||
}
|
||||
const fallbackNormalized = [];
|
||||
for (const provider of fallbackOrder) {
|
||||
if (!fallbackNormalized.includes(provider)) {
|
||||
fallbackNormalized.push(provider);
|
||||
}
|
||||
}
|
||||
return fallbackNormalized.slice(0, 3);
|
||||
}
|
||||
function resolveNormalizedProviderOrderForRuntime(state = {}) {
|
||||
const rawOrder = Array.isArray(state?.phoneSmsProviderOrder) ? state.phoneSmsProviderOrder : [];
|
||||
const normalizedOrder = normalizePhoneSmsProviderOrderValue(rawOrder, []);
|
||||
if (normalizedOrder.length) {
|
||||
return normalizedOrder;
|
||||
}
|
||||
const fallbackProvider = String(state?.phoneSmsProvider || selectPhoneSmsProvider?.value || 'hero-sms').trim().toLowerCase() || 'hero-sms';
|
||||
return [fallbackProvider];
|
||||
}
|
||||
function updatePhoneSmsProviderOrderSummary() {}
|
||||
const rowHeroSmsPlatform = { style: { display: 'none' } };
|
||||
const rowHeroSmsCountry = { style: { display: 'none' } };
|
||||
const rowHeroSmsCountryFallback = { style: { display: 'none' } };
|
||||
@@ -102,20 +160,36 @@ const rowHeroSmsAcquirePriority = { style: { display: 'none' } };
|
||||
const rowHeroSmsApiKey = { style: { display: 'none' } };
|
||||
const rowHeroSmsMaxPrice = { style: { display: 'none' } };
|
||||
const rowHeroSmsCurrentNumber = { style: { display: 'none' } };
|
||||
const rowHeroSmsCurrentCountdown = { style: { display: 'none' } };
|
||||
const rowHeroSmsPriceTiers = { style: { display: 'none' } };
|
||||
const rowHeroSmsCurrentCode = { style: { display: 'none' } };
|
||||
const rowHeroSmsPreferredActivation = { style: { display: 'none' } };
|
||||
const rowPhoneVerificationResendCount = { style: { display: 'none' } };
|
||||
const rowPhoneReplacementLimit = { style: { display: 'none' } };
|
||||
const rowPhoneCodeWaitSeconds = { style: { display: 'none' } };
|
||||
const rowPhoneCodeTimeoutWindows = { style: { display: 'none' } };
|
||||
const rowPhoneCodePollIntervalSeconds = { style: { display: 'none' } };
|
||||
const rowPhoneCodePollMaxRounds = { style: { display: 'none' } };
|
||||
const rowFiveSimApiKey = { style: { display: 'none' } };
|
||||
const rowFiveSimCountry = { style: { display: 'none' } };
|
||||
const rowFiveSimCountryFallback = { style: { display: 'none' } };
|
||||
const rowFiveSimOperator = { style: { display: 'none' } };
|
||||
const rowFiveSimProduct = { style: { display: 'none' } };
|
||||
const rowNexSmsApiKey = { style: { display: 'none' } };
|
||||
const rowNexSmsCountry = { style: { display: 'none' } };
|
||||
const rowNexSmsCountryFallback = { style: { display: 'none' } };
|
||||
const rowNexSmsServiceCode = { style: { display: 'none' } };
|
||||
|
||||
${extractFunction('updatePhoneVerificationSettingsUI')}
|
||||
|
||||
return {
|
||||
setLatestState: (state) => { latestState = state || {}; },
|
||||
rowPhoneVerificationEnabled,
|
||||
rowPhoneVerificationFold,
|
||||
rowPhoneSmsProvider,
|
||||
rowPhoneSmsProviderOrder,
|
||||
rowPhoneSmsProviderOrderActions,
|
||||
selectPhoneSmsProvider,
|
||||
btnTogglePhoneVerificationSection,
|
||||
inputPhoneVerificationEnabled,
|
||||
rowHeroSmsPlatform,
|
||||
@@ -125,14 +199,25 @@ return {
|
||||
rowHeroSmsApiKey,
|
||||
rowHeroSmsMaxPrice,
|
||||
rowHeroSmsCurrentNumber,
|
||||
rowHeroSmsCurrentCountdown,
|
||||
rowHeroSmsPriceTiers,
|
||||
rowHeroSmsCurrentCode,
|
||||
rowHeroSmsPreferredActivation,
|
||||
rowPhoneVerificationResendCount,
|
||||
rowPhoneReplacementLimit,
|
||||
rowPhoneCodeWaitSeconds,
|
||||
rowPhoneCodeTimeoutWindows,
|
||||
rowPhoneCodePollIntervalSeconds,
|
||||
rowPhoneCodePollMaxRounds,
|
||||
rowFiveSimApiKey,
|
||||
rowFiveSimCountry,
|
||||
rowFiveSimCountryFallback,
|
||||
rowFiveSimOperator,
|
||||
rowFiveSimProduct,
|
||||
rowNexSmsApiKey,
|
||||
rowNexSmsCountry,
|
||||
rowNexSmsCountryFallback,
|
||||
rowNexSmsServiceCode,
|
||||
updatePhoneVerificationSettingsUI,
|
||||
};
|
||||
`)();
|
||||
@@ -140,6 +225,9 @@ return {
|
||||
api.updatePhoneVerificationSettingsUI();
|
||||
assert.equal(api.rowPhoneVerificationEnabled.style.display, '');
|
||||
assert.equal(api.rowPhoneVerificationFold.style.display, 'none');
|
||||
assert.equal(api.rowPhoneSmsProvider.style.display, 'none');
|
||||
assert.equal(api.rowPhoneSmsProviderOrder.style.display, 'none');
|
||||
assert.equal(api.rowPhoneSmsProviderOrderActions.style.display, 'none');
|
||||
assert.equal(api.btnTogglePhoneVerificationSection.disabled, true);
|
||||
assert.equal(api.btnTogglePhoneVerificationSection.textContent, '展开设置');
|
||||
assert.equal(api.rowHeroSmsPlatform.style.display, 'none');
|
||||
@@ -149,18 +237,32 @@ return {
|
||||
assert.equal(api.rowHeroSmsApiKey.style.display, 'none');
|
||||
assert.equal(api.rowHeroSmsMaxPrice.style.display, 'none');
|
||||
assert.equal(api.rowHeroSmsCurrentNumber.style.display, 'none');
|
||||
assert.equal(api.rowHeroSmsCurrentCountdown.style.display, 'none');
|
||||
assert.equal(api.rowHeroSmsPriceTiers.style.display, 'none');
|
||||
assert.equal(api.rowHeroSmsCurrentCode.style.display, 'none');
|
||||
assert.equal(api.rowHeroSmsPreferredActivation.style.display, 'none');
|
||||
assert.equal(api.rowPhoneVerificationResendCount.style.display, 'none');
|
||||
assert.equal(api.rowPhoneReplacementLimit.style.display, 'none');
|
||||
assert.equal(api.rowPhoneCodeWaitSeconds.style.display, 'none');
|
||||
assert.equal(api.rowPhoneCodeTimeoutWindows.style.display, 'none');
|
||||
assert.equal(api.rowPhoneCodePollIntervalSeconds.style.display, 'none');
|
||||
assert.equal(api.rowPhoneCodePollMaxRounds.style.display, 'none');
|
||||
assert.equal(api.rowFiveSimApiKey.style.display, 'none');
|
||||
assert.equal(api.rowFiveSimCountry.style.display, 'none');
|
||||
assert.equal(api.rowFiveSimCountryFallback.style.display, 'none');
|
||||
assert.equal(api.rowFiveSimOperator.style.display, 'none');
|
||||
assert.equal(api.rowFiveSimProduct.style.display, 'none');
|
||||
assert.equal(api.rowNexSmsApiKey.style.display, 'none');
|
||||
assert.equal(api.rowNexSmsCountry.style.display, 'none');
|
||||
assert.equal(api.rowNexSmsCountryFallback.style.display, 'none');
|
||||
assert.equal(api.rowNexSmsServiceCode.style.display, 'none');
|
||||
|
||||
api.inputPhoneVerificationEnabled.checked = true;
|
||||
api.updatePhoneVerificationSettingsUI();
|
||||
assert.equal(api.rowPhoneVerificationFold.style.display, '');
|
||||
assert.equal(api.rowPhoneSmsProvider.style.display, '');
|
||||
assert.equal(api.rowPhoneSmsProviderOrder.style.display, '');
|
||||
assert.equal(api.rowPhoneSmsProviderOrderActions.style.display, '');
|
||||
assert.equal(api.btnTogglePhoneVerificationSection.disabled, false);
|
||||
assert.equal(api.btnTogglePhoneVerificationSection.textContent, '收起设置');
|
||||
assert.equal(api.rowHeroSmsPlatform.style.display, '');
|
||||
@@ -170,14 +272,51 @@ return {
|
||||
assert.equal(api.rowHeroSmsApiKey.style.display, '');
|
||||
assert.equal(api.rowHeroSmsMaxPrice.style.display, '');
|
||||
assert.equal(api.rowHeroSmsCurrentNumber.style.display, '');
|
||||
assert.equal(api.rowHeroSmsCurrentCountdown.style.display, '');
|
||||
assert.equal(api.rowHeroSmsPriceTiers.style.display, 'none');
|
||||
assert.equal(api.rowHeroSmsCurrentCode.style.display, '');
|
||||
assert.equal(api.rowHeroSmsPreferredActivation.style.display, '');
|
||||
assert.equal(api.rowPhoneVerificationResendCount.style.display, '');
|
||||
assert.equal(api.rowPhoneReplacementLimit.style.display, '');
|
||||
assert.equal(api.rowPhoneCodeWaitSeconds.style.display, '');
|
||||
assert.equal(api.rowPhoneCodeTimeoutWindows.style.display, '');
|
||||
assert.equal(api.rowPhoneCodePollIntervalSeconds.style.display, '');
|
||||
assert.equal(api.rowPhoneCodePollMaxRounds.style.display, '');
|
||||
assert.equal(api.rowFiveSimApiKey.style.display, 'none');
|
||||
assert.equal(api.rowFiveSimCountry.style.display, 'none');
|
||||
assert.equal(api.rowFiveSimCountryFallback.style.display, 'none');
|
||||
assert.equal(api.rowFiveSimOperator.style.display, 'none');
|
||||
assert.equal(api.rowFiveSimProduct.style.display, 'none');
|
||||
assert.equal(api.rowNexSmsApiKey.style.display, 'none');
|
||||
assert.equal(api.rowNexSmsCountry.style.display, 'none');
|
||||
assert.equal(api.rowNexSmsCountryFallback.style.display, 'none');
|
||||
assert.equal(api.rowNexSmsServiceCode.style.display, 'none');
|
||||
|
||||
api.selectPhoneSmsProvider.value = '5sim';
|
||||
api.setLatestState({ phoneSmsProviderOrder: ['5sim'] });
|
||||
api.updatePhoneVerificationSettingsUI();
|
||||
assert.equal(api.rowHeroSmsCountry.style.display, 'none');
|
||||
assert.equal(api.rowHeroSmsApiKey.style.display, 'none');
|
||||
assert.equal(api.rowFiveSimApiKey.style.display, '');
|
||||
assert.equal(api.rowFiveSimCountry.style.display, '');
|
||||
assert.equal(api.rowFiveSimCountryFallback.style.display, '');
|
||||
assert.equal(api.rowFiveSimOperator.style.display, '');
|
||||
assert.equal(api.rowFiveSimProduct.style.display, '');
|
||||
assert.equal(api.rowNexSmsApiKey.style.display, 'none');
|
||||
assert.equal(api.rowNexSmsCountry.style.display, 'none');
|
||||
assert.equal(api.rowNexSmsCountryFallback.style.display, 'none');
|
||||
assert.equal(api.rowNexSmsServiceCode.style.display, 'none');
|
||||
|
||||
api.selectPhoneSmsProvider.value = 'nexsms';
|
||||
api.setLatestState({ phoneSmsProviderOrder: ['nexsms'] });
|
||||
api.updatePhoneVerificationSettingsUI();
|
||||
assert.equal(api.rowHeroSmsCountry.style.display, 'none');
|
||||
assert.equal(api.rowFiveSimApiKey.style.display, 'none');
|
||||
assert.equal(api.rowFiveSimCountry.style.display, 'none');
|
||||
assert.equal(api.rowNexSmsApiKey.style.display, '');
|
||||
assert.equal(api.rowNexSmsCountry.style.display, '');
|
||||
assert.equal(api.rowNexSmsCountryFallback.style.display, '');
|
||||
assert.equal(api.rowNexSmsServiceCode.style.display, '');
|
||||
});
|
||||
|
||||
test('collectSettingsPayload keeps local helper sync enabled while persisting sms toggle state', () => {
|
||||
@@ -186,6 +325,7 @@ let latestState = {
|
||||
contributionMode: false,
|
||||
mail2925UseAccountPool: false,
|
||||
currentMail2925AccountId: '',
|
||||
fiveSimCountryOrder: ['thailand', 'england'],
|
||||
};
|
||||
let cloudflareDomainEditMode = false;
|
||||
let cloudflareTempEmailDomainEditMode = false;
|
||||
@@ -225,12 +365,26 @@ const inputAutoSkipFailuresThreadIntervalMinutes = { value: '0' };
|
||||
const inputAutoDelayEnabled = { checked: false };
|
||||
const inputAutoDelayMinutes = { value: '30' };
|
||||
const inputAutoStepDelaySeconds = { value: '' };
|
||||
const inputOAuthFlowTimeoutEnabled = { checked: false };
|
||||
const inputPhoneVerificationEnabled = { checked: true };
|
||||
const selectPhoneSmsProvider = { value: 'hero-sms' };
|
||||
const inputVerificationResendCount = { value: '4' };
|
||||
const inputHeroSmsApiKey = { value: 'demo-key' };
|
||||
const inputFiveSimApiKey = { value: 'five-sim-key' };
|
||||
const inputFiveSimOperator = { value: 'any' };
|
||||
const inputFiveSimProduct = { value: 'openai' };
|
||||
const inputHeroSmsReuseEnabled = { checked: true };
|
||||
const selectHeroSmsAcquirePriority = { value: 'price' };
|
||||
function getSelectedPhonePreferredActivation() {
|
||||
return {
|
||||
provider: 'hero-sms',
|
||||
activationId: 'demo-activation',
|
||||
phoneNumber: '66958889999',
|
||||
countryId: 52,
|
||||
countryLabel: 'Thailand',
|
||||
successfulUses: 0,
|
||||
maxUses: 3,
|
||||
};
|
||||
}
|
||||
const inputHeroSmsMaxPrice = { value: '0.12' };
|
||||
const inputPhoneReplacementLimit = { value: '5' };
|
||||
const inputPhoneCodeWaitSeconds = { value: '75' };
|
||||
@@ -303,13 +457,26 @@ return { collectSettingsPayload };
|
||||
const payload = api.collectSettingsPayload();
|
||||
|
||||
assert.equal(payload.phoneVerificationEnabled, true);
|
||||
assert.equal(payload.oauthFlowTimeoutEnabled, false);
|
||||
assert.equal(payload.phoneSmsProvider, 'hero-sms');
|
||||
assert.equal(payload.accountRunHistoryTextEnabled, true);
|
||||
assert.equal(payload.accountRunHistoryHelperBaseUrl, 'http://127.0.0.1:17373');
|
||||
assert.equal(payload.heroSmsApiKey, 'demo-key');
|
||||
assert.equal(payload.fiveSimApiKey, 'five-sim-key');
|
||||
assert.deepStrictEqual(payload.fiveSimCountryOrder, ['thailand', 'england']);
|
||||
assert.equal(payload.fiveSimOperator, 'any');
|
||||
assert.equal(payload.fiveSimProduct, 'openai');
|
||||
assert.equal(payload.heroSmsReuseEnabled, true);
|
||||
assert.equal(payload.heroSmsAcquirePriority, 'price');
|
||||
assert.equal(payload.heroSmsMaxPrice, '0.12');
|
||||
assert.deepStrictEqual(payload.phonePreferredActivation, {
|
||||
provider: 'hero-sms',
|
||||
activationId: 'demo-activation',
|
||||
phoneNumber: '66958889999',
|
||||
countryId: 52,
|
||||
countryLabel: 'Thailand',
|
||||
successfulUses: 0,
|
||||
maxUses: 3,
|
||||
});
|
||||
assert.equal(payload.phoneVerificationReplacementLimit, 5);
|
||||
assert.equal(payload.phoneCodeWaitSeconds, 75);
|
||||
assert.equal(payload.phoneCodeTimeoutWindows, 3);
|
||||
|
||||
Reference in New Issue
Block a user