mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Start installing updates automatically when quitting application
Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
This commit is contained in:
parent
e3579d82cb
commit
244f283998
@ -18,12 +18,14 @@ import downloadPlatformUpdateInjectable from "../../main/update-app/download-pla
|
|||||||
import selectedUpdateChannelInjectable from "../../main/update-app/selected-update-channel.injectable";
|
import selectedUpdateChannelInjectable from "../../main/update-app/selected-update-channel.injectable";
|
||||||
import progressOfUpdateDownloadInjectable from "../../main/update-app/progress-of-update-download.injectable";
|
import progressOfUpdateDownloadInjectable from "../../main/update-app/progress-of-update-download.injectable";
|
||||||
import type { IComputedValue } from "mobx";
|
import type { IComputedValue } from "mobx";
|
||||||
|
import setUpdateOnQuitInjectable from "../../main/electron-app/features/set-update-on-quit.injectable";
|
||||||
|
|
||||||
describe("installing update using tray", () => {
|
describe("installing update using tray", () => {
|
||||||
let applicationBuilder: ApplicationBuilder;
|
let applicationBuilder: ApplicationBuilder;
|
||||||
let quitAndInstallUpdateMock: jest.Mock;
|
let quitAndInstallUpdateMock: jest.Mock;
|
||||||
let checkForPlatformUpdatesMock: AsyncFnMock<CheckForPlatformUpdates>;
|
let checkForPlatformUpdatesMock: AsyncFnMock<CheckForPlatformUpdates>;
|
||||||
let downloadPlatformUpdateMock: AsyncFnMock<() => void>;
|
let downloadPlatformUpdateMock: AsyncFnMock<() => void>;
|
||||||
|
let setUpdateOnQuitMock: jest.Mock;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
applicationBuilder = getApplicationBuilder();
|
applicationBuilder = getApplicationBuilder();
|
||||||
@ -32,6 +34,9 @@ describe("installing update using tray", () => {
|
|||||||
quitAndInstallUpdateMock = jest.fn();
|
quitAndInstallUpdateMock = jest.fn();
|
||||||
checkForPlatformUpdatesMock = asyncFn();
|
checkForPlatformUpdatesMock = asyncFn();
|
||||||
downloadPlatformUpdateMock = asyncFn();
|
downloadPlatformUpdateMock = asyncFn();
|
||||||
|
setUpdateOnQuitMock = jest.fn();
|
||||||
|
|
||||||
|
mainDi.override(setUpdateOnQuitInjectable, () => setUpdateOnQuitMock);
|
||||||
|
|
||||||
mainDi.override(
|
mainDi.override(
|
||||||
checkForPlatformUpdatesInjectable,
|
checkForPlatformUpdatesInjectable,
|
||||||
@ -150,7 +155,7 @@ describe("installing update using tray", () => {
|
|||||||
await checkForUpdatesPromise;
|
await checkForUpdatesPromise;
|
||||||
});
|
});
|
||||||
|
|
||||||
it("starts downloading the update!?!?", () => {
|
it("starts downloading the update", () => {
|
||||||
expect(downloadPlatformUpdateMock).toHaveBeenCalled();
|
expect(downloadPlatformUpdateMock).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -289,7 +294,9 @@ describe("installing update using tray", () => {
|
|||||||
it("when update is discovered, does not check update from other update channels", async () => {
|
it("when update is discovered, does not check update from other update channels", async () => {
|
||||||
checkForPlatformUpdatesMock.mockClear();
|
checkForPlatformUpdatesMock.mockClear();
|
||||||
|
|
||||||
await checkForPlatformUpdatesMock.resolve({ updateWasDiscovered: true });
|
await checkForPlatformUpdatesMock.resolve({
|
||||||
|
updateWasDiscovered: true,
|
||||||
|
});
|
||||||
|
|
||||||
expect(checkForPlatformUpdatesMock).not.toHaveBeenCalled();
|
expect(checkForPlatformUpdatesMock).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
@ -298,7 +305,9 @@ describe("installing update using tray", () => {
|
|||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
checkForPlatformUpdatesMock.mockClear();
|
checkForPlatformUpdatesMock.mockClear();
|
||||||
|
|
||||||
await checkForPlatformUpdatesMock.resolve({ updateWasDiscovered: false });
|
await checkForPlatformUpdatesMock.resolve({
|
||||||
|
updateWasDiscovered: false,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('checks updates from update channel "beta"', () => {
|
it('checks updates from update channel "beta"', () => {
|
||||||
@ -310,7 +319,9 @@ describe("installing update using tray", () => {
|
|||||||
it("when update is discovered, does not check update from other update channels", async () => {
|
it("when update is discovered, does not check update from other update channels", async () => {
|
||||||
checkForPlatformUpdatesMock.mockClear();
|
checkForPlatformUpdatesMock.mockClear();
|
||||||
|
|
||||||
await checkForPlatformUpdatesMock.resolve({ updateWasDiscovered: true });
|
await checkForPlatformUpdatesMock.resolve({
|
||||||
|
updateWasDiscovered: true,
|
||||||
|
});
|
||||||
|
|
||||||
expect(checkForPlatformUpdatesMock).not.toHaveBeenCalled();
|
expect(checkForPlatformUpdatesMock).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
@ -319,7 +330,9 @@ describe("installing update using tray", () => {
|
|||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
checkForPlatformUpdatesMock.mockClear();
|
checkForPlatformUpdatesMock.mockClear();
|
||||||
|
|
||||||
await checkForPlatformUpdatesMock.resolve({ updateWasDiscovered: false });
|
await checkForPlatformUpdatesMock.resolve({
|
||||||
|
updateWasDiscovered: false,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('finally checks updates from update channel "latest"', () => {
|
it('finally checks updates from update channel "latest"', () => {
|
||||||
@ -331,13 +344,67 @@ describe("installing update using tray", () => {
|
|||||||
it("when update is discovered, does not check update from other update channels", async () => {
|
it("when update is discovered, does not check update from other update channels", async () => {
|
||||||
checkForPlatformUpdatesMock.mockClear();
|
checkForPlatformUpdatesMock.mockClear();
|
||||||
|
|
||||||
await checkForPlatformUpdatesMock.resolve({ updateWasDiscovered: true });
|
await checkForPlatformUpdatesMock.resolve({
|
||||||
|
updateWasDiscovered: true,
|
||||||
|
});
|
||||||
|
|
||||||
expect(checkForPlatformUpdatesMock).not.toHaveBeenCalled();
|
expect(checkForPlatformUpdatesMock).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('given update channel "beta" is selected', () => {
|
||||||
|
let selectedUpdateChannel: {
|
||||||
|
value: IComputedValue<UpdateChannel>;
|
||||||
|
setValue: (channelId: UpdateChannelId) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
selectedUpdateChannel = applicationBuilder.dis.mainDi.inject(
|
||||||
|
selectedUpdateChannelInjectable,
|
||||||
|
);
|
||||||
|
|
||||||
|
selectedUpdateChannel.setValue(updateChannels.beta.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when checking for updates", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
applicationBuilder.tray.click("check-for-updates");
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when update from "beta" channel is discovered', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await checkForPlatformUpdatesMock.resolve({
|
||||||
|
updateWasDiscovered: true,
|
||||||
|
version: "some-beta-version",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when update is downloaded", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await downloadPlatformUpdateMock.resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("when user would close the application, installs the update", () => {
|
||||||
|
expect(setUpdateOnQuitMock).toHaveBeenLastCalledWith(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('given user changes update channel to "latest", when user would close the application, does not install the update for not being stable enough', () => {
|
||||||
|
selectedUpdateChannel.setValue(updateChannels.latest.id);
|
||||||
|
|
||||||
|
expect(setUpdateOnQuitMock).toHaveBeenLastCalledWith(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('given user changes update channel to "alpha", when user would close the application, installs the update for being stable enough', () => {
|
||||||
|
selectedUpdateChannel.setValue(updateChannels.alpha.id);
|
||||||
|
|
||||||
|
expect(setUpdateOnQuitMock).toHaveBeenLastCalledWith(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
xdescribe("given a non-installed update is already downloaded, when started", () => {
|
xdescribe("given a non-installed update is already downloaded, when started", () => {
|
||||||
@ -445,7 +512,9 @@ describe("installing update using tray", () => {
|
|||||||
await checkForUpdatesPromise;
|
await checkForUpdatesPromise;
|
||||||
});
|
});
|
||||||
|
|
||||||
it("starts downloading the update!?!?", () => {});
|
it("starts downloading the update", () => {
|
||||||
|
expect(downloadPlatformUpdateMock).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
it("user cannot check for updates again yet", () => {
|
it("user cannot check for updates again yet", () => {
|
||||||
expect(
|
expect(
|
||||||
|
|||||||
@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import electronUpdaterInjectable from "./electron-updater.injectable";
|
||||||
|
|
||||||
|
const setUpdateOnQuitInjectable = getInjectable({
|
||||||
|
id: "set-update-on-quit",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const electronUpdater = di.inject(electronUpdaterInjectable);
|
||||||
|
|
||||||
|
return (updateOnQuit: boolean) => {
|
||||||
|
electronUpdater.autoInstallOnAppQuit = updateOnQuit;
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default setUpdateOnQuitInjectable;
|
||||||
@ -22,9 +22,11 @@ const versionUpdateInjectable = getInjectable({
|
|||||||
const discoveredVersionState = observable.box<string>();
|
const discoveredVersionState = observable.box<string>();
|
||||||
const downloadingState = observable.box<boolean>(false);
|
const downloadingState = observable.box<boolean>(false);
|
||||||
const checkingState = observable.box<boolean>(false);
|
const checkingState = observable.box<boolean>(false);
|
||||||
|
const discoveredFromUpdateChannelState = observable.box<UpdateChannel>();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
discoveredVersion: computed(() => discoveredVersionState.get()),
|
discoveredVersion: computed(() => discoveredVersionState.get()),
|
||||||
|
discoveredFromUpdateChannel: computed(() => discoveredFromUpdateChannelState.get()),
|
||||||
downloading: computed(() => downloadingState.get()),
|
downloading: computed(() => downloadingState.get()),
|
||||||
checking: computed(() => checkingState.get()),
|
checking: computed(() => checkingState.get()),
|
||||||
|
|
||||||
@ -33,6 +35,7 @@ const versionUpdateInjectable = getInjectable({
|
|||||||
discoveredVersionState,
|
discoveredVersionState,
|
||||||
checkingState,
|
checkingState,
|
||||||
selectedUpdateChannel.value,
|
selectedUpdateChannel.value,
|
||||||
|
discoveredFromUpdateChannelState,
|
||||||
),
|
),
|
||||||
|
|
||||||
downloadUpdate: downloadUpdateFor(
|
downloadUpdate: downloadUpdateFor(
|
||||||
@ -68,6 +71,7 @@ const checkForUpdatesFor =
|
|||||||
discoveredVersionState: IObservableValue<string>,
|
discoveredVersionState: IObservableValue<string>,
|
||||||
checkingState: IObservableValue<boolean>,
|
checkingState: IObservableValue<boolean>,
|
||||||
selectedUpdateChannel: IComputedValue<UpdateChannel>,
|
selectedUpdateChannel: IComputedValue<UpdateChannel>,
|
||||||
|
discoveredFromUpdateChannelState: IObservableValue<UpdateChannel>,
|
||||||
) =>
|
) =>
|
||||||
async () => {
|
async () => {
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
@ -77,11 +81,12 @@ const checkForUpdatesFor =
|
|||||||
const checkForUpdatesStartingFromChannel =
|
const checkForUpdatesStartingFromChannel =
|
||||||
checkForUpdatesStartingFromChannelFor(checkForPlatformUpdates);
|
checkForUpdatesStartingFromChannelFor(checkForPlatformUpdates);
|
||||||
|
|
||||||
const { updateWasDiscovered, version } = await checkForUpdatesStartingFromChannel(
|
const { updateWasDiscovered, version, actualUpdateChannel } = await checkForUpdatesStartingFromChannel(
|
||||||
selectedUpdateChannel.get(),
|
selectedUpdateChannel.get(),
|
||||||
);
|
);
|
||||||
|
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
|
discoveredFromUpdateChannelState.set(actualUpdateChannel);
|
||||||
discoveredVersionState.set(version);
|
discoveredVersionState.set(version);
|
||||||
checkingState.set(false);
|
checkingState.set(false);
|
||||||
});
|
});
|
||||||
@ -90,12 +95,24 @@ const checkForUpdatesFor =
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const checkForUpdatesStartingFromChannelFor = (checkForPlatformUpdates: CheckForPlatformUpdates) => {
|
const checkForUpdatesStartingFromChannelFor = (
|
||||||
const _recursiveCheck = async (updateChannel: UpdateChannel): Promise<{ updateWasDiscovered: boolean; version?: string }> => {
|
checkForPlatformUpdates: CheckForPlatformUpdates,
|
||||||
|
) => {
|
||||||
|
const _recursiveCheck = async (
|
||||||
|
updateChannel: UpdateChannel,
|
||||||
|
): Promise<{
|
||||||
|
updateWasDiscovered: boolean;
|
||||||
|
version?: string;
|
||||||
|
actualUpdateChannel?: UpdateChannel;
|
||||||
|
}> => {
|
||||||
const result = await checkForPlatformUpdates(updateChannel);
|
const result = await checkForPlatformUpdates(updateChannel);
|
||||||
|
|
||||||
if (result.updateWasDiscovered) {
|
if (result.updateWasDiscovered) {
|
||||||
return { updateWasDiscovered: true, version: result.version };
|
return {
|
||||||
|
updateWasDiscovered: true,
|
||||||
|
version: result.version,
|
||||||
|
actualUpdateChannel: updateChannel,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updateChannel.moreStableUpdateChannel) {
|
if (updateChannel.moreStableUpdateChannel) {
|
||||||
|
|||||||
@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { onLoadOfApplicationInjectionToken } from "../../start-main-application/runnable-tokens/on-load-of-application-injection-token";
|
||||||
|
import watchIfUpdateShouldHappenOnQuitInjectable from "./watch-if-update-should-happen-on-quit.injectable";
|
||||||
|
|
||||||
|
const startWatchingIfUpdateShouldHappenOnQuitInjectable = getInjectable({
|
||||||
|
id: "start-watching-if-update-should-happen-on-quit",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const watchIfUpdateShouldHappenOnQuit = di.inject(watchIfUpdateShouldHappenOnQuitInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
run: () => {
|
||||||
|
watchIfUpdateShouldHappenOnQuit.start();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: onLoadOfApplicationInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default startWatchingIfUpdateShouldHappenOnQuitInjectable;
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import watchIfUpdateShouldHappenOnQuitInjectable from "./watch-if-update-should-happen-on-quit.injectable";
|
||||||
|
import { beforeQuitOfBackEndInjectionToken } from "../../start-main-application/runnable-tokens/before-quit-of-back-end-injection-token";
|
||||||
|
|
||||||
|
const stopWatchingIfUpdateShouldHappenOnQuitInjectable = getInjectable({
|
||||||
|
id: "stop-watching-if-update-should-happen-on-quit",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const watchIfUpdateShouldHappenOnQuit = di.inject(watchIfUpdateShouldHappenOnQuitInjectable);
|
||||||
|
|
||||||
|
return {
|
||||||
|
run: () => {
|
||||||
|
watchIfUpdateShouldHappenOnQuit.stop();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: beforeQuitOfBackEndInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default stopWatchingIfUpdateShouldHappenOnQuitInjectable;
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { autorun } from "mobx";
|
||||||
|
import { getStartableStoppable } from "../../../common/utils/get-startable-stoppable";
|
||||||
|
import setUpdateOnQuitInjectable from "../../electron-app/features/set-update-on-quit.injectable";
|
||||||
|
import versionUpdateInjectable from "../version-update.injectable";
|
||||||
|
import selectedUpdateChannelInjectable from "../selected-update-channel.injectable";
|
||||||
|
import type { UpdateChannel } from "../update-channels";
|
||||||
|
|
||||||
|
const watchIfUpdateShouldHappenOnQuitInjectable = getInjectable({
|
||||||
|
id: "watch-if-update-should-happen-on-quit",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const setUpdateOnQuit = di.inject(setUpdateOnQuitInjectable);
|
||||||
|
const versionUpdate = di.inject(versionUpdateInjectable);
|
||||||
|
const selectedUpdateChannel = di.inject(selectedUpdateChannelInjectable);
|
||||||
|
|
||||||
|
return getStartableStoppable("watch-if-update-should-happen-on-quit", () =>
|
||||||
|
autorun(() => {
|
||||||
|
const sufficientlyStableUpdateChannels =
|
||||||
|
getSufficientlyStableUpdateChannels(selectedUpdateChannel.value.get());
|
||||||
|
|
||||||
|
const updateIsDiscoveredFromChannel = versionUpdate.discoveredFromUpdateChannel.get();
|
||||||
|
|
||||||
|
const updateOnQuit = sufficientlyStableUpdateChannels.includes(updateIsDiscoveredFromChannel);
|
||||||
|
|
||||||
|
setUpdateOnQuit(updateOnQuit);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const getSufficientlyStableUpdateChannels = (updateChannel: UpdateChannel): UpdateChannel[] => {
|
||||||
|
if (!updateChannel.moreStableUpdateChannel) {
|
||||||
|
return [updateChannel];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
updateChannel,
|
||||||
|
|
||||||
|
...getSufficientlyStableUpdateChannels(updateChannel.moreStableUpdateChannel),
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
export default watchIfUpdateShouldHappenOnQuitInjectable;
|
||||||
Loading…
Reference in New Issue
Block a user