Skip to content

Commit

Permalink
feat: refactor Command component
Browse files Browse the repository at this point in the history
  • Loading branch information
therealemjy committed Oct 7, 2024
1 parent 7a57307 commit 7162f23
Show file tree
Hide file tree
Showing 35 changed files with 1,332 additions and 602 deletions.
14 changes: 7 additions & 7 deletions apps/evm/src/__mocks__/models/proposals.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import BigNumber from 'bignumber.js';
import type { Proposal } from 'types';
import { type Proposal, ProposalState } from 'types';
import { remoteProposals } from './remoteProposals';

export const proposals: Proposal[] = [
Expand All @@ -19,7 +19,7 @@ export const proposals: Proposal[] = [
proposalId: 98,
proposerAddress: '0x2ce1d0ffd7e869d9df33e28552b12ddded326706',
startDate: new Date('2023-09-20T07:47:05.000Z'),
state: 3,
state: ProposalState.Defeated,
createdTxHash: '0xb8a70919dbf83e5c63af8efbad418b2a81ca9f4937b12f806482581abaf03b65',
totalVotesMantissa: new BigNumber('605461000000000000000000'),
proposalActions: [],
Expand Down Expand Up @@ -53,7 +53,7 @@ export const proposals: Proposal[] = [
proposalId: 97,
proposerAddress: '0x2ce1d0ffd7e869d9df33e28552b12ddded326706',
startDate: new Date('2023-09-20T07:47:05.000Z'),
state: 1,
state: ProposalState.Active,
createdTxHash: '0xb8a70919dbf83e5c63af8efbad418b2a81ca9f4937b12f806482581abaf03b65',
totalVotesMantissa: new BigNumber('1.605461e+24'),
proposalActions: [],
Expand Down Expand Up @@ -106,7 +106,7 @@ export const proposals: Proposal[] = [
queuedDate: new Date('2023-09-19T07:49:29.000Z'),
executionEtaDate: new Date('2023-09-19T07:59:29.000Z'),
startDate: new Date('2023-09-18T11:27:11.000Z'),
state: 2,
state: ProposalState.Canceled,
createdTxHash: '0x67c11aa7e66f92063d8e0fbfa3f528ad3266dafb3d26a976e008da930fde8209',
cancelTxHash: '0xec844bf514a6803c33ae93c168933d149ed16919a882f222a450b45f7895f86c',
queuedTxHash: '0x7f288a72f9d53e35720f6eaed2c3ad344cb1e08944a554a26004aa73cd16800c',
Expand Down Expand Up @@ -144,7 +144,7 @@ export const proposals: Proposal[] = [
proposalId: 95,
proposerAddress: '0x2ce1d0ffd7e869d9df33e28552b12ddded326706',
startDate: new Date('2023-09-15T10:15:50.000Z'),
state: 3,
state: ProposalState.Defeated,
createdTxHash: '0xfe924152536a7f775689c664aca3754c9694b78040c2ae7a0b56f84fed602acb',
totalVotesMantissa: new BigNumber('605461000000000000000000'),
proposalActions: [],
Expand Down Expand Up @@ -180,7 +180,7 @@ export const proposals: Proposal[] = [
proposalId: 94,
proposerAddress: '0x6eace20e1f89d0b24e5b295af1802dfbc730b37d',
startDate: new Date('2023-09-14T19:27:45.000Z'),
state: 4,
state: ProposalState.Succeeded,
createdTxHash: '0x27f1c81bfb014d08d2181af3bd9fa363b93a022e3f3c6798395e74b02f238a5f',
totalVotesMantissa: new BigNumber('605461000000000000000000'),
proposalActions: [],
Expand Down Expand Up @@ -216,7 +216,7 @@ export const proposals: Proposal[] = [
proposalId: 93,
proposerAddress: '0x6eace20e1f89d0b24e5b295af1802dfbc730b37d',
startDate: new Date('2023-09-14T16:04:05.000Z'),
state: 5,
state: ProposalState.Queued,
createdTxHash: '0xd016993b6b81bfbc5e6070edd88106809ebb0b7b58e67d33b526d027c1f5f076',
totalVotesMantissa: new BigNumber('605461000000000000000000'),
proposalActions: [],
Expand Down
6 changes: 3 additions & 3 deletions apps/evm/src/__mocks__/subgraph/bscProposals.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"remoteProposals": [
{
"id": "0xb1270000b401",
"proposalId": null,
"proposalId": "4",
"targets": ["0xf3118a17863996b9f2a073c9a66faaa664355cf8"],
"values": ["0"],
"signatures": ["faucet(uint256)"],
Expand All @@ -59,7 +59,7 @@
},
{
"id": "0xda270000b401",
"proposalId": null,
"proposalId": "5",
"targets": ["0x8ac9b3801d0a8f5055428ae0bf301ca1da976855"],
"values": ["0"],
"signatures": ["faucet(uint256)"],
Expand All @@ -72,7 +72,7 @@
},
{
"id": "0xf7270000b401",
"proposalId": null,
"proposalId": "6",
"targets": ["0x772d68929655ce7234c8c94256526dda66ef641e"],
"values": ["0"],
"signatures": ["faucet(uint256)"],
Expand Down
15 changes: 9 additions & 6 deletions apps/evm/src/clients/api/__mocks__/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -721,28 +721,31 @@ export const useCreateProposal = (options?: MutationObserverOptions) =>
});

export const cancelProposal = vi.fn(async () => fakeContractTransaction);
export const useCancelProposal = (options?: MutationObserverOptions) =>
export const useCancelProposal = vi.fn((options?: MutationObserverOptions) =>
useMutation({
mutationKey: [FunctionKey.CANCEL_PROPOSAL],
mutationFn: cancelProposal,
...options,
});
}),
);

export const executeProposal = vi.fn(async () => fakeContractTransaction);
export const useExecuteProposal = (options?: MutationObserverOptions) =>
export const useExecuteProposal = vi.fn((options?: MutationObserverOptions) =>
useMutation({
mutationKey: [FunctionKey.EXECUTE_PROPOSAL],
mutationFn: executeProposal,
...options,
});
}),
);

export const queueProposal = vi.fn(async () => fakeContractTransaction);
export const useQueueProposal = (options?: MutationObserverOptions) =>
export const useQueueProposal = vi.fn((options?: MutationObserverOptions) =>
useMutation({
mutationKey: [FunctionKey.QUEUE_PROPOSAL],
mutationFn: queueProposal,
...options,
});
}),
);

export const stakeInXvsVault = vi.fn();
export const useStakeInXvsVault = (_variables: never, options?: MutationObserverOptions) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ vi.mock('../../formatToProposalActions');

const params = {
layerZeroChainId: 10161,
proposalId: 1,
remoteProposalId: 1,
gqlRemoteProposal: nonBscProposalsResponse.proposals[0],
proposalState: ProposalState.Executed,
Expand Down
7 changes: 7 additions & 0 deletions apps/evm/src/containers/ConnectWallet/Container/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { cn } from 'utilities';

export interface ContainerProps extends React.HTMLAttributes<HTMLDivElement> {}

export const Container: React.FC<ContainerProps> = ({ className, ...otherProps }) => (
<div className={cn('w-full', className)} {...otherProps} />
);
91 changes: 91 additions & 0 deletions apps/evm/src/containers/ConnectWallet/__tests__/index.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { fireEvent, waitFor } from '@testing-library/react';
import type Vi from 'vitest';

import fakeAccountAddress from '__mocks__/models/address';
import { en } from 'libs/translations';
import { useAuthModal, useSwitchChain } from 'libs/wallet';
import { renderComponent } from 'testUtils/render';
import { ChainId } from 'types';
import { ConnectWallet } from '..';

describe('ConnectWallet', () => {
beforeEach(() => {
(useAuthModal as Vi.Mock).mockReturnValue({ openAuthModal: vi.fn() });
(useSwitchChain as Vi.Mock).mockReturnValue({ switchChain: vi.fn() });
});

it('renders without crashing', () => {
renderComponent(<ConnectWallet />);
});

it('displays authentication button when user is not connected', async () => {
const { getByText } = renderComponent(<ConnectWallet />);
const connectButton = getByText(en.connectWallet.connectButton);
expect(connectButton).toBeInTheDocument();
});

it('calls openAuthModal when connect button is clicked', async () => {
const mockOpenAuthModal = vi.fn();
(useAuthModal as Vi.Mock).mockReturnValue({ openAuthModal: mockOpenAuthModal });

const { getByText } = renderComponent(<ConnectWallet />);
const connectButton = getByText(en.connectWallet.connectButton);

fireEvent.click(connectButton);

await waitFor(() => {
expect(mockOpenAuthModal).toHaveBeenCalledTimes(1);
});
});

it('displays chain switching button when current chain is different from chainId parameter', async () => {
const { getByText } = renderComponent(<ConnectWallet chainId={ChainId.OPBNB_TESTNET} />, {
accountAddress: fakeAccountAddress,
});

const switchChainButton = getByText(
en.connectWallet.switchChain.replace('{{chainName}}', 'opBNB testnet'),
);
expect(switchChainButton).toBeInTheDocument();
});

it('calls switchChain when switch chain button is clicked', async () => {
const mockSwitchChain = vi.fn();
(useSwitchChain as Vi.Mock).mockReturnValue({ switchChain: mockSwitchChain });

const { getByText } = renderComponent(<ConnectWallet chainId={ChainId.OPBNB_TESTNET} />, {
accountAddress: fakeAccountAddress,
});

const switchChainButton = getByText(
en.connectWallet.switchChain.replace('{{chainName}}', 'opBNB testnet'),
);

fireEvent.click(switchChainButton);

await waitFor(() => {
expect(mockSwitchChain).toHaveBeenCalledTimes(1);
expect(mockSwitchChain).toHaveBeenCalledWith({ chainId: ChainId.OPBNB_TESTNET });
});
});

it('renders children when user is connected and on the correct chain', () => {
const { getByText } = renderComponent(
<ConnectWallet chainId={ChainId.BSC_TESTNET}>
<div>Child Component</div>
</ConnectWallet>,
{
accountAddress: fakeAccountAddress,
},
);

expect(getByText('Child Component')).toBeInTheDocument();
});

it('displays the message prop when provided', () => {
const message = 'Custom connect wallet message';
const { getByText } = renderComponent(<ConnectWallet message={message} />);

expect(getByText(message)).toBeInTheDocument();
});
});
18 changes: 0 additions & 18 deletions apps/evm/src/containers/ConnectWallet/index.stories.tsx

This file was deleted.

83 changes: 51 additions & 32 deletions apps/evm/src/containers/ConnectWallet/index.tsx
Original file line number Diff line number Diff line change
@@ -1,50 +1,69 @@
/** @jsxImportSource @emotion/react */
import { useTranslation } from 'libs/translations';
import { useAccountAddress, useAuthModal } from 'libs/wallet';
import { useAccountAddress, useAuthModal, useChainId, useSwitchChain } from 'libs/wallet';

import { CHAIN_METADATA } from 'constants/chainMetadata';
import { useMemo } from 'react';
import type { ChainId } from 'types';
import { Button, type Variant } from '../../components/Button';
import { NoticeInfo } from '../../components/Notice';
import { useStyles } from './styles';
import { Container } from './Container';

export interface PromptProps {
openAuthModal: () => void;
connected: boolean;
export interface ConnectWalletProps extends React.HTMLAttributes<HTMLDivElement> {
chainId?: ChainId;
buttonVariant?: Variant;
message?: string;
className?: string;
children?: React.ReactNode;
}

export const Prompt: React.FC<PromptProps> = ({
message,
openAuthModal,
className,
export const ConnectWallet: React.FC<ConnectWalletProps> = ({
children,
connected,
buttonVariant = 'secondary',
chainId,
message,
buttonVariant,
...otherProps
}) => {
const styles = useStyles();
const { t } = useTranslation();
const { accountAddress } = useAccountAddress();
const isUserConnected = !!accountAddress;

return (
<div css={styles.container} className={className}>
{connected ? (
children
) : (
<>
{!!message && <NoticeInfo css={styles.notice} description={message} />}

<Button variant={buttonVariant} className="w-full" onClick={openAuthModal}>
{t('connectWallet.connectButton')}
</Button>
</>
)}
</div>
const { chainId: currentChainId } = useChainId();

const isOnWrongChain = useMemo(
() => chainId && currentChainId !== chainId,
[currentChainId, chainId],
);
};

export const ConnectWallet: React.FC<Omit<PromptProps, 'connected' | 'openAuthModal'>> = props => {
const { accountAddress } = useAccountAddress();
const chainMetadata = chainId && CHAIN_METADATA[chainId];

const { openAuthModal } = useAuthModal();
return <Prompt {...props} openAuthModal={openAuthModal} connected={!!accountAddress} />;
const { switchChain } = useSwitchChain();
const handleSwitchChain = () => chainId && switchChain({ chainId });

const { t } = useTranslation();

if (!isUserConnected) {
return (
<Container {...otherProps}>
{!!message && <NoticeInfo className="mb-8" description={message} />}

<Button variant={buttonVariant} className="w-full" onClick={openAuthModal}>
{t('connectWallet.connectButton')}
</Button>
</Container>
);
}

if (isOnWrongChain) {
return (
<Container {...otherProps}>
<Button variant={buttonVariant} className="w-full" onClick={handleSwitchChain}>
{t('connectWallet.switchChain', {
chainName: chainMetadata?.name,
})}
</Button>
</Container>
);
}

return <Container {...otherProps}>{children}</Container>;
};
15 changes: 0 additions & 15 deletions apps/evm/src/containers/ConnectWallet/styles.ts

This file was deleted.

9 changes: 0 additions & 9 deletions apps/evm/src/hooks/useFormatTo/__tests__/index.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
import type Vi from 'vitest';

import { renderHook } from 'testUtils/render';

import { useChainId } from 'libs/wallet';
import { CHAIN_ID_SEARCH_PARAM } from 'libs/wallet/constants';
import { ChainId } from 'types';

import { useFormatTo } from '..';

describe('useFormatTo', () => {
beforeEach(() => {
(useChainId as Vi.Mock).mockImplementation(() => ({
chainId: ChainId.BSC_TESTNET,
}));
});

it('formats string with existing query', () => {
const { result } = renderHook(() => useFormatTo());
const formattedTo = result.current.formatTo({ to: '/path?param=value' });
Expand Down
Loading

0 comments on commit 7162f23

Please sign in to comment.