From 826f0145b804ea97ca032aae83475fd304cdbfcc Mon Sep 17 00:00:00 2001 From: asiaznik Date: Mon, 27 Nov 2023 20:39:21 +0100 Subject: [PATCH] chore(trading): don't redirect to inactive markets --- apps/trading/client-pages/home/home.tsx | 27 +-------- .../hooks/use-navigate-to-last-market.spec.ts | 60 +++++++++++++++++++ .../lib/hooks/use-navigate-to-last-market.ts | 40 +++++++++++++ 3 files changed, 102 insertions(+), 25 deletions(-) create mode 100644 apps/trading/lib/hooks/use-navigate-to-last-market.spec.ts create mode 100644 apps/trading/lib/hooks/use-navigate-to-last-market.ts diff --git a/apps/trading/client-pages/home/home.tsx b/apps/trading/client-pages/home/home.tsx index 76be931cb..12cf909cb 100644 --- a/apps/trading/client-pages/home/home.tsx +++ b/apps/trading/client-pages/home/home.tsx @@ -1,34 +1,11 @@ -import { useEffect } from 'react'; -import { useNavigate } from 'react-router-dom'; import { Loader, Splash } from '@vegaprotocol/ui-toolkit'; -import { useGlobalStore } from '../../stores'; -import { useTopTradedMarkets } from '../../lib/hooks/use-top-traded-markets'; -import { Links } from '../../lib/links'; +import { useNavigateToLastMarket } from '../../lib/hooks/use-navigate-to-last-market'; // The home pages only purpose is to redirect to the users last market, // the top traded if they are new, or fall back to the list of markets. // Thats why we just render a loader here export const Home = () => { - const navigate = useNavigate(); - const { data } = useTopTradedMarkets(); - const marketId = useGlobalStore((store) => store.marketId); - - useEffect(() => { - if (marketId) { - navigate(Links.MARKET(marketId), { - replace: true, - }); - } else if (data) { - const marketDataId = data[0]?.id; - if (marketDataId) { - navigate(Links.MARKET(marketDataId), { - replace: true, - }); - } else { - navigate(Links.MARKETS()); - } - } - }, [marketId, data, navigate]); + useNavigateToLastMarket(); return ( diff --git a/apps/trading/lib/hooks/use-navigate-to-last-market.spec.ts b/apps/trading/lib/hooks/use-navigate-to-last-market.spec.ts new file mode 100644 index 000000000..b3b2e2ad6 --- /dev/null +++ b/apps/trading/lib/hooks/use-navigate-to-last-market.spec.ts @@ -0,0 +1,60 @@ +import * as router from 'react-router'; +import { useNavigateToLastMarket } from './use-navigate-to-last-market'; +import { useGlobalStore } from '../../stores'; +import { renderHook } from '@testing-library/react'; +import { useTopTradedMarkets } from './use-top-traded-markets'; +import { Links } from '../links'; + +const mockLastMarketId = 'LAST'; + +jest.mock('../../stores', () => { + const original = jest.requireActual('../../stores'); + return { + ...original, + useGlobalStore: jest.fn(), + }; +}); + +jest.mock('./use-top-traded-markets', () => { + return { + useTopTradedMarkets: jest.fn(), + }; +}); + +describe('useNavigateToLastMarket', () => { + const navigate = jest.fn(); + beforeAll(() => { + jest.spyOn(router, 'useNavigate').mockImplementation(() => navigate); + }); + + it('navigates to the last market when it is active', () => { + (useGlobalStore as unknown as jest.Mock).mockReturnValue(mockLastMarketId); + (useTopTradedMarkets as jest.Mock).mockReturnValue({ + data: [{ id: mockLastMarketId }], + }); + renderHook(() => useNavigateToLastMarket()); + expect(navigate).toHaveBeenCalledWith(Links.MARKET(mockLastMarketId), { + replace: true, + }); + }); + + it('navigates to the top traded market if the last one is not active', () => { + (useGlobalStore as unknown as jest.Mock).mockReturnValue(mockLastMarketId); + (useTopTradedMarkets as jest.Mock).mockReturnValue({ + data: [{ id: 'TOP' }], + }); + renderHook(() => useNavigateToLastMarket()); + expect(navigate).toHaveBeenCalledWith(Links.MARKET('TOP'), { + replace: true, + }); + }); + + it('navigates to the list of markets when all of the markets are not active', () => { + (useGlobalStore as unknown as jest.Mock).mockReturnValue(mockLastMarketId); + (useTopTradedMarkets as jest.Mock).mockReturnValue({ + data: [], + }); + renderHook(() => useNavigateToLastMarket()); + expect(navigate).toHaveBeenCalledWith(Links.MARKETS()); + }); +}); diff --git a/apps/trading/lib/hooks/use-navigate-to-last-market.ts b/apps/trading/lib/hooks/use-navigate-to-last-market.ts new file mode 100644 index 000000000..aa222cb9c --- /dev/null +++ b/apps/trading/lib/hooks/use-navigate-to-last-market.ts @@ -0,0 +1,40 @@ +import { useGlobalStore } from '../../stores'; +import { useNavigate } from 'react-router-dom'; +import { useTopTradedMarkets } from './use-top-traded-markets'; +import { useEffect } from 'react'; +import { Links } from '../links'; + +export const useNavigateToLastMarket = () => { + const navigate = useNavigate(); + + // this returns a list of active markets ordered by traded factor + // hence there's no need to pull markets again or find out in separate + // query of the state of last market + const { data } = useTopTradedMarkets(); + const lastMarketId = useGlobalStore((store) => store.marketId); + const isLastMarketActive = data?.some((m) => m.id === lastMarketId); + + useEffect(() => { + if (!data) return; + + // if last market id is set and it is active, navigate to that market + if (lastMarketId && isLastMarketActive) { + navigate(Links.MARKET(lastMarketId), { + replace: true, + }); + return; + } + + // otherwise if there's a top traded market, navigate to that market + const marketDataId = data[0]?.id; + if (marketDataId) { + navigate(Links.MARKET(marketDataId), { + replace: true, + }); + return; + } + + // otherwise navigate to the list of all markets + navigate(Links.MARKETS()); + }, [lastMarketId, data, navigate, isLastMarketActive]); +};