fix(desktop): update from the splash only after the user clicks (#3280)

This commit is contained in:
Hampus authored and GitHub committed 2026-10-08 17:25:34 +02:00
1 parent f1373a63c3
commit 7937d5f802
90 files changed
+6888 -11255

No files matched your search

@@ -0,0 +1,77 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import assert from 'node:assert/strict';
import {describe, test} from 'node:test';
import {installElectronStub} from './LocalAppTestSupport.test.mjs';
installElectronStub();
const {
armDesktopUpdate,
checkDesktopUpdateNow,
getDesktopUpdateState,
observeDesktopUpdateState,
publishDesktopUpdateCheck,
startDesktopUpdate,
} = await import('@electron/main/DesktopUpdateGate');
function deferred() {
let resolve;
const promise = new Promise((resolvePromise) => {
resolve = resolvePromise;
});
return {promise, resolve};
}
describe('DesktopUpdateGate', () => {
test('nothing is available and nothing starts before the bootstrap arms the gate', async () => {
assert.deepEqual(getDesktopUpdateState(), {available: false});
assert.deepEqual(await checkDesktopUpdateNow(), {available: false});
assert.equal(startDesktopUpdate(), false);
});
test('a check publishes the update and one click runs it exactly once', async () => {
const states = [];
const stop = observeDesktopUpdateState((state) => states.push(state.available));
const running = deferred();
let starts = 0;
armDesktopUpdate({
check: async () => ({shellNewer: false, modulesChanged: true}),
start: async () => {
starts += 1;
await running.promise;
publishDesktopUpdateCheck({shellNewer: false, modulesChanged: false});
},
});
assert.deepEqual(await checkDesktopUpdateNow(), {available: true});
assert.equal(startDesktopUpdate(), true);
assert.equal(startDesktopUpdate(), false, 'a second click while the update runs is a no-op');
assert.deepEqual(getDesktopUpdateState(), {available: false}, 'the affordance hides the moment it is clicked');
assert.deepEqual(await checkDesktopUpdateNow(), {available: false}, 'a poll during the update changes nothing');
running.resolve();
await new Promise((resolve) => setImmediate(resolve));
assert.equal(starts, 1);
assert.deepEqual(getDesktopUpdateState(), {available: false});
assert.deepEqual(states, [true, false]);
stop();
});
test('a shell update that could not finish stays available for the next click', async () => {
armDesktopUpdate({
check: async () => ({shellNewer: true, modulesChanged: false}),
start: async () => {
publishDesktopUpdateCheck({shellNewer: true, modulesChanged: false});
},
});
await checkDesktopUpdateNow();
assert.equal(startDesktopUpdate(), true);
await new Promise((resolve) => setImmediate(resolve));
assert.deepEqual(getDesktopUpdateState(), {available: true});
assert.equal(startDesktopUpdate(), true);
});
});