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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- "Copy details" button on each route card — copies the route path, fee,
and time as plain text to the clipboard (resolves #21).
- Unit test for `availableCurrencies()` (resolves #27).
- Component tests for `RouteList` covering the not-searched, empty, and
populated states (resolves #25).

### Fixed

Expand Down
73 changes: 73 additions & 0 deletions tests/RouteList.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { describe, it, expect, beforeEach, afterEach } from 'vitest'
import { act } from 'react'
import { createRoot } from 'react-dom/client'
import RouteList from '../src/components/RouteList'

const routes = [
{
hops: [
{ anchorId: 'a', anchorName: 'MockAnchor US', fromCurrency: 'USD', toCurrency: 'USDC', feePercent: 0.1, estimatedMinutes: 5 },
],
totalFeePercent: 0.1,
totalEstimatedMinutes: 5,
outputAmount: 99.9,
totalCost: 15,
},
{
hops: [
{ anchorId: 'b', anchorName: 'MockAnchor UK', fromCurrency: 'USDC', toCurrency: 'GBP', feePercent: 0.4, estimatedMinutes: 20 },
],
totalFeePercent: 0.4,
totalEstimatedMinutes: 20,
outputAmount: 99.6,
totalCost: 60,
},
]

function setup({ searched, routes: list }) {
const container = document.createElement('div')
document.body.appendChild(container)
const root = createRoot(container)
act(() => {
root.render(<RouteList searched={searched} routes={list} />)
})
return { container, root }
}

function cleanup(root) {
act(() => {
root.unmount()
})
}

beforeEach(() => {
globalThis.IS_REACT_ACT_ENVIRONMENT = true
})

afterEach(() => {
globalThis.IS_REACT_ACT_ENVIRONMENT = false
document.body.innerHTML = ''
})

describe('RouteList', () => {
it('renders nothing when not searched', () => {
const { container, root } = setup({ searched: false, routes: [] })
expect(container.textContent).toBe('')
cleanup(root)
})

it('shows a no-route message when searched with no results', () => {
const { container, root } = setup({ searched: true, routes: [] })
expect(container.textContent).toContain('No route found for that currency pair and amount.')
cleanup(root)
})

it('renders a card for each route when populated', () => {
const { container, root } = setup({ searched: true, routes })
const cards = container.querySelectorAll('.route-card')
expect(cards.length).toBe(2)
expect(container.textContent).toContain('USD → USDC')
expect(container.textContent).toContain('USDC → GBP')
cleanup(root)
})
})
31 changes: 31 additions & 0 deletions tests/availableCurrencies.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { describe, it, expect } from 'vitest'
import { mockAnchors, availableCurrencies } from '../src/data/mockAnchors'

describe('availableCurrencies', () => {
it('returns a deduplicated, sorted list of every currency in mockAnchors', () => {
const expected = [...new Set(mockAnchors.flatMap((a) => [a.fromCurrency, a.toCurrency]))].sort()
expect(availableCurrencies()).toEqual(expected)
})

it('includes every currency appearing as either fromCurrency or toCurrency', () => {
const currencies = availableCurrencies()
mockAnchors.forEach((anchor) => {
expect(currencies).toContain(anchor.fromCurrency)
expect(currencies).toContain(anchor.toCurrency)
})
})

it('does not duplicate currencies that appear on both sides', () => {
const currencies = availableCurrencies()
expect(new Set(currencies).size).toBe(currencies.length)
})

it('returns a sorted list', () => {
const currencies = availableCurrencies()
expect(currencies).toEqual([...currencies].sort())
})

it('matches the exact expected list for the current dataset', () => {
expect(availableCurrencies()).toEqual(['EUR', 'GBP', 'NGN', 'USD', 'USDC'])
})
})