From a98ab775c3347e7e5b18959a393c09cdb28d2adc Mon Sep 17 00:00:00 2001 From: Sam Keen Date: Thu, 19 Oct 2023 11:16:00 +0100 Subject: [PATCH] feat(governance): transfers destination field can fallback to type (#5092) --- .../proposal-header.spec.tsx | 83 ++++++++++++++++++- .../proposal-header.tsx | 25 ++++-- 2 files changed, 100 insertions(+), 8 deletions(-) diff --git a/apps/governance/src/routes/proposals/components/proposal-detail-header/proposal-header.spec.tsx b/apps/governance/src/routes/proposals/components/proposal-detail-header/proposal-header.spec.tsx index def3377e3..01652c52e 100644 --- a/apps/governance/src/routes/proposals/components/proposal-detail-header/proposal-header.spec.tsx +++ b/apps/governance/src/routes/proposals/components/proposal-detail-header/proposal-header.spec.tsx @@ -12,18 +12,19 @@ import { generateProposal, generateYesVotes, } from '../../test-helpers/generate-proposals'; -import { ProposalHeader } from './proposal-header'; +import { ProposalHeader, NewTransferSummary } from './proposal-header'; import { lastWeek, nextWeek, mockWalletContext, createUserVoteQueryMock, } from '../../test-helpers/mocks'; -import type { ProposalQuery } from '../../proposal/__generated__/Proposal'; -import type { MockedResponse } from '@apollo/client/testing'; import { FLAGS } from '@vegaprotocol/environment'; import { BrowserRouter } from 'react-router-dom'; import { VoteState } from '../vote-details/use-user-vote'; +import { useNewTransferProposalDetails } from '@vegaprotocol/proposals'; +import type { ProposalQuery } from '../../proposal/__generated__/Proposal'; +import type { MockedResponse } from '@apollo/client/testing'; jest.mock('@vegaprotocol/proposals', () => ({ ...jest.requireActual('@vegaprotocol/proposals'), @@ -31,6 +32,7 @@ jest.mock('@vegaprotocol/proposals', () => ({ code: 'PARENT_CODE', parentMarketId: 'PARENT_ID', }), + useNewTransferProposalDetails: jest.fn(), })); const renderComponent = ( @@ -418,3 +420,78 @@ describe('Proposal header', () => { expect(await screen.findByTestId('user-voted-yes')).toBeInTheDocument(); }); }); + +jest.mock('@vegaprotocol/proposals'); + +describe('', () => { + it('renders null if no details are provided', () => { + (useNewTransferProposalDetails as jest.Mock).mockReturnValue(null); + const { container } = render(); + expect(container.firstChild).toBeNull(); + }); + + it('handles OneOffGovernanceTransfer', () => { + (useNewTransferProposalDetails as jest.Mock).mockReturnValue({ + kind: { __typename: 'OneOffGovernanceTransfer', deliverOn: null }, + source: '0x123', + sourceType: 'wallet', + destination: '0x456', + destinationType: 'contract', + }); + const { getByText } = render(); + const textMatch = (content: string) => content.includes('One off transfer'); + expect(getByText(textMatch)).toBeInTheDocument(); + }); + + it('handles RecurringGovernanceTransfer', () => { + (useNewTransferProposalDetails as jest.Mock).mockReturnValue({ + kind: { + __typename: 'RecurringGovernanceTransfer', + startEpoch: 1, + endEpoch: 5, + }, + source: '0x123', + sourceType: 'wallet', + destination: '0x456', + destinationType: 'contract', + }); + const { getByText } = render(); + const textMatch = (content: string) => + content.includes('Recurring transfer'); + expect(getByText(textMatch)).toBeInTheDocument(); + }); + + it('should fallback to translated sourceType when source is not set', () => { + (useNewTransferProposalDetails as jest.Mock).mockReturnValue({ + kind: { + __typename: 'RecurringGovernanceTransfer', + startEpoch: 1, + endEpoch: 5, + }, + source: undefined, + sourceType: 'ACCOUNT_TYPE_GENERAL', + destination: '0x456', + destinationType: 'ACCOUNT_TYPE_GENERAL', + }); + + render(); + expect(screen.getByText('General account')).toBeInTheDocument(); + }); + + it('should fallback to translated destinationType when destination is not set', () => { + (useNewTransferProposalDetails as jest.Mock).mockReturnValue({ + kind: { + __typename: 'RecurringGovernanceTransfer', + startEpoch: 1, + endEpoch: 5, + }, + source: '0x123', + sourceType: 'ACCOUNT_TYPE_GENERAL', + destination: undefined, + destinationType: 'ACCOUNT_TYPE_GLOBAL_INSURANCE', + }); + + render(); + expect(screen.getByText('Global insurance account')).toBeInTheDocument(); + }); +}); diff --git a/apps/governance/src/routes/proposals/components/proposal-detail-header/proposal-header.tsx b/apps/governance/src/routes/proposals/components/proposal-detail-header/proposal-header.tsx index 1524edeac..836b62822 100644 --- a/apps/governance/src/routes/proposals/components/proposal-detail-header/proposal-header.tsx +++ b/apps/governance/src/routes/proposals/components/proposal-detail-header/proposal-header.tsx @@ -237,7 +237,11 @@ export const ProposalHeader = ({ ); }; -const SuccessorCode = ({ proposalId }: { proposalId?: string | null }) => { +export const SuccessorCode = ({ + proposalId, +}: { + proposalId?: string | null; +}) => { const { t } = useTranslation(); const successor = useSuccessorMarketProposalDetails(proposalId); @@ -254,7 +258,11 @@ const SuccessorCode = ({ proposalId }: { proposalId?: string | null }) => { ) : null; }; -const NewTransferSummary = ({ proposalId }: { proposalId?: string | null }) => { +export const NewTransferSummary = ({ + proposalId, +}: { + proposalId?: string | null; +}) => { const { t } = useTranslation(); const details = useNewTransferProposalDetails(proposalId); @@ -265,14 +273,21 @@ const NewTransferSummary = ({ proposalId }: { proposalId?: string | null }) => { {GovernanceTransferKindMapping[details.kind.__typename]}{' '} {t('transfer from')}{' '} - {truncateMiddle(details.source) || t(details.sourceType)} + {details.source + ? truncateMiddle(details.source) + : t(details.sourceType)} {' '} - {t('to')} {truncateMiddle(details.destination)} + {t('to')}{' '} + + {details.destination + ? truncateMiddle(details.destination) + : t(details.destinationType)} + ); }; -const CancelTransferSummary = ({ +export const CancelTransferSummary = ({ proposalId, }: { proposalId?: string | null;