mirror of
https://github.com/amitwh/markdown-converter.git
synced 2026-10-01 17:29:29 +05:30
electron-updater integration so users get fixes automatically:
- new dependency electron-updater@^6.6.2 in package.json
- electron-builder.config.js publishes to GitHub releases
(owner: concreteinfo, repo: markdownconverter)
- new src/main/auto-updater.js wraps autoUpdater: wires the six
lifecycle events to a 'updates:status' IPC channel, exposes
check() and install() helpers, dev-gates via isDev(), and
swallows the 'missing app-update.yml' error that dev runs hit
- main.js: ensureAutoUpdater() forwards status to the renderer
via mainWindow.webContents.send; ipcMain handlers for
'updates:check' (invoke) and 'updates:install' (invoke)
- preload.js: 'updates:check' / 'updates:install' added to
ALLOWED_SEND_CHANNELS; 'updates:status' added to receive
channels; electronAPI.updates.{check, install, onStatus}
exposed
7 new tests cover event registration, dev-gate behaviour,
'not-available' fallback for missing app-update.yml, typed event
payloads, error forwarding, and install() quitAndInstall.
Amit Haridas
115 lines
3.4 KiB
JavaScript
115 lines
3.4 KiB
JavaScript
/**
|
|
* @jest-environment node
|
|
*
|
|
* Auto-updater — unit test the controller without bringing up electron.
|
|
* The electron-updater module is mocked because the real one requires the
|
|
* Electron app to be initialised.
|
|
*/
|
|
|
|
const mockAutoUpdater = {
|
|
on: jest.fn(),
|
|
autoDownload: false,
|
|
autoInstallOnAppQuit: false,
|
|
checkForUpdates: jest.fn().mockResolvedValue(null),
|
|
quitAndInstall: jest.fn(),
|
|
};
|
|
|
|
jest.mock('electron-updater', () => ({ autoUpdater: mockAutoUpdater }), { virtual: true });
|
|
|
|
const { setupAutoUpdater } = require('../src/main/auto-updater');
|
|
|
|
describe('setupAutoUpdater', () => {
|
|
let send;
|
|
let updater;
|
|
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
mockAutoUpdater.on.mockReset();
|
|
send = jest.fn();
|
|
updater = setupAutoUpdater({ send });
|
|
});
|
|
|
|
test('registers all six event handlers', () => {
|
|
const events = mockAutoUpdater.on.mock.calls.map((c) => c[0]);
|
|
expect(events).toEqual(
|
|
expect.arrayContaining([
|
|
'checking-for-update',
|
|
'update-available',
|
|
'update-not-available',
|
|
'download-progress',
|
|
'update-downloaded',
|
|
'error',
|
|
])
|
|
);
|
|
});
|
|
|
|
test('enables autoDownload and autoInstallOnAppQuit', () => {
|
|
expect(mockAutoUpdater.autoDownload).toBe(true);
|
|
expect(mockAutoUpdater.autoInstallOnAppQuit).toBe(true);
|
|
});
|
|
|
|
test('check() forwards "not-available" when app-update.yml is missing (dev)', async () => {
|
|
mockAutoUpdater.checkForUpdates.mockRejectedValueOnce(
|
|
new Error('Cannot find any update manifest (app-update.yml) in resources')
|
|
);
|
|
await updater.check();
|
|
expect(send).toHaveBeenCalledWith('updates:status', { state: 'not-available' });
|
|
});
|
|
|
|
test('check() forwards "error" for non-benign failures', async () => {
|
|
mockAutoUpdater.checkForUpdates.mockRejectedValueOnce(new Error('network down'));
|
|
await updater.check();
|
|
expect(send).toHaveBeenCalledWith('updates:status', {
|
|
state: 'error',
|
|
message: 'network down',
|
|
});
|
|
});
|
|
|
|
test('check() respects isDev() and does not invoke autoUpdater', async () => {
|
|
const isDev = jest.fn(() => true);
|
|
const u2 = setupAutoUpdater({ send, isDev });
|
|
await u2.check();
|
|
expect(isDev).toHaveBeenCalled();
|
|
expect(mockAutoUpdater.checkForUpdates).not.toHaveBeenCalled();
|
|
});
|
|
|
|
test('install() calls quitAndInstall', () => {
|
|
updater.install();
|
|
expect(mockAutoUpdater.quitAndInstall).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
test('forwarded events carry typed payloads', () => {
|
|
// Find each handler and invoke it; assert what got sent.
|
|
const map = new Map();
|
|
for (const [event, cb] of mockAutoUpdater.on.mock.calls) map.set(event, cb);
|
|
|
|
send.mockClear();
|
|
map.get('checking-for-update')();
|
|
expect(send).toHaveBeenLastCalledWith('updates:status', { state: 'checking' });
|
|
|
|
map.get('update-available')({ version: '4.13.0' });
|
|
expect(send).toHaveBeenLastCalledWith('updates:status', {
|
|
state: 'available',
|
|
version: '4.13.0',
|
|
});
|
|
|
|
map.get('download-progress')({ percent: 42.7 });
|
|
expect(send).toHaveBeenLastCalledWith('updates:status', {
|
|
state: 'downloading',
|
|
percent: 43,
|
|
});
|
|
|
|
map.get('update-downloaded')({ version: '4.13.0' });
|
|
expect(send).toHaveBeenLastCalledWith('updates:status', {
|
|
state: 'downloaded',
|
|
version: '4.13.0',
|
|
});
|
|
|
|
map.get('error')(new Error('boom'));
|
|
expect(send).toHaveBeenLastCalledWith('updates:status', {
|
|
state: 'error',
|
|
message: 'boom',
|
|
});
|
|
});
|
|
});
|