From 4ed5720a261be46ba7a7aa04e850c6ec38451840 Mon Sep 17 00:00:00 2001 From: QLHazyCoder <2825305047@qq.com> Date: Mon, 11 May 2026 19:12:35 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E7=A7=BB=E9=99=A4=E4=B8=8D?= =?UTF-8?q?=E5=BF=85=E8=A6=81=E7=9A=84=20gopayHelperPhoneMode=20=E9=80=BB?= =?UTF-8?q?=E8=BE=91=EF=BC=8C=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- background/steps/create-plus-checkout.js | 1 - background/steps/fill-plus-checkout.js | 1 - sidepanel/sidepanel.js | 42 +++------ ...us-checkout-billing-tab-resolution.test.js | 2 +- tests/plus-checkout-create-wait.test.js | 4 +- tests/sidepanel-plus-payment-method.test.js | 87 +++++++++++++++---- 6 files changed, 85 insertions(+), 52 deletions(-) diff --git a/background/steps/create-plus-checkout.js b/background/steps/create-plus-checkout.js index 905e874..5ac76a5 100644 --- a/background/steps/create-plus-checkout.js +++ b/background/steps/create-plus-checkout.js @@ -440,7 +440,6 @@ gopayHelperTaskStatus: result.taskStatus, gopayHelperStatusText: result.statusText, gopayHelperRemoteStage: result.remoteStage, - gopayHelperPhoneMode: result.phoneMode || normalizeGpcHelperPhoneMode(state?.gopayHelperPhoneMode || state?.phoneMode), gopayHelperTaskPayload: result.responsePayload, gopayHelperTaskProgressSignature: '', gopayHelperTaskProgressAt: 0, diff --git a/background/steps/fill-plus-checkout.js b/background/steps/fill-plus-checkout.js index 11f1f92..a6a5766 100644 --- a/background/steps/fill-plus-checkout.js +++ b/background/steps/fill-plus-checkout.js @@ -412,7 +412,6 @@ gopayHelperTaskId: task.task_id, gopayHelperTaskStatus: task.status, gopayHelperStatusText: task.status_text, - gopayHelperPhoneMode: task.phone_mode, gopayHelperRemoteStage: task.remote_stage, gopayHelperApiWaitingFor: task.api_waiting_for, gopayHelperApiInputDeadlineAt: task.api_input_deadline_at, diff --git a/sidepanel/sidepanel.js b/sidepanel/sidepanel.js index 85f23d5..8fc6b94 100644 --- a/sidepanel/sidepanel.js +++ b/sidepanel/sidepanel.js @@ -3419,12 +3419,7 @@ function collectSettingsPayload() { ? selectGpcHelperPhoneMode.value : (latestState?.gopayHelperPhoneMode || 'manual') ); - const preserveSelectedGpcAutoMode = typeof shouldPreserveSelectedGpcAutoMode === 'function' - ? shouldPreserveSelectedGpcAutoMode(latestState) - : false; - const effectiveGpcPhoneMode = (!preserveSelectedGpcAutoMode && typeof isGpcAutoModePermissionDenied === 'function' && isGpcAutoModePermissionDenied(latestState)) - ? 'manual' - : selectedGpcPhoneMode; + const effectiveGpcPhoneMode = selectedGpcPhoneMode; const selectedGpcOtpChannel = normalizeGpcOtpChannelSafe( typeof selectGpcHelperOtpChannel !== 'undefined' && selectGpcHelperOtpChannel ? selectGpcHelperOtpChannel.value @@ -7402,12 +7397,8 @@ function updatePlusModeUI() { : (latestState?.gopayHelperPhoneMode || 'manual') ); const gpcAutoModeDenied = isGpcAutoModePermissionDenied(latestState); - const gpcAutoModeEnabled = getGpcHelperAutoModeEnabled(latestState); - const preserveSelectedGpcAutoMode = typeof shouldPreserveSelectedGpcAutoMode === 'function' - ? shouldPreserveSelectedGpcAutoMode(latestState) - : false; - const effectiveGpcAutoModeDenied = gpcAutoModeDenied && !preserveSelectedGpcAutoMode; - const isGpcAutoMode = !effectiveGpcAutoModeDenied && gpcPhoneMode === GPC_HELPER_PHONE_MODE_AUTO; + const isGpcAutoMode = gpcPhoneMode === GPC_HELPER_PHONE_MODE_AUTO; + const gpcAutoModeBlocked = isGpcAutoMode && gpcAutoModeDenied; const gpcOtpChannel = normalizeGpcOtpChannelValue( typeof selectGpcHelperOtpChannel !== 'undefined' && selectGpcHelperOtpChannel ? selectGpcHelperOtpChannel.value @@ -7422,7 +7413,7 @@ function updatePlusModeUI() { ? normalizePlusPaymentMethod(selectPlusPaymentMethod.value) : method; const gpcRowsVisible = enabled && selectedMethod === gpcValue; - const canShowGpcModeSelector = gpcRowsVisible && (gpcAutoModeEnabled || !effectiveGpcAutoModeDenied); + const canShowGpcModeSelector = gpcRowsVisible; const localSmsControlsVisible = gpcRowsVisible && !isGpcAutoMode; const effectiveLocalSmsEnabled = !isGpcAutoMode && localSmsEnabled; if (typeof selectPlusPaymentMethod !== 'undefined' && selectPlusPaymentMethod) { @@ -7438,6 +7429,9 @@ function updatePlusModeUI() { ? 'GoPay 印尼订阅链路' : 'PayPal 订阅链路'; } + if (typeof plusPaymentMethodCaption !== 'undefined' && plusPaymentMethodCaption && method === gpcValue && gpcAutoModeBlocked) { + plusPaymentMethodCaption.textContent = 'GPC 自动订阅链路(需手动切换)'; + } [ typeof rowPlusPaymentMethod !== 'undefined' ? rowPlusPaymentMethod : null, ].forEach((row) => { @@ -7467,7 +7461,7 @@ function updatePlusModeUI() { rowGpcHelperPhoneMode.style.display = canShowGpcModeSelector ? '' : 'none'; } if (typeof selectGpcHelperPhoneMode !== 'undefined' && selectGpcHelperPhoneMode) { - selectGpcHelperPhoneMode.value = effectiveGpcAutoModeDenied ? GPC_HELPER_PHONE_MODE_MANUAL : gpcPhoneMode; + selectGpcHelperPhoneMode.value = gpcPhoneMode; } [ typeof rowGpcHelperCountryCode !== 'undefined' ? rowGpcHelperCountryCode : null, @@ -7773,13 +7767,7 @@ async function ensureGpcApiKeyReadyForStart(options = {}) { } if (selectedMode === GPC_HELPER_PHONE_MODE_AUTO && isGpcAutoModePermissionDenied(balanceState)) { - if (typeof selectGpcHelperPhoneMode !== 'undefined' && selectGpcHelperPhoneMode) { - selectGpcHelperPhoneMode.value = GPC_HELPER_PHONE_MODE_MANUAL; - } - syncLatestState({ gopayHelperPhoneMode: GPC_HELPER_PHONE_MODE_MANUAL }); - updatePlusModeUI(); - await saveSettings({ silent: true, force: true }).catch(() => {}); - await showGpcStartBlockedDialog('当前 GPC API Key 未开通自动模式,已切回手动模式,不能以自动模式开启任务。'); + await showGpcStartBlockedDialog('当前 GPC API Key 未开通自动模式,已保留你的当前选择。如需继续,请由你手动切换到手动模式后再开启任务。'); return false; } @@ -11808,10 +11796,7 @@ btnGpcHelperBalance?.addEventListener('click', async () => { const selectedModeBeforeBalanceState = getSelectedGpcHelperPhoneMode(); syncLatestState(nextState); if (nextAutoModeDenied && selectedModeBeforeBalanceState === GPC_HELPER_PHONE_MODE_AUTO) { - selectGpcHelperPhoneMode.value = GPC_HELPER_PHONE_MODE_MANUAL; - syncLatestState({ gopayHelperPhoneMode: GPC_HELPER_PHONE_MODE_MANUAL }); - await saveSettings({ silent: true, force: true }).catch(() => {}); - showToast('当前 API Key 未开通自动模式,已切回手动模式。', 'warn'); + showToast('当前 API Key 未开通自动模式,已保留当前选择;如需继续请手动切换到手动模式。', 'warn'); } else if (nextAutoModeDenied) { showToast('GPC 余额已更新,当前 API Key 只能使用手动模式。', 'success'); } else if (nextAutoModeConfirmed) { @@ -13773,13 +13758,6 @@ chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => { if (message.payload.gopayHelperPhoneMode !== undefined && selectGpcHelperPhoneMode) { selectGpcHelperPhoneMode.value = normalizeGpcHelperPhoneModeValue(message.payload.gopayHelperPhoneMode); } - if (message.payload.gopayHelperAutoModeEnabled === false - && selectGpcHelperPhoneMode?.value === GPC_HELPER_PHONE_MODE_AUTO - && isGpcAutoModePermissionDenied(latestState)) { - selectGpcHelperPhoneMode.value = GPC_HELPER_PHONE_MODE_MANUAL; - syncLatestState({ gopayHelperPhoneMode: GPC_HELPER_PHONE_MODE_MANUAL }); - showToast('当前 API Key 未开通自动模式,已切回手动模式。', 'warn', 2200); - } if (message.payload.gopayHelperOtpChannel !== undefined && selectGpcHelperOtpChannel) { selectGpcHelperOtpChannel.value = normalizeGpcOtpChannelValue(message.payload.gopayHelperOtpChannel); } diff --git a/tests/plus-checkout-billing-tab-resolution.test.js b/tests/plus-checkout-billing-tab-resolution.test.js index dd3995c..648731e 100644 --- a/tests/plus-checkout-billing-tab-resolution.test.js +++ b/tests/plus-checkout-billing-tab-resolution.test.js @@ -960,7 +960,7 @@ test('GPC billing auto mode only polls until completed without OTP or PIN submis assert.equal(events.logs.some((entry) => entry.message === '步骤 7:GPC 任务状态:等待自动 OTP'), true); assert.equal(events.logs.some((entry) => /auto_otp_wait/.test(entry.message)), false); assert.equal(events.states.some((state) => state.plusManualConfirmationMethod === 'gopay-otp'), false); - assert.equal(events.states.some((state) => state.gopayHelperTaskId === 'task_auto' && state.gopayHelperPhoneMode === 'auto' && state.gopayHelperTaskStatus === 'completed'), true); + assert.equal(events.states.some((state) => state.gopayHelperTaskId === 'task_auto' && state.gopayHelperTaskStatus === 'completed'), true); assert.equal(events.completed[0].step, 7); assert.equal(events.completed[0].payload.plusCheckoutSource, 'gpc-helper'); }); diff --git a/tests/plus-checkout-create-wait.test.js b/tests/plus-checkout-create-wait.test.js index 6c13520..dd688bd 100644 --- a/tests/plus-checkout-create-wait.test.js +++ b/tests/plus-checkout-create-wait.test.js @@ -505,7 +505,7 @@ test('GPC auto checkout only sends access token and API Key', async () => { assert.equal(Object.prototype.hasOwnProperty.call(helperPayload, 'pin'), false); const statePayload = events.find((event) => event.type === 'set-state')?.payload || {}; assert.equal(statePayload.gopayHelperTaskId, 'task_auto'); - assert.equal(statePayload.gopayHelperPhoneMode, 'auto'); + assert.equal(Object.prototype.hasOwnProperty.call(statePayload, 'gopayHelperPhoneMode'), false); assert.equal(statePayload.gopayHelperTaskStatus, 'queued'); assert.equal(events.find((event) => event.type === 'complete')?.step, 6); }); @@ -563,7 +563,7 @@ test('GPC auto checkout keeps running when balance payload omits auto mode permi assert.equal(helperPayload.phone_mode, 'auto'); const statePayload = events.find((event) => event.type === 'set-state')?.payload || {}; assert.equal(statePayload.gopayHelperTaskId, 'task_auto_unknown_permission'); - assert.equal(statePayload.gopayHelperPhoneMode, 'auto'); + assert.equal(Object.prototype.hasOwnProperty.call(statePayload, 'gopayHelperPhoneMode'), false); assert.equal(events.find((event) => event.type === 'complete')?.step, 6); }); diff --git a/tests/sidepanel-plus-payment-method.test.js b/tests/sidepanel-plus-payment-method.test.js index fdd8e6d..ded1b45 100644 --- a/tests/sidepanel-plus-payment-method.test.js +++ b/tests/sidepanel-plus-payment-method.test.js @@ -310,7 +310,7 @@ return { assert.equal(api.rowPayPalAccount.style.display, 'none'); }); -test('sidepanel hides GPC auto mode selector when API Key has no auto permission', () => { +test('sidepanel keeps selected GPC auto mode when API Key has no auto permission', () => { const bundle = [ extractFunction('normalizePlusPaymentMethod'), extractFunction('getSelectedPlusPaymentMethod'), @@ -354,11 +354,11 @@ return { updatePlusModeUI, selectGpcHelperPhoneMode, plusPaymentMethodCaption, r api.updatePlusModeUI(); - assert.equal(api.rows.rowGpcHelperPhoneMode.style.display, 'none'); - assert.equal(api.selectGpcHelperPhoneMode.value, 'manual'); - assert.equal(api.rows.rowGpcHelperPhone.style.display, ''); - assert.equal(api.rows.rowGpcHelperOtpChannel.style.display, ''); - assert.equal(api.rows.rowGpcHelperPin.style.display, ''); + assert.equal(api.rows.rowGpcHelperPhoneMode.style.display, ''); + assert.equal(api.selectGpcHelperPhoneMode.value, 'auto'); + assert.equal(api.rows.rowGpcHelperPhone.style.display, 'none'); + assert.equal(api.rows.rowGpcHelperOtpChannel.style.display, 'none'); + assert.equal(api.rows.rowGpcHelperPin.style.display, 'none'); assert.match(api.plusPaymentMethodCaption.textContent, /手动/); }); @@ -412,9 +412,7 @@ return { getSelectedPhoneMode() { return selectGpcHelperPhoneMode.value; }, getPayloadPhoneMode() { return (() => { - const selectedGpcPhoneMode = normalizeGpcHelperPhoneModeValue(selectGpcHelperPhoneMode.value); - const preserveSelectedGpcAutoMode = shouldPreserveSelectedGpcAutoMode(latestState); - return (!preserveSelectedGpcAutoMode && isGpcAutoModePermissionDenied(latestState)) ? 'manual' : selectedGpcPhoneMode; + return normalizeGpcHelperPhoneModeValue(selectGpcHelperPhoneMode.value); })(); }, applyDataUpdated(payload) { @@ -422,12 +420,6 @@ return { if (payload.gopayHelperPhoneMode !== undefined) { selectGpcHelperPhoneMode.value = normalizeGpcHelperPhoneModeValue(payload.gopayHelperPhoneMode); } - if (payload.gopayHelperAutoModeEnabled === false - && selectGpcHelperPhoneMode?.value === GPC_HELPER_PHONE_MODE_AUTO - && isGpcAutoModePermissionDenied(latestState)) { - selectGpcHelperPhoneMode.value = GPC_HELPER_PHONE_MODE_MANUAL; - syncLatestState({ gopayHelperPhoneMode: GPC_HELPER_PHONE_MODE_MANUAL }); - } updatePlusModeUI(); }, rows: { rowGpcHelperPhoneMode, rowGpcHelperPhone, rowGpcHelperOtpChannel, rowGpcHelperPin }, @@ -566,6 +558,71 @@ return { assert.deepEqual(api.getDialogs(), []); }); +test('sidepanel start check blocks unsupported GPC auto mode without rewriting selection', async () => { + const bundle = [ + extractFunction('normalizeGpcAutoModePermissionValue'), + extractFunction('getGpcAutoModePermissionFromPayload'), + extractFunction('isGpcAutoModePermissionDenied'), + extractFunction('normalizeGpcRemainingUsesValue'), + extractFunction('ensureGpcApiKeyReadyForStart'), + ].join('\n'); + + const api = new Function(` +let latestState = { gopayHelperPhoneMode: 'auto' }; +const GPC_HELPER_PHONE_MODE_AUTO = 'auto'; +const GPC_HELPER_PHONE_MODE_MANUAL = 'manual'; +const selectGpcHelperPhoneMode = { value: 'auto' }; +const dialogs = []; +let saveCalls = 0; +let updateCalls = 0; +${bundle} +function isGpcHelperCheckoutSelected() { return true; } +function getSelectedGpcHelperPhoneMode() { return selectGpcHelperPhoneMode.value; } +async function refreshGpcBalanceForStart() { + return { + gopayHelperRemainingUses: 998, + gopayHelperApiKeyStatus: 'active', + gopayHelperAutoModeEnabled: false, + gopayHelperBalancePayload: { + status: 'active', + remaining_uses: 998, + auto_mode_enabled: false, + }, + }; +} +async function showGpcStartBlockedDialog(message) { + dialogs.push(message); +} +function syncLatestState(nextState) { + latestState = { ...latestState, ...nextState }; +} +function updatePlusModeUI() { + updateCalls += 1; +} +async function saveSettings() { + saveCalls += 1; +} +function showToast() {} +return { + ensureGpcApiKeyReadyForStart, + selectGpcHelperPhoneMode, + getDialogs: () => dialogs.slice(), + getSaveCalls: () => saveCalls, + getUpdateCalls: () => updateCalls, + getPersistedPhoneMode: () => latestState.gopayHelperPhoneMode, +}; +`)(); + + const allowed = await api.ensureGpcApiKeyReadyForStart(); + + assert.equal(allowed, false); + assert.equal(api.selectGpcHelperPhoneMode.value, 'auto'); + assert.equal(api.getPersistedPhoneMode(), 'auto'); + assert.equal(api.getSaveCalls(), 0); + assert.equal(api.getUpdateCalls(), 0); + assert.equal(api.getDialogs().length, 1); +}); + test('sidepanel resolves pending GoPay manual confirmation from DATA_UPDATED state', async () => { const bundle = [ extractFunction('openPlusManualConfirmationDialog'),