Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions __tests__/hooks/use-token-price.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@

it('returns totalUsd=0 for an empty stream list', async () => {
const { result } = renderHook(() => usePortfolioValue([]))
expect(result.current.totalUsd).toBe(0)

Check failure on line 74 in __tests__/hooks/use-token-price.test.ts

View workflow job for this annotation

GitHub Actions / build

__tests__/hooks/use-token-price.test.ts > usePortfolioValue > returns totalUsd=0 for an empty stream list

AssertionError: expected null to be +0 // Object.is equality - Expected: 0 + Received: null ❯ __tests__/hooks/use-token-price.test.ts:74:37
expect(result.current.loading).toBe(false)
})

Expand Down Expand Up @@ -99,4 +99,71 @@
expect(result.current.totalUsd).toBe(10_000)
})
})

it('shows USD value for known tokens and ignores unknown tokens', async () => {
const streams: StreamData[] = [
{
id: '1',
sender: 'GSENDER',
recipient: 'GRECIPIENT',
token: { address: 'CUSDC', symbol: 'USDC', decimals: 7 },
depositedAmount: 5_000_0000000n,
withdrawnAmount: 0n,
startTime: 0n,
endTime: 9999999999n,
cliffTime: 0n,
cliffAmount: 0n,
amountPerSecond: 1n,
linearAmount: 5_000_0000000n,
duration: 9999999999n,
cancelled: false,
},
{
id: '2',
sender: 'GSENDER',
recipient: 'GRECIPIENT',
token: { address: 'CUSTOM_TOKEN', symbol: 'CUSTOM', decimals: 6 },
depositedAmount: 1_000_000000n,
withdrawnAmount: 0n,
startTime: 0n,
endTime: 9999999999n,
cliffTime: 0n,
cliffAmount: 0n,
amountPerSecond: 1n,
linearAmount: 1_000_000000n,
duration: 9999999999n,
cancelled: false,
},
]
const { result } = renderHook(() => usePortfolioValue(streams))
await waitFor(() => {
// Should show 5000 USD from USDC, not null despite unknown CUSTOM token
expect(result.current.totalUsd).toBe(5_000)
})
})

it('returns null when all streams use unknown tokens', async () => {
const streams: StreamData[] = [
{
id: '1',
sender: 'GSENDER',
recipient: 'GRECIPIENT',
token: { address: 'CUSTOM_TOKEN', symbol: 'CUSTOM', decimals: 6 },
depositedAmount: 1_000_000000n,
withdrawnAmount: 0n,
startTime: 0n,
endTime: 9999999999n,
cliffTime: 0n,
cliffAmount: 0n,
amountPerSecond: 1n,
linearAmount: 1_000_000000n,
duration: 9999999999n,
cancelled: false,
},
]
const { result } = renderHook(() => usePortfolioValue(streams))
await waitFor(() => {
expect(result.current.totalUsd).toBeNull()
})
})
})
39 changes: 0 additions & 39 deletions __tests__/hooks/useBulkActions.test.ts

This file was deleted.

45 changes: 0 additions & 45 deletions __tests__/hooks/useBulkSelect.test.ts

This file was deleted.

76 changes: 0 additions & 76 deletions __tests__/hooks/useNotifications.test.ts

This file was deleted.

127 changes: 127 additions & 0 deletions __tests__/lib/error-messages.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,133 @@
const result = mapError(new Error('mystery error'))
expect(result.details).toBe('mystery error')
})

// Soroban contract error codes
it('maps Error(Contract, 1) - InvalidAmount', () => {
const result = mapError(new Error('Error(Contract, 1)'))
expect(result.message).toBe('Invalid stream amount')
expect(result.category).toBe('contract')
})

it('maps Error(Contract, 2) - InvalidTimeRange', () => {
const result = mapError(new Error('Error(Contract, 2)'))
expect(result.message).toBe('Invalid time range')
expect(result.category).toBe('contract')
})

it('maps Error(Contract, 3) - InvalidCliff', () => {
const result = mapError(new Error('Error(Contract, 3)'))
expect(result.message).toBe('Invalid cliff configuration')
expect(result.category).toBe('contract')
})

it('maps Error(Contract, 4) - SelfStream', () => {
const result = mapError(new Error('Error(Contract, 4)'))
expect(result.message).toBe('Cannot create self-directed stream')
expect(result.category).toBe('user')
})

it('maps Error(Contract, 5) - StreamNotFound', () => {
const result = mapError(new Error('Error(Contract, 5)'))
expect(result.message).toBe('Stream not found')
expect(result.category).toBe('contract')
})

it('maps Error(Contract, 6) - StreamCancelled', () => {
const result = mapError(new Error('Error(Contract, 6)'))
expect(result.message).toBe('Stream has been cancelled')
expect(result.category).toBe('contract')
})

it('maps Error(Contract, 7) - Unauthorized', () => {
const result = mapError(new Error('Error(Contract, 7)'))
expect(result.message).toBe('Unauthorized operation')
expect(result.category).toBe('user')
})

it('maps Error(Contract, 8) - InsufficientFunds', () => {
const result = mapError(new Error('Error(Contract, 8)'))
expect(result.message).toBe('Insufficient funds in stream')
expect(result.category).toBe('user')
})

it('maps Error(Contract, 9) - StreamEnded', () => {
const result = mapError(new Error('Error(Contract, 9)'))
expect(result.message).toBe('Stream has ended')
expect(result.category).toBe('contract')
})

it('maps Error(Contract, 10) - SameRecipient', () => {
const result = mapError(new Error('Error(Contract, 10)'))
expect(result.message).toBe('Recipient already set')
expect(result.category).toBe('user')
})

it('maps Error(Contract, 11) - BatchSizeExceeded', () => {
const result = mapError(new Error('Error(Contract, 11)'))
expect(result.message).toBe('Batch size exceeds maximum')
expect(result.category).toBe('user')
})

it('maps Error(Contract, 12) - BatchEmpty', () => {
const result = mapError(new Error('Error(Contract, 12)'))
expect(result.message).toBe('Batch cannot be empty')
expect(result.category).toBe('user')
})

it('maps Error(Contract, 13) - ArithmeticOverflow', () => {
const result = mapError(new Error('Error(Contract, 13)'))
expect(result.message).toBe('Arithmetic overflow in calculation')
expect(result.category).toBe('contract')
})

it('maps Error(Contract, 14) - AlreadyInitialized', () => {
const result = mapError(new Error('Error(Contract, 14)'))
expect(result.message).toBe('Contract already initialized')
expect(result.category).toBe('contract')
})

it('maps Error(Contract, 15) - NotInitialized', () => {
const result = mapError(new Error('Error(Contract, 15)'))
expect(result.message).toBe('Contract not initialized')
expect(result.category).toBe('contract')
})

it('maps Error(Contract, 16) - ContractPaused', () => {
const result = mapError(new Error('Error(Contract, 16)'))
expect(result.message).toBe('Contract is paused')
expect(result.category).toBe('network')
})

it('maps Error(Contract, 17) - DurationExceedsMaximum', () => {
const result = mapError(new Error('Error(Contract, 17)'))
expect(result.message).toBe('Stream duration exceeds maximum')
expect(result.category).toBe('user')
})

it('maps Error(Contract, 18) - InvalidRecipient', () => {
const result = mapError(new Error('Error(Contract, 18)'))
expect(result.message).toBe('Invalid recipient address')
expect(result.category).toBe('user')
})

it('maps Error(Contract, 19) - RateIsZero', () => {
const result = mapError(new Error('Error(Contract, 19)'))
expect(result.message).toBe('Stream amount too small for duration')
expect(result.category).toBe('user')
})

it('maps Error(Contract, 20) - StreamNotEligibleForCleanup', () => {
const result = mapError(new Error('Error(Contract, 20)'))
expect(result.message).toBe('Stream not eligible for cleanup')
expect(result.category).toBe('contract')
})

it('handles soroban error with extra whitespace', () => {
const result = mapError(new Error('Error(Contract, 1 )'))
expect(result.message).toBe('Invalid stream amount')

Check failure on line 252 in __tests__/lib/error-messages.test.ts

View workflow job for this annotation

GitHub Actions / build

__tests__/lib/error-messages.test.ts > mapError > handles soroban error with extra whitespace

AssertionError: expected 'Transaction failed' to be 'Invalid stream amount' // Object.is equality Expected: "Invalid stream amount" Received: "Transaction failed" ❯ __tests__/lib/error-messages.test.ts:252:28
expect(result.category).toBe('contract')
})
})

// ─── categoryLabel ────────────────────────────────────────────────────────────
Expand Down
Loading
Loading