diff --git a/src/behaviours/update-app/installing-update-using-tray.test.ts b/src/behaviours/update-app/installing-update-using-tray.test.ts index a48d80d9be..7d94eea490 100644 --- a/src/behaviours/update-app/installing-update-using-tray.test.ts +++ b/src/behaviours/update-app/installing-update-using-tray.test.ts @@ -14,22 +14,21 @@ import type { AsyncFnMock } from "@async-fn/jest"; import asyncFn from "@async-fn/jest"; import type { UpdateChannel, UpdateChannelId } from "../../main/update-app/update-channels"; import { updateChannels } from "../../main/update-app/update-channels"; +import type { DownloadPlatformUpdate } from "../../main/update-app/download-platform-update/download-platform-update.injectable"; import downloadPlatformUpdateInjectable from "../../main/update-app/download-platform-update/download-platform-update.injectable"; import selectedUpdateChannelInjectable from "../../main/update-app/selected-update-channel.injectable"; -import progressOfUpdateDownloadInjectable from "../../main/update-app/progress-of-update-download.injectable"; import type { IComputedValue } from "mobx"; import setUpdateOnQuitInjectable from "../../main/electron-app/features/set-update-on-quit.injectable"; import showApplicationWindowInjectable from "../../main/start-main-application/lens-window/show-application-window.injectable"; import type { AskBoolean } from "../../main/ask-boolean/ask-boolean.injectable"; import askBooleanInjectable from "../../main/ask-boolean/ask-boolean.injectable"; -import showNotificationInjectable from "../../renderer/components/notifications/show-notification.injectable"; - +import progressOfUpdateDownloadInjectable from "../../common/application-update/progress-of-update-download/progress-of-update-download.injectable"; describe("installing update using tray", () => { let applicationBuilder: ApplicationBuilder; let quitAndInstallUpdateMock: jest.Mock; let checkForPlatformUpdatesMock: AsyncFnMock; - let downloadPlatformUpdateMock: AsyncFnMock<() => { downloadWasSuccessful: boolean }>; + let downloadPlatformUpdateMock: AsyncFnMock; let setUpdateOnQuitMock: jest.Mock; let showApplicationWindowMock: jest.Mock; let showNotificationMock: jest.Mock; @@ -38,7 +37,7 @@ describe("installing update using tray", () => { beforeEach(() => { applicationBuilder = getApplicationBuilder(); - applicationBuilder.beforeApplicationStart(({ mainDi, rendererDi }) => { + applicationBuilder.beforeApplicationStart(({ mainDi }) => { quitAndInstallUpdateMock = jest.fn(); checkForPlatformUpdatesMock = asyncFn(); downloadPlatformUpdateMock = asyncFn(); @@ -47,7 +46,6 @@ describe("installing update using tray", () => { showNotificationMock = jest.fn(() => () => {}); askBooleanMock = asyncFn(); - rendererDi.override(showNotificationInjectable, () => showNotificationMock); mainDi.override(askBooleanInjectable, () => askBooleanMock); mainDi.override(showApplicationWindowInjectable, () => showApplicationWindowMock); mainDi.override(setUpdateOnQuitInjectable, () => setUpdateOnQuitMock); @@ -111,13 +109,13 @@ describe("installing update using tray", () => { it("user cannot check for updates again", () => { expect( - applicationBuilder.tray.get("check-for-updates").enabled.get(), + applicationBuilder.tray.get("check-for-updates")?.enabled.get(), ).toBe(false); }); it("name of tray item for checking updates indicates that checking is happening", () => { expect( - applicationBuilder.tray.get("check-for-updates").label.get(), + applicationBuilder.tray.get("check-for-updates")?.label?.get(), ).toBe("Checking for updates..."); }); @@ -158,13 +156,13 @@ describe("installing update using tray", () => { it("user can check for updates again", () => { expect( - applicationBuilder.tray.get("check-for-updates").enabled.get(), + applicationBuilder.tray.get("check-for-updates")?.enabled.get(), ).toBe(true); }); it("name of tray item for checking updates no longer indicates that checking is happening", () => { expect( - applicationBuilder.tray.get("check-for-updates").label.get(), + applicationBuilder.tray.get("check-for-updates")?.label?.get(), ).toBe("Check for updates"); }); @@ -197,13 +195,13 @@ describe("installing update using tray", () => { it("user cannot check for updates again yet", () => { expect( - applicationBuilder.tray.get("check-for-updates").enabled.get(), + applicationBuilder.tray.get("check-for-updates")?.enabled.get(), ).toBe(false); }); it("name of tray item for checking updates indicates that downloading is happening", () => { expect( - applicationBuilder.tray.get("check-for-updates").label.get(), + applicationBuilder.tray.get("check-for-updates")?.label?.get(), ).toBe("Downloading update some-version (0%)..."); }); @@ -212,10 +210,10 @@ describe("installing update using tray", () => { progressOfUpdateDownloadInjectable, ); - progressOfUpdateDownload.setValue(42); + progressOfUpdateDownload.set(42); expect( - applicationBuilder.tray.get("check-for-updates").label.get(), + applicationBuilder.tray.get("check-for-updates")?.label?.get(), ).toBe("Downloading update some-version (42%)..."); }); @@ -244,7 +242,7 @@ describe("installing update using tray", () => { it("user can check for updates again", () => { expect( - applicationBuilder.tray.get("check-for-updates").enabled.get(), + applicationBuilder.tray.get("check-for-updates")?.enabled.get(), ).toBe(true); }); @@ -254,7 +252,7 @@ describe("installing update using tray", () => { it("name of tray item for checking updates no longer indicates that downloading is happening", () => { expect( - applicationBuilder.tray.get("check-for-updates").label.get(), + applicationBuilder.tray.get("check-for-updates")?.label?.get(), ).toBe("Check for updates"); }); @@ -278,19 +276,19 @@ describe("installing update using tray", () => { it("user can install update", () => { expect( - applicationBuilder.tray.get("install-update").label.get(), + applicationBuilder.tray.get("install-update")?.label?.get(), ).toBe("Install update some-version"); }); it("user can check for updates again", () => { expect( - applicationBuilder.tray.get("check-for-updates").enabled.get(), + applicationBuilder.tray.get("check-for-updates")?.enabled.get(), ).toBe(true); }); it("name of tray item for checking updates no longer indicates that downloading is happening", () => { expect( - applicationBuilder.tray.get("check-for-updates").label.get(), + applicationBuilder.tray.get("check-for-updates")?.label?.get(), ).toBe("Check for updates"); }); diff --git a/src/main/update-app/progress-of-update-download.injectable.ts b/src/common/application-update/progress-of-update-download/progress-of-update-download.injectable.ts similarity index 51% rename from src/main/update-app/progress-of-update-download.injectable.ts rename to src/common/application-update/progress-of-update-download/progress-of-update-download.injectable.ts index 9ecf8602e6..36fb0171f6 100644 --- a/src/main/update-app/progress-of-update-download.injectable.ts +++ b/src/common/application-update/progress-of-update-download/progress-of-update-download.injectable.ts @@ -3,21 +3,15 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import { action, computed, observable } from "mobx"; +import createSyncBoxInjectable from "../../sync-box/create-sync-box.injectable"; const progressOfUpdateDownloadInjectable = getInjectable({ - id: "progress-of-update-download", + id: "progress-of-update-download-state", - instantiate: () => { - const state = observable.box(0); + instantiate: (di) => { + const createSyncBox = di.inject(createSyncBoxInjectable); - return { - value: computed(() => state.get()), - - setValue: action((percentage: number) => { - state.set(percentage); - }), - }; + return createSyncBox("progress-of-update-download"); }, }); diff --git a/src/main/update-app/check-for-updates-tray-item.injectable.ts b/src/main/update-app/check-for-updates-tray-item.injectable.ts index 449e421ec9..9da2bf4ba4 100644 --- a/src/main/update-app/check-for-updates-tray-item.injectable.ts +++ b/src/main/update-app/check-for-updates-tray-item.injectable.ts @@ -6,7 +6,6 @@ import { getInjectable } from "@ogre-tools/injectable"; import { computed } from "mobx"; import updatingIsEnabledInjectable from "./updating-is-enabled.injectable"; import { trayMenuItemInjectionToken } from "../tray/tray-menu-item/tray-menu-item-injection-token"; -import progressOfUpdateDownloadInjectable from "./progress-of-update-download.injectable"; import showApplicationWindowInjectable from "../start-main-application/lens-window/show-application-window.injectable"; import showNotificationInjectable from "../show-notification/show-notification.injectable"; import askBooleanInjectable from "../ask-boolean/ask-boolean.injectable"; @@ -16,6 +15,7 @@ import downloadingUpdateStateInjectable from "../../common/application-update/do import checkingForUpdatesStateInjectable from "../../common/application-update/checking-for-updates/checking-for-updates-state.injectable"; import checkForUpdatesInjectable from "./check-for-updates/check-for-updates.injectable"; import downloadUpdateInjectable from "./download-update/download-update.injectable"; +import progressOfUpdateDownloadInjectable from "../../common/application-update/progress-of-update-download/progress-of-update-download.injectable"; const checkForUpdatesTrayItemInjectable = getInjectable({ id: "check-for-updates-tray-item", diff --git a/src/main/update-app/download-platform-update/download-platform-update.injectable.ts b/src/main/update-app/download-platform-update/download-platform-update.injectable.ts index cf4f5574bb..a8981fa89d 100644 --- a/src/main/update-app/download-platform-update/download-platform-update.injectable.ts +++ b/src/main/update-app/download-platform-update/download-platform-update.injectable.ts @@ -3,25 +3,25 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import type { ProgressInfo } from "electron-updater"; import electronUpdaterInjectable from "../../electron-app/features/electron-updater.injectable"; -import progressOfUpdateDownloadInjectable from "../progress-of-update-download.injectable"; import loggerInjectable from "../../../common/logger.injectable"; +import type { ProgressInfo } from "electron-updater"; + +export type DownloadPlatformUpdate = ( + onDownloadProgress: (percentage: number) => void +) => Promise<{ downloadWasSuccessful: boolean }>; const downloadPlatformUpdateInjectable = getInjectable({ id: "download-platform-update", - instantiate: (di) => { + instantiate: (di): DownloadPlatformUpdate => { const electronUpdater = di.inject(electronUpdaterInjectable); - const progressOfUpdateDownload = di.inject(progressOfUpdateDownloadInjectable); const logger = di.inject(loggerInjectable); - const updateDownloadProgress = ({ percent }: ProgressInfo) => { - progressOfUpdateDownload.setValue(percent); - }; + return async (onDownloadProgress) => { + onDownloadProgress(0); - return async () => { - progressOfUpdateDownload.setValue(0); + const updateDownloadProgress = ({ percent }: ProgressInfo) => onDownloadProgress(percent); electronUpdater.on("download-progress", updateDownloadProgress); diff --git a/src/main/update-app/download-platform-update/download-platform-update.test.ts b/src/main/update-app/download-platform-update/download-platform-update.test.ts index ef4d34e40c..df088e6bab 100644 --- a/src/main/update-app/download-platform-update/download-platform-update.test.ts +++ b/src/main/update-app/download-platform-update/download-platform-update.test.ts @@ -9,19 +9,17 @@ import type { AppUpdater } from "electron-updater"; import type { AsyncFnMock } from "@async-fn/jest"; import asyncFn from "@async-fn/jest"; import { getPromiseStatus } from "../../../common/test-utils/get-promise-status"; -import progressOfUpdateDownloadInjectable from "../progress-of-update-download.injectable"; import type { DiContainer } from "@ogre-tools/injectable"; import loggerInjectable from "../../../common/logger.injectable"; import type { Logger } from "../../../common/logger"; describe("download-platform-update", () => { - let downloadPlatformUpdate: () => Promise<{ downloadWasSuccessful: boolean }>; + let downloadPlatformUpdate: (onDownloadProgress: (percentage: number) => void) => Promise<{ downloadWasSuccessful: boolean }>; let downloadUpdateMock: AsyncFnMock<() => void>; let electronUpdaterFake: AppUpdater; let electronUpdaterOnMock: jest.Mock; let electronUpdaterOffMock: jest.Mock; let di: DiContainer; - let progressOfUpdateDownload: { value: { get: () => number }}; let logErrorMock: jest.Mock; beforeEach(() => { @@ -47,14 +45,16 @@ describe("download-platform-update", () => { di.override(loggerInjectable, () => ({ error: logErrorMock }) as unknown as Logger); downloadPlatformUpdate = di.inject(downloadPlatformUpdateInjectable); - progressOfUpdateDownload = di.inject(progressOfUpdateDownloadInjectable); }); describe("when called", () => { let actualPromise: Promise<{ downloadWasSuccessful: boolean }>; + let onDownloadProgressMock: jest.Mock; beforeEach(() => { - actualPromise = downloadPlatformUpdate(); + onDownloadProgressMock = jest.fn(); + + actualPromise = downloadPlatformUpdate(onDownloadProgressMock); }); it("calls for downloading of update", () => { @@ -68,11 +68,13 @@ describe("download-platform-update", () => { }); it("starts progress of download from 0", () => { - expect(progressOfUpdateDownload.value.get()).toBe(0); + expect(onDownloadProgressMock).toHaveBeenCalledWith(0); }); describe("when downloading progresses", () => { beforeEach(() => { + onDownloadProgressMock.mockClear(); + const [, callback] = electronUpdaterOnMock.mock.calls.find( ([event]) => event === "download-progress", ); @@ -87,11 +89,13 @@ describe("download-platform-update", () => { }); it("updates progress of the download", () => { - expect(progressOfUpdateDownload.value.get()).toBe(42); + expect(onDownloadProgressMock).toHaveBeenCalledWith(42); }); describe("when downloading resolves", () => { beforeEach(async () => { + onDownloadProgressMock.mockClear(); + await downloadUpdateMock.resolve(); }); @@ -102,7 +106,7 @@ describe("download-platform-update", () => { }); it("does not reset progress of download yet", () => { - expect(progressOfUpdateDownload.value.get()).toBe(42); + expect(onDownloadProgressMock).not.toHaveBeenCalled(); }); it("stops watching for download progress", () => { @@ -113,9 +117,9 @@ describe("download-platform-update", () => { }); it("when starting download again, resets progress of download", () => { - downloadPlatformUpdate(); + downloadPlatformUpdate(onDownloadProgressMock); - expect(progressOfUpdateDownload.value.get()).toBe(0); + expect(onDownloadProgressMock).toHaveBeenCalledWith(0); }); }); diff --git a/src/main/update-app/download-update/download-update.injectable.ts b/src/main/update-app/download-update/download-update.injectable.ts index 8ebc7b609c..4a0c740bc5 100644 --- a/src/main/update-app/download-update/download-update.injectable.ts +++ b/src/main/update-app/download-update/download-update.injectable.ts @@ -6,21 +6,31 @@ import { getInjectable } from "@ogre-tools/injectable"; import downloadPlatformUpdateInjectable from "../download-platform-update/download-platform-update.injectable"; import downloadingUpdateStateInjectable from "../../../common/application-update/downloading-update/downloading-update-state.injectable"; import discoveredVersionStateInjectable from "../../../common/application-update/discovered-version/discovered-version-state.injectable"; -import { runInAction } from "mobx"; +import { action, runInAction } from "mobx"; +import progressOfUpdateDownloadInjectable from "../../../common/application-update/progress-of-update-download/progress-of-update-download.injectable"; const downloadUpdateInjectable = getInjectable({ id: "download-update", + instantiate: (di) => { const downloadPlatformUpdate = di.inject(downloadPlatformUpdateInjectable); const downloadingUpdateState = di.inject(downloadingUpdateStateInjectable); const discoveredVersionState = di.inject(discoveredVersionStateInjectable); + const progressOfUpdateDownload = di.inject(progressOfUpdateDownloadInjectable); + + const updateDownloadProgress = action((percentage: number) => { + progressOfUpdateDownload.set(percentage); + }); return async () => { runInAction(() => { + progressOfUpdateDownload.set(0); downloadingUpdateState.set(true); }); - const { downloadWasSuccessful } = await downloadPlatformUpdate(); + const { downloadWasSuccessful } = await downloadPlatformUpdate( + updateDownloadProgress, + ); runInAction(() => { if (!downloadWasSuccessful) {