mirror of
https://github.com/trezor/trezor-suite.git
synced 2026-02-19 16:22:25 +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 { 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,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -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