-
Notifications
You must be signed in to change notification settings - Fork 231
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add additional Earn components (#1883)
Co-authored-by: Alissa Crane <[email protected]>
- Loading branch information
1 parent
74f27a8
commit 8cd8eb2
Showing
25 changed files
with
1,010 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
import type { Call } from '@/transaction/types'; | ||
import { render, screen } from '@testing-library/react'; | ||
import type { Address } from 'viem'; | ||
import { describe, expect, it, vi } from 'vitest'; | ||
import { DepositButton } from './DepositButton'; | ||
import { useEarnContext } from './EarnProvider'; | ||
|
||
vi.mock('./EarnProvider', () => ({ | ||
useEarnContext: vi.fn(), | ||
})); | ||
|
||
vi.mock('wagmi', () => ({ | ||
useAccount: vi.fn(), | ||
useConfig: vi.fn(), | ||
useCapabilities: vi.fn(), | ||
})); | ||
|
||
const baseContext = { | ||
convertedBalance: '1000', | ||
setDepositAmount: vi.fn(), | ||
vaultAddress: '0x123' as Address, | ||
depositAmount: '0', | ||
depositedAmount: '0', | ||
withdrawAmount: '0', | ||
setWithdrawAmount: vi.fn(), | ||
depositCalls: [], | ||
withdrawCalls: [], | ||
}; | ||
|
||
vi.mock('@/transaction', async (importOriginal) => { | ||
return { | ||
...(await importOriginal<typeof import('@/transaction')>()), | ||
TransactionLifecycleStatus: vi.fn(), | ||
TransactionButton: ({ | ||
text, | ||
disabled, | ||
}: { text: string; disabled: boolean }) => ( | ||
<button type="button" disabled={disabled} data-testid="transactionButton"> | ||
{text} | ||
</button> | ||
), | ||
Transaction: ({ | ||
onStatus, | ||
children, | ||
capabilities, | ||
}: { | ||
onStatus: (status: { statusName: string }) => void; | ||
children: React.ReactNode; | ||
capabilities: { paymasterService: { url: string } }; | ||
}) => ( | ||
<> | ||
<div data-testid="transaction"> | ||
<button | ||
type="button" | ||
data-testid="transaction-button" | ||
onClick={() => onStatus({ statusName: 'transactionPending' })} | ||
> | ||
TransactionPending | ||
</button> | ||
<button | ||
type="button" | ||
data-testid="transaction-button" | ||
onClick={() => | ||
onStatus({ statusName: 'transactionLegacyExecuted' }) | ||
} | ||
> | ||
TransactionLegacyExecuted | ||
</button> | ||
<button | ||
type="button" | ||
data-testid="transaction-button" | ||
onClick={() => onStatus({ statusName: 'success' })} | ||
> | ||
Success | ||
</button> | ||
<button | ||
type="button" | ||
data-testid="transaction-button" | ||
onClick={() => onStatus({ statusName: 'error' })} | ||
> | ||
Error | ||
</button> | ||
<div>{capabilities?.paymasterService?.url}</div> | ||
</div> | ||
{children} | ||
</> | ||
), | ||
TransactionSponsor: vi.fn(), | ||
TransactionStatus: vi.fn(), | ||
TransactionStatusAction: vi.fn(), | ||
TransactionStatusLabel: vi.fn(), | ||
}; | ||
}); | ||
|
||
vi.mock('@/internal/hooks/useTheme', () => ({ | ||
useTheme: vi.fn(), | ||
})); | ||
|
||
describe('DepositButton Component', () => { | ||
it('renders Transaction with depositCalls from EarnProvider', () => { | ||
const mockDepositCalls = [{ to: '0x123', data: '0x456' }] as Call[]; | ||
vi.mocked(useEarnContext).mockReturnValue({ | ||
...baseContext, | ||
depositCalls: mockDepositCalls, | ||
}); | ||
|
||
render(<DepositButton />); | ||
|
||
const transactionElement = screen.getByTestId('transaction'); | ||
expect(transactionElement).toBeInTheDocument(); | ||
}); | ||
|
||
it('renders TransactionButton with the correct text', () => { | ||
vi.mocked(useEarnContext).mockReturnValue({ | ||
...baseContext, | ||
depositCalls: [], | ||
}); | ||
|
||
const { container } = render(<DepositButton />); | ||
|
||
expect(container).toHaveTextContent('Deposit'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { Transaction, TransactionButton } from '@/transaction'; | ||
import type { DepositButtonReact } from '../types'; | ||
import { useEarnContext } from './EarnProvider'; | ||
|
||
export function DepositButton({ className }: DepositButtonReact) { | ||
const { depositCalls } = useEarnContext(); | ||
|
||
return ( | ||
<Transaction className={className} calls={depositCalls}> | ||
<TransactionButton text="Deposit" /> | ||
</Transaction> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { usdcToken } from '@/token/constants'; | ||
import { render, screen } from '@testing-library/react'; | ||
import type { Address } from 'viem'; | ||
import { type Mock, describe, expect, it, vi } from 'vitest'; | ||
import { DepositDetails } from './DepositDetails'; | ||
import { useEarnContext } from './EarnProvider'; | ||
|
||
vi.mock('./EarnProvider', () => ({ | ||
useEarnContext: vi.fn(), | ||
})); | ||
|
||
vi.mock('@/internal/hooks/useTheme', () => ({ | ||
useTheme: vi.fn(), | ||
})); | ||
|
||
const baseContext = { | ||
convertedBalance: '1000', | ||
setDepositAmount: vi.fn(), | ||
vaultAddress: '0x123' as Address, | ||
depositAmount: '0', | ||
depositedAmount: '0', | ||
withdrawAmount: '0', | ||
setWithdrawAmount: vi.fn(), | ||
depositCalls: [], | ||
withdrawCalls: [], | ||
}; | ||
|
||
describe('DepositDetails Component', () => { | ||
it('renders EarnDetails with default APY tag when APY is provided', () => { | ||
const mockApy = '5.00%'; | ||
vi.mocked(useEarnContext).mockReturnValue({ ...baseContext, apy: mockApy }); | ||
|
||
const { container } = render(<DepositDetails />); | ||
|
||
const tokenElement = screen.getByTestId('ockTokenChip_Button'); | ||
expect(tokenElement).toHaveTextContent(usdcToken.name); | ||
|
||
// const tagElement = screen.getByTestId('tag'); | ||
expect(container).toHaveTextContent(`APY ${mockApy}`); | ||
}); | ||
|
||
it('renders EarnDetails with an empty tag when APY is not provided', () => { | ||
vi.mocked(useEarnContext).mockReturnValue({ ...baseContext, apy: '' }); | ||
|
||
render(<DepositDetails />); | ||
|
||
const tokenElement = screen.getByTestId('ockTokenChip_Button'); | ||
expect(tokenElement).toHaveTextContent(usdcToken.name); | ||
}); | ||
|
||
it('applies custom className to the EarnDetails container', () => { | ||
const customClass = 'custom-class'; | ||
(useEarnContext as Mock).mockReturnValue({ apy: null }); | ||
|
||
render(<DepositDetails className={customClass} />); | ||
|
||
const earnDetails = screen.getByTestId('ockEarnDetails'); | ||
expect(earnDetails).toHaveClass(customClass); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { usdcToken } from '@/token/constants'; | ||
import { useMemo } from 'react'; | ||
import type { DepositDetailsReact } from '../types'; | ||
import { EarnDetails } from './EarnDetails'; | ||
import { useEarnContext } from './EarnProvider'; | ||
|
||
export function DepositDetails({ className }: DepositDetailsReact) { | ||
const { apy } = useEarnContext(); | ||
|
||
const tag = useMemo(() => { | ||
if (apy) { | ||
return `APY ${apy}`; | ||
} | ||
return ''; | ||
}, [apy]); | ||
|
||
// TODO: update token when we have logic to fetch vault info | ||
return ( | ||
<EarnDetails | ||
className={className} | ||
token={usdcToken} | ||
tag={tag} | ||
tagVariant="default" | ||
/> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import type { Call } from '@/transaction/types'; | ||
import { useGetTokenBalance } from '@/wallet/hooks/useGetTokenBalance'; | ||
import { render, screen } from '@testing-library/react'; | ||
import { type Mock, beforeEach, describe, expect, it, vi } from 'vitest'; | ||
import { useAccount, useConfig } from 'wagmi'; | ||
import { Earn } from './Earn'; | ||
|
||
vi.mock('wagmi', () => ({ | ||
useAccount: vi.fn(), | ||
useConfig: vi.fn(), | ||
useCapabilities: vi.fn(), | ||
})); | ||
|
||
vi.mock('@/transaction', () => ({ | ||
Transaction: ({ | ||
className, | ||
calls, | ||
children, | ||
}: { className: string; calls: Call[]; children: React.ReactNode }) => ( | ||
<div | ||
data-testid="transaction" | ||
className={className} | ||
data-calls={JSON.stringify(calls)} | ||
> | ||
{children} | ||
</div> | ||
), | ||
TransactionButton: ({ text }: { text: string }) => ( | ||
<button data-testid="transaction-button" type="button"> | ||
{text} | ||
</button> | ||
), | ||
})); | ||
|
||
vi.mock('@/wallet/hooks/useGetTokenBalance', () => ({ | ||
useGetTokenBalance: vi.fn(), | ||
})); | ||
|
||
vi.mock('@/internal/hooks/useTheme', () => ({ | ||
useTheme: vi.fn(), | ||
})); | ||
|
||
describe('Earn Component', () => { | ||
beforeEach(() => { | ||
(useAccount as Mock).mockReturnValue({ | ||
address: '0x123', | ||
}); | ||
(useGetTokenBalance as Mock).mockReturnValue({ | ||
convertedBalance: '0.0', | ||
error: null, | ||
}); | ||
(useConfig as Mock).mockReturnValue({}); | ||
}); | ||
|
||
it('renders custom children when provided', () => { | ||
const customChildren = <p>Custom Children</p>; | ||
render(<Earn vaultAddress="0x123">{customChildren}</Earn>); | ||
|
||
expect(screen.getByText('Custom Children')).toBeInTheDocument(); | ||
expect(screen.queryByTestId('tabs')).not.toBeInTheDocument(); | ||
}); | ||
|
||
it('renders default tabs and their contents when children are not provided', () => { | ||
const { container } = render(<Earn vaultAddress="0x123" />); | ||
|
||
const tabs = screen.getByTestId('ockTabs'); | ||
expect(tabs).toBeInTheDocument(); | ||
|
||
expect(container).toHaveTextContent('Deposit'); | ||
expect(container).toHaveTextContent('Withdraw'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import { Tab, TabContent, Tabs, TabsList } from '@/internal'; | ||
import { border, cn } from '@/styles/theme'; | ||
import type { EarnReact } from '../types'; | ||
import { EarnDeposit } from './EarnDeposit'; | ||
import { EarnProvider } from './EarnProvider'; | ||
import { EarnWithdraw } from './EarnWithdraw'; | ||
|
||
export function Earn({ | ||
children = <EarnDefaultContent />, | ||
className, | ||
vaultAddress, | ||
}: EarnReact) { | ||
return ( | ||
<EarnProvider vaultAddress={vaultAddress}> | ||
<div | ||
className={cn( | ||
'flex w-[375px] flex-col overflow-hidden', | ||
border.radius, | ||
border.lineDefault, | ||
className, | ||
)} | ||
> | ||
{children} | ||
</div> | ||
</EarnProvider> | ||
); | ||
} | ||
|
||
function EarnDefaultContent() { | ||
return ( | ||
<Tabs defaultValue="deposit"> | ||
<TabsList> | ||
<Tab value="deposit">Deposit</Tab> | ||
<Tab value="withdraw">Withdraw</Tab> | ||
</TabsList> | ||
<TabContent | ||
value="deposit" | ||
className={cn( | ||
border.lineDefault, | ||
'!border-l-0 !border-b-0 !border-r-0', | ||
)} | ||
> | ||
<EarnDeposit /> | ||
</TabContent> | ||
<TabContent | ||
value="withdraw" | ||
className={cn( | ||
border.lineDefault, | ||
'!border-l-0 !border-b-0 !border-r-0', | ||
)} | ||
> | ||
<EarnWithdraw /> | ||
</TabContent> | ||
</Tabs> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.