From 6a16a4ce07b35ec3795cf46f1a9241f6ac2ce1d8 Mon Sep 17 00:00:00 2001 From: Oleg Chendighelean Date: Thu, 13 Jun 2024 22:23:05 +0300 Subject: [PATCH] Update useDataPolling hook to show only one notification --- .../utils/dataPolling/useDataPolling.test.ts | 119 +++++++----------- .../src/utils/dataPolling/useDataPolling.ts | 45 +++---- 2 files changed, 58 insertions(+), 106 deletions(-) diff --git a/apps/desktop/src/utils/dataPolling/useDataPolling.test.ts b/apps/desktop/src/utils/dataPolling/useDataPolling.test.ts index ca4618ac3d..1fb15dd861 100644 --- a/apps/desktop/src/utils/dataPolling/useDataPolling.test.ts +++ b/apps/desktop/src/utils/dataPolling/useDataPolling.test.ts @@ -5,6 +5,7 @@ import { usePollBlock } from "./usePollBlock"; import { usePollConversionRate } from "./usePollConversionRate"; import { usePollMultisigs } from "./usePollMultisigs"; import { usePollPendingOperations } from "./usePollPendingOperations"; +import { usePollProtocolSettings } from "./usePollProtocolSettings"; import { usePollTokenBalances } from "./usePollTokenBalances"; import { usePollUnstakeRequests } from "./usePollUnstakeRequests"; import { renderHook } from "../../mocks/testUtils"; @@ -34,107 +35,73 @@ const usePollTokenBalancesMock = jest.mocked(usePollTokenBalances); jest.mock("./usePollUnstakeRequests"); const usePollUnstakeRequestsMock = jest.mocked(usePollUnstakeRequests); +jest.mock("./usePollProtocolSettings"); +const usePollProtocolSettingsMock = jest.mocked(usePollProtocolSettings); + describe("useDataPolling", () => { describe("isLoading", () => { it.each([ + { hookName: "usePollAccountStates", mock: usePollAccountStatesMock }, + { hookName: "usePollBakers", mock: usePollBakersMock }, + { hookName: "usePollBlock", mock: usePollBlockMock }, + { hookName: "usePollConversionRate", mock: usePollConversionRateMock }, { hookName: "usePollMultisigs", mock: usePollMultisigsMock }, { hookName: "usePollPendingOperations", mock: usePollPendingOperationsMock }, - { hookName: "usePollAccountStates", mock: usePollAccountStatesMock }, + { hookName: "usePollProtocolSettings", mock: usePollProtocolSettingsMock }, { hookName: "usePollTokenBalances", mock: usePollTokenBalancesMock }, { hookName: "usePollUnstakeRequests", mock: usePollUnstakeRequestsMock }, ])("is true when the data is being fetched by $hookName", ({ mock }) => { [ + usePollAccountStatesMock, usePollBakersMock, usePollBlockMock, usePollConversionRateMock, usePollMultisigsMock, usePollPendingOperationsMock, - usePollAccountStatesMock, + usePollProtocolSettingsMock, usePollTokenBalancesMock, usePollUnstakeRequestsMock, ].forEach(hookMock => { - if (hookMock === mock) { - // @ts-expect-error 2590 - hookMock.mockReturnValue({ - isFetching: true, - dataUpdatedAt: 1, - }); - } else { - hookMock.mockReturnValue({ - isFetching: false, - dataUpdatedAt: 1, - }); - } + // @ts-expect-error TS2590 + hookMock.mockReturnValue({ + isFetching: hookMock === mock, + dataUpdatedAt: 1, + }); }); renderHook(() => useDataPolling()); expect(store.getState().assets.isLoading).toBe(true); }); + }); + describe("lastTimeUpdated", () => { it.each([ + { hookName: "usePollAccountStates", mock: usePollAccountStatesMock }, { hookName: "usePollBakers", mock: usePollBakersMock }, { hookName: "usePollBlock", mock: usePollBlockMock }, { hookName: "usePollConversionRate", mock: usePollConversionRateMock }, - ])("is not affected by $hookName", ({ mock }) => { - [ - usePollBakersMock, - usePollBlockMock, - usePollConversionRateMock, - usePollMultisigsMock, - usePollPendingOperationsMock, - usePollAccountStatesMock, - usePollTokenBalancesMock, - usePollUnstakeRequestsMock, - ].forEach(hookMock => { - if (hookMock === mock) { - hookMock.mockReturnValue({ - isFetching: true, - dataUpdatedAt: 1, - }); - } else { - hookMock.mockReturnValue({ - isFetching: false, - dataUpdatedAt: 1, - }); - } - }); - - renderHook(() => useDataPolling()); - - expect(store.getState().assets.isLoading).toBe(false); - }); - }); - - describe("lastUpdatedAt", () => { - it.each([ { hookName: "usePollMultisigs", mock: usePollMultisigsMock }, { hookName: "usePollPendingOperations", mock: usePollPendingOperationsMock }, - { hookName: "usePollAccountStates", mock: usePollAccountStatesMock }, + { hookName: "usePollProtocolSettings", mock: usePollProtocolSettingsMock }, { hookName: "usePollTokenBalances", mock: usePollTokenBalancesMock }, { hookName: "usePollUnstakeRequests", mock: usePollUnstakeRequestsMock }, - ])("is true when the data is being fetched by $hookName", ({ mock }) => { + ])("is set to the lastUpdatedAt of the $hookName hook if it is the latest one", ({ mock }) => { [ + usePollAccountStatesMock, usePollBakersMock, usePollBlockMock, usePollConversionRateMock, usePollMultisigsMock, usePollPendingOperationsMock, - usePollAccountStatesMock, + usePollProtocolSettingsMock, usePollTokenBalancesMock, usePollUnstakeRequestsMock, ].forEach(hookMock => { - if (hookMock === mock) { - hookMock.mockReturnValue({ - isFetching: false, - dataUpdatedAt: 1000, - }); - } else { - hookMock.mockReturnValue({ - isFetching: false, - dataUpdatedAt: 1, - }); - } + hookMock.mockReturnValue({ + isFetching: false, + dataUpdatedAt: hookMock === mock ? 1000 : 1, + }); }); renderHook(() => useDataPolling()); @@ -143,36 +110,36 @@ describe("useDataPolling", () => { }); it.each([ + { hookName: "usePollAccountStates", mock: usePollAccountStatesMock }, { hookName: "usePollBakers", mock: usePollBakersMock }, { hookName: "usePollBlock", mock: usePollBlockMock }, { hookName: "usePollConversionRate", mock: usePollConversionRateMock }, - ])("is not affected by $hookName", ({ mock }) => { + { hookName: "usePollMultisigs", mock: usePollMultisigsMock }, + { hookName: "usePollPendingOperations", mock: usePollPendingOperationsMock }, + { hookName: "usePollProtocolSettings", mock: usePollProtocolSettingsMock }, + { hookName: "usePollTokenBalances", mock: usePollTokenBalancesMock }, + { hookName: "usePollUnstakeRequests", mock: usePollUnstakeRequestsMock }, + ])("does not change lastTimeUpdated if $hookName is loading", ({ mock }) => { [ - usePollMultisigsMock, - usePollPendingOperationsMock, usePollAccountStatesMock, - usePollTokenBalancesMock, usePollBakersMock, usePollBlockMock, usePollConversionRateMock, + usePollMultisigsMock, + usePollPendingOperationsMock, + usePollProtocolSettingsMock, + usePollTokenBalancesMock, usePollUnstakeRequestsMock, ].forEach(hookMock => { - if (hookMock === mock) { - hookMock.mockReturnValue({ - isFetching: false, - dataUpdatedAt: 5, - }); - } else { - hookMock.mockReturnValue({ - isFetching: false, - dataUpdatedAt: 1, - }); - } + hookMock.mockReturnValue({ + isFetching: hookMock === mock, + dataUpdatedAt: 1000, + }); }); renderHook(() => useDataPolling()); - expect(store.getState().assets.lastTimeUpdated).toBe("Thu, 01 Jan 1970 00:00:00 GMT"); + expect(store.getState().assets.lastTimeUpdated).toBeNull(); }); }); }); diff --git a/apps/desktop/src/utils/dataPolling/useDataPolling.ts b/apps/desktop/src/utils/dataPolling/useDataPolling.ts index 434345b69d..0cfee56692 100644 --- a/apps/desktop/src/utils/dataPolling/useDataPolling.ts +++ b/apps/desktop/src/utils/dataPolling/useDataPolling.ts @@ -1,4 +1,5 @@ import { fromUnixTime } from "date-fns"; +import { max } from "lodash"; import { useEffect } from "react"; import { usePollAccountStates } from "./usePollAccountStates"; @@ -16,36 +17,20 @@ import { assetsActions } from "../redux/slices/assetsSlice"; export const useDataPolling = () => { const dispatch = useAppDispatch(); - const { dataUpdatedAt: isMultisigsUpdatedAt, isFetching: isMultisigsFetching } = - usePollMultisigs(); - const { dataUpdatedAt: isPendingOperationsUpdatedAt, isFetching: isPendingOperationsFetching } = - usePollPendingOperations(); - const { dataUpdatedAt: isAccountStatesUpdatedAt, isFetching: isAccountStatesFetching } = - usePollAccountStates(); - const { dataUpdatedAt: isUnstakeRequestUpdatedAt, isFetching: isUnstakeRequestFetching } = - usePollUnstakeRequests(); - const { dataUpdatedAt: isTokenBalancesUpdatedAt, isFetching: isTokenBalancesFetching } = - usePollTokenBalances(); - - usePollConversionRate(); - usePollBlock(); - usePollBakers(); - usePollProtocolSettings(); - - const isFetching = - isMultisigsFetching || - isPendingOperationsFetching || - isAccountStatesFetching || - isTokenBalancesFetching || - isUnstakeRequestFetching; - - const lastUpdatedAt = Math.max( - isMultisigsUpdatedAt, - isPendingOperationsUpdatedAt, - isAccountStatesUpdatedAt, - isTokenBalancesUpdatedAt, - isUnstakeRequestUpdatedAt - ); + const pollers = [ + usePollAccountStates(), + usePollBakers(), + usePollBlock(), + usePollConversionRate(), + usePollMultisigs(), + usePollPendingOperations(), + usePollProtocolSettings(), + usePollTokenBalances(), + usePollUnstakeRequests(), + ]; + + const isFetching = pollers.some(poller => poller.isFetching); + const lastUpdatedAt = max(pollers.map(poller => poller.dataUpdatedAt)); useEffect(() => { dispatch(assetsActions.setIsLoading(isFetching));