Skip to content

Commit

Permalink
Update useDataPolling hook to show only one notification
Browse files Browse the repository at this point in the history
  • Loading branch information
OKendigelyan authored and serjonya-trili committed Jun 17, 2024
1 parent 8036c20 commit 98eaf1d
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 106 deletions.
118 changes: 42 additions & 76 deletions apps/desktop/src/utils/dataPolling/useDataPolling.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -34,107 +35,72 @@ 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,
});
}
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());
Expand All @@ -143,36 +109,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();
});
});
});
45 changes: 15 additions & 30 deletions apps/desktop/src/utils/dataPolling/useDataPolling.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { fromUnixTime } from "date-fns";
import { max } from "lodash";
import { useEffect } from "react";

import { usePollAccountStates } from "./usePollAccountStates";
Expand All @@ -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));
Expand Down

0 comments on commit 98eaf1d

Please sign in to comment.