uniswap-interface-uncensored/src/hooks/useCombinedTrade.test.ts

208 lines
8.6 KiB
TypeScript
Raw Normal View History

feat: routing api integration (#2116) * initial routing api integration * add routing api slice * display route in dialog * addressed pr feedback * improved routing * switch to `get` * first pass at integration new MultiRouteTrade * initial implementation of RoutingDiagram * add RoutingDiagram tests * improve tests in RoutingDiagram * integrate with v3-sdk 3.3.1 * removed references to MultiRouteTrade * revert swapcallback * fix abi compilation error * added useRoute hook to build a Route from edges and nodes * added react-hooks-testing-library * integrated latest changes * renamed router hook to routerTrade * improve integration * fixed routing * usability * mock RoutingDiagram children to reduce size * undo mocked children * adjust ui * better support long routes * use routing api logo and adjust ux * set default percent to 0 * added intermediary hook to combine local and routing api trades * added intermediary hook to combine local and routing api trades * make account optional * improve ux * improve router * fixed duplicate pool bug and inputAmount undefined bug * extract input/outputAmounts from routes * add todo * fixed uninitialized issue and added % * fixed tests * fix duplicate pool bug * added routing api setting * change router label based on router version * improve useRoutes and fix duplicate pool bug * debounce routing api/local routing * removed single hop setting * fix bug when moving between v2/v3 * consider isUnitialized non loading * ui fixes * reverted change to usedebounce * use new route schema * visual updates * log quoteId for polish session * fix: persist advanced swap details toggle state * fix no route found * poll every 10s * derive currencies from pool rather than input * polish query status handling in useRouterTrade * removed RouterVersion * update ui * update ui * update loading state * animate auto router * apply loading treatment to out * disable routing api on l2 and support auto slippage * use opacity on the whole element * show loading card when syncing * updated gradient * polished ui * create routerlabel component * disable router on all bu mainnet * polish * feat: [draft] routing api polish (#2224) * show loading card when syncing * updated gradient * polished ui * create routerlabel component * disable router on all bu mainnet * polish * polished loading state * add dashes * fixed tooltip styles * fixed merge conflict * few updates * polish * updated yarn.lock * fixed styles * updated routing diagram * Fix code style issues with ESLint * routing api enabled without localstorage upgrade * fixed lint error * Fix code style issues with ESLint * refined mocks in routing diagram tests * addressed pr feedback * polish * revert sending eth * improved loading animation * handle stale routing api * Fix code style issues with ESLint * updated yarn.lock * support native eth * Compute gas adjusted quote for V2 trade and compare to V3 gas adjusted quote * Incorporate approval gas cost estimate * feat: simplify routing api ux (#2258) * support native eth * simplified ui * perf optimization * implement realized lp fee * improved route realized lp fee * fix lp realized fee * fix auto router gradient * initial route overlay * add auto router svg * adjusted ux to mocks * fix lp fee * upddated routing diagram * optimize tradeBetter hook * adjust type and name * add useBetterTrade * useBetterTrade takes gasEstimateWei * implement gasEstimateForApproval * import state from react * use gas estimate * improve integration with gas estimate comparison * remove dependency on account * fix currency switch bug * improve syncing state * add loadingbar * style tooltip container * updated tooltip styles * increase opacity range * always keep dependent currency input interactable * show placeholders in tooltips * Revert v2 gas estimates and approval estimates * Add debug logs * refactor * fix bug * removed comment * update engish key * add try-catch * addressed pr feedback * remove loading bar for price impact * addressed pr feedback and bug bash feedback * fix: use url to force version * addressed pr feedback and bug bash feedback * stop fetching when losing focus * only show auto router label when activated * avoid showing syncing status * move V3TradeSTate to own file * make useRoutes a function rather than hook * use logo from active list when possible * renamed and refactored hook * renamed and refactored hook * update status * polish * remove unused import * fixed merge error * updated combined trade tests * remove priceimpact while loading * Design tweaks * polish latest design * removed some styles * log gaevent on tooltip open and clean up origin * Small tweaks * addressed pr feedback * wrap route length in a loading container * renamed local to clientside * fix percent and token logo * addressed pr feedback * avoid comparing trades when v3 not ready * some refactor Co-authored-by: Lint Action <lint-action@samuelmeuli.com> Co-authored-by: Will Pote <will@uniswap.org> Co-authored-by: Callil Capuozzo <callil.capuozzo@gmail.com>
2021-09-16 17:50:58 +03:00
import { renderHook } from '@testing-library/react-hooks'
import { CurrencyAmount } from '@uniswap/sdk-core'
import { DAI, USDC } from 'constants/tokens'
import { V3TradeState } from 'state/routing/types'
import { useRoutingAPIEnabled } from 'state/user/hooks'
import { useRoutingAPITradeExactIn, useRoutingAPITradeExactOut } from '../state/routing/useRoutingAPITrade'
import { useV3TradeExactIn, useV3TradeExactOut } from './useCombinedV3Trade'
import useDebounce from './useDebounce'
import useIsWindowVisible from './useIsWindowVisible'
import { useClientV3TradeExactIn, useClientSideV3TradeExactOut } from './useClientSideV3Trade'
const USDCAmount = CurrencyAmount.fromRawAmount(USDC, '10000')
const DAIAmount = CurrencyAmount.fromRawAmount(DAI, '10000')
jest.mock('./useDebounce')
const mockUseDebounce = useDebounce as jest.MockedFunction<typeof useDebounce>
// mock modules containing hooks
jest.mock('state/routing/useRoutingAPITrade')
jest.mock('./useClientSideV3Trade')
jest.mock('state/user/hooks')
jest.mock('./useIsWindowVisible')
const mockUseRoutingAPIEnabled = useRoutingAPIEnabled as jest.MockedFunction<typeof useRoutingAPIEnabled>
const mockUseIsWindowVisible = useIsWindowVisible as jest.MockedFunction<typeof useIsWindowVisible>
// useRouterTrade mocks
const mockUseRoutingAPITradeExactIn = useRoutingAPITradeExactIn as jest.MockedFunction<typeof useRoutingAPITradeExactIn>
const mockUseRoutingAPITradeExactOut = useRoutingAPITradeExactOut as jest.MockedFunction<
typeof useRoutingAPITradeExactOut
>
// useClientSideV3Trade mocks
const mockUseClientSideV3TradeExactIn = useClientV3TradeExactIn as jest.MockedFunction<typeof useClientV3TradeExactIn>
const mockUseClientSideV3TradeExactOut = useClientSideV3TradeExactOut as jest.MockedFunction<
typeof useClientSideV3TradeExactOut
>
// helpers to set mock expectations
const expectRouterMock = (state: V3TradeState) => {
mockUseRoutingAPITradeExactIn.mockReturnValue({ state, trade: null })
mockUseRoutingAPITradeExactOut.mockReturnValue({ state, trade: null })
}
const expectClientSideMock = (state: V3TradeState) => {
mockUseClientSideV3TradeExactIn.mockReturnValue({ state, trade: null })
mockUseClientSideV3TradeExactOut.mockReturnValue({ state, trade: null })
}
beforeEach(() => {
// ignore debounced value
mockUseDebounce.mockImplementation((value) => value)
mockUseIsWindowVisible.mockReturnValue(true)
mockUseRoutingAPIEnabled.mockReturnValue(true)
})
describe('#useV3TradeExactIn', () => {
it('does not compute routing api trade when routing API is disabled', () => {
mockUseRoutingAPIEnabled.mockReturnValue(false)
expectRouterMock(V3TradeState.INVALID)
expectClientSideMock(V3TradeState.VALID)
const { result } = renderHook(() => useV3TradeExactIn(USDCAmount, DAI))
expect(mockUseRoutingAPITradeExactIn).toHaveBeenCalledWith(undefined, DAI)
expect(mockUseClientSideV3TradeExactIn).toHaveBeenCalledWith(USDCAmount, DAI)
expect(result.current).toEqual({ state: V3TradeState.VALID, trade: null })
})
it('does not compute routing api trade when window is not focused', () => {
mockUseIsWindowVisible.mockReturnValue(false)
expectRouterMock(V3TradeState.NO_ROUTE_FOUND)
expectClientSideMock(V3TradeState.VALID)
const { result } = renderHook(() => useV3TradeExactIn(USDCAmount, DAI))
expect(mockUseRoutingAPITradeExactIn).toHaveBeenCalledWith(undefined, DAI)
expect(mockUseClientSideV3TradeExactIn).toHaveBeenCalledWith(USDCAmount, DAI)
expect(result.current).toEqual({ state: V3TradeState.VALID, trade: null })
})
describe('when routing api is in non-error state', () => {
it('does not compute client side v3 trade if routing api is LOADING', () => {
expectRouterMock(V3TradeState.LOADING)
const { result } = renderHook(() => useV3TradeExactIn(USDCAmount, DAI))
expect(mockUseClientSideV3TradeExactIn).toHaveBeenCalledWith(undefined, undefined)
expect(result.current).toEqual({ state: V3TradeState.LOADING, trade: null })
})
it('does not compute client side v3 trade if routing api is VALID', () => {
expectRouterMock(V3TradeState.VALID)
const { result } = renderHook(() => useV3TradeExactIn(USDCAmount, DAI))
expect(mockUseClientSideV3TradeExactIn).toHaveBeenCalledWith(undefined, undefined)
expect(result.current).toEqual({ state: V3TradeState.VALID, trade: null })
})
it('does not compute client side v3 trade if routing api is SYNCING', () => {
expectRouterMock(V3TradeState.SYNCING)
const { result } = renderHook(() => useV3TradeExactIn(USDCAmount, DAI))
expect(mockUseClientSideV3TradeExactIn).toHaveBeenCalledWith(undefined, undefined)
expect(result.current).toEqual({ state: V3TradeState.SYNCING, trade: null })
})
})
describe('when routing api is in error state', () => {
it('does not compute client side v3 trade if routing api is INVALID', () => {
expectRouterMock(V3TradeState.INVALID)
expectClientSideMock(V3TradeState.VALID)
renderHook(() => useV3TradeExactIn(USDCAmount, DAI))
expect(mockUseClientSideV3TradeExactIn).toHaveBeenCalledWith(undefined, undefined)
})
it('computes client side v3 trade if routing api is NO_ROUTE_FOUND', () => {
expectRouterMock(V3TradeState.NO_ROUTE_FOUND)
expectClientSideMock(V3TradeState.VALID)
const { result } = renderHook(() => useV3TradeExactIn(USDCAmount, DAI))
expect(mockUseClientSideV3TradeExactIn).toHaveBeenCalledWith(USDCAmount, DAI)
expect(result.current).toEqual({ state: V3TradeState.VALID, trade: null })
})
})
})
describe('#useV3TradeExactOut', () => {
it('does not compute routing api trade when routing API is disabled', () => {
mockUseRoutingAPIEnabled.mockReturnValue(false)
expectRouterMock(V3TradeState.INVALID)
expectClientSideMock(V3TradeState.VALID)
const { result } = renderHook(() => useV3TradeExactOut(USDC, DAIAmount))
expect(mockUseRoutingAPITradeExactOut).toHaveBeenCalledWith(undefined, DAIAmount)
expect(mockUseClientSideV3TradeExactOut).toHaveBeenCalledWith(USDC, DAIAmount)
expect(result.current).toEqual({ state: V3TradeState.VALID, trade: null })
})
it('does not compute routing api trade when window is not focused', () => {
mockUseIsWindowVisible.mockReturnValue(false)
expectRouterMock(V3TradeState.NO_ROUTE_FOUND)
expectClientSideMock(V3TradeState.VALID)
const { result } = renderHook(() => useV3TradeExactOut(USDC, DAIAmount))
expect(mockUseRoutingAPITradeExactOut).toHaveBeenCalledWith(undefined, DAIAmount)
expect(mockUseClientSideV3TradeExactOut).toHaveBeenCalledWith(USDC, DAIAmount)
expect(result.current).toEqual({ state: V3TradeState.VALID, trade: null })
})
describe('when routing api is in non-error state', () => {
it('does not compute client side v3 trade if routing api is LOADING', () => {
expectRouterMock(V3TradeState.LOADING)
const { result } = renderHook(() => useV3TradeExactOut(USDC, DAIAmount))
expect(mockUseClientSideV3TradeExactOut).toHaveBeenCalledWith(undefined, undefined)
expect(result.current).toEqual({ state: V3TradeState.LOADING, trade: null })
})
it('does not compute client side v3 trade if routing api is VALID', () => {
expectRouterMock(V3TradeState.VALID)
const { result } = renderHook(() => useV3TradeExactOut(USDC, DAIAmount))
expect(mockUseClientSideV3TradeExactOut).toHaveBeenCalledWith(undefined, undefined)
expect(result.current).toEqual({ state: V3TradeState.VALID, trade: null })
})
it('does not compute client side v3 trade if routing api is SYNCING', () => {
expectRouterMock(V3TradeState.SYNCING)
const { result } = renderHook(() => useV3TradeExactOut(USDC, DAIAmount))
expect(mockUseClientSideV3TradeExactOut).toHaveBeenCalledWith(undefined, undefined)
expect(result.current).toEqual({ state: V3TradeState.SYNCING, trade: null })
})
})
describe('when routing api is in error state', () => {
it('computes client side v3 trade if routing api is INVALID', () => {
expectRouterMock(V3TradeState.INVALID)
expectClientSideMock(V3TradeState.VALID)
renderHook(() => useV3TradeExactOut(USDC, DAIAmount))
expect(mockUseClientSideV3TradeExactOut).toHaveBeenCalledWith(undefined, undefined)
})
it('computes client side v3 trade if routing api is NO_ROUTE_FOUND', () => {
expectRouterMock(V3TradeState.NO_ROUTE_FOUND)
expectClientSideMock(V3TradeState.VALID)
const { result } = renderHook(() => useV3TradeExactOut(USDC, DAIAmount))
expect(mockUseClientSideV3TradeExactOut).toHaveBeenCalledWith(USDC, DAIAmount)
expect(result.current).toEqual({ state: V3TradeState.VALID, trade: null })
})
})
})