From e7f8e3d9130eac98898de40b8a7a81ff7b519dc2 Mon Sep 17 00:00:00 2001 From: jamaljsr <1356600+jamaljsr@users.noreply.github.com> Date: Mon, 6 May 2024 09:12:57 -0500 Subject: [PATCH] feat: remember node counts when creating new networks --- src/components/network/NewNetwork.spec.tsx | 4 +- src/components/network/NewNetwork.tsx | 8 ++-- src/lib/settings/settingsService.spec.ts | 8 ++++ src/store/models/app.spec.ts | 51 +++++++++++++++++++--- src/store/models/app.ts | 22 +++++++++- src/store/models/network.ts | 12 +++++ src/types/index.ts | 2 + 7 files changed, 94 insertions(+), 13 deletions(-) diff --git a/src/components/network/NewNetwork.spec.tsx b/src/components/network/NewNetwork.spec.tsx index 5c9268d88..907faf14b 100644 --- a/src/components/network/NewNetwork.spec.tsx +++ b/src/components/network/NewNetwork.spec.tsx @@ -83,9 +83,7 @@ describe('NewNetwork component', () => { it('should disable c-lightning input on Windows', () => { mockOS.platform.mockReturnValue('win32'); const { getByLabelText, getByText } = renderComponent(); - expect(getByLabelText('Core Lightning')).toHaveValue('0'); - expect(getByLabelText('LND')).toHaveValue('2'); - expect(getByLabelText('Eclair')).toHaveValue('1'); + expect(getByLabelText('Core Lightning')).toBeDisabled(); expect(getByText('Not supported on Windows yet.')).toBeInTheDocument(); }); diff --git a/src/components/network/NewNetwork.tsx b/src/components/network/NewNetwork.tsx index 61f19f2f8..f78ba7a98 100644 --- a/src/components/network/NewNetwork.tsx +++ b/src/components/network/NewNetwork.tsx @@ -73,10 +73,10 @@ const NewNetwork: React.FC = () => { layout="vertical" colon={false} initialValues={{ - lndNodes: isWindows() ? 2 : 1, - clightningNodes: isWindows() ? 0 : 1, - eclairNodes: 1, - bitcoindNodes: 1, + lndNodes: settings.newNodeCounts.LND, + clightningNodes: settings.newNodeCounts['c-lightning'], + eclairNodes: settings.newNodeCounts.eclair, + bitcoindNodes: settings.newNodeCounts.bitcoind, customNodes: initialCustomValues, }} onFinish={createAsync.execute} diff --git a/src/lib/settings/settingsService.spec.ts b/src/lib/settings/settingsService.spec.ts index feee81464..7811d39df 100644 --- a/src/lib/settings/settingsService.spec.ts +++ b/src/lib/settings/settingsService.spec.ts @@ -20,6 +20,14 @@ describe('SettingsService', () => { checkForUpdatesOnStartup: false, theme: 'dark', nodeImages: { custom: [], managed: [] }, + newNodeCounts: { + LND: 1, + 'c-lightning': 1, + eclair: 1, + bitcoind: 1, + btcd: 0, + tapd: 0, + }, }; }); diff --git a/src/store/models/app.spec.ts b/src/store/models/app.spec.ts index 31bec5d86..dc018ea7e 100644 --- a/src/store/models/app.spec.ts +++ b/src/store/models/app.spec.ts @@ -1,5 +1,6 @@ import { notification } from 'antd'; import { createStore } from 'easy-peasy'; +import os from 'os'; import { defaultRepoState } from 'utils/constants'; import { injections } from 'utils/tests'; import appModel from './app'; @@ -7,6 +8,9 @@ import designerModel from './designer'; import modalsModel from './modals'; import networkModel from './network'; +jest.mock('os'); + +const mockOS = os as jest.Mocked; const mockDockerService = injections.dockerService as jest.Mocked< typeof injections.dockerService >; @@ -43,6 +47,14 @@ describe('App model', () => { checkForUpdatesOnStartup: false, theme: 'dark', nodeImages: { custom: [], managed: [] }, + newNodeCounts: { + LND: 1, + 'c-lightning': 1, + eclair: 1, + bitcoind: 1, + btcd: 0, + tapd: 0, + }, }); mockRepoService.load.mockResolvedValue({ ...defaultRepoState, @@ -53,9 +65,30 @@ describe('App model', () => { it('should initialize', async () => { await store.getActions().app.initialize(); expect(store.getState().app.initialized).toBe(true); - expect(mockSettingsService.load).toBeCalledTimes(1); - expect(mockDockerService.getVersions).toBeCalledTimes(1); - expect(mockDockerService.loadNetworks).toBeCalledTimes(1); + expect(mockSettingsService.load).toHaveBeenCalledTimes(1); + expect(mockDockerService.getVersions).toHaveBeenCalledTimes(1); + expect(mockDockerService.loadNetworks).toHaveBeenCalledTimes(1); + }); + + it('should have correct default node counts on Windows', async () => { + mockOS.platform.mockReturnValue('win32'); + mockSettingsService.load.mockResolvedValue({ + lang: 'en-US', + showAllNodeVersions: true, + checkForUpdatesOnStartup: false, + theme: 'dark', + nodeImages: { custom: [], managed: [] }, + } as any); + await store.getActions().app.initialize(); + expect(store.getState().app.initialized).toBe(true); + expect(store.getState().app.settings.newNodeCounts).toEqual({ + LND: 2, + 'c-lightning': 0, + eclair: 1, + bitcoind: 1, + btcd: 0, + tapd: 0, + }); }); it('should initialize with missing settings', async () => { @@ -97,6 +130,14 @@ describe('App model', () => { checkForUpdatesOnStartup: true, theme: 'dark', nodeImages: { custom: [], managed: [] }, + newNodeCounts: { + LND: 1, + 'c-lightning': 1, + eclair: 1, + bitcoind: 1, + btcd: 1, + tapd: 1, + }, }); }); @@ -106,7 +147,7 @@ describe('App model', () => { }); await store.getActions().app.initialize(); expect(store.getState().app.initialized).toBe(true); - expect(mockRepoService.checkForUpdates).toBeCalledTimes(1); + expect(mockRepoService.checkForUpdates).toHaveBeenCalledTimes(1); expect(store.getState().modals.imageUpdates.visible).toBe(false); }); @@ -125,7 +166,7 @@ describe('App model', () => { await store.getActions().app.initialize(); expect(store.getState().app.initialized).toBe(true); - expect(mockRepoService.checkForUpdates).toBeCalledTimes(1); + expect(mockRepoService.checkForUpdates).toHaveBeenCalledTimes(1); expect(store.getState().modals.imageUpdates.visible).toBe(true); }); diff --git a/src/store/models/app.ts b/src/store/models/app.ts index 8a0acd439..dfed20f3a 100644 --- a/src/store/models/app.ts +++ b/src/store/models/app.ts @@ -17,6 +17,7 @@ import { StoreInjections, } from 'types'; import { defaultRepoState } from 'utils/constants'; +import { isWindows } from 'utils/system'; import { changeTheme } from 'utils/theme'; import { NETWORK_VIEW } from 'components/routing'; import { RootModel } from './'; @@ -79,6 +80,14 @@ const appModel: AppModel = { managed: [], custom: [], }, + newNodeCounts: { + LND: 1, + 'c-lightning': 1, + eclair: 1, + bitcoind: 1, + btcd: 0, + tapd: 0, + }, }, dockerVersions: { docker: '', compose: '' }, dockerImages: [], @@ -123,7 +132,18 @@ const appModel: AppModel = { ...settings, }; }), - loadSettings: thunk(async (actions, _, { injections }) => { + loadSettings: thunk(async (actions, _, { injections, getState }) => { + // before loading settings, set the default CLN count to 0 on Windows + if (isWindows()) { + actions.setSettings({ + newNodeCounts: { + ...getState().settings.newNodeCounts, + LND: 2, + 'c-lightning': 0, + }, + }); + } + const settings = await injections.settingsService.load(); if (settings) { actions.setSettings(settings); diff --git a/src/store/models/network.ts b/src/store/models/network.ts index 8e268eb49..32008e23f 100644 --- a/src/store/models/network.ts +++ b/src/store/models/network.ts @@ -278,6 +278,18 @@ const networkModel: NetworkModel = { getStoreActions().designer.setChart({ id: newNetwork.id, chart }); getStoreActions().designer.setActiveId(newNetwork.id); await actions.save(); + + await getStoreActions().app.updateSettings({ + newNodeCounts: { + LND: lndNodes, + 'c-lightning': clightningNodes, + eclair: eclairNodes, + bitcoind: bitcoindNodes, + btcd: 0, + tapd: 0, + }, + }); + dispatch(push(NETWORK_VIEW(newNetwork.id))); }, ), diff --git a/src/types/index.ts b/src/types/index.ts index 1c47c186b..ae39356aa 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -60,6 +60,8 @@ export interface AppSettings { managed: ManagedImage[]; custom: CustomImage[]; }; + /** The default number of each node when creating a new network */ + newNodeCounts: Record; } export interface SettingsInjection {