mirror of
https://github.com/trezor/trezor-suite.git
synced 2026-02-20 00:33:07 +01:00
chore(suite-common): Add tests for useTradingFiatValues
This commit is contained in:
committed by
Jiří Bažant
parent
52be006507
commit
d7161ab78b
@@ -1,10 +1,15 @@
|
|||||||
import { ReactNode } from 'react';
|
|
||||||
import { Provider } from 'react-redux';
|
|
||||||
|
|
||||||
import { combineReducers } from '@reduxjs/toolkit';
|
import { combineReducers } from '@reduxjs/toolkit';
|
||||||
import { RenderHookOptions, renderHook } from '@testing-library/react';
|
|
||||||
|
|
||||||
import { configureMockStore } from '@suite-common/test-utils';
|
import {
|
||||||
|
RenderHookOptions,
|
||||||
|
configureMockStore,
|
||||||
|
renderHookWithStoreProvider,
|
||||||
|
} from '@suite-common/test-utils';
|
||||||
|
import {
|
||||||
|
FiatRatesState,
|
||||||
|
WalletSettingsState,
|
||||||
|
initialWalletSettingsState,
|
||||||
|
} from '@suite-common/wallet-core';
|
||||||
|
|
||||||
import { TradingState, initialState, tradingCommonReducer } from '../reducers/tradingCommonReducer';
|
import { TradingState, initialState, tradingCommonReducer } from '../reducers/tradingCommonReducer';
|
||||||
import { regional } from '../regional';
|
import { regional } from '../regional';
|
||||||
@@ -21,8 +26,16 @@ export type TradingTestState = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type TradingTestStateWithWalletSettings = {
|
||||||
|
wallet: {
|
||||||
|
trading: TradingState;
|
||||||
|
settings: WalletSettingsState;
|
||||||
|
fiat: FiatRatesState;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
type RenderHookWithTradingStoreOptions<Props> = RenderHookOptions<Props> & {
|
type RenderHookWithTradingStoreOptions<Props> = RenderHookOptions<Props> & {
|
||||||
preloadedState?: Partial<TradingTestState>;
|
preloadedState?: Partial<TradingTestStateWithWalletSettings> | Partial<TradingTestState>;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -50,6 +63,21 @@ export const createTradingTestState = (
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const createTestStateWithWalletSettings = (
|
||||||
|
overrides: Partial<TradingTestStateWithWalletSettings['wallet']> = {},
|
||||||
|
): TradingTestStateWithWalletSettings => ({
|
||||||
|
wallet: {
|
||||||
|
trading: initialState,
|
||||||
|
settings: initialWalletSettingsState,
|
||||||
|
fiat: {
|
||||||
|
current: {},
|
||||||
|
lastWeek: {},
|
||||||
|
historic: {},
|
||||||
|
},
|
||||||
|
...overrides,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a partial BuyInfo state for testing.
|
* Creates a partial BuyInfo state for testing.
|
||||||
*
|
*
|
||||||
@@ -156,17 +184,21 @@ export const renderHookWithTradingStore = <Result, Props = unknown>(
|
|||||||
reducer: combineReducers({
|
reducer: combineReducers({
|
||||||
wallet: combineReducers({
|
wallet: combineReducers({
|
||||||
trading: tradingCommonReducer,
|
trading: tradingCommonReducer,
|
||||||
|
settings: (state = { localCurrency: 'usd' }) => state,
|
||||||
|
fiat: (
|
||||||
|
state = {
|
||||||
|
current: {},
|
||||||
|
lastWeek: {},
|
||||||
|
historic: {},
|
||||||
|
},
|
||||||
|
) => state,
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
preloadedState: preloadedState || createTradingTestState(),
|
preloadedState: preloadedState || createTradingTestState(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const wrapper = ({ children }: { children: ReactNode }) => (
|
|
||||||
<Provider store={store}>{children}</Provider>
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...renderHook(callback, { wrapper, ...options }),
|
...renderHookWithStoreProvider(callback, { store, ...options }),
|
||||||
store,
|
store,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,284 @@
|
|||||||
|
import { CryptoId, FiatCurrencyCode } from 'invity-api';
|
||||||
|
|
||||||
|
import { NetworkSymbol } from '@suite-common/wallet-config';
|
||||||
|
import { initialWalletSettingsState } from '@suite-common/wallet-core';
|
||||||
|
import { Rate, Timestamp } from '@suite-common/wallet-types';
|
||||||
|
import { getFiatRateKey } from '@suite-common/wallet-utils';
|
||||||
|
|
||||||
|
import {
|
||||||
|
TradingTestStateWithWalletSettings,
|
||||||
|
createTestStateWithWalletSettings,
|
||||||
|
renderHookWithTradingStore,
|
||||||
|
} from '../../__tests__/testUtils';
|
||||||
|
import {
|
||||||
|
TradingFiatRatesProps,
|
||||||
|
TradingFiatRatesReturn,
|
||||||
|
useTradingFiatValues,
|
||||||
|
} from '../useTradingFiatValues';
|
||||||
|
|
||||||
|
// Mock crypto IDs for testing
|
||||||
|
const BITCOIN_CRYPTO_ID = 'bitcoin' as CryptoId;
|
||||||
|
const ETHEREUM_CRYPTO_ID = 'ethereum' as CryptoId;
|
||||||
|
|
||||||
|
const createMockRate = (rate: number, symbol: NetworkSymbol = 'btc'): Rate => ({
|
||||||
|
rate,
|
||||||
|
lastTickerTimestamp: 1000000 as Timestamp,
|
||||||
|
lastSuccessfulFetchTimestamp: Date.now() as Timestamp,
|
||||||
|
isLoading: false,
|
||||||
|
error: null,
|
||||||
|
ticker: {
|
||||||
|
symbol,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const getPreloadedState = () => {
|
||||||
|
const btcRate = createMockRate(50000);
|
||||||
|
const fiatRateKey = getFiatRateKey('btc', 'usd');
|
||||||
|
|
||||||
|
return createTestStateWithWalletSettings({
|
||||||
|
fiat: {
|
||||||
|
current: {
|
||||||
|
[fiatRateKey]: btcRate,
|
||||||
|
},
|
||||||
|
lastWeek: {},
|
||||||
|
historic: {},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderUseTradingFiatValues = (
|
||||||
|
props: TradingFiatRatesProps,
|
||||||
|
preloadedState: TradingTestStateWithWalletSettings = createTestStateWithWalletSettings(),
|
||||||
|
) => renderHookWithTradingStore(() => useTradingFiatValues(props), { preloadedState });
|
||||||
|
|
||||||
|
describe('useTradingFiatValues', () => {
|
||||||
|
describe('returns null when required parameters are missing', () => {
|
||||||
|
it('should return null when cryptoId is undefined', () => {
|
||||||
|
const { result } = renderUseTradingFiatValues({
|
||||||
|
cryptoId: undefined,
|
||||||
|
fiatCurrency: 'usd' as FiatCurrencyCode,
|
||||||
|
amount: '100',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.current).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return null when fiatCurrency is undefined', () => {
|
||||||
|
const { result } = renderUseTradingFiatValues({
|
||||||
|
cryptoId: BITCOIN_CRYPTO_ID,
|
||||||
|
fiatCurrency: undefined,
|
||||||
|
amount: '100',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.current).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return null when amount is undefined', () => {
|
||||||
|
const { result } = renderUseTradingFiatValues({
|
||||||
|
cryptoId: BITCOIN_CRYPTO_ID,
|
||||||
|
fiatCurrency: 'usd' as FiatCurrencyCode,
|
||||||
|
amount: undefined,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.current).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return null when all parameters are missing', () => {
|
||||||
|
const { result } = renderUseTradingFiatValues({});
|
||||||
|
|
||||||
|
expect(result.current).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('returns correct values for native tokens', () => {
|
||||||
|
it('should calculate fiat value for Bitcoin', () => {
|
||||||
|
const preloadedState = getPreloadedState();
|
||||||
|
|
||||||
|
const { result } = renderUseTradingFiatValues(
|
||||||
|
{
|
||||||
|
cryptoId: BITCOIN_CRYPTO_ID,
|
||||||
|
fiatCurrency: 'usd' as FiatCurrencyCode,
|
||||||
|
amount: '1',
|
||||||
|
},
|
||||||
|
preloadedState,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result.current).not.toBeNull();
|
||||||
|
expect(result.current?.fiatValue).toBe('50000.00');
|
||||||
|
expect(result.current?.symbol).toBe('btc');
|
||||||
|
expect(result.current?.accountBalance).toBe('1');
|
||||||
|
expect(result.current?.tokenAddress).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should calculate fiat value for Ethereum', () => {
|
||||||
|
const ethRate = createMockRate(3000, 'eth');
|
||||||
|
const fiatRateKey = getFiatRateKey('eth', 'eur');
|
||||||
|
|
||||||
|
const preloadedState = createTestStateWithWalletSettings({
|
||||||
|
settings: {
|
||||||
|
...initialWalletSettingsState,
|
||||||
|
localCurrency: 'eur',
|
||||||
|
},
|
||||||
|
fiat: {
|
||||||
|
current: {
|
||||||
|
[fiatRateKey]: ethRate,
|
||||||
|
},
|
||||||
|
lastWeek: {},
|
||||||
|
historic: {},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const { result } = renderUseTradingFiatValues(
|
||||||
|
{
|
||||||
|
cryptoId: ETHEREUM_CRYPTO_ID,
|
||||||
|
fiatCurrency: 'eur' as FiatCurrencyCode,
|
||||||
|
amount: '2.5',
|
||||||
|
},
|
||||||
|
preloadedState,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result.current).not.toBeNull();
|
||||||
|
expect(result.current?.fiatValue).toBe('7500.00');
|
||||||
|
expect(result.current?.symbol).toBe('eth');
|
||||||
|
expect(result.current?.tokenAddress).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct network decimals for Bitcoin', () => {
|
||||||
|
const preloadedState = getPreloadedState();
|
||||||
|
|
||||||
|
const { result } = renderUseTradingFiatValues(
|
||||||
|
{
|
||||||
|
cryptoId: BITCOIN_CRYPTO_ID,
|
||||||
|
fiatCurrency: 'usd' as FiatCurrencyCode,
|
||||||
|
amount: '1',
|
||||||
|
},
|
||||||
|
preloadedState,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result.current?.networkDecimals).toBe(8);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('handles fiat rate unavailability', () => {
|
||||||
|
it('should return null fiatValue when rate is not available', () => {
|
||||||
|
const preloadedState = createTestStateWithWalletSettings({
|
||||||
|
fiat: {
|
||||||
|
current: {},
|
||||||
|
lastWeek: {},
|
||||||
|
historic: {},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const { result } = renderUseTradingFiatValues(
|
||||||
|
{
|
||||||
|
cryptoId: BITCOIN_CRYPTO_ID,
|
||||||
|
fiatCurrency: 'usd' as FiatCurrencyCode,
|
||||||
|
amount: '1',
|
||||||
|
},
|
||||||
|
preloadedState,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result.current).not.toBeNull();
|
||||||
|
expect(result.current?.fiatValue).toBeNull();
|
||||||
|
expect(result.current?.fiatRate).toBeUndefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('handles shouldSendInSats option', () => {
|
||||||
|
it('should convert amount to satoshis when shouldSendInSats is true', () => {
|
||||||
|
const preloadedState = getPreloadedState();
|
||||||
|
|
||||||
|
const { result } = renderUseTradingFiatValues(
|
||||||
|
{
|
||||||
|
cryptoId: BITCOIN_CRYPTO_ID,
|
||||||
|
fiatCurrency: 'usd' as FiatCurrencyCode,
|
||||||
|
amount: '1',
|
||||||
|
shouldSendInSats: true,
|
||||||
|
},
|
||||||
|
preloadedState,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result.current).not.toBeNull();
|
||||||
|
// 1 BTC = 100,000,000 satoshis
|
||||||
|
expect(result.current?.formattedBalance).toBe('100000000');
|
||||||
|
expect(result.current?.accountBalance).toBe('1');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not convert amount when shouldSendInSats is false', () => {
|
||||||
|
const preloadedState = getPreloadedState();
|
||||||
|
|
||||||
|
const { result } = renderUseTradingFiatValues(
|
||||||
|
{
|
||||||
|
cryptoId: BITCOIN_CRYPTO_ID,
|
||||||
|
fiatCurrency: 'usd' as FiatCurrencyCode,
|
||||||
|
amount: '1',
|
||||||
|
shouldSendInSats: false,
|
||||||
|
},
|
||||||
|
preloadedState,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result.current).not.toBeNull();
|
||||||
|
expect(result.current?.formattedBalance).toBe('1');
|
||||||
|
expect(result.current?.accountBalance).toBe('1');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('fiatRatesUpdater function', () => {
|
||||||
|
it('should return fiatRatesUpdater function', () => {
|
||||||
|
const preloadedState = getPreloadedState();
|
||||||
|
|
||||||
|
const { result } = renderUseTradingFiatValues(
|
||||||
|
{
|
||||||
|
cryptoId: BITCOIN_CRYPTO_ID,
|
||||||
|
fiatCurrency: 'usd' as FiatCurrencyCode,
|
||||||
|
amount: '1',
|
||||||
|
},
|
||||||
|
preloadedState,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result.current).not.toBeNull();
|
||||||
|
expect(typeof result.current?.fiatRatesUpdater).toBe('function');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return null when fiatRatesUpdater is called with undefined value', async () => {
|
||||||
|
const preloadedState = getPreloadedState();
|
||||||
|
|
||||||
|
const { result } = renderUseTradingFiatValues(
|
||||||
|
{
|
||||||
|
cryptoId: BITCOIN_CRYPTO_ID,
|
||||||
|
fiatCurrency: 'usd' as FiatCurrencyCode,
|
||||||
|
amount: '1',
|
||||||
|
},
|
||||||
|
preloadedState,
|
||||||
|
);
|
||||||
|
|
||||||
|
const updaterResult = await result.current?.fiatRatesUpdater(undefined);
|
||||||
|
expect(updaterResult).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('return value structure', () => {
|
||||||
|
it('should return all expected properties', () => {
|
||||||
|
const preloadedState = getPreloadedState();
|
||||||
|
|
||||||
|
const { result } = renderUseTradingFiatValues(
|
||||||
|
{
|
||||||
|
cryptoId: BITCOIN_CRYPTO_ID,
|
||||||
|
fiatCurrency: 'usd' as FiatCurrencyCode,
|
||||||
|
amount: '1',
|
||||||
|
},
|
||||||
|
preloadedState,
|
||||||
|
);
|
||||||
|
|
||||||
|
const returnValue = result.current as TradingFiatRatesReturn;
|
||||||
|
expect(returnValue).toHaveProperty('fiatValue');
|
||||||
|
expect(returnValue).toHaveProperty('fiatRate');
|
||||||
|
expect(returnValue).toHaveProperty('accountBalance');
|
||||||
|
expect(returnValue).toHaveProperty('formattedBalance');
|
||||||
|
expect(returnValue).toHaveProperty('symbol');
|
||||||
|
expect(returnValue).toHaveProperty('networkDecimals');
|
||||||
|
expect(returnValue).toHaveProperty('tokenAddress');
|
||||||
|
expect(returnValue).toHaveProperty('fiatRatesUpdater');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user