diff --git a/tests/mocks/state.ts b/tests/mocks/state.ts index 5fb1f5ea2c..cccb47856c 100644 --- a/tests/mocks/state.ts +++ b/tests/mocks/state.ts @@ -17,6 +17,7 @@ import { objectDifference } from '../utils'; export class StateMock { public acceleratorsToBlock: BlockableAccelerator[] = []; public activeGistAction = GistActionState.none; + public activeVersions = new Set(); public channelsToShow: ElectronReleaseChannel[] = []; public editorMosaic = new EditorMosaic(); public environmentVariables: string[] = []; @@ -85,6 +86,7 @@ export class StateMock { public setVersion = jest.fn().mockImplementation((version: string) => { this.currentElectronVersion = this.versions[version]; this.version = version; + this.activeVersions.add(version); }); public isVersionUsable = jest.fn().mockImplementation(() => { return { ver: this.currentElectronVersion }; @@ -120,6 +122,7 @@ export class StateMock { makeObservable(this, { acceleratorsToBlock: observable, activeGistAction: observable, + activeVersions: observable, channelsToShow: observable, editorMosaic: observable, environmentVariables: observable, diff --git a/tests/renderer/components/settings-electron-spec.tsx b/tests/renderer/components/settings-electron-spec.tsx index 3f5ff2709b..391047ecf6 100644 --- a/tests/renderer/components/settings-electron-spec.tsx +++ b/tests/renderer/components/settings-electron-spec.tsx @@ -12,6 +12,7 @@ import { ElectronSettings } from '../../../src/renderer/components/settings-elec import { AppState } from '../../../src/renderer/state'; import { disableDownload } from '../../../src/renderer/utils/disable-download'; import { AppMock, StateMock, VersionsMock } from '../../mocks/mocks'; +import { waitFor } from '../../utils'; jest.mock('../../../src/renderer/utils/disable-download.ts'); @@ -19,12 +20,13 @@ describe('ElectronSettings component', () => { let store: StateMock; let mockVersions: Record; let mockVersionsArray: RunnableVersion[]; + const version = '2.0.1'; beforeEach(() => { ({ mockVersions, mockVersionsArray } = new VersionsMock()); ({ state: store } = window.ElectronFiddle.app as unknown as AppMock); - store.initVersions('2.0.1', { ...mockVersions }); + store.initVersions(version, { ...mockVersions }); store.channelsToShow = [ ElectronReleaseChannel.stable, ElectronReleaseChannel.beta, @@ -38,7 +40,7 @@ describe('ElectronSettings component', () => { store.versionsToShow[i++].state = InstallState.installing; }); - it('renders', () => { + it('renders', async () => { const spy = jest .spyOn(window.ElectronFiddle, 'getOldestSupportedMajor') .mockReturnValue(9); @@ -64,6 +66,10 @@ describe('ElectronSettings component', () => { const wrapper = shallow( , ); + + await store.setVersion(version); + await waitFor(() => store.activeVersions.size > 0); + expect(wrapper).toMatchSnapshot(); spy.mockRestore(); diff --git a/tests/renderer/state-spec.ts b/tests/renderer/state-spec.ts index 4509003256..dbf6185d61 100644 --- a/tests/renderer/state-spec.ts +++ b/tests/renderer/state-spec.ts @@ -20,7 +20,11 @@ import { saveLocalVersions, } from '../../src/renderer/versions'; import { VersionsMock, createEditorValues } from '../mocks/mocks'; -import { overrideRendererPlatform, resetRendererPlatform } from '../utils'; +import { + overrideRendererPlatform, + resetRendererPlatform, + waitFor, +} from '../utils'; jest.mock('../../src/renderer/versions', () => { const { getReleaseChannel } = jest.requireActual( @@ -310,6 +314,10 @@ describe('AppState', () => { it('does not remove the active version', async () => { const ver = appState.versions[active]; + + await appState.setVersion(ver.version); + await waitFor(() => appState.activeVersions.size > 0); + broadcastMessageSpy.mockClear(); await appState.removeVersion(ver); expect(removeSpy).not.toHaveBeenCalled(); diff --git a/tests/setup.ts b/tests/setup.ts index 746d400e21..3f4d79b13a 100644 --- a/tests/setup.ts +++ b/tests/setup.ts @@ -75,6 +75,52 @@ delete (window as any).localStorage; window.navigator = window.navigator ?? {}; (window.navigator.clipboard as any) = {}; +class FakeNavigatorLocks implements LockManager { + locks = { + held: new Set(), + pending: new Set(), + }; + + query = async () => { + const result = { + held: [...this.locks.held], + pending: [...this.locks.pending], + }; + + return result as LockManagerSnapshot; + }; + + /** + * WIP. Right now, this is a **very** naive mock that will just happily grant a shared lock when one is requested, + * but I'll add some bookkeeping and expand it to cover the exclusive lock case as well. + * + * @TODO remove this comment + */ + request = (async (...args: Parameters) => { + const [ + name, + options = { + mode: 'exclusive', + }, + cb, + ] = args; + + const { mode } = options; + + const lock = { name, mode, cb } as Lock; + + if (mode === 'shared') { + this.locks.held.add(lock); + + await cb(lock); + + return; + } + }) as LockManager['request']; +} + +(window.navigator.locks as any) = new FakeNavigatorLocks(); + /** * Mock these properties twice so that they're available * both at the top-level of files and also within the