mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-05-26 00:55:16 -07:00
feat: add auto update support (#65)
This commit is contained in:
@@ -44,7 +44,9 @@ function createDeps(overrides: Partial<UpdateServiceDeps> = {}) {
|
||||
calls.push('restart-dialog');
|
||||
return 'later';
|
||||
},
|
||||
quitAndInstall: () => calls.push('quit-install'),
|
||||
quitAndInstall: () => {
|
||||
calls.push('quit-install');
|
||||
},
|
||||
notifyUpdateAvailable: async (version) => {
|
||||
calls.push(`notify:${version}`);
|
||||
},
|
||||
@@ -90,6 +92,32 @@ test('manual update check falls back to GitHub release when app metadata is unav
|
||||
assert.deepEqual(calls, ['available-dialog:0.15.0']);
|
||||
});
|
||||
|
||||
test('manual update check reports available when no update asset was applied', async () => {
|
||||
const { deps, calls } = createDeps({
|
||||
checkAppUpdate: async () => ({ available: false, version: '0.14.0', canUpdate: false }),
|
||||
fetchLatestStableRelease: async () => ({
|
||||
tag_name: 'v0.15.0',
|
||||
prerelease: false,
|
||||
draft: false,
|
||||
assets: [],
|
||||
}),
|
||||
showUpdateAvailableDialog: async (version) => {
|
||||
calls.push(`available-dialog:${version}`);
|
||||
return 'update';
|
||||
},
|
||||
updateLauncher: async (_launcherPath, channel) => {
|
||||
calls.push(`launcher:${channel}`);
|
||||
return { status: 'skipped' };
|
||||
},
|
||||
});
|
||||
const service = createUpdateService(deps);
|
||||
|
||||
const result = await service.checkForUpdates({ source: 'manual' });
|
||||
|
||||
assert.equal(result.status, 'update-available');
|
||||
assert.deepEqual(calls, ['available-dialog:0.15.0', 'launcher:stable']);
|
||||
});
|
||||
|
||||
test('automatic update check skips inside configured interval', async () => {
|
||||
const { deps, calls, setState } = createDeps();
|
||||
setState({ lastAutomaticCheckAt: 1_000_000 - 60 * 60 * 1000 });
|
||||
@@ -141,6 +169,57 @@ test('concurrent update checks share one in-flight check', async () => {
|
||||
assert.equal(checkCount, 1);
|
||||
});
|
||||
|
||||
test('manual update check does not reuse in-flight automatic check', async () => {
|
||||
let checkCount = 0;
|
||||
const resolveChecks: Array<(value: { available: boolean; version: string }) => void> = [];
|
||||
const { deps } = createDeps({
|
||||
checkAppUpdate: () =>
|
||||
new Promise((resolve) => {
|
||||
checkCount += 1;
|
||||
resolveChecks.push(resolve);
|
||||
}),
|
||||
});
|
||||
const service = createUpdateService(deps);
|
||||
const automatic = service.checkForUpdates({ source: 'automatic', force: true });
|
||||
const manual = service.checkForUpdates({ source: 'manual' });
|
||||
|
||||
await Promise.resolve();
|
||||
assert.equal(checkCount, 2);
|
||||
for (const resolve of resolveChecks) {
|
||||
resolve({ available: false, version: '0.14.0' });
|
||||
}
|
||||
await Promise.all([automatic, manual]);
|
||||
});
|
||||
|
||||
test('manual update check passes selected GitHub release to launcher update', async () => {
|
||||
const selectedRelease = {
|
||||
tag_name: 'v0.15.0',
|
||||
prerelease: false,
|
||||
draft: false,
|
||||
assets: [],
|
||||
};
|
||||
let forwardedRelease: unknown;
|
||||
const { deps, calls } = createDeps({
|
||||
checkAppUpdate: async () => ({ available: true, version: '0.15.0' }),
|
||||
fetchLatestStableRelease: async () => selectedRelease,
|
||||
showUpdateAvailableDialog: async (version) => {
|
||||
calls.push(`available-dialog:${version}`);
|
||||
return 'update';
|
||||
},
|
||||
updateLauncher: (async (...args: unknown[]) => {
|
||||
calls.push(`launcher:${args[1]}`);
|
||||
forwardedRelease = args[2];
|
||||
return { status: 'updated' };
|
||||
}) as UpdateServiceDeps['updateLauncher'],
|
||||
});
|
||||
const service = createUpdateService(deps);
|
||||
|
||||
const result = await service.checkForUpdates({ source: 'manual' });
|
||||
|
||||
assert.equal(result.status, 'updated');
|
||||
assert.equal(forwardedRelease, selectedRelease);
|
||||
});
|
||||
|
||||
test('manual prerelease update check uses prerelease release and launcher channel', async () => {
|
||||
const { deps, calls } = createDeps({
|
||||
getConfig: () => ({
|
||||
|
||||
Reference in New Issue
Block a user