Skip to content

Commit

Permalink
Merge pull request #5338 from LiskHQ/5336-clean-up-redux-persited-state
Browse files Browse the repository at this point in the history
Clean up recursive and dead state in redux
  • Loading branch information
ManuGowda authored Sep 29, 2023
2 parents 9d21443 + d4d53c0 commit 51a6a1f
Show file tree
Hide file tree
Showing 9 changed files with 119 additions and 14 deletions.
2 changes: 2 additions & 0 deletions setup/react/app/ApplicationBootstrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
import { useNetworkStatus } from '@network/hooks/queries';
import { useBlockchainApplicationMeta } from '@blockchainApplication/manage/hooks/queries/useBlockchainApplicationMeta';
import { Client } from 'src/utils/api/client';
import { useReduxStateModifier } from 'src/utils/useReduxStateModifier';
import { useLedgerDeviceListener } from '@libs/hardwareWallet/ledger/ledgerDeviceListener/useLedgerDeviceListener';

export const ApplicationBootstrapContext = createContext({
Expand Down Expand Up @@ -80,6 +81,7 @@ const ApplicationBootstrap = ({ children }) => {
]);

useLedgerDeviceListener();
useReduxStateModifier();

return (
<ApplicationBootstrapContext.Provider
Expand Down
6 changes: 3 additions & 3 deletions src/modules/blockchainApplication/manage/store/action.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ export const deleteApplication = (chainId, network) => ({
network,
});

export const deleteNetworkInApplications = (network) => ({
type: actionTypes.deleteNetworkInApplications,
network,
export const deleteNetworksInApplications = (networks) => ({
type: actionTypes.deleteNetworksInApplications,
networks,
});

export const updateNetworkNameInApplications = (currentName, newName) => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const actionTypes = {
deleteApplicationByChainId: 'DELETE_APPLICATION_BY_CHAIN_ID',
setCurrentApplication: 'SET_CURRENT_APPLICATION',
setApplications: 'SET_APPLICATIONS',
deleteNetworkInApplications: 'DELETE_NETWORK_IN_APPLICATIONS',
deleteNetworksInApplications: 'DELETE_NETWORKS_IN_APPLICATIONS',
updateNetworkNameInApplications: 'UPDATE_NETWORK_NAME_IN_APPLICATIONS',
};

Expand Down
8 changes: 5 additions & 3 deletions src/modules/blockchainApplication/manage/store/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const pins = (state = initialState.pins, { type, chainId }) => {

export const applications = (
state = initialState.applications,
{ type, app, apps, chainId, network, currentName, newName }
{ type, app, apps, chainId, network, currentName, newName, networks }
) => {
switch (type) {
case actionTypes.addApplicationByChainId:
Expand All @@ -49,8 +49,10 @@ export const applications = (
);
}

case actionTypes.deleteNetworkInApplications: {
delete state[network];
case actionTypes.deleteNetworksInApplications: {
networks.forEach((networkToDelete) => {
delete state[networkToDelete];
});
return { ...state };
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,10 @@ describe('BlockchainApplication reducer', () => {
expect(changedState).not.toHaveProperty(actionData.chainId);
});

it('should delete network in applications', async () => {
it('should delete networks in applications', async () => {
const actionData = {
type: actionTypes.deleteNetworkInApplications,
network: 'devnet',
type: actionTypes.deleteNetworksInApplications,
networks: ['devnet'],
};

const changedState = applications(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { OutlineButton, PrimaryButton } from '@theme/buttons';
import useSettings from '@settings/hooks/useSettings';
import { parseSearchParams, removeSearchParamsFromUrl } from 'src/utils/searchParams';
import { immutableDeleteFromArrayById } from 'src/utils/immutableUtils';
import { deleteNetworkInApplications } from '@blockchainApplication/manage/store/action';
import { deleteNetworksInApplications } from '@blockchainApplication/manage/store/action';
import { useDispatch } from 'react-redux';
import styles from './DialogRemoveNetwork.css';

Expand All @@ -29,7 +29,7 @@ const DialogRemoveNetwork = () => {
const onConfirm = () => {
const modifiedCustomNetworks = immutableDeleteFromArrayById(customNetworks, 'name', name);
setValue(modifiedCustomNetworks);
dispatch(deleteNetworkInApplications(name));
dispatch(deleteNetworksInApplications([name]));
removeSearchParamsFromUrl(history, ['modal'], true);
toast.info(t(`Network removed "${name}"`), { position: 'bottom-right' });
};
Expand Down
3 changes: 1 addition & 2 deletions src/modules/settings/store/reducer.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { persistReducer } from 'redux-persist';
import { deepMergeObj } from 'src/utils/helpers';
import { storage } from 'src/redux/store';
import networks from '@network/configuration/networks';
import { DEFAULT_NETWORK } from 'src/const/config';
Expand Down Expand Up @@ -33,7 +32,7 @@ export const initialState = {
const settings = (state = initialState, action) => {
switch (action.type) {
case actionTypes.settingsUpdated:
return deepMergeObj(state, action.data);
return { ...state, ...action.data };
case actionTypes.settingsReset:
return {
...state,
Expand Down
47 changes: 47 additions & 0 deletions src/utils/useReduxStateModifier.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { selectApplications } from '@blockchainApplication/manage/store/selectors';
import networks from '@network/configuration/networks';
import { deleteNetworksInApplications } from '@blockchainApplication/manage/store/action';
import useSettings from '@settings/hooks/useSettings';

const useReduxStateModifier = () => {
const dispatch = useDispatch();
const { customNetworks } = useSettings('customNetworks');
const { setValue: setMainChainNetwork, mainChainNetwork } = useSettings('mainChainNetwork');
const applications = useSelector(selectApplications) || {};

const removeDeadApplicationNetworkDomains = () => {
const customNetworksHashmap = customNetworks.reduce((accum, customNetwork) => {
accum[customNetwork.name] = customNetwork;
return accum;
}, {});

const allNetworks = { ...networks, ...customNetworksHashmap };

const applicationNetworkDomainsToRemove = Object.keys(applications).filter(
(applicationName) => {
const network = allNetworks[applicationName];
return !network;
}
);
if (applicationNetworkDomainsToRemove.length > 0) {
dispatch(deleteNetworksInApplications(applicationNetworkDomainsToRemove));
}
};

const removeCircularMainChainNetwork = () => {
const { mainChainNetwork: circularObject, ...rest } = mainChainNetwork;

if (circularObject) {
setMainChainNetwork(rest);
}
};

useEffect(() => {
removeDeadApplicationNetworkDomains();
removeCircularMainChainNetwork();
}, []);
};

export { useReduxStateModifier };
55 changes: 55 additions & 0 deletions src/utils/useReduxStateModifier.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { renderHook } from '@testing-library/react-hooks';
import { queryWrapper as wrapper } from 'src/utils/test/queryWrapper';
import useSettings from '@settings/hooks/useSettings';
import { applicationsMap } from '@tests/fixtures/blockchainApplicationsManage';

import networks from '@network/configuration/networks';
import { deleteNetworksInApplications } from '@blockchainApplication/manage/store/action';
import { useReduxStateModifier } from './useReduxStateModifier';

jest.mock('@settings/hooks/useSettings');

jest.useRealTimers();

const mockState = {
blockChainApplications: {
applications: { devnet: applicationsMap, toBeRemoved: applicationsMap },
},
};

const mockDispatch = jest.fn();
jest.mock('react-redux', () => ({
useSelector: jest.fn().mockImplementation((fn) => fn(mockState)),
useDispatch: () => mockDispatch,
}));

const mockSetValueToSettings = jest.fn();

useSettings.mockReturnValue({
customNetworks: [
{
name: 'custom_network_one',
label: 'custom_network_one',
serviceUrl: 'http://custom-network-service.com',
wsServiceUrl: 'http://custom-network-service.com',
isAvailable: true,
},
],
mainChainNetwork: {
...networks.devnet,
mainChainNetwork: networks.devnet,
},
setValue: mockSetValueToSettings,
});

describe('useReduxStateModifier hook', () => {
it('Should remove circular mainChainNetwork', async () => {
renderHook(() => useReduxStateModifier(), { wrapper });
expect(mockSetValueToSettings).toHaveBeenCalledWith(networks.devnet);
});

it('Should remove dead application network domains', async () => {
renderHook(() => useReduxStateModifier(), { wrapper });
expect(mockDispatch).toHaveBeenCalledWith(deleteNetworksInApplications(['toBeRemoved']));
});
});

0 comments on commit 51a6a1f

Please sign in to comment.