import { render, screen } from '@testing-library/react'; import type { Account } from '@vegaprotocol/accounts'; import { AccountType, AssetStatus } from '@vegaprotocol/types'; import { MemoryRouter } from 'react-router-dom'; import { RewardPot, Vesting, type RewardPotProps, Multipliers, } from './rewards-container'; const rewardAsset = { id: 'asset-1', symbol: 'ASSET 1', name: 'Asset 1', decimals: 2, quantum: '1', status: AssetStatus.STATUS_ENABLED, source: { __typename: 'ERC20' as const, contractAddress: '0x123', lifetimeLimit: '100', withdrawThreshold: '100', }, }; describe('RewardPot', () => { const renderComponent = (props: RewardPotProps) => { return render( ); }; it('Shows no rewards message if no accounts or vesting balances provided', () => { renderComponent({ pubKey: 'pubkey', assetId: rewardAsset.id, accounts: [], vestingBalancesSummary: { lockedBalances: [], vestingBalances: [], }, }); expect(screen.getByText(/No rewards/)).toBeInTheDocument(); }); it('Calculates all the rewards', () => { const asset2 = { id: 'asset-2', symbol: 'ASSET 2', name: 'Asset 2', decimals: 0, quantum: '1000000', status: AssetStatus.STATUS_ENABLED, source: { __typename: 'ERC20' as const, contractAddress: '0x123', lifetimeLimit: '100', withdrawThreshold: '100', }, }; const accounts: Account[] = [ { type: AccountType.ACCOUNT_TYPE_GENERAL, balance: '100', asset: rewardAsset, }, // should include this in total: { type: AccountType.ACCOUNT_TYPE_VESTED_REWARDS, balance: '100', asset: rewardAsset, }, // should include this in total: { type: AccountType.ACCOUNT_TYPE_VESTED_REWARDS, balance: '50', asset: rewardAsset, }, { type: AccountType.ACCOUNT_TYPE_VESTED_REWARDS, balance: '500000', asset: asset2, }, { type: AccountType.ACCOUNT_TYPE_VESTING_REWARDS, // should be ignored as its vesting balance: '100', asset: rewardAsset, }, { type: AccountType.ACCOUNT_TYPE_VESTING_REWARDS, // should be ignored balance: '2000000', asset: asset2, }, ]; const props = { pubKey: 'pubkey', assetId: rewardAsset.id, accounts: accounts, vestingBalancesSummary: { epoch: 1, lockedBalances: [ { balance: '150', asset: rewardAsset, untilEpoch: 1, }, { balance: '100', asset: rewardAsset, untilEpoch: 1, }, { balance: '100', asset: asset2, // should be ignored untilEpoch: 1, }, ], vestingBalances: [ { balance: '250', asset: rewardAsset, }, { balance: '200', asset: rewardAsset, }, { balance: '100', asset: asset2, // should be ignored }, ], }, }; renderComponent(props); expect(screen.getByText(/Locked/).nextElementSibling).toHaveTextContent( '2.50' ); expect(screen.getByText(/Vesting/).nextElementSibling).toHaveTextContent( '4.50' ); expect( screen.getByText(/Available to withdraw/).nextElementSibling ).toHaveTextContent('1.50'); // should be sum of the above expect(screen.getByTestId('total-rewards')).toHaveTextContent( `8.50 ${rewardAsset.symbol}` ); }); }); describe('Vesting', () => { it('renders vesting rates', () => { render(); expect(screen.getByTestId('vesting-rate')).toHaveTextContent('50%'); expect(screen.getByText('Base rate').nextElementSibling).toHaveTextContent( '25%' ); expect( screen.getByText('Vesting multiplier').nextSibling ).toHaveTextContent('2x'); }); it('doesnt use multiplier if not connected', () => { render( ); expect(screen.getByTestId('vesting-rate')).toHaveTextContent('25%'); expect(screen.getByText('Base rate').nextElementSibling).toHaveTextContent( '25%' ); expect(screen.queryByText('Vesting multiplier')).not.toBeInTheDocument(); }); }); describe('Multipliers', () => { it('shows combined multipliers', () => { render( ); expect(screen.getByTestId('combined-multipliers')).toHaveTextContent('6x'); expect( screen.getByText('Streak reward multiplier').nextElementSibling ).toHaveTextContent('3x'); expect( screen.getByText('Hoarder reward multiplier').nextElementSibling ).toHaveTextContent('2x'); }); it('shows not connected state', () => { render( ); expect( screen.queryByTestId('combined-multipliers') ).not.toBeInTheDocument(); expect( screen.queryByText('Streak reward multiplier') ).not.toBeInTheDocument(); expect( screen.queryByText('Hoarder reward multiplier') ).not.toBeInTheDocument(); expect(screen.getByText('Not connected')).toBeInTheDocument(); }); });