fix(flow): harden proxy phone and checkout recovery paths
This commit is contained in:
@@ -451,6 +451,9 @@ const PERSISTED_SETTING_DEFAULTS = {
|
||||
luckmailBaseUrl: DEFAULT_LUCKMAIL_BASE_URL,
|
||||
luckmailEmailType: DEFAULT_LUCKMAIL_EMAIL_TYPE,
|
||||
luckmailDomain: '',
|
||||
luckmailUsedPurchases: {},
|
||||
luckmailPreserveTagId: 0,
|
||||
luckmailPreserveTagName: '保留',
|
||||
};
|
||||
const PERSISTED_SETTING_KEYS = Object.keys(PERSISTED_SETTING_DEFAULTS);
|
||||
function normalizeLuckmailBaseUrl(value) {
|
||||
@@ -462,6 +465,18 @@ function normalizeLuckmailEmailType(value) {
|
||||
? String(value || '').trim()
|
||||
: DEFAULT_LUCKMAIL_EMAIL_TYPE;
|
||||
}
|
||||
function normalizeLuckmailPurchaseId(value) {
|
||||
const numeric = Number(value);
|
||||
return Number.isFinite(numeric) && numeric > 0 ? String(Math.floor(numeric)) : '';
|
||||
}
|
||||
function normalizeLuckmailUsedPurchases(value) {
|
||||
if (!value || typeof value !== 'object' || Array.isArray(value)) return {};
|
||||
return Object.entries(value).reduce((result, [key, used]) => {
|
||||
const normalizedKey = normalizeLuckmailPurchaseId(key);
|
||||
if (normalizedKey) result[normalizedKey] = Boolean(used);
|
||||
return result;
|
||||
}, {});
|
||||
}
|
||||
function resolveLegacyAutoStepDelaySeconds() {
|
||||
return undefined;
|
||||
}
|
||||
@@ -487,6 +502,17 @@ return {
|
||||
luckmailEmailType: 'ms_imap',
|
||||
luckmailDomain: 'outlook.com',
|
||||
});
|
||||
|
||||
const statePayload = api.buildPersistentSettingsPayload({
|
||||
luckmailUsedPurchases: { 88: true, 99: false, bad: true },
|
||||
luckmailPreserveTagId: '9',
|
||||
luckmailPreserveTagName: ' 保留邮箱 ',
|
||||
});
|
||||
assert.deepStrictEqual(statePayload, {
|
||||
luckmailUsedPurchases: { 88: true, 99: false },
|
||||
luckmailPreserveTagId: 9,
|
||||
luckmailPreserveTagName: '保留邮箱',
|
||||
});
|
||||
});
|
||||
|
||||
test('listLuckmailPurchasesByProject only keeps openai purchases', async () => {
|
||||
@@ -879,3 +905,117 @@ return {
|
||||
assert.deepStrictEqual(snapshot.usedMarker, { purchaseId: 456, used: true });
|
||||
assert.equal(snapshot.logs.some((entry) => /已在本地标记为已用/.test(entry.message)), true);
|
||||
});
|
||||
|
||||
test('setLuckmailPurchaseUsedState persists used map to storage.local so reload keeps it non-reusable', async () => {
|
||||
const bundle = [
|
||||
extractFunction('getLuckmailUsedPurchases'),
|
||||
extractFunction('setLuckmailUsedPurchasesState'),
|
||||
extractFunction('setLuckmailPurchaseUsedState'),
|
||||
].join('\n');
|
||||
|
||||
const factory = new Function(`
|
||||
let sessionState = {
|
||||
luckmailUsedPurchases: { 7: true },
|
||||
};
|
||||
let persistentUpdates = [];
|
||||
let sessionUpdates = [];
|
||||
let broadcasts = [];
|
||||
function normalizeLuckmailPurchaseId(value) {
|
||||
const numeric = Number(value);
|
||||
return Number.isFinite(numeric) && numeric > 0 ? String(Math.floor(numeric)) : '';
|
||||
}
|
||||
function normalizeLuckmailUsedPurchases(value) {
|
||||
if (!value || typeof value !== 'object' || Array.isArray(value)) return {};
|
||||
return Object.entries(value).reduce((result, [key, used]) => {
|
||||
const normalizedKey = normalizeLuckmailPurchaseId(key);
|
||||
if (normalizedKey) result[normalizedKey] = Boolean(used);
|
||||
return result;
|
||||
}, {});
|
||||
}
|
||||
async function getState() {
|
||||
return { ...sessionState };
|
||||
}
|
||||
async function setPersistentSettings(updates) {
|
||||
persistentUpdates.push(updates);
|
||||
}
|
||||
async function setState(updates) {
|
||||
sessionUpdates.push(updates);
|
||||
sessionState = { ...sessionState, ...updates };
|
||||
}
|
||||
function broadcastDataUpdate(updates) {
|
||||
broadcasts.push(updates);
|
||||
}
|
||||
|
||||
${bundle}
|
||||
|
||||
return {
|
||||
setLuckmailPurchaseUsedState,
|
||||
snapshot() {
|
||||
return { sessionState, persistentUpdates, sessionUpdates, broadcasts };
|
||||
},
|
||||
};
|
||||
`);
|
||||
|
||||
const api = factory();
|
||||
const result = await api.setLuckmailPurchaseUsedState(88, true);
|
||||
const snapshot = api.snapshot();
|
||||
|
||||
assert.deepStrictEqual(result, { purchaseId: 88, used: true });
|
||||
assert.deepStrictEqual(snapshot.sessionState.luckmailUsedPurchases, { 7: true, 88: true });
|
||||
assert.deepStrictEqual(snapshot.persistentUpdates, [
|
||||
{ luckmailUsedPurchases: { 7: true, 88: true } },
|
||||
]);
|
||||
assert.deepStrictEqual(snapshot.sessionUpdates, [
|
||||
{ luckmailUsedPurchases: { 7: true, 88: true } },
|
||||
]);
|
||||
assert.deepStrictEqual(snapshot.broadcasts, [
|
||||
{ luckmailUsedPurchases: { 7: true, 88: true } },
|
||||
]);
|
||||
});
|
||||
|
||||
test('setLuckmailPreserveTagInfo persists tag cache to storage.local', async () => {
|
||||
const bundle = extractFunction('setLuckmailPreserveTagInfo');
|
||||
|
||||
const factory = new Function(`
|
||||
let persistentUpdates = [];
|
||||
let sessionUpdates = [];
|
||||
let broadcasts = [];
|
||||
const DEFAULT_LUCKMAIL_PRESERVE_TAG_NAME = '保留';
|
||||
function normalizeLuckmailTags(tags) {
|
||||
return (Array.isArray(tags) ? tags : []).map((tag) => ({
|
||||
id: Number(tag?.id) || 0,
|
||||
name: String(tag?.name || '').trim(),
|
||||
})).filter((tag) => tag.id > 0 || tag.name);
|
||||
}
|
||||
async function setPersistentSettings(updates) {
|
||||
persistentUpdates.push(updates);
|
||||
}
|
||||
async function setState(updates) {
|
||||
sessionUpdates.push(updates);
|
||||
}
|
||||
function broadcastDataUpdate(updates) {
|
||||
broadcasts.push(updates);
|
||||
}
|
||||
|
||||
${bundle}
|
||||
|
||||
return {
|
||||
setLuckmailPreserveTagInfo,
|
||||
snapshot() {
|
||||
return { persistentUpdates, sessionUpdates, broadcasts };
|
||||
},
|
||||
};
|
||||
`);
|
||||
|
||||
const api = factory();
|
||||
const result = await api.setLuckmailPreserveTagInfo({ id: '12', name: ' 保留邮箱 ' });
|
||||
const expected = {
|
||||
luckmailPreserveTagId: 12,
|
||||
luckmailPreserveTagName: '保留邮箱',
|
||||
};
|
||||
|
||||
assert.deepStrictEqual(result, expected);
|
||||
assert.deepStrictEqual(api.snapshot().persistentUpdates, [expected]);
|
||||
assert.deepStrictEqual(api.snapshot().sessionUpdates, [expected]);
|
||||
assert.deepStrictEqual(api.snapshot().broadcasts, [expected]);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user