diff --git a/apps/governance/src/routes/proposals/components/proposal-change-table/proposal-change-table.spec.tsx b/apps/governance/src/routes/proposals/components/proposal-change-table/proposal-change-table.spec.tsx
index 1b538be80..cb28a6639 100644
--- a/apps/governance/src/routes/proposals/components/proposal-change-table/proposal-change-table.spec.tsx
+++ b/apps/governance/src/routes/proposals/components/proposal-change-table/proposal-change-table.spec.tsx
@@ -16,17 +16,12 @@ it('Renders all data for table', () => {
render();
expect(screen.getByText('ID')).toBeInTheDocument();
expect(screen.getByText(proposal?.id as string)).toBeInTheDocument();
-
- expect(screen.getByText('State')).toBeInTheDocument();
- expect(screen.getByText('Open')).toBeInTheDocument();
-
expect(screen.getByText('Closes on')).toBeInTheDocument();
expect(
screen.getByText(
formatDateWithLocalTimezone(new Date(proposal?.terms.closingDatetime))
)
).toBeInTheDocument();
-
expect(screen.getByText('Proposed enactment')).toBeInTheDocument();
expect(
screen.getByText(
@@ -35,17 +30,12 @@ it('Renders all data for table', () => {
)
)
).toBeInTheDocument();
-
expect(screen.getByText('Proposed by')).toBeInTheDocument();
expect(screen.getByText(proposal?.party.id ?? '')).toBeInTheDocument();
-
expect(screen.getByText('Proposed on')).toBeInTheDocument();
expect(
screen.getByText(formatDateWithLocalTimezone(new Date(proposal?.datetime)))
).toBeInTheDocument();
-
- expect(screen.getByText('Type')).toBeInTheDocument();
- expect(screen.getByText('Network parameter')).toBeInTheDocument();
});
it('Changes data based on if data is in future or past', () => {
@@ -53,17 +43,12 @@ it('Changes data based on if data is in future or past', () => {
state: ProposalState.STATE_ENACTED,
});
render();
-
- expect(screen.getByText('State')).toBeInTheDocument();
- expect(screen.getByText('Enacted')).toBeInTheDocument();
-
expect(screen.getByText('Closed on')).toBeInTheDocument();
expect(
screen.getByText(
formatDateWithLocalTimezone(new Date(proposal?.terms.closingDatetime))
)
).toBeInTheDocument();
-
expect(screen.getByText('Enacted on')).toBeInTheDocument();
expect(
screen.getByText(
@@ -104,7 +89,6 @@ it('Renders error details and rejection reason if present', () => {
render();
expect(screen.getByText('Error details')).toBeInTheDocument();
expect(screen.getByText(errorDetails)).toBeInTheDocument();
-
expect(screen.getByText('Rejection reason')).toBeInTheDocument();
expect(
screen.getByText(ProposalRejectionReason.PROPOSAL_ERROR_CLOSE_TIME_TOO_LATE)
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 449df276e..96d18c079 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
@@ -1,41 +1,45 @@
import { render, screen } from '@testing-library/react';
-import { generateProposal } from '../../test-helpers/generate-proposals';
+import {
+ generateNoVotes,
+ generateProposal,
+ generateYesVotes,
+} from '../../test-helpers/generate-proposals';
import { ProposalHeader } from './proposal-header';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
+import { ProposalRejectionReason, ProposalState } from '@vegaprotocol/types';
+import { lastWeek, nextWeek } from '../../test-helpers/mocks';
const renderComponent = (
proposal: ProposalQuery['proposal'],
isListItem = true
-) => ;
+) => render();
describe('Proposal header', () => {
it('Renders New market proposal', () => {
- render(
- renderComponent(
- generateProposal({
- rationale: {
- title: 'New some market',
- description: 'A new some market',
- },
- terms: {
- change: {
- __typename: 'NewMarket',
- instrument: {
- __typename: 'InstrumentConfiguration',
- name: 'Some market',
- code: 'FX:BTCUSD/DEC99',
- futureProduct: {
- __typename: 'FutureProduct',
- settlementAsset: {
- __typename: 'Asset',
- symbol: 'tGBP',
- },
+ renderComponent(
+ generateProposal({
+ rationale: {
+ title: 'New some market',
+ description: 'A new some market',
+ },
+ terms: {
+ change: {
+ __typename: 'NewMarket',
+ instrument: {
+ __typename: 'InstrumentConfiguration',
+ name: 'Some market',
+ code: 'FX:BTCUSD/DEC99',
+ futureProduct: {
+ __typename: 'FutureProduct',
+ settlementAsset: {
+ __typename: 'Asset',
+ symbol: 'tGBP',
},
},
},
},
- })
- )
+ },
+ })
);
expect(screen.getByTestId('proposal-title')).toHaveTextContent(
'New some market'
@@ -47,20 +51,18 @@ describe('Proposal header', () => {
});
it('Renders Update market proposal', () => {
- render(
- renderComponent(
- generateProposal({
- rationale: {
- title: 'New market id',
+ renderComponent(
+ generateProposal({
+ rationale: {
+ title: 'New market id',
+ },
+ terms: {
+ change: {
+ __typename: 'UpdateMarket',
+ marketId: 'MarketId',
},
- terms: {
- change: {
- __typename: 'UpdateMarket',
- marketId: 'MarketId',
- },
- },
- })
- )
+ },
+ })
);
expect(screen.getByTestId('proposal-title')).toHaveTextContent(
'New market id'
@@ -72,58 +74,54 @@ describe('Proposal header', () => {
screen.queryByTestId('proposal-description')
).not.toBeInTheDocument();
expect(screen.getByTestId('proposal-details')).toHaveTextContent(
- 'Market change:MarketId'
+ 'Market change: MarketId'
);
});
it('Renders New asset proposal - ERC20', () => {
- render(
- renderComponent(
- generateProposal({
- rationale: {
- title: 'New asset: Fake currency',
- description: '',
- },
- terms: {
- change: {
- __typename: 'NewAsset',
- name: 'Fake currency',
- symbol: 'FAKE',
- source: {
- __typename: 'ERC20',
- contractAddress: '0x0',
- },
+ renderComponent(
+ generateProposal({
+ rationale: {
+ title: 'New asset: Fake currency',
+ description: '',
+ },
+ terms: {
+ change: {
+ __typename: 'NewAsset',
+ name: 'Fake currency',
+ symbol: 'FAKE',
+ source: {
+ __typename: 'ERC20',
+ contractAddress: '0x0',
},
},
- })
- )
+ },
+ })
);
expect(screen.getByTestId('proposal-title')).toHaveTextContent(
'New asset: Fake currency'
);
expect(screen.getByTestId('proposal-type')).toHaveTextContent('New asset');
expect(screen.getByTestId('proposal-details')).toHaveTextContent(
- 'Symbol: FAKE. ERC20 0x0'
+ 'Symbol: FAKE. ERC20 contract address: 0x0'
);
});
it('Renders New asset proposal - BuiltInAsset', () => {
- render(
- renderComponent(
- generateProposal({
- terms: {
- change: {
- __typename: 'NewAsset',
- name: 'Fake currency',
- symbol: 'BIA',
- source: {
- __typename: 'BuiltinAsset',
- maxFaucetAmountMint: '300',
- },
+ renderComponent(
+ generateProposal({
+ terms: {
+ change: {
+ __typename: 'NewAsset',
+ name: 'Fake currency',
+ symbol: 'BIA',
+ source: {
+ __typename: 'BuiltinAsset',
+ maxFaucetAmountMint: '300',
},
},
- })
- )
+ },
+ })
);
expect(screen.getByTestId('proposal-title')).toHaveTextContent(
'Unknown proposal'
@@ -135,24 +133,22 @@ describe('Proposal header', () => {
});
it('Renders Update network', () => {
- render(
- renderComponent(
- generateProposal({
- rationale: {
- title: 'Network parameter',
- },
- terms: {
- change: {
- __typename: 'UpdateNetworkParameter',
- networkParameter: {
- __typename: 'NetworkParameter',
- key: 'Network key',
- value: 'Network value',
- },
+ renderComponent(
+ generateProposal({
+ rationale: {
+ title: 'Network parameter',
+ },
+ terms: {
+ change: {
+ __typename: 'UpdateNetworkParameter',
+ networkParameter: {
+ __typename: 'NetworkParameter',
+ key: 'Network key',
+ value: 'Network value',
},
},
- })
- )
+ },
+ })
);
expect(screen.getByTestId('proposal-title')).toHaveTextContent(
'Network parameter'
@@ -166,20 +162,18 @@ describe('Proposal header', () => {
});
it('Renders Freeform proposal - short rationale', () => {
- render(
- renderComponent(
- generateProposal({
- id: 'short',
- rationale: {
- title: '0x0',
+ renderComponent(
+ generateProposal({
+ id: 'short',
+ rationale: {
+ title: '0x0',
+ },
+ terms: {
+ change: {
+ __typename: 'NewFreeform',
},
- terms: {
- change: {
- __typename: 'NewFreeform',
- },
- },
- })
- )
+ },
+ })
);
expect(screen.getByTestId('proposal-title')).toHaveTextContent('0x0');
expect(screen.getByTestId('proposal-type')).toHaveTextContent('Freeform');
@@ -189,22 +183,20 @@ describe('Proposal header', () => {
});
it('Renders Freeform proposal - long rationale (105 chars) - listing', () => {
- render(
- renderComponent(
- generateProposal({
- id: 'long',
- rationale: {
- title: '0x0',
- description:
- 'Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aenean dolor.',
+ renderComponent(
+ generateProposal({
+ id: 'long',
+ rationale: {
+ title: '0x0',
+ description:
+ 'Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aenean dolor.',
+ },
+ terms: {
+ change: {
+ __typename: 'NewFreeform',
},
- terms: {
- change: {
- __typename: 'NewFreeform',
- },
- },
- })
- )
+ },
+ })
);
expect(screen.getByTestId('proposal-title')).toHaveTextContent('0x0');
expect(screen.getByTestId('proposal-type')).toHaveTextContent('Freeform');
@@ -215,23 +207,21 @@ describe('Proposal header', () => {
});
it('Renders Freeform proposal - long rationale (105 chars) - details', () => {
- render(
- renderComponent(
- generateProposal({
- id: 'long',
- rationale: {
- title: '0x0',
- description:
- 'Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aenean dolor.',
+ renderComponent(
+ generateProposal({
+ id: 'long',
+ rationale: {
+ title: '0x0',
+ description:
+ 'Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aenean dolor.',
+ },
+ terms: {
+ change: {
+ __typename: 'NewFreeform',
},
- terms: {
- change: {
- __typename: 'NewFreeform',
- },
- },
- }),
- false
- )
+ },
+ }),
+ false
);
expect(screen.getByTestId('proposal-description')).toHaveTextContent(
/Class aptent/
@@ -240,20 +230,18 @@ describe('Proposal header', () => {
// Remove once proposals have rationale and re-enable above tests
it('Renders Freeform proposal - id for title', () => {
- render(
- renderComponent(
- generateProposal({
- id: 'freeform id',
- rationale: {
- title: 'freeform',
+ renderComponent(
+ generateProposal({
+ id: 'freeform id',
+ rationale: {
+ title: 'freeform',
+ },
+ terms: {
+ change: {
+ __typename: 'NewFreeform',
},
- terms: {
- change: {
- __typename: 'NewFreeform',
- },
- },
- })
- )
+ },
+ })
);
expect(screen.getByTestId('proposal-title')).toHaveTextContent('freeform');
expect(screen.getByTestId('proposal-type')).toHaveTextContent('Freeform');
@@ -263,17 +251,15 @@ describe('Proposal header', () => {
});
it('Renders asset change proposal header', () => {
- render(
- renderComponent(
- generateProposal({
- terms: {
- change: {
- __typename: 'UpdateAsset',
- assetId: 'foo',
- },
+ renderComponent(
+ generateProposal({
+ terms: {
+ change: {
+ __typename: 'UpdateAsset',
+ assetId: 'foo',
},
- })
- )
+ },
+ })
);
expect(screen.getByTestId('proposal-type')).toHaveTextContent(
'Update asset'
@@ -282,20 +268,104 @@ describe('Proposal header', () => {
});
it("Renders unknown proposal if it's a different proposal type", () => {
- render(
- renderComponent(
- generateProposal({
- terms: {
- change: {
- // @ts-ignore unknown proposal
- __typename: 'Foo',
- },
+ renderComponent(
+ generateProposal({
+ terms: {
+ change: {
+ // @ts-ignore unknown proposal
+ __typename: 'Foo',
},
- })
- )
+ },
+ })
);
expect(screen.getByTestId('proposal-title')).toHaveTextContent(
'Unknown proposal'
);
});
+
+ it('Renders proposal state: Enacted', () => {
+ renderComponent(
+ generateProposal({
+ state: ProposalState.STATE_ENACTED,
+ terms: {
+ enactmentDatetime: lastWeek.toString(),
+ },
+ })
+ );
+ expect(screen.getByTestId('proposal-status')).toHaveTextContent('Enacted');
+ });
+
+ it('Renders proposal state: Passed', () => {
+ renderComponent(
+ generateProposal({
+ state: ProposalState.STATE_PASSED,
+ terms: {
+ closingDatetime: lastWeek.toString(),
+ enactmentDatetime: nextWeek.toString(),
+ },
+ })
+ );
+ expect(screen.getByTestId('proposal-status')).toHaveTextContent('Passed');
+ });
+
+ it('Renders proposal state: Waiting for node vote', () => {
+ renderComponent(
+ generateProposal({
+ state: ProposalState.STATE_WAITING_FOR_NODE_VOTE,
+ terms: {
+ enactmentDatetime: nextWeek.toString(),
+ },
+ })
+ );
+ expect(screen.getByTestId('proposal-status')).toHaveTextContent(
+ 'Waiting for node vote'
+ );
+ });
+
+ it('Renders proposal state: Open', () => {
+ renderComponent(
+ generateProposal({
+ state: ProposalState.STATE_OPEN,
+ votes: {
+ __typename: 'ProposalVotes',
+ yes: generateYesVotes(3000, 1000000000000000000),
+ no: generateNoVotes(0),
+ },
+ terms: {
+ closingDatetime: nextWeek.toString(),
+ },
+ })
+ );
+ expect(screen.getByTestId('proposal-status')).toHaveTextContent('Open');
+ });
+
+ it('Renders proposal state: Declined - majority not reached', () => {
+ renderComponent(
+ generateProposal({
+ state: ProposalState.STATE_DECLINED,
+ terms: {
+ enactmentDatetime: lastWeek.toString(),
+ },
+ votes: {
+ no: generateNoVotes(1, 1000000000000000000),
+ yes: generateYesVotes(1, 1000000000000000000),
+ },
+ })
+ );
+ expect(screen.getByTestId('proposal-status')).toHaveTextContent('Declined');
+ });
+
+ it('Renders proposal state: Rejected', () => {
+ renderComponent(
+ generateProposal({
+ state: ProposalState.STATE_REJECTED,
+ terms: {
+ enactmentDatetime: lastWeek.toString(),
+ },
+ rejectionReason:
+ ProposalRejectionReason.PROPOSAL_ERROR_INVALID_FUTURE_PRODUCT,
+ })
+ );
+ expect(screen.getByTestId('proposal-status')).toHaveTextContent('Rejected');
+ });
});
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 b93a57980..96ef4b707 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
@@ -19,7 +19,6 @@ export const ProposalHeader = ({
}) => {
const { t } = useTranslation();
const change = proposal?.terms.change;
- const inlineTitleClasses = 'mr-2';
let details: ReactNode;
let proposalType = '';
@@ -40,7 +39,7 @@ export const ProposalHeader = ({
<>
{t('Code')}: {change.instrument.code}.
-
+ {' '}
{change.instrument.futureProduct?.settlementAsset.symbol ? (
<>
@@ -59,7 +58,7 @@ export const ProposalHeader = ({
proposalType = 'UpdateMarket';
details = (
<>
- {t('Market change')}:
+ {t('Market change')}:{' '}
{truncateMiddle(change.marketId)}
>
);
@@ -69,17 +68,16 @@ export const ProposalHeader = ({
proposalType = 'NewAsset';
details = (
<>
- {t('Symbol')}:
- {change.symbol}.
+ {t('Symbol')}: {change.symbol}.{' '}
{change.source.__typename === 'ERC20' && (
<>
- {t('ERC20ContractAddress')}:
+ {t('ERC20ContractAddress')}:{' '}
{change.source.contractAddress}
>
- )}
+ )}{' '}
{change.source.__typename === 'BuiltinAsset' && (
<>
- {t('MaxFaucetAmountMint')}:
+ {t('MaxFaucetAmountMint')}:{' '}
{change.source.maxFaucetAmountMint}
>
)}
@@ -91,9 +89,9 @@ export const ProposalHeader = ({
proposalType = 'NetworkParameter';
details = (
<>
- {t('Change')}:
- {change.networkParameter.key}
- {t('to')}
+ {t('Change')}:{' '}
+ {change.networkParameter.key}{' '}
+ {t('to')}{' '}
{change.networkParameter.value}
@@ -110,7 +108,7 @@ export const ProposalHeader = ({
proposalType = 'UpdateAsset';
details = (
<>
- {t('AssetID')}:
+ {t('AssetID')}:{' '}
{truncateMiddle(change.assetId)}
>
);
@@ -137,7 +135,7 @@ export const ProposalHeader = ({
-
diff --git a/apps/governance/src/routes/proposals/components/proposals-list-item/proposals-list-item-details.spec.tsx b/apps/governance/src/routes/proposals/components/proposals-list-item/proposals-list-item-details.spec.tsx
index 7bbdbe608..f45b7d784 100644
--- a/apps/governance/src/routes/proposals/components/proposals-list-item/proposals-list-item-details.spec.tsx
+++ b/apps/governance/src/routes/proposals/components/proposals-list-item/proposals-list-item-details.spec.tsx
@@ -97,7 +97,6 @@ describe('Proposals list item details', () => {
},
})
);
- expect(screen.getByTestId('proposal-status')).toHaveTextContent('Enacted');
expect(screen.getByTestId('vote-details')).toHaveTextContent(
format(lastWeek, DATE_FORMAT_DETAILED)
);
@@ -113,7 +112,6 @@ describe('Proposals list item details', () => {
},
})
);
- expect(screen.getByTestId('proposal-status')).toHaveTextContent('Passed');
expect(screen.getByTestId('vote-details')).toHaveTextContent(
`Enacts on ${format(nextWeek, DATE_FORMAT_DETAILED)}`
);
@@ -128,9 +126,6 @@ describe('Proposals list item details', () => {
},
})
);
- expect(screen.getByTestId('proposal-status')).toHaveTextContent(
- 'Waiting for node vote'
- );
expect(screen.getByTestId('vote-details')).toHaveTextContent(
`Enacts on ${format(nextWeek, DATE_FORMAT_DETAILED)}`
);
@@ -221,7 +216,6 @@ describe('Proposals list item details', () => {
},
})
);
- expect(screen.getByTestId('proposal-status')).toHaveTextContent('Open');
expect(screen.getByTestId('vote-details')).toHaveTextContent(
'5 minutes left to vote'
);
@@ -236,7 +230,6 @@ describe('Proposals list item details', () => {
},
})
);
- expect(screen.getByTestId('proposal-status')).toHaveTextContent('Open');
expect(screen.getByTestId('vote-details')).toHaveTextContent(
'5 hours left to vote'
);
@@ -251,7 +244,6 @@ describe('Proposals list item details', () => {
},
})
);
- expect(screen.getByTestId('proposal-status')).toHaveTextContent('Open');
expect(screen.getByTestId('vote-details')).toHaveTextContent(
'5 days left to vote'
);
@@ -268,10 +260,7 @@ describe('Proposals list item details', () => {
networkParamsQueryMock,
createUserVoteQueryMock(proposal?.id, VoteValue.VALUE_YES),
]);
- expect(screen.getByTestId('proposal-status')).toHaveTextContent('Open');
-
- expect(await screen.findByText('You voted')).toBeInTheDocument();
- expect(await screen.findByText('For')).toBeInTheDocument();
+ expect(await screen.findByText('You voted For')).toBeInTheDocument();
});
it('Renders proposal state: Open - user voted against', async () => {
@@ -285,9 +274,7 @@ describe('Proposals list item details', () => {
networkParamsQueryMock,
createUserVoteQueryMock(proposal?.id, VoteValue.VALUE_NO),
]);
- expect(screen.getByTestId('proposal-status')).toHaveTextContent('Open');
- expect(await screen.findByText('You voted')).toBeInTheDocument();
- expect(await screen.findByText('Against')).toBeInTheDocument();
+ expect(await screen.findByText('You voted Against')).toBeInTheDocument();
});
it('Renders proposal state: Open - participation not reached', () => {
@@ -303,7 +290,6 @@ describe('Proposals list item details', () => {
},
})
);
- expect(screen.getByTestId('proposal-status')).toHaveTextContent('Open');
expect(screen.getByTestId('vote-status')).toHaveTextContent(
'Participation not reached'
);
@@ -322,7 +308,6 @@ describe('Proposals list item details', () => {
},
})
);
- expect(screen.getByTestId('proposal-status')).toHaveTextContent('Open');
expect(screen.getByTestId('vote-status')).toHaveTextContent(
'Majority not reached'
);
@@ -342,7 +327,6 @@ describe('Proposals list item details', () => {
},
})
);
- expect(screen.getByTestId('proposal-status')).toHaveTextContent('Open');
expect(screen.getByTestId('vote-status')).toHaveTextContent('Set to pass');
});
@@ -359,7 +343,6 @@ describe('Proposals list item details', () => {
},
})
);
- expect(screen.getByTestId('proposal-status')).toHaveTextContent('Declined');
expect(screen.getByTestId('vote-status')).toHaveTextContent(
'Participation not reached'
);
@@ -378,7 +361,6 @@ describe('Proposals list item details', () => {
},
})
);
- expect(screen.getByTestId('proposal-status')).toHaveTextContent('Declined');
expect(screen.getByTestId('vote-status')).toHaveTextContent(
'Majority not reached'
);
@@ -395,7 +377,6 @@ describe('Proposals list item details', () => {
ProposalRejectionReason.PROPOSAL_ERROR_INVALID_FUTURE_PRODUCT,
})
);
- expect(screen.getByTestId('proposal-status')).toHaveTextContent('Rejected');
expect(screen.getByTestId('vote-status')).toHaveTextContent(
'Invalid future product'
);