Fix/1685 connet wrong on associate (#1718)

* fix: incorrect connection logic on the associate page

* test: add tests for staking wallet container

* chore: move files to be consistent with other routes structures

* chore: rename to be consistent with other route strcutures

* style: lint

* test: allow seeing of node information when not connected to wallets

* test: add test for disassociate page
This commit is contained in:
Dexter Edwards 2022-10-13 15:10:27 +01:00 committed by GitHub
parent 1fce4c0ed6
commit 56d9a70b97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 204 additions and 62 deletions

View File

@ -70,7 +70,7 @@ const LazyStakingAssociate = React.lazy(
const LazyStakingDisassociate = React.lazy(
() =>
import(
/* webpackChunkName: "route-staking-disassociate", webpackPrefetch: true */ './staking/disassociate/disassociate-page-container'
/* webpackChunkName: "route-staking-disassociate", webpackPrefetch: true */ './staking/disassociate'
)
);

View File

@ -1,5 +1,5 @@
import { useEthereumConfig } from '@vegaprotocol/web3';
import { StakingWalletsContainer } from '../staking-wallets-container';
import { StakingWalletsContainer } from '../components/staking-wallets-container/staking-wallets-container';
import { AssociatePage } from './associate-page';
import { AssociatePageNoVega } from './associate-page-no-vega';

View File

@ -0,0 +1 @@
export { StakingWalletsContainer } from './staking-wallets-container';

View File

@ -0,0 +1,82 @@
import { render, screen } from '@testing-library/react';
import type { useWeb3React } from '@web3-react/core';
import { StakingWalletsContainer } from './staking-wallets-container';
jest.mock('../../connect-to-vega', () => ({
ConnectToVega: () => <div data-testid="connect-to-vega" />,
}));
jest.mock('../../../../components/eth-connect-prompt', () => ({
EthConnectPrompt: () => <div data-testid="eth-connect-prompt" />,
}));
const defaultHookValue = {
isActive: false,
error: undefined,
connector: null,
chainId: 3,
account: null,
} as unknown as ReturnType<typeof useWeb3React>;
let mockHookValue: ReturnType<typeof useWeb3React>;
jest.mock('@web3-react/core', () => {
const original = jest.requireActual('@web3-react/core');
return {
...original,
useWeb3React: jest.fn(() => mockHookValue),
};
});
let mockVegaWalletHookValue: {
pubKey: string | null;
} = {
pubKey: null,
};
jest.mock('@vegaprotocol/wallet', () => ({
...jest.requireActual('@vegaprotocol/wallet'),
useVegaWallet: jest.fn(() => mockVegaWalletHookValue),
}));
const renderComponent = () => {
return render(
<StakingWalletsContainer>
{({ address, pubKey }) => (
<div>
<div data-testid="eth-address">{address}</div>
<div data-testid="vega-pubkey">{pubKey}</div>
</div>
)}
</StakingWalletsContainer>
);
};
describe('Staking wallets container', () => {
it('should render connect to eth button if not connected', () => {
mockHookValue = defaultHookValue;
renderComponent();
expect(screen.getByTestId('eth-connect-prompt')).toBeInTheDocument();
});
it('should render connect to vega button if there is no pubkey', () => {
mockHookValue = {
...defaultHookValue,
account: '0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f',
};
renderComponent();
expect(screen.getByTestId('connect-to-vega')).toBeInTheDocument();
});
it('should render children if both are connected', () => {
mockVegaWalletHookValue = { pubKey: 'foo' };
mockHookValue = {
...defaultHookValue,
account: '0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f',
};
renderComponent();
expect(screen.getByTestId('eth-address')).toHaveTextContent(
'0xb2d6DEC77558Cf8EdB7c428d23E70Eab0688544f'
);
expect(screen.getByTestId('vega-pubkey')).toHaveTextContent('foo');
});
});

View File

@ -1,24 +1,20 @@
import { useWeb3React } from '@web3-react/core';
import { useTranslation } from 'react-i18next';
import { EthConnectPrompt } from '../../components/eth-connect-prompt';
import { EthConnectPrompt } from '../../../../components/eth-connect-prompt';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { ConnectToVega } from './connect-to-vega';
import { ConnectToVega } from '../../connect-to-vega';
export const StakingWalletsContainer = ({
needsEthereum,
needsVega,
children,
}: {
needsEthereum?: boolean;
needsVega?: boolean;
children: (data: { address: string; pubKey: string }) => React.ReactElement;
}) => {
const { t } = useTranslation();
const { account } = useWeb3React();
const { pubKey } = useVegaWallet();
if (!account && needsEthereum) {
if (!account) {
return (
<EthConnectPrompt>
<p>{t('associateInfo1')}</p>
@ -27,16 +23,8 @@ export const StakingWalletsContainer = ({
);
}
if (!pubKey || needsVega) {
return (
<>
<EthConnectPrompt>
<p>{t('associateInfo1')}</p>
<p>{t('associateInfo2')}</p>
</EthConnectPrompt>
<ConnectToVega />
</>
);
if (!pubKey) {
return <ConnectToVega />;
}
return children({ address: account || '', pubKey });

View File

@ -1,19 +1,19 @@
import { DisassociateTransaction } from './disassociate-transaction';
import { formatNumber } from '../../../lib/format-number';
import { DisassociateTransaction } from '../disassociate-transaction';
import { formatNumber } from '../../../../../lib/format-number';
import { remove0x, toBigNum } from '@vegaprotocol/react-helpers';
import { Select } from '@vegaprotocol/ui-toolkit';
import { StakingMethod } from '../../../components/staking-method-radio';
import { TokenInput } from '../../../components/token-input';
import { TxState } from '../../../hooks/transaction-reducer';
import { useAppState } from '../../../contexts/app-state/app-state-context';
import { useRefreshAssociatedBalances } from '../../../hooks/use-refresh-associated-balances';
import { useRemoveStake } from './hooks';
import type { RemoveStakePayload } from './hooks';
import { StakingMethod } from '../../../../../components/staking-method-radio';
import { TokenInput } from '../../../../../components/token-input';
import { TxState } from '../../../../../hooks/transaction-reducer';
import { useAppState } from '../../../../../contexts/app-state/app-state-context';
import { useRefreshAssociatedBalances } from '../../../../../hooks/use-refresh-associated-balances';
import { useRemoveStake } from '../../hooks';
import type { RemoveStakePayload } from '../../hooks';
import { useState, useEffect, useMemo, useCallback } from 'react';
import type { ChangeEvent } from 'react';
import { useTranslation } from 'react-i18next';
import type { BigNumber } from '../../../lib/bignumber';
import { truncateMiddle } from '../../../lib/truncate-middle';
import type { BigNumber } from '../../../../../lib/bignumber';
import { truncateMiddle } from '../../../../../lib/truncate-middle';
type Association = {
/**
@ -68,7 +68,7 @@ export const DisassociatePage = ({
...toListOfAssociations(vestingAssociations, StakingMethod.Contract),
].map((a) => ({
...a,
label: `${truncateMiddle(a.key)} ${t(`via${a.stakingMethod}`)}
label: `${truncateMiddle(a.key)} ${t(`via${a.stakingMethod}`)}
(${formatNumber(a.amount, 18)} ${t('tokens')})`,
})),
[stakingAssociations, vestingAssociations, t]

View File

@ -0,0 +1 @@
export { DisassociatePage } from './disassociate-page';

View File

@ -3,14 +3,14 @@ import React from 'react';
import { useTranslation } from 'react-i18next';
import { Link } from 'react-router-dom';
import { StakingMethod } from '../../../components/staking-method-radio';
import { TransactionCallout } from '../../../components/transaction-callout';
import { StakingMethod } from '../../../../../components/staking-method-radio';
import { TransactionCallout } from '../../../../../components/transaction-callout';
import type {
TransactionAction,
TransactionState,
} from '../../../hooks/transaction-reducer';
import { TransactionActionType } from '../../../hooks/transaction-reducer';
import Routes from '../../routes';
} from '../../../../../hooks/transaction-reducer';
import { TransactionActionType } from '../../../../../hooks/transaction-reducer';
import Routes from '../../../../routes';
export const DisassociateTransaction = ({
amount,

View File

@ -0,0 +1 @@
export { DisassociateTransaction } from './disassociate-transaction';

View File

@ -1,14 +0,0 @@
import { StakingWalletsContainer } from '../staking-wallets-container';
import { DisassociatePage } from './disassociate-page';
export const DisassociateContainer = () => {
return (
<StakingWalletsContainer needsEthereum={true} needsVega={false}>
{({ address, pubKey }) => (
<DisassociatePage address={address} vegaKey={pubKey ?? ''} />
)}
</StakingWalletsContainer>
);
};
export default DisassociateContainer;

View File

@ -0,0 +1,71 @@
import { render, screen } from '@testing-library/react';
import type { useWeb3React } from '@web3-react/core';
import Disassociate from './index';
jest.mock('../../../components/eth-connect-prompt', () => ({
EthConnectPrompt: () => <div data-testid="eth-connect-prompt" />,
}));
jest.mock('./components/disassociate-page', () => ({
DisassociatePage: () => <div data-testid="disassociate-page" />,
}));
const defaultHookValue = {
isActive: false,
error: undefined,
connector: null,
chainId: 3,
account: null,
} as unknown as ReturnType<typeof useWeb3React>;
let mockHookValue: ReturnType<typeof useWeb3React>;
jest.mock('@web3-react/core', () => {
const original = jest.requireActual('@web3-react/core');
return {
...original,
useWeb3React: jest.fn(() => mockHookValue),
};
});
let mockVegaWalletHookValue: {
pubKey: string | null;
} = {
pubKey: null,
};
jest.mock('@vegaprotocol/wallet', () => ({
...jest.requireActual('@vegaprotocol/wallet'),
useVegaWallet: jest.fn(() => mockVegaWalletHookValue),
}));
const renderComponent = () => {
return render(<Disassociate />);
};
describe('Disassociate', () => {
it('should render connect to eth button if not connected', () => {
mockHookValue = defaultHookValue;
renderComponent();
expect(screen.getByTestId('eth-connect-prompt')).toBeInTheDocument();
});
it('should render disassociate page if eth wallet is connected and vega wallet is not', () => {
mockHookValue = {
...defaultHookValue,
account: 'foo',
};
renderComponent();
expect(screen.queryByTestId('eth-connect-prompt')).toBeFalsy();
expect(screen.getByTestId('disassociate-page')).toBeInTheDocument();
});
it('should render disassociate page if both wallets connected', () => {
mockHookValue = {
...defaultHookValue,
account: 'foo',
};
mockVegaWalletHookValue = { pubKey: 'foo' };
renderComponent();
expect(screen.getByTestId('disassociate-page')).toBeInTheDocument();
});
});

View File

@ -0,0 +1,17 @@
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useWeb3React } from '@web3-react/core';
import { EthConnectPrompt } from '../../../components/eth-connect-prompt';
import { DisassociatePage } from './components/disassociate-page';
export const DisassociateContainer = () => {
const { account } = useWeb3React();
const { pubKey } = useVegaWallet();
if (!account) {
return <EthConnectPrompt />;
}
return <DisassociatePage address={account} vegaKey={pubKey ?? ''} />;
};
export default DisassociateContainer;

View File

@ -7,29 +7,25 @@ import { BigNumber } from '../../lib/bignumber';
import type { Staking as StakingQueryResult } from './__generated__/Staking';
import { ConnectToVega } from './connect-to-vega';
import { StakingForm } from './staking-form';
import { StakingNodesContainer } from './staking-nodes-container';
import { StakingWalletsContainer } from './staking-wallets-container';
import { ValidatorTable } from './validator-table';
import { YourStake } from './your-stake';
import StakingNodesContainer from './staking-nodes-container';
import { useVegaWallet } from '@vegaprotocol/wallet';
export const StakingNodeContainer = () => {
return (
<StakingWalletsContainer>
{({ pubKey }) => (
<StakingNodesContainer>
{({ data }) => <StakingNode pubKey={pubKey} data={data} />}
</StakingNodesContainer>
)}
</StakingWalletsContainer>
<StakingNodesContainer>
{({ data }) => <StakingNode data={data} />}
</StakingNodesContainer>
);
};
interface StakingNodeProps {
pubKey: string;
data?: StakingQueryResult;
}
export const StakingNode = ({ pubKey: vegaKey, data }: StakingNodeProps) => {
export const StakingNode = ({ data }: StakingNodeProps) => {
const { pubKey: vegaKey } = useVegaWallet();
const { node } = useParams<{ node: string }>();
const { t } = useTranslation();

View File

@ -85,7 +85,6 @@ export const StakingNodesContainer = ({
STAKING_QUERY,
{
variables: { partyId: pubKey || '' },
skip: !pubKey,
}
);