From 607a20a9fab2e31ee33ba83ecd16ed403e768ddf Mon Sep 17 00:00:00 2001 From: Aaron DeRuvo Date: Tue, 25 Feb 2025 17:17:41 +0100 Subject: [PATCH] fix 160 allow voting with only delegated votes (non personally locked) --- .../transactions/TransactionFlow.test.tsx | 20 ++++++++++++++- src/features/transactions/TransactionFlow.tsx | 25 +++++++++++++++++-- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/features/transactions/TransactionFlow.test.tsx b/src/features/transactions/TransactionFlow.test.tsx index 02877f58..e4295237 100644 --- a/src/features/transactions/TransactionFlow.test.tsx +++ b/src/features/transactions/TransactionFlow.test.tsx @@ -4,6 +4,7 @@ import { DelegationForm } from 'src/features/delegation/DelegationForm'; import * as useDelegatees from 'src/features/delegation/hooks/useDelegatees'; import * as useDelegationBalances from 'src/features/delegation/hooks/useDelegationBalances'; import * as useGovernanceProposals from 'src/features/governance/hooks/useGovernanceProposals'; +import * as votingHooks from 'src/features/governance/hooks/useVotingStatus'; import { VoteForm } from 'src/features/governance/VoteForm'; import * as useLockedStatus from 'src/features/locking/useLockedStatus'; import * as useStakingBalances from 'src/features/staking/useStakingBalances'; @@ -145,6 +146,17 @@ describe('', () => { await waitFor(async () => expect(await flow.findByTestId('register-form')).toBeTruthy()); }); }); + describe('as a account which has been delegated votes', () => { + test('renders for account', async () => { + setupHooks({ isRegistered: true, lockedGoldBalance: 0n, votingPower: 1n }); + + const flow = render( + {}} />, + ); + + await waitFor(async () => expect(await flow.findByTestId('vote-form')).toBeTruthy()); + }); + }); }); }); @@ -152,6 +164,7 @@ type SetupHooksOptions = { isRegistered?: boolean; lockedGoldBalance?: bigint; voteSignerForAddress?: string; + votingPower?: bigint; }; // Mocks all necessary hooks for the TransactionFlow component @@ -166,7 +179,6 @@ const setupHooks = (options?: SetupHooksOptions) => { isError: false, isLoading: false, } as any); - vi.spyOn(useDelegatees, 'useDelegatees').mockReturnValue({} as any); vi.spyOn(useDelegationBalances, 'useDelegationBalances').mockReturnValue({} as any); vi.spyOn(useLockedStatus, 'useLockedStatus').mockReturnValue({} as any); @@ -174,6 +186,12 @@ const setupHooks = (options?: SetupHooksOptions) => { vi.spyOn(useGovernanceProposals, 'useGovernanceProposals').mockReturnValue({} as any); vi.spyOn(useGovernanceProposals, 'useGovernanceProposal').mockReturnValue({} as any); + vi.spyOn(votingHooks, 'useGovernanceVotingPower').mockReturnValue({ + isLoading: false, + votingPower: options?.votingPower ?? 0n, + isError: false, + }); + vi.spyOn(hooks, 'useAccountDetails').mockReturnValue({ isError: false, isLoading: false, diff --git a/src/features/transactions/TransactionFlow.tsx b/src/features/transactions/TransactionFlow.tsx index 11375540..b989c5aa 100644 --- a/src/features/transactions/TransactionFlow.tsx +++ b/src/features/transactions/TransactionFlow.tsx @@ -3,6 +3,8 @@ import { SpinnerWithLabel } from 'src/components/animation/Spinner'; import { AccountRegisterForm } from 'src/features/account/AccountRegisterForm'; import { useAccountDetails, useLockedBalance, useVoteSigner } from 'src/features/account/hooks'; import { DelegationForm } from 'src/features/delegation/DelegationForm'; +import { useGovernanceVotingPower } from 'src/features/governance/hooks/useVotingStatus'; +import { VoteForm } from 'src/features/governance/VoteForm'; import { LockForm } from 'src/features/locking/LockForm'; import { TransactionConfirmation } from 'src/features/transactions/TransactionConfirmation'; import { ConfirmationDetails, OnConfirmedFn } from 'src/features/transactions/types'; @@ -33,12 +35,31 @@ export function TransactionFlow({ const isDelegatingAsVoteSigner = FormComponent.name === DelegationForm.name && voteSigner && voteSigner !== address; + const votingPower = useGovernanceVotingPower(address); + + const hasVotingPower = + typeof votingPower.votingPower === 'bigint' && votingPower.votingPower > 0n; + + // voting power includes votes delegated to the account and locked celo + const willVoteAndHasVotingPower = FormComponent.name === VoteForm.name && hasVotingPower; + let Component: ReactNode; - if (!address || isNullish(lockedBalance) || isNullish(isRegistered) || isVoteSignerLoading) { + if ( + !address || + isNullish(lockedBalance) || + isNullish(isRegistered) || + isVoteSignerLoading || + votingPower.isLoading + ) { Component = Loading account data...; } else if (!isRegistered && !isDelegatingAsVoteSigner) { Component = ; - } else if (lockedBalance <= 0n && requiresLockedFunds && !isDelegatingAsVoteSigner) { + } else if ( + lockedBalance <= 0n && + requiresLockedFunds && + !isDelegatingAsVoteSigner && + !willVoteAndHasVotingPower + ) { Component = ; } else if (!confirmationDetails) { Component = ;