Feat/1666: Added min requirements for raw proposal form. Tests failing (#1884)

* Feat/1666: Added min requirements for raw proposal form. Tests failing

* Feat/1666: Tests now passing
This commit is contained in:
Sam Keen 2022-10-31 16:02:04 +00:00 committed by GitHub
parent 03e39e8323
commit 1f8469a97a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 230 additions and 13 deletions

View File

@ -702,5 +702,7 @@
"FreeformProposal": "Freeform proposal",
"unknownReason": "unknown reason",
"votingEnded": "Voting has ended.",
"STATUS": "STATUS"
"STATUS": "STATUS",
"ProposalMinimumAmounts": "Different proposal types can have different minimum token requirements. You must have the greater of the proposal minimum or spam protection minimum from the table below",
"SpamProtectionMin": "Spam protection minimum"
}

View File

@ -13,6 +13,9 @@ interface ProposalFormMinRequirementsProps {
userAction: ProposalUserAction.CREATE | ProposalUserAction.VOTE;
}
export const formatMinRequiredBalance = (balance: string) =>
new BigNumber(addDecimal(balance, 18));
// Returns the larger, formatted value of the two token amounts
export const ProposalMinRequirements = ({
minProposalBalance,
@ -20,12 +23,10 @@ export const ProposalMinRequirements = ({
userAction,
}: ProposalFormMinRequirementsProps) => {
const { t } = useTranslation();
const minProposalBalanceFormatted = new BigNumber(
addDecimal(minProposalBalance, 18)
);
const spamProtectionMinFormatted = new BigNumber(
addDecimal(spamProtectionMin, 18)
);
const minProposalBalanceFormatted =
formatMinRequiredBalance(minProposalBalance);
const spamProtectionMinFormatted =
formatMinRequiredBalance(spamProtectionMin);
const larger =
minProposalBalanceFormatted > spamProtectionMinFormatted

View File

@ -15,7 +15,7 @@ jest.mock('@vegaprotocol/environment', () => ({
}),
}));
const updateMarketNetworkParamsQueryMock: MockedResponse<NetworkParamsQuery> = {
const newAssetNetworkParamsQueryMock: MockedResponse<NetworkParamsQuery> = {
request: {
query: NETWORK_PARAMETERS_QUERY,
},
@ -60,7 +60,7 @@ const updateMarketNetworkParamsQueryMock: MockedResponse<NetworkParamsQuery> = {
const renderComponent = () =>
render(
<Router>
<MockedProvider mocks={[updateMarketNetworkParamsQueryMock]}>
<MockedProvider mocks={[newAssetNetworkParamsQueryMock]}>
<AppStateProvider>
<VegaWalletContext.Provider value={mockWalletContext}>
<ProposeNewAsset />

View File

@ -0,0 +1,104 @@
import { useTranslation } from 'react-i18next';
import { KeyValueTable, KeyValueTableRow } from '@vegaprotocol/ui-toolkit';
import { formatMinRequiredBalance } from '../../components/shared';
import type { ReactNode } from 'react';
export interface ProposalRawMinRequirementsProps {
assetMin: string;
updateAssetMin: string;
marketMin: string;
updateMarketMin: string;
updateNetParamMin: string;
freeformMin: string;
spamProtectionMin: string;
}
const Wrapper = ({ children }: { children: ReactNode }) => (
<div className="mb-4" data-testid="proposal-raw-min-requirements">
{children}
</div>
);
export const ProposalRawMinRequirements = ({
assetMin,
updateAssetMin,
marketMin,
updateMarketMin,
updateNetParamMin,
freeformMin,
spamProtectionMin,
}: ProposalRawMinRequirementsProps) => {
const { t } = useTranslation();
if (
assetMin <= spamProtectionMin &&
updateAssetMin <= spamProtectionMin &&
marketMin <= spamProtectionMin &&
updateMarketMin <= spamProtectionMin &&
updateNetParamMin <= spamProtectionMin &&
freeformMin <= spamProtectionMin
) {
return (
<Wrapper>
{t('MinProposalRequirements', {
value: Number(formatMinRequiredBalance(spamProtectionMin)),
})}
</Wrapper>
);
}
if (
assetMin === updateAssetMin &&
assetMin === marketMin &&
assetMin === updateMarketMin &&
assetMin === updateNetParamMin &&
assetMin === freeformMin
) {
return (
<Wrapper>
{t('MinProposalRequirements', {
value: Number(formatMinRequiredBalance(assetMin)),
})}
</Wrapper>
);
}
return (
<Wrapper>
<div className="mb-4">
{t(
'Different proposal types can have different minimum token requirements. You must have the greater of the proposal minimum or spam protection minimum from the table below'
)}
</div>
<KeyValueTable>
<KeyValueTableRow>
{t('NewAsset')}
{`${formatMinRequiredBalance(assetMin).toString()} VEGA`}
</KeyValueTableRow>
<KeyValueTableRow>
{t('UpdateAsset')}
{`${formatMinRequiredBalance(updateAssetMin).toString()} VEGA`}
</KeyValueTableRow>
<KeyValueTableRow>
{t('NewMarket')}
{`${formatMinRequiredBalance(marketMin).toString()} VEGA`}
</KeyValueTableRow>
<KeyValueTableRow>
{t('UpdateMarket')}
{`${formatMinRequiredBalance(updateMarketMin).toString()} VEGA`}
</KeyValueTableRow>
<KeyValueTableRow>
{t('NetworkParameter')}
{`${formatMinRequiredBalance(updateNetParamMin).toString()} VEGA`}
</KeyValueTableRow>
<KeyValueTableRow>
{t('Freeform')}
{`${formatMinRequiredBalance(freeformMin).toString()} VEGA`}
</KeyValueTableRow>
<KeyValueTableRow>
{t('SpamProtectionMin')}
{`${formatMinRequiredBalance(spamProtectionMin).toString()} VEGA`}
</KeyValueTableRow>
</KeyValueTable>
</Wrapper>
);
};

View File

@ -13,6 +13,58 @@ import {
import { ProposeRaw } from './propose-raw';
import { ProposalEventDocument } from '@vegaprotocol/governance';
import type { ProposalEventSubscription } from '@vegaprotocol/governance';
import { NETWORK_PARAMETERS_QUERY } from '@vegaprotocol/react-helpers';
import type { NetworkParamsQuery } from '@vegaprotocol/web3';
const paramsDelay = 20;
const rawProposalNetworkParamsQueryMock: MockedResponse<NetworkParamsQuery> = {
request: {
query: NETWORK_PARAMETERS_QUERY,
},
result: {
data: {
networkParameters: [
{
__typename: 'NetworkParameter',
key: 'governance.proposal.asset.minProposerBalance',
value: '1',
},
{
__typename: 'NetworkParameter',
key: 'governance.proposal.updateAsset.minProposerBalance',
value: '1',
},
{
__typename: 'NetworkParameter',
key: 'governance.proposal.market.minProposerBalance',
value: '1',
},
{
__typename: 'NetworkParameter',
key: 'governance.proposal.updateMarket.minProposerBalance',
value: '1',
},
{
__typename: 'NetworkParameter',
key: 'governance.proposal.updateNetParam.minProposerBalance',
value: '1',
},
{
__typename: 'NetworkParameter',
key: 'governance.proposal.freeform.minProposerBalance',
value: '1',
},
{
__typename: 'NetworkParameter',
key: 'spam.protection.proposal.min.tokens',
value: '1000000000000000000',
},
],
},
},
delay: paramsDelay,
};
describe('Raw proposal form', () => {
const pubKey = '0x123';
@ -47,7 +99,9 @@ describe('Raw proposal form', () => {
const setup = (mockSendTx = jest.fn()) => {
return render(
<AppStateProvider>
<MockedProvider mocks={[mockProposalEvent]}>
<MockedProvider
mocks={[rawProposalNetworkParamsQueryMock, mockProposalEvent]}
>
<VegaWalletContext.Provider
value={
{
@ -74,6 +128,8 @@ describe('Raw proposal form', () => {
it('handles validation', async () => {
const mockSendTx = jest.fn().mockReturnValue(Promise.resolve());
setup(mockSendTx);
expect(await screen.findByTestId('proposal-submit')).toBeTruthy();
await act(async () => {
fireEvent.click(screen.getByTestId('proposal-submit'));
});
@ -113,6 +169,10 @@ describe('Raw proposal form', () => {
);
setup(mockSendTx);
await act(async () => {
jest.advanceTimersByTime(paramsDelay);
});
const inputJSON = JSON.stringify({
rationale: {
description: 'Update governance.proposal.freeform.minVoterBalance',
@ -129,6 +189,7 @@ describe('Raw proposal form', () => {
enactmentTimestamp: Math.floor(getTime(addHours(new Date(), 3)) / 1000),
},
});
fireEvent.change(screen.getByTestId('proposal-data'), {
target: { value: inputJSON },
});
@ -170,7 +231,14 @@ describe('Raw proposal form', () => {
);
setup(mockSendTx);
await act(async () => {
jest.advanceTimersByTime(paramsDelay);
});
const inputJSON = '{}';
expect(await screen.findByTestId('proposal-data')).toBeTruthy();
fireEvent.change(screen.getByTestId('proposal-data'), {
target: { value: inputJSON },
});

View File

@ -4,23 +4,43 @@ import { useEnvironment } from '@vegaprotocol/environment';
import { Heading } from '../../../../components/heading';
import { VegaWalletContainer } from '../../../../components/vega-wallet-container';
import {
AsyncRenderer,
FormGroup,
InputError,
Link,
TextArea,
} from '@vegaprotocol/ui-toolkit';
import { validateJson } from '@vegaprotocol/react-helpers';
import {
NetworkParams,
useNetworkParams,
validateJson,
} from '@vegaprotocol/react-helpers';
import { useProposalSubmit } from '@vegaprotocol/governance';
import {
ProposalFormSubmit,
ProposalFormTransactionDialog,
} from '../../components/propose';
import { ProposalRawMinRequirements } from './proposal-raw-min-requirements';
export interface RawProposalFormFields {
rawProposalData: string;
}
export const ProposeRaw = () => {
const {
params,
loading: networkParamsLoading,
error: networkParamsError,
} = useNetworkParams([
NetworkParams.governance_proposal_asset_minProposerBalance,
NetworkParams.governance_proposal_updateAsset_minProposerBalance,
NetworkParams.governance_proposal_market_minProposerBalance,
NetworkParams.governance_proposal_updateMarket_minProposerBalance,
NetworkParams.governance_proposal_updateNetParam_minProposerBalance,
NetworkParams.governance_proposal_freeform_minProposerBalance,
NetworkParams.spam_protection_proposal_min_tokens,
]);
const { VEGA_EXPLORER_URL, VEGA_DOCS_URL } = useEnvironment();
const { t } = useTranslation();
const {
@ -37,11 +57,33 @@ export const ProposeRaw = () => {
};
return (
<>
<AsyncRenderer
loading={networkParamsLoading}
error={networkParamsError}
data={params}
>
<Heading title={t('NewRawProposal')} />
<VegaWalletContainer>
{() => (
<>
<ProposalRawMinRequirements
assetMin={params.governance_proposal_asset_minProposerBalance}
updateAssetMin={
params.governance_proposal_updateAsset_minProposerBalance
}
marketMin={params.governance_proposal_market_minProposerBalance}
updateMarketMin={
params.governance_proposal_updateMarket_minProposerBalance
}
updateNetParamMin={
params.governance_proposal_updateNetParam_minProposerBalance
}
freeformMin={
params.governance_proposal_freeform_minProposerBalance
}
spamProtectionMin={params.spam_protection_proposal_min_tokens}
/>
{VEGA_DOCS_URL && (
<p className="text-sm" data-testid="proposal-docs-link">
<span className="mr-1">{t('ProposalTermsText')}</span>
@ -94,6 +136,6 @@ export const ProposeRaw = () => {
</>
)}
</VegaWalletContainer>
</>
</AsyncRenderer>
);
};