feat: 增加对自动运行状态的管理,优化轮数同步逻辑及相关测试

This commit is contained in:
QLHazyCoder
2026-05-04 14:20:38 +08:00
parent 104e629394
commit 5d70d2b681
5 changed files with 185 additions and 9 deletions
+78
View File
@@ -157,6 +157,84 @@ return {
assert.equal(api.isDisabled(), true);
});
test('sidepanel pending auto-run start ignores stale active run count sync', () => {
const source = fs.readFileSync('sidepanel/sidepanel.js', 'utf8');
const bundle = [
extractFunction(source, 'hasOwnStateValue'),
extractFunction(source, 'readAutoRunStateValue'),
extractFunction(source, 'normalizePendingAutoRunStartRunCount'),
extractFunction(source, 'registerPendingAutoRunStartRunCount'),
extractFunction(source, 'clearPendingAutoRunStartRunCount'),
extractFunction(source, 'getPendingAutoRunStartRunCount'),
extractFunction(source, 'getAutoRunSourceTotalRuns'),
extractFunction(source, 'syncAutoRunState'),
extractFunction(source, 'isAutoRunLockedPhase'),
extractFunction(source, 'isAutoRunPausedPhase'),
extractFunction(source, 'isAutoRunScheduledPhase'),
extractFunction(source, 'isAutoRunSourceSyncPhase'),
extractFunction(source, 'shouldSyncRunCountFromAutoRunSource'),
extractFunction(source, 'applyAutoRunStatus'),
].join('\n');
const api = new Function(`
let currentAutoRun = {
autoRunning: false,
phase: 'idle',
currentRun: 0,
totalRuns: 1,
attemptRun: 0,
scheduledAt: null,
countdownAt: null,
countdownTitle: '',
countdownNote: '',
};
let pendingAutoRunStartTotalRuns = 0;
let pendingAutoRunStartExpiresAt = 0;
const inputRunCount = { value: '20', disabled: false };
const btnAutoRun = { disabled: false, innerHTML: '' };
const btnFetchEmail = { disabled: false };
const inputEmail = { disabled: false };
const inputAutoSkipFailures = { disabled: false };
const autoContinueBar = { style: { display: '' } };
function setSettingsCardLocked() {}
function getAutoRunLabel() { return ''; }
function getLockedRunCountFromEmailPool() { return 0; }
function isCustomMailProvider() { return false; }
function usesCustomEmailPoolGenerator() { return false; }
function setDefaultAutoRunButton() {}
function updateAutoDelayInputState() {}
function updateFallbackThreadIntervalInputState() {}
function syncScheduledCountdownTicker() {}
function updateStopButtonState() {}
function getStepStatuses() { return {}; }
function updateConfigMenuControls() {}
function renderContributionMode() {}
${bundle}
return {
applyAutoRunStatus,
registerPendingAutoRunStartRunCount,
getValue() {
return inputRunCount.value;
},
getPending() {
return pendingAutoRunStartTotalRuns;
},
};
`)();
api.registerPendingAutoRunStartRunCount(20);
api.applyAutoRunStatus({ autoRunning: true, autoRunPhase: 'running', autoRunTotalRuns: 1 });
assert.equal(api.getValue(), '20');
assert.equal(api.getPending(), 20);
api.applyAutoRunStatus({ autoRunning: true, autoRunPhase: 'running', autoRunTotalRuns: 20 });
assert.equal(api.getValue(), '20');
assert.equal(api.getPending(), 0);
});
test('background normalizeRunCount no longer clamps values to 50', () => {
const source = fs.readFileSync('background.js', 'utf8');
const bundle = extractFunction(source, 'normalizeRunCount');
@@ -56,8 +56,14 @@ function createApi({
plusRiskConfirmed = true,
plusRiskDismissPrompt = false,
plusContributionImpl,
persistImpl,
} = {}) {
const bundle = extractFunction('startAutoRunFromCurrentSettings');
const bundle = [
extractFunction('normalizePendingAutoRunStartRunCount'),
extractFunction('registerPendingAutoRunStartRunCount'),
extractFunction('clearPendingAutoRunStartRunCount'),
extractFunction('startAutoRunFromCurrentSettings'),
].join('\n');
return new Function(`
const events = [];
@@ -72,6 +78,9 @@ const inputAutoDelayEnabled = { checked: false };
const inputAutoDelayMinutes = { value: '30' };
const btnAutoRun = { disabled: false, innerHTML: '' };
const inputRunCount = { disabled: false };
let runCountValue = ${Math.max(1, Number(runCount) || 1)};
let pendingAutoRunStartTotalRuns = 0;
let pendingAutoRunStartExpiresAt = 0;
const chrome = {
runtime: {
async sendMessage(message) {
@@ -87,8 +96,16 @@ const console = {
};
async function persistCurrentSettingsForAction() {
events.push({ type: 'sync-settings' });
${persistImpl ? `return (${persistImpl})(events, {
setRunCount(value) {
runCountValue = Math.max(1, Number(value) || 1);
},
getRunCount() {
return runCountValue;
},
});` : ''}
}
function getRunCountValue() { return ${Math.max(1, Number(runCount) || 1)}; }
function getRunCountValue() { return Math.max(1, Number(runCountValue) || 1); }
function normalizeAutoRunThreadIntervalMinutes(value) { return Number(value) || 0; }
function shouldOfferAutoModeChoice() { return false; }
async function openAutoStartChoiceDialog() { throw new Error('should not be called'); }
@@ -177,6 +194,26 @@ test('startAutoRunFromCurrentSettings does not block auto run when contribution
);
});
test('startAutoRunFromCurrentSettings freezes run count before async settings sync can repaint it', async () => {
const api = createApi({
runCount: 20,
persistImpl: `(events, controls) => {
controls.setRunCount(1);
events.push({ type: 'stale-status-reset', runCount: controls.getRunCount() });
}`,
});
const result = await api.startAutoRunFromCurrentSettings();
const events = api.getEvents();
assert.equal(result, true);
assert.deepEqual(
events.map((entry) => entry.type),
['refresh', 'sync-settings', 'stale-status-reset', 'send']
);
assert.equal(events[3].message.payload.totalRuns, 20);
});
test('startAutoRunFromCurrentSettings shows Plus risk warning before starting more than 3 runs', async () => {
const api = createApi({
runCount: 4,