mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-05-26 12:55:16 -07:00
282 lines
8.6 KiB
TypeScript
282 lines
8.6 KiB
TypeScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import {
|
|
configureAutoUpdater,
|
|
createElectronAppUpdater,
|
|
isKnownLinuxPackageManagedAppImage,
|
|
isNativeUpdaterSupported,
|
|
resolveMacAppBundlePath,
|
|
type ElectronAutoUpdaterLike,
|
|
} from './app-updater';
|
|
|
|
type UpdaterLogger = {
|
|
info: (message: string) => void;
|
|
debug: (message: string) => void;
|
|
warn: (message: string) => void;
|
|
error: (message: string) => void;
|
|
};
|
|
|
|
test('configureAutoUpdater disables eager update behavior and suppresses info logging', () => {
|
|
const logged: string[] = [];
|
|
const updater: ElectronAutoUpdaterLike & { logger?: UpdaterLogger | null } = {
|
|
autoDownload: true,
|
|
allowPrerelease: true,
|
|
allowDowngrade: true,
|
|
logger: null,
|
|
checkForUpdates: async () => null,
|
|
downloadUpdate: async () => [],
|
|
quitAndInstall: () => {},
|
|
};
|
|
|
|
configureAutoUpdater(updater, (message) => logged.push(message));
|
|
|
|
assert.equal(updater.autoDownload, false);
|
|
assert.equal(updater.allowPrerelease, false);
|
|
assert.equal(updater.allowDowngrade, false);
|
|
assert.ok(updater.logger);
|
|
|
|
updater.logger.info('Checking for update');
|
|
updater.logger.debug('Generated new staging user ID');
|
|
updater.logger.warn('metadata missing');
|
|
updater.logger.error('download failed');
|
|
|
|
assert.deepEqual(logged, ['metadata missing', 'download failed']);
|
|
});
|
|
|
|
test('configureAutoUpdater allows prereleases only for the prerelease channel', () => {
|
|
const updater: ElectronAutoUpdaterLike = {
|
|
autoDownload: true,
|
|
allowPrerelease: false,
|
|
allowDowngrade: true,
|
|
logger: null,
|
|
checkForUpdates: async () => null,
|
|
downloadUpdate: async () => [],
|
|
quitAndInstall: () => {},
|
|
};
|
|
|
|
configureAutoUpdater(updater, () => {}, 'prerelease');
|
|
assert.equal(updater.allowPrerelease, true);
|
|
|
|
configureAutoUpdater(updater, () => {}, 'stable');
|
|
assert.equal(updater.allowPrerelease, false);
|
|
});
|
|
|
|
test('configureAutoUpdater handles late updater error events', () => {
|
|
const logged: string[] = [];
|
|
const errorListeners: Array<(error: unknown) => void> = [];
|
|
const updater: ElectronAutoUpdaterLike & {
|
|
on: (event: string, listener: (error: unknown) => void) => typeof updater;
|
|
} = {
|
|
autoDownload: true,
|
|
allowPrerelease: false,
|
|
allowDowngrade: true,
|
|
logger: null,
|
|
checkForUpdates: async () => null,
|
|
downloadUpdate: async () => [],
|
|
quitAndInstall: () => {},
|
|
on: (event, listener) => {
|
|
if (event === 'error') errorListeners.push(listener);
|
|
return updater;
|
|
},
|
|
};
|
|
|
|
configureAutoUpdater(updater, (message) => logged.push(message));
|
|
|
|
const [errorListener] = errorListeners;
|
|
assert.ok(errorListener);
|
|
errorListener(new Error('APPIMAGE env is not defined'));
|
|
assert.deepEqual(logged, ['Updater error event: APPIMAGE env is not defined']);
|
|
});
|
|
|
|
test('app updater skips native update checks when native updater is unsupported', async () => {
|
|
let checked = false;
|
|
const updater: ElectronAutoUpdaterLike = {
|
|
autoDownload: true,
|
|
allowPrerelease: false,
|
|
allowDowngrade: true,
|
|
logger: null,
|
|
checkForUpdates: async () => {
|
|
checked = true;
|
|
return {
|
|
updateInfo: {
|
|
version: '0.15.0',
|
|
},
|
|
};
|
|
},
|
|
downloadUpdate: async () => [],
|
|
quitAndInstall: () => {},
|
|
};
|
|
const logged: string[] = [];
|
|
const appUpdater = createElectronAppUpdater({
|
|
currentVersion: '0.14.0',
|
|
isPackaged: true,
|
|
updater,
|
|
log: (message) => logged.push(message),
|
|
isNativeUpdaterSupported: () => false,
|
|
});
|
|
|
|
const result = await appUpdater.checkForUpdates('stable');
|
|
|
|
assert.equal(checked, false);
|
|
assert.deepEqual(result, {
|
|
available: false,
|
|
version: '0.14.0',
|
|
canUpdate: false,
|
|
});
|
|
assert.deepEqual(logged, [
|
|
'Skipping native app update check because native updater is unsupported.',
|
|
]);
|
|
});
|
|
|
|
test('app updater skips native downloads when native updater is unsupported', async () => {
|
|
let downloaded = false;
|
|
const updater: ElectronAutoUpdaterLike = {
|
|
autoDownload: true,
|
|
allowPrerelease: false,
|
|
allowDowngrade: true,
|
|
logger: null,
|
|
checkForUpdates: async () => null,
|
|
downloadUpdate: async () => {
|
|
downloaded = true;
|
|
return [];
|
|
},
|
|
quitAndInstall: () => {},
|
|
};
|
|
const logged: string[] = [];
|
|
const appUpdater = createElectronAppUpdater({
|
|
currentVersion: '0.14.0',
|
|
isPackaged: true,
|
|
updater,
|
|
log: (message) => logged.push(message),
|
|
isNativeUpdaterSupported: () => false,
|
|
});
|
|
|
|
await appUpdater.downloadUpdate();
|
|
|
|
assert.equal(downloaded, false);
|
|
assert.deepEqual(logged, ['Skipping app update download because native updater is unsupported.']);
|
|
});
|
|
|
|
test('resolveMacAppBundlePath resolves packaged macOS executable path', () => {
|
|
assert.equal(
|
|
resolveMacAppBundlePath('/Applications/SubMiner.app/Contents/MacOS/SubMiner'),
|
|
'/Applications/SubMiner.app',
|
|
);
|
|
assert.equal(resolveMacAppBundlePath('/usr/local/bin/SubMiner'), null);
|
|
});
|
|
|
|
test('mac native updater is unsupported for ad-hoc signed app bundles', async () => {
|
|
const logged: string[] = [];
|
|
const supported = await isNativeUpdaterSupported({
|
|
platform: 'darwin',
|
|
isPackaged: true,
|
|
execPath: '/Applications/SubMiner.app/Contents/MacOS/SubMiner',
|
|
readCodeSignature: () =>
|
|
['Signature=adhoc', 'TeamIdentifier=not set', 'Runtime Version=26.0.0'].join('\n'),
|
|
log: (message) => logged.push(message),
|
|
});
|
|
|
|
assert.equal(supported, false);
|
|
assert.deepEqual(logged, ['Skipping native macOS updater because this build is ad-hoc signed.']);
|
|
});
|
|
|
|
test('mac native updater is supported for Developer ID signed app bundles', async () => {
|
|
const supported = await isNativeUpdaterSupported({
|
|
platform: 'darwin',
|
|
isPackaged: true,
|
|
execPath: '/Applications/SubMiner.app/Contents/MacOS/SubMiner',
|
|
readCodeSignature: () =>
|
|
['Authority=Developer ID Application: Example', 'TeamIdentifier=ABCDE12345'].join('\n'),
|
|
});
|
|
|
|
assert.equal(supported, true);
|
|
});
|
|
|
|
test('linux native updater is unsupported even for writable direct AppImage installs', async () => {
|
|
const logged: string[] = [];
|
|
const supported = await isNativeUpdaterSupported({
|
|
platform: 'linux',
|
|
isPackaged: true,
|
|
execPath: '/tmp/.mount_SubMiner/SubMiner',
|
|
env: {
|
|
APPIMAGE: '/home/tester/.local/bin/SubMiner.AppImage',
|
|
},
|
|
log: (message) => logged.push(message),
|
|
});
|
|
|
|
assert.equal(supported, false);
|
|
assert.deepEqual(logged, [
|
|
'Skipping native Linux updater because Linux tray checks use GitHub release assets.',
|
|
]);
|
|
});
|
|
|
|
test('linux native updater is unsupported when APPIMAGE is missing', async () => {
|
|
const logged: string[] = [];
|
|
const supported = await isNativeUpdaterSupported({
|
|
platform: 'linux',
|
|
isPackaged: true,
|
|
execPath: '/tmp/.mount_SubMiner/SubMiner',
|
|
env: {},
|
|
log: (message) => logged.push(message),
|
|
});
|
|
|
|
assert.equal(supported, false);
|
|
assert.deepEqual(logged, [
|
|
'Skipping native Linux updater because Linux tray checks use GitHub release assets.',
|
|
]);
|
|
});
|
|
|
|
test('linux native updater is unsupported for non-writable AppImage installs', async () => {
|
|
const logged: string[] = [];
|
|
const supported = await isNativeUpdaterSupported({
|
|
platform: 'linux',
|
|
isPackaged: true,
|
|
execPath: '/tmp/.mount_SubMiner/SubMiner',
|
|
env: {
|
|
APPIMAGE: '/home/tester/.local/bin/SubMiner.AppImage',
|
|
},
|
|
log: (message) => logged.push(message),
|
|
});
|
|
|
|
assert.equal(supported, false);
|
|
assert.deepEqual(logged, [
|
|
'Skipping native Linux updater because Linux tray checks use GitHub release assets.',
|
|
]);
|
|
});
|
|
|
|
test('linux native updater is unsupported for package-managed AppImage installs', async () => {
|
|
const logged: string[] = [];
|
|
const supported = await isNativeUpdaterSupported({
|
|
platform: 'linux',
|
|
isPackaged: true,
|
|
execPath: '/tmp/.mount_SubMiner/SubMiner',
|
|
env: {
|
|
APPIMAGE: '/opt/SubMiner/SubMiner.AppImage',
|
|
},
|
|
log: (message) => logged.push(message),
|
|
});
|
|
|
|
assert.equal(supported, false);
|
|
assert.deepEqual(logged, [
|
|
'Skipping native Linux updater because Linux tray checks use GitHub release assets.',
|
|
]);
|
|
});
|
|
|
|
test('known Linux package-managed AppImage detection follows the canonical AUR path', () => {
|
|
assert.equal(isKnownLinuxPackageManagedAppImage('/opt/SubMiner/SubMiner.AppImage'), true);
|
|
assert.equal(
|
|
isKnownLinuxPackageManagedAppImage('/home/tester/.local/bin/SubMiner.AppImage'),
|
|
false,
|
|
);
|
|
});
|
|
|
|
test('native updater is unsupported on Windows by default', async () => {
|
|
const supported = await isNativeUpdaterSupported({
|
|
platform: 'win32',
|
|
isPackaged: true,
|
|
execPath: 'C:\\Program Files\\SubMiner\\SubMiner.exe',
|
|
});
|
|
|
|
assert.equal(supported, false);
|
|
});
|