chore(suite-common): Add tests for useTradingFiatValues

This commit is contained in:
Jirka Bažant
2026-02-18 16:54:26 +01:00
committed by Jiří Bažant
parent 52be006507
commit d7161ab78b
2 changed files with 327 additions and 11 deletions

View File

@@ -1,10 +1,15 @@
import { ReactNode } from 'react';
import { Provider } from 'react-redux';
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 { 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> & {
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.
*
@@ -156,17 +184,21 @@ export const renderHookWithTradingStore = <Result, Props = unknown>(
reducer: combineReducers({
wallet: combineReducers({
trading: tradingCommonReducer,
settings: (state = { localCurrency: 'usd' }) => state,
fiat: (
state = {
current: {},
lastWeek: {},
historic: {},
},
) => state,
}),
}),
preloadedState: preloadedState || createTradingTestState(),
});
const wrapper = ({ children }: { children: ReactNode }) => (
<Provider store={store}>{children}</Provider>
);
return {
...renderHook(callback, { wrapper, ...options }),
...renderHookWithStoreProvider(callback, { store, ...options }),
store,
};
};

View File

@@ -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');
});
});
});