diff --git a/app/autoUpdater.js b/app/autoUpdater.js index bb06b74..174baaf 100644 --- a/app/autoUpdater.js +++ b/app/autoUpdater.js @@ -140,6 +140,7 @@ async function downloadUpdate() { await autoUpdater.downloadUpdate(); } catch (err) { logger.error("Download failed:", err.message); + throw err; } } diff --git a/public/script/autoUpdate.js b/public/script/autoUpdate.js index f8fbcad..af0b553 100644 --- a/public/script/autoUpdate.js +++ b/public/script/autoUpdate.js @@ -45,13 +45,31 @@ async function initUpdateUI() { return; } - btn.onclick = () => { - window.electronAPI.downloadUpdate(); + const initialButtonText = btn.textContent; + const initialIconText = icon.textContent; + const initialTitleText = title.textContent; + const initialSubText = sub.textContent; + + btn.onclick = async () => { btn.disabled = true; btn.textContent = "Downloading..."; icon.textContent = "download"; title.textContent = "Downloading update"; progressWrap.style.display = "flex"; + + try { + await window.electronAPI.downloadUpdate(); + } catch { + btn.disabled = false; + btn.textContent = initialButtonText; + icon.textContent = initialIconText; + title.textContent = initialTitleText; + sub.textContent = initialSubText; + progressWrap.style.display = "none"; + progressFill.style.width = "0%"; + progressPct.textContent = "0%"; + progressEta.textContent = ""; + } }; window.electronAPI.onDownloadProgress((progress) => { diff --git a/test/unit/autoUpdater.test.js b/test/unit/autoUpdater.test.js new file mode 100644 index 0000000..cf0da48 --- /dev/null +++ b/test/unit/autoUpdater.test.js @@ -0,0 +1,53 @@ +const mockDownloadUpdate = jest.fn(); +const mockCheckForUpdates = jest.fn(); +const mockOn = jest.fn(); +const mockQuitAndInstall = jest.fn(); + +jest.mock("electron-updater", () => ({ + autoUpdater: { + autoDownload: true, + autoInstallOnAppQuit: true, + on: mockOn, + checkForUpdates: mockCheckForUpdates, + downloadUpdate: mockDownloadUpdate, + quitAndInstall: mockQuitAndInstall, + }, +})); + +jest.mock("electron", () => ({ + app: { + isPackaged: true, + }, +})); + +const mockLoggerError = jest.fn(); +jest.mock("../../server/logger", () => ({ + logger: { + info: jest.fn(), + warn: jest.fn(), + error: mockLoggerError, + }, +})); + +const { downloadUpdate } = require("../../app/autoUpdater"); + +describe("autoUpdater.downloadUpdate", () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + test("resolves when electron-updater download succeeds", async () => { + mockDownloadUpdate.mockResolvedValue(undefined); + + await expect(downloadUpdate()).resolves.toBeUndefined(); + expect(mockDownloadUpdate).toHaveBeenCalledTimes(1); + }); + + test("rejects when electron-updater download fails", async () => { + const error = new Error("network down"); + mockDownloadUpdate.mockRejectedValue(error); + + await expect(downloadUpdate()).rejects.toThrow("network down"); + expect(mockLoggerError).toHaveBeenCalledWith("Download failed:", "network down"); + }); +});