From db60d1dace11e02284e04d4b9da9a85ff479508e Mon Sep 17 00:00:00 2001 From: Janne Savolainen Date: Thu, 19 May 2022 13:49:33 +0300 Subject: [PATCH] Reorganize tests for installing update under separate scenarios Signed-off-by: Janne Savolainen --- .../installing-update-using-tray.test.ts.snap | 513 ++++++++++++++++-- .../installing-update.test.ts.snap | 81 +++ .../installing-update-using-tray.test.ts | 291 +--------- .../update-app/installing-update.test.ts | 396 ++++++++++++++ 4 files changed, 956 insertions(+), 325 deletions(-) create mode 100644 src/behaviours/update-app/__snapshots__/installing-update.test.ts.snap create mode 100644 src/behaviours/update-app/installing-update.test.ts diff --git a/src/behaviours/update-app/__snapshots__/installing-update-using-tray.test.ts.snap b/src/behaviours/update-app/__snapshots__/installing-update-using-tray.test.ts.snap index 75d9716a6d..0afca9055a 100644 --- a/src/behaviours/update-app/__snapshots__/installing-update-using-tray.test.ts.snap +++ b/src/behaviours/update-app/__snapshots__/installing-update-using-tray.test.ts.snap @@ -15,7 +15,48 @@ exports[`installing update using tray given no update is already downloaded, and
+ > +
+
+ + + info_outline + + +
+
+ Checking for updates... +
+
+ + + close + + +
+
+
`; @@ -25,7 +66,88 @@ exports[`installing update using tray given no update is already downloaded, and
+ > +
+
+ + + info_outline + + +
+
+ Checking for updates... +
+
+ + + close + + +
+
+
+
+ + + info_outline + + +
+
+ Download for version some-version started... +
+
+ + + close + + +
+
+
`; @@ -35,7 +157,128 @@ exports[`installing update using tray given no update is already downloaded, and
+ > +
+
+ + + info_outline + + +
+
+ Checking for updates... +
+
+ + + close + + +
+
+
+
+ + + info_outline + + +
+
+ Download for version some-version started... +
+
+ + + close + + +
+
+
+
+ + + info_outline + + +
+
+ Download of update failed +
+
+ + + close + + +
+
+
`; @@ -45,37 +288,156 @@ exports[`installing update using tray given no update is already downloaded, and
-
- -`; - -exports[`installing update using tray given no update is already downloaded, and "latest" update channel is selected, when started when user checks for updates using tray when new update is discovered when download succeeds when user answers not to install the update renders 1`] = ` - -
-
-
- -`; - -exports[`installing update using tray given no update is already downloaded, and "latest" update channel is selected, when started when user checks for updates using tray when new update is discovered when download succeeds when user answers to install the update renders 1`] = ` - -
-
-
- -`; - -exports[`installing update using tray given no update is already downloaded, and "latest" update channel is selected, when started when user checks for updates using tray when new update is discovered when download succeeds when user disregards the question and installs the update using tray renders 1`] = ` - -
-
+ > +
+
+ + + info_outline + + +
+
+ Checking for updates... +
+
+ + + close + + +
+
+
+
+ + + info_outline + + +
+
+ Download for version some-version started... +
+
+ + + close + + +
+
+
+
+ + + info_outline + + +
+
+
+ + Update Available + +

+ Version some-version of Lens IDE is available and ready to be installed. Would you like to update now? +

+
+ + +
+
+
+
+ + + close + + +
+
+
`; @@ -85,7 +447,88 @@ exports[`installing update using tray given no update is already downloaded, and
+ > +
+
+ + + info_outline + + +
+
+ Checking for updates... +
+
+ + + close + + +
+
+
+
+ + + info_outline + + +
+
+ No new updates available +
+
+ + + close + + +
+
+
`; diff --git a/src/behaviours/update-app/__snapshots__/installing-update.test.ts.snap b/src/behaviours/update-app/__snapshots__/installing-update.test.ts.snap new file mode 100644 index 0000000000..fb28aa568c --- /dev/null +++ b/src/behaviours/update-app/__snapshots__/installing-update.test.ts.snap @@ -0,0 +1,81 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`installing update given no update is already downloaded, and "latest" update channel is selected, when started renders 1`] = ` + +
+
+
+ +`; + +exports[`installing update given no update is already downloaded, and "latest" update channel is selected, when started when user checks for updates renders 1`] = ` + +
+
+
+ +`; + +exports[`installing update given no update is already downloaded, and "latest" update channel is selected, when started when user checks for updates when new update is discovered renders 1`] = ` + +
+
+
+ +`; + +exports[`installing update given no update is already downloaded, and "latest" update channel is selected, when started when user checks for updates when new update is discovered when download fails renders 1`] = ` + +
+
+
+ +`; + +exports[`installing update given no update is already downloaded, and "latest" update channel is selected, when started when user checks for updates when new update is discovered when download succeeds renders 1`] = ` + +
+
+
+ +`; + +exports[`installing update given no update is already downloaded, and "latest" update channel is selected, when started when user checks for updates when new update is discovered when download succeeds when user answers not to install the update renders 1`] = ` + +
+
+
+ +`; + +exports[`installing update given no update is already downloaded, and "latest" update channel is selected, when started when user checks for updates when new update is discovered when download succeeds when user answers to install the update renders 1`] = ` + +
+
+
+ +`; + +exports[`installing update given no update is already downloaded, and "latest" update channel is selected, when started when user checks for updates when no new update is discovered renders 1`] = ` + +
+
+
+ +`; 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 33ec5a6e14..d838dea32b 100644 --- a/src/behaviours/update-app/installing-update-using-tray.test.ts +++ b/src/behaviours/update-app/installing-update-using-tray.test.ts @@ -4,7 +4,6 @@ */ import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder"; import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder"; -import quitAndInstallUpdateInjectable from "../../main/electron-app/features/quit-and-install-update.injectable"; import type { RenderResult } from "@testing-library/react"; import electronUpdaterIsActiveInjectable from "../../main/electron-app/features/electron-updater-is-active.injectable"; import publishIsConfiguredInjectable from "../../main/update-app/publish-is-configured.injectable"; @@ -12,46 +11,26 @@ import type { CheckForPlatformUpdates } from "../../main/update-app/check-for-pl import checkForPlatformUpdatesInjectable from "../../main/update-app/check-for-platform-updates/check-for-platform-updates.injectable"; 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 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 progressOfUpdateDownloadInjectable from "../../common/application-update/progress-of-update-download/progress-of-update-download.injectable"; -import showInfoNotificationInjectable from "../../renderer/components/notifications/show-info-notification.injectable"; describe("installing update using tray", () => { let applicationBuilder: ApplicationBuilder; - let quitAndInstallUpdateMock: jest.Mock; let checkForPlatformUpdatesMock: AsyncFnMock; let downloadPlatformUpdateMock: AsyncFnMock; - let setUpdateOnQuitMock: jest.Mock; let showApplicationWindowMock: jest.Mock; - let showInfoNotificationMock: jest.Mock; - let askBooleanMock: AsyncFnMock; beforeEach(() => { applicationBuilder = getApplicationBuilder(); - applicationBuilder.beforeApplicationStart(({ mainDi, rendererDi }) => { - quitAndInstallUpdateMock = jest.fn(); + applicationBuilder.beforeApplicationStart(({ mainDi }) => { checkForPlatformUpdatesMock = asyncFn(); downloadPlatformUpdateMock = asyncFn(); - setUpdateOnQuitMock = jest.fn(); showApplicationWindowMock = jest.fn(); - showInfoNotificationMock = jest.fn(() => () => {}); - askBooleanMock = asyncFn(); - rendererDi.override(showInfoNotificationInjectable, () => showInfoNotificationMock); - - mainDi.override(askBooleanInjectable, () => askBooleanMock); mainDi.override(showApplicationWindowInjectable, () => showApplicationWindowMock); - mainDi.override(setUpdateOnQuitInjectable, () => setUpdateOnQuitMock); mainDi.override( checkForPlatformUpdatesInjectable, @@ -63,11 +42,6 @@ describe("installing update using tray", () => { () => downloadPlatformUpdateMock, ); - mainDi.override( - quitAndInstallUpdateInjectable, - () => quitAndInstallUpdateMock, - ); - mainDi.override(electronUpdaterIsActiveInjectable, () => true); mainDi.override(publishIsConfiguredInjectable, () => true); }); @@ -96,20 +70,10 @@ describe("installing update using tray", () => { applicationBuilder.tray.click("check-for-updates"); }); - it('checks for updates from "latest" update channel', () => { - expect(checkForPlatformUpdatesMock).toHaveBeenCalledWith( - updateChannels.latest, - ); - }); - it("does not show application window yet", () => { expect(showApplicationWindowMock).not.toHaveBeenCalled(); }); - it("notifies the user that checking for updates is happening", () => { - expect(showInfoNotificationMock).toHaveBeenCalledWith("Checking for updates..."); - }); - it("user cannot check for updates again", () => { expect( applicationBuilder.tray.get("check-for-updates")?.enabled.get(), @@ -132,8 +96,6 @@ describe("installing update using tray", () => { describe("when no new update is discovered", () => { beforeEach(async () => { - showInfoNotificationMock.mockClear(); - await checkForPlatformUpdatesMock.resolve({ updateWasDiscovered: false, }); @@ -145,14 +107,6 @@ describe("installing update using tray", () => { expect(showApplicationWindowMock).toHaveBeenCalled(); }); - it("notifies the user", () => { - expect(showInfoNotificationMock).toHaveBeenCalledWith("No new updates available"); - }); - - it("does not start downloading update", () => { - expect(downloadPlatformUpdateMock).not.toHaveBeenCalled(); - }); - it("user cannot install update", () => { expect(applicationBuilder.tray.get("install-update")).toBeUndefined(); }); @@ -188,14 +142,6 @@ describe("installing update using tray", () => { expect(showApplicationWindowMock).toHaveBeenCalled(); }); - it("starts downloading the update", () => { - expect(downloadPlatformUpdateMock).toHaveBeenCalled(); - }); - - it("notifies the user that download is happening", () => { - expect(showInfoNotificationMock).toHaveBeenCalledWith("Download for version some-version started..."); - }); - it("user cannot check for updates again yet", () => { expect( applicationBuilder.tray.get("check-for-updates")?.enabled.get(), @@ -233,10 +179,6 @@ describe("installing update using tray", () => { await downloadPlatformUpdateMock.resolve({ downloadWasSuccessful: false }); }); - it("does not quit and install update yet", () => { - expect(quitAndInstallUpdateMock).not.toHaveBeenCalled(); - }); - it("user cannot install update", () => { expect( applicationBuilder.tray.get("install-update"), @@ -249,20 +191,12 @@ describe("installing update using tray", () => { ).toBe(true); }); - it("notifies the user about failed download", () => { - expect(showInfoNotificationMock).toHaveBeenCalledWith("Download of update failed"); - }); - it("name of tray item for checking updates no longer indicates that downloading is happening", () => { expect( applicationBuilder.tray.get("check-for-updates")?.label?.get(), ).toBe("Check for updates"); }); - it("does not ask user to install update", () => { - expect(askBooleanMock).not.toHaveBeenCalled(); - }); - it("renders", () => { expect(rendered.baseElement).toMatchSnapshot(); }); @@ -273,10 +207,6 @@ describe("installing update using tray", () => { await downloadPlatformUpdateMock.resolve({ downloadWasSuccessful: true }); }); - it("does not quit and install update yet", () => { - expect(quitAndInstallUpdateMock).not.toHaveBeenCalled(); - }); - it("user can install update", () => { expect( applicationBuilder.tray.get("install-update")?.label?.get(), @@ -298,225 +228,6 @@ describe("installing update using tray", () => { it("renders", () => { expect(rendered.baseElement).toMatchSnapshot(); }); - - it("asks user to install update immediately", () => { - expect(askBooleanMock).toHaveBeenCalledWith({ - id: "install-update", - title: "Update Available", - question: - "Version some-version of Lens IDE is available and ready to be installed. Would you like to update now?", - }); - }); - - describe("when user answers to install the update", () => { - beforeEach(async () => { - await askBooleanMock.resolve(true); - }); - - it("renders", () => { - expect(rendered.baseElement).toMatchSnapshot(); - }); - - it("quits application and installs the update", () => { - expect(quitAndInstallUpdateMock).toHaveBeenCalled(); - }); - }); - - describe("when user answers not to install the update", () => { - beforeEach(async () => { - await askBooleanMock.resolve(false); - }); - - it("renders", () => { - expect(rendered.baseElement).toMatchSnapshot(); - }); - - it("does not quit application and install the update", () => { - expect(quitAndInstallUpdateMock).not.toHaveBeenCalled(); - }); - }); - - describe("when user disregards the question and installs the update using tray", () => { - beforeEach(async () => { - await applicationBuilder.tray.click("install-update"); - }); - - it("renders", () => { - expect(rendered.baseElement).toMatchSnapshot(); - }); - - it("quits application and installs the update", () => { - expect(quitAndInstallUpdateMock).toHaveBeenCalled(); - }); - }); - }); - - describe("when user changes update channel to other channel instead of just installing", () => { - beforeEach(() => { - const selectedUpdateChannel = applicationBuilder.dis.mainDi.inject( - selectedUpdateChannelInjectable, - ); - - selectedUpdateChannel.setValue(updateChannels.beta.id); - }); - - it("user cannot install existing update for being from wrong update channel", () => {}); - - describe("when user installs an update", () => { - beforeEach(() => {}); - - it('still installs the update from "latest" update channel', () => {}); - }); - - it("when checking updates again, checks for updates from the other update channel", async () => { - checkForPlatformUpdatesMock.mockClear(); - - applicationBuilder.tray.click("check-for-updates"); - - expect(checkForPlatformUpdatesMock).toHaveBeenCalledWith( - updateChannels.beta, - ); - }); - }); - }); - }); - - describe('given update channel "alpha" is selected, when checking for updates', () => { - let selectedUpdateChannel: { - value: IComputedValue; - setValue: (channelId: UpdateChannelId) => void; - }; - - beforeEach(() => { - selectedUpdateChannel = applicationBuilder.dis.mainDi.inject( - selectedUpdateChannelInjectable, - ); - - selectedUpdateChannel.setValue(updateChannels.alpha.id); - - applicationBuilder.tray.click("check-for-updates"); - }); - - it('checks updates from update channel "alpha"', () => { - expect(checkForPlatformUpdatesMock).toHaveBeenCalledWith( - updateChannels.alpha, - ); - }); - - it("when update is discovered, does not check update from other update channels", async () => { - checkForPlatformUpdatesMock.mockClear(); - - await checkForPlatformUpdatesMock.resolve({ - updateWasDiscovered: true, - version: "some-version", - }); - - expect(checkForPlatformUpdatesMock).not.toHaveBeenCalled(); - }); - - describe("when no update is discovered", () => { - beforeEach(async () => { - checkForPlatformUpdatesMock.mockClear(); - - await checkForPlatformUpdatesMock.resolve({ - updateWasDiscovered: false, - }); - }); - - it('checks updates from update channel "beta"', () => { - expect(checkForPlatformUpdatesMock).toHaveBeenCalledWith( - updateChannels.beta, - ); - }); - - it("when update is discovered, does not check update from other update channels", async () => { - checkForPlatformUpdatesMock.mockClear(); - - await checkForPlatformUpdatesMock.resolve({ - updateWasDiscovered: true, - version: "some-version", - }); - - expect(checkForPlatformUpdatesMock).not.toHaveBeenCalled(); - }); - - describe("when no update is discovered again", () => { - beforeEach(async () => { - checkForPlatformUpdatesMock.mockClear(); - - await checkForPlatformUpdatesMock.resolve({ - updateWasDiscovered: false, - }); - }); - - it('finally checks updates from update channel "latest"', () => { - expect(checkForPlatformUpdatesMock).toHaveBeenCalledWith( - updateChannels.latest, - ); - }); - - it("when update is discovered, does not check update from other update channels", async () => { - checkForPlatformUpdatesMock.mockClear(); - - await checkForPlatformUpdatesMock.resolve({ - updateWasDiscovered: true, - version: "some-version", - }); - - expect(checkForPlatformUpdatesMock).not.toHaveBeenCalled(); - }); - }); - }); - }); - - describe('given update channel "beta" is selected', () => { - let selectedUpdateChannel: { - value: IComputedValue; - 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({ downloadWasSuccessful: true }); - }); - - 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); - }); - }); }); }); }); diff --git a/src/behaviours/update-app/installing-update.test.ts b/src/behaviours/update-app/installing-update.test.ts new file mode 100644 index 0000000000..8250cbb03e --- /dev/null +++ b/src/behaviours/update-app/installing-update.test.ts @@ -0,0 +1,396 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder"; +import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder"; +import quitAndInstallUpdateInjectable from "../../main/electron-app/features/quit-and-install-update.injectable"; +import type { RenderResult } from "@testing-library/react"; +import electronUpdaterIsActiveInjectable from "../../main/electron-app/features/electron-updater-is-active.injectable"; +import publishIsConfiguredInjectable from "../../main/update-app/publish-is-configured.injectable"; +import type { CheckForPlatformUpdates } from "../../main/update-app/check-for-platform-updates/check-for-platform-updates.injectable"; +import checkForPlatformUpdatesInjectable from "../../main/update-app/check-for-platform-updates/check-for-platform-updates.injectable"; +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 type { IComputedValue } from "mobx"; +import setUpdateOnQuitInjectable from "../../main/electron-app/features/set-update-on-quit.injectable"; +import type { AskBoolean } from "../../main/ask-boolean/ask-boolean.injectable"; +import askBooleanInjectable from "../../main/ask-boolean/ask-boolean.injectable"; +import showInfoNotificationInjectable from "../../renderer/components/notifications/show-info-notification.injectable"; +import checkForUpdatesInjectable from "../../main/update-app/check-for-updates/check-for-updates.injectable"; + +describe("installing update", () => { + let applicationBuilder: ApplicationBuilder; + let quitAndInstallUpdateMock: jest.Mock; + let checkForPlatformUpdatesMock: AsyncFnMock; + let downloadPlatformUpdateMock: AsyncFnMock; + let setUpdateOnQuitMock: jest.Mock; + let showInfoNotificationMock: jest.Mock; + let askBooleanMock: AsyncFnMock; + + beforeEach(() => { + applicationBuilder = getApplicationBuilder(); + + applicationBuilder.beforeApplicationStart(({ mainDi, rendererDi }) => { + quitAndInstallUpdateMock = jest.fn(); + checkForPlatformUpdatesMock = asyncFn(); + downloadPlatformUpdateMock = asyncFn(); + setUpdateOnQuitMock = jest.fn(); + showInfoNotificationMock = jest.fn(() => () => {}); + askBooleanMock = asyncFn(); + + rendererDi.override(showInfoNotificationInjectable, () => showInfoNotificationMock); + + mainDi.override(askBooleanInjectable, () => askBooleanMock); + mainDi.override(setUpdateOnQuitInjectable, () => setUpdateOnQuitMock); + + mainDi.override( + checkForPlatformUpdatesInjectable, + () => checkForPlatformUpdatesMock, + ); + + mainDi.override( + downloadPlatformUpdateInjectable, + () => downloadPlatformUpdateMock, + ); + + mainDi.override( + quitAndInstallUpdateInjectable, + () => quitAndInstallUpdateMock, + ); + + mainDi.override(electronUpdaterIsActiveInjectable, () => true); + mainDi.override(publishIsConfiguredInjectable, () => true); + }); + }); + + describe('given no update is already downloaded, and "latest" update channel is selected, when started', () => { + let rendered: RenderResult; + let checkForUpdates: () => Promise; + + beforeEach(async () => { + rendered = await applicationBuilder.render(); + + checkForUpdates = applicationBuilder.dis.mainDi.inject(checkForUpdatesInjectable); + }); + + it("renders", () => { + expect(rendered.baseElement).toMatchSnapshot(); + }); + + describe("when user checks for updates", () => { + let checkForUpdatesPromise: Promise; + + beforeEach(async () => { + checkForUpdatesPromise = checkForUpdates(); + }); + + it('checks for updates from "latest" update channel', () => { + expect(checkForPlatformUpdatesMock).toHaveBeenCalledWith( + updateChannels.latest, + ); + }); + + it("notifies the user that checking for updates is happening", () => { + expect(showInfoNotificationMock).toHaveBeenCalledWith("Checking for updates..."); + }); + + it("renders", () => { + expect(rendered.baseElement).toMatchSnapshot(); + }); + + describe("when no new update is discovered", () => { + beforeEach(async () => { + showInfoNotificationMock.mockClear(); + + await checkForPlatformUpdatesMock.resolve({ + updateWasDiscovered: false, + }); + + await checkForUpdatesPromise; + }); + + it("notifies the user", () => { + expect(showInfoNotificationMock).toHaveBeenCalledWith("No new updates available"); + }); + + it("does not start downloading update", () => { + expect(downloadPlatformUpdateMock).not.toHaveBeenCalled(); + }); + + it("renders", () => { + expect(rendered.baseElement).toMatchSnapshot(); + }); + }); + + describe("when new update is discovered", () => { + beforeEach(async () => { + await checkForPlatformUpdatesMock.resolve({ + updateWasDiscovered: true, + version: "some-version", + }); + + await checkForUpdatesPromise; + }); + + it("starts downloading the update", () => { + expect(downloadPlatformUpdateMock).toHaveBeenCalled(); + }); + + it("notifies the user that download is happening", () => { + expect(showInfoNotificationMock).toHaveBeenCalledWith("Download for version some-version started..."); + }); + + it("renders", () => { + expect(rendered.baseElement).toMatchSnapshot(); + }); + + describe("when download fails", () => { + beforeEach(async () => { + await downloadPlatformUpdateMock.resolve({ downloadWasSuccessful: false }); + }); + + it("does not quit and install update yet", () => { + expect(quitAndInstallUpdateMock).not.toHaveBeenCalled(); + }); + + it("notifies the user about failed download", () => { + expect(showInfoNotificationMock).toHaveBeenCalledWith("Download of update failed"); + }); + + it("does not ask user to install update", () => { + expect(askBooleanMock).not.toHaveBeenCalled(); + }); + + it("renders", () => { + expect(rendered.baseElement).toMatchSnapshot(); + }); + }); + + describe("when download succeeds", () => { + beforeEach(async () => { + await downloadPlatformUpdateMock.resolve({ downloadWasSuccessful: true }); + }); + + it("does not quit and install update yet", () => { + expect(quitAndInstallUpdateMock).not.toHaveBeenCalled(); + }); + + it("renders", () => { + expect(rendered.baseElement).toMatchSnapshot(); + }); + + it("asks user to install update immediately", () => { + expect(askBooleanMock).toHaveBeenCalledWith({ + id: "install-update", + title: "Update Available", + question: + "Version some-version of Lens IDE is available and ready to be installed. Would you like to update now?", + }); + }); + + describe("when user answers to install the update", () => { + beforeEach(async () => { + await askBooleanMock.resolve(true); + }); + + it("renders", () => { + expect(rendered.baseElement).toMatchSnapshot(); + }); + + it("quits application and installs the update", () => { + expect(quitAndInstallUpdateMock).toHaveBeenCalled(); + }); + }); + + describe("when user answers not to install the update", () => { + beforeEach(async () => { + await askBooleanMock.resolve(false); + }); + + it("renders", () => { + expect(rendered.baseElement).toMatchSnapshot(); + }); + + it("does not quit application and install the update", () => { + expect(quitAndInstallUpdateMock).not.toHaveBeenCalled(); + }); + }); + }); + + describe("when user changes update channel to other channel instead of just installing", () => { + beforeEach(() => { + const selectedUpdateChannel = applicationBuilder.dis.mainDi.inject( + selectedUpdateChannelInjectable, + ); + + selectedUpdateChannel.setValue(updateChannels.beta.id); + }); + + it("user cannot install existing update for being from wrong update channel", () => {}); + + describe("when user installs an update", () => { + beforeEach(() => {}); + + it('still installs the update from "latest" update channel', () => {}); + }); + + it("when checking updates again, checks for updates from the other update channel", async () => { + checkForPlatformUpdatesMock.mockClear(); + + checkForUpdates(); + + expect(checkForPlatformUpdatesMock).toHaveBeenCalledWith( + updateChannels.beta, + ); + }); + }); + }); + }); + + describe('given update channel "alpha" is selected, when checking for updates', () => { + let selectedUpdateChannel: { + value: IComputedValue; + setValue: (channelId: UpdateChannelId) => void; + }; + + beforeEach(() => { + selectedUpdateChannel = applicationBuilder.dis.mainDi.inject( + selectedUpdateChannelInjectable, + ); + + selectedUpdateChannel.setValue(updateChannels.alpha.id); + + checkForUpdates(); + }); + + it('checks updates from update channel "alpha"', () => { + expect(checkForPlatformUpdatesMock).toHaveBeenCalledWith( + updateChannels.alpha, + ); + }); + + it("when update is discovered, does not check update from other update channels", async () => { + checkForPlatformUpdatesMock.mockClear(); + + await checkForPlatformUpdatesMock.resolve({ + updateWasDiscovered: true, + version: "some-version", + }); + + expect(checkForPlatformUpdatesMock).not.toHaveBeenCalled(); + }); + + describe("when no update is discovered", () => { + beforeEach(async () => { + checkForPlatformUpdatesMock.mockClear(); + + await checkForPlatformUpdatesMock.resolve({ + updateWasDiscovered: false, + }); + }); + + it('checks updates from update channel "beta"', () => { + expect(checkForPlatformUpdatesMock).toHaveBeenCalledWith( + updateChannels.beta, + ); + }); + + it("when update is discovered, does not check update from other update channels", async () => { + checkForPlatformUpdatesMock.mockClear(); + + await checkForPlatformUpdatesMock.resolve({ + updateWasDiscovered: true, + version: "some-version", + }); + + expect(checkForPlatformUpdatesMock).not.toHaveBeenCalled(); + }); + + describe("when no update is discovered again", () => { + beforeEach(async () => { + checkForPlatformUpdatesMock.mockClear(); + + await checkForPlatformUpdatesMock.resolve({ + updateWasDiscovered: false, + }); + }); + + it('finally checks updates from update channel "latest"', () => { + expect(checkForPlatformUpdatesMock).toHaveBeenCalledWith( + updateChannels.latest, + ); + }); + + it("when update is discovered, does not check update from other update channels", async () => { + checkForPlatformUpdatesMock.mockClear(); + + await checkForPlatformUpdatesMock.resolve({ + updateWasDiscovered: true, + version: "some-version", + }); + + expect(checkForPlatformUpdatesMock).not.toHaveBeenCalled(); + }); + }); + }); + }); + + describe('given update channel "beta" is selected', () => { + let selectedUpdateChannel: { + value: IComputedValue; + setValue: (channelId: UpdateChannelId) => void; + }; + + beforeEach(() => { + selectedUpdateChannel = applicationBuilder.dis.mainDi.inject( + selectedUpdateChannelInjectable, + ); + + selectedUpdateChannel.setValue(updateChannels.beta.id); + }); + + describe("when checking for updates", () => { + beforeEach(() => { + checkForUpdates(); + }); + + 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({ downloadWasSuccessful: true }); + }); + + 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); + }); + }); + }); + }); + }); + }); +});