Skip to content

Commit f8dc8a7

Browse files
committed
Add tests for bookkeeper components
1 parent 094e7e8 commit f8dc8a7

File tree

14 files changed

+783
-16
lines changed

14 files changed

+783
-16
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,101 @@
1-
import { render, screen } from '@testing-library/react';
1+
import { act, fireEvent, waitFor } from '@testing-library/react';
22
import BalanceSheetGraph from './BalanceSheetGraph';
3+
import {
4+
getMockStoreData,
5+
mockBalanceSheetData,
6+
renderWithMockContext,
7+
} from '../../../../utilities/test-utilities';
38

4-
jest.mock('react-router-dom', () => ({
5-
...jest.requireActual('react-router-dom'),
6-
useNavigate: jest.fn(),
7-
}));
9+
describe('Balance Sheet Graph component ', () => {
10+
let providerProps = JSON.parse(JSON.stringify(getMockStoreData()));
11+
let container;
812

9-
describe.skip('Balance Sheet Graph component ', () => {
10-
beforeEach(() => render(<BalanceSheetGraph balanceSheetData={undefined} width={900} />));
13+
beforeEach(() => {
14+
({ container } = renderWithMockContext(
15+
<BalanceSheetGraph balanceSheetData={mockBalanceSheetData} width={900} />,
16+
{ providerProps },
17+
));
18+
});
19+
20+
it('should render the graph', () => {
21+
const svg = container.querySelector('svg');
22+
expect(svg).toBeInTheDocument();
23+
});
24+
25+
it('renders correctly with empty data', () => {
26+
renderWithMockContext(<BalanceSheetGraph balanceSheetData={{ periods: [] }} width={900} />, {
27+
providerProps,
28+
});
29+
const svg = container.querySelector('svg');
30+
expect(svg).toBeInTheDocument();
31+
});
32+
33+
it('renders correct number of bars for the periods', () => {
34+
const bars = container.querySelectorAll('g.bar-group');
35+
expect(bars.length).toBe(2);
36+
});
37+
38+
it('displays tooltip with correct content on hover', async () => {
39+
const bar = container.querySelector('rect.bar');
40+
let tooltip = container.querySelector('.sats-flow-tooltip');
41+
42+
expect(tooltip).toBeNull();
43+
expect(bar).not.toBeNull();
44+
45+
await act(async () => fireEvent.mouseOver(bar));
46+
47+
tooltip = await waitFor(() => {
48+
const tooltipElement = document.querySelector('.balance-sheet-tooltip');
49+
if (!tooltipElement) throw new Error('Tooltip not found');
50+
return tooltipElement;
51+
});
52+
53+
expect(tooltip).toBeVisible();
54+
55+
const tooltipText = tooltip.textContent?.replace(/\s+/g, ' ').trim();
56+
const expectedText = `
57+
Short Channel ID: 12345x12345x1
58+
Remote Alias: Wallet 1
59+
Balance: 500,000.000
60+
Percentage: 50%
61+
Account: onchain_wallet
62+
Total Period Balance: 1,000,000.000
63+
`
64+
.replace(/\s+/g, ' ')
65+
.trim();
66+
expect(tooltipText).toContain(expectedText);
67+
});
68+
69+
it('hides tooltip on mouseout', async () => {
70+
const bar = container.querySelector('rect.bar');
71+
let tooltip = container.querySelector('.balance-sheet-tooltip');
72+
73+
await act(async () => fireEvent.mouseOver(bar));
74+
75+
tooltip = await waitFor(() => {
76+
const tooltipElement = document.querySelector('.balance-sheet-tooltip');
77+
if (!tooltipElement) throw new Error('Tooltip not found');
78+
return tooltipElement;
79+
});
80+
81+
expect(tooltip).toBeVisible();
82+
83+
await act(async () => fireEvent.mouseOut(bar));
84+
85+
tooltip = await waitFor(() => {
86+
const tooltipElement = document.querySelector('.balance-sheet-tooltip');
87+
if (!tooltipElement) throw new Error('Tooltip not found');
88+
return tooltipElement;
89+
});
90+
91+
expect(tooltip).not.toBeVisible();
92+
});
93+
it('renders the x-axis and y-axis correctly', () => {
94+
const xAxisLabels = container.querySelectorAll('.x-axis text');
95+
const yAxisLabels = container.querySelectorAll('.y-axis text');
1196

12-
it('should be in the document', () => {
13-
expect(screen.getByTestId('balancesheetgraph-container')).not.toBeEmptyDOMElement()
97+
expect(xAxisLabels.length).toBe(mockBalanceSheetData.periods.length);
98+
expect(yAxisLabels.length).toBeGreaterThan(0);
99+
expect(xAxisLabels[0].textContent).toBe(mockBalanceSheetData.periods[0].periodKey);
14100
});
15101
});

apps/frontend/src/components/bookkeeper/BalanceSheet/Graph/BalanceSheetGraph.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ function BalanceSheetGraph({ balanceSheetData, width }) {
124124
barsGroup.attr("clip-path", "url(#chart-area-clip");
125125

126126
svg.append("g")
127+
.attr("class", "y-axis")
127128
.call(d3.axisLeft(yScale)
128129
.tickSizeInner(0)
129130
.tickSizeOuter(0)
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,79 @@
1-
import { render, screen } from '@testing-library/react';
1+
import { act, fireEvent, screen } from '@testing-library/react';
22
import Bookkeeper from './BkprRoot';
3+
import { useNavigate } from 'react-router-dom';
4+
import { getMockStoreData, renderWithMockContext } from '../../../utilities/test-utilities';
35

46
describe('Bookkeeper component ', () => {
5-
beforeEach(() => render(<Bookkeeper />));
7+
let mockNavigate: jest.Mock;
8+
let providerProps = JSON.parse(JSON.stringify(getMockStoreData()));
9+
10+
beforeEach(() => {
11+
mockNavigate = jest.fn();
12+
(useNavigate as jest.Mock).mockReturnValue(mockNavigate);
13+
renderWithMockContext(<Bookkeeper />, { providerProps });
14+
});
615

716
it('should be in the document', () => {
8-
expect(screen.getByTestId('bookkeeper-container')).not.toBeEmptyDOMElement()
17+
expect(screen.getByTestId('bookkeeper-container')).not.toBeEmptyDOMElement();
18+
});
19+
20+
it('should display the dashboard header', () => {
21+
expect(screen.getByText('Bookkeeper Dashboard')).toBeInTheDocument();
22+
});
23+
24+
it('should display the Balance Sheet section', () => {
25+
expect(screen.getByText('Balance Sheet')).toBeInTheDocument();
26+
expect(screen.getByText('Total Number of Channels')).toBeInTheDocument();
27+
expect(screen.getByText('Total Balance in Channels')).toBeInTheDocument();
28+
expect(screen.getByText('Total Balance in Wallet')).toBeInTheDocument();
29+
});
30+
31+
it('should display the Sats Flow section', () => {
32+
expect(screen.getByText('Sats Flow')).toBeInTheDocument();
33+
expect(screen.getByText('Inflow this month')).toBeInTheDocument();
34+
expect(screen.getByText('Outflow this month')).toBeInTheDocument();
35+
});
36+
37+
it('should display the Volume Chart section', () => {
38+
expect(screen.getByText('Volume Chart')).toBeInTheDocument();
39+
expect(screen.getByText('Track route performance.')).toBeInTheDocument();
40+
});
41+
42+
it('should navigate to Terminal when the Terminal button is clicked', async () => {
43+
const terminalButton = screen.getByText('Terminal');
44+
await act(async () => fireEvent.click(terminalButton));
45+
46+
expect(mockNavigate).toHaveBeenCalledWith('/bookkeeper/terminal');
47+
});
48+
49+
it('should navigate to Balance Sheet on View More click', async () => {
50+
const viewMoreButton = screen.getAllByText('View More')[0];
51+
await act(async () => fireEvent.click(viewMoreButton));
52+
53+
expect(mockNavigate).toHaveBeenCalledWith('/bookkeeper/balancesheet');
54+
});
55+
56+
it('should navigate to Sats Flow on View More click', async () => {
57+
const viewMoreButton = screen.getAllByText('View More')[1];
58+
await act(async () => fireEvent.click(viewMoreButton));
59+
60+
expect(mockNavigate).toHaveBeenCalledWith('/bookkeeper/satsflow');
61+
});
62+
63+
it('should navigate to Volume on View More click', async () => {
64+
const viewMoreButton = screen.getAllByText('View More')[2];
65+
await act(async () => fireEvent.click(viewMoreButton));
66+
67+
expect(mockNavigate).toHaveBeenCalledWith('/bookkeeper/volume');
68+
});
69+
70+
it('should display fetched data when available', async () => {
71+
expect(await screen.findByText('5')).toBeInTheDocument();
72+
expect(await screen.findByText('100,000.000')).toBeInTheDocument();
73+
expect(await screen.findByText('50,000.000')).toBeInTheDocument();
74+
expect(await screen.findByText('2,000.000')).toBeInTheDocument();
75+
expect(await screen.findByText('−1,000.000')).toBeInTheDocument();
76+
expect(await screen.findByText('route1')).toBeInTheDocument();
77+
expect(await screen.findByText('route2')).toBeInTheDocument();
978
});
1079
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import SatsFlowGraph from './SatsFlowGraph';
2+
import {
3+
getMockStoreData,
4+
mockSatsFlowData,
5+
renderWithMockContext,
6+
} from '../../../../utilities/test-utilities';
7+
import { act, fireEvent, waitFor } from '@testing-library/react';
8+
9+
describe('Sats Flow Graph component ', () => {
10+
let providerProps = JSON.parse(JSON.stringify(getMockStoreData()));
11+
let container;
12+
13+
beforeEach(() => {
14+
({ container } = renderWithMockContext(
15+
<SatsFlowGraph satsFlowData={mockSatsFlowData} width={900} />,
16+
{
17+
providerProps,
18+
},
19+
));
20+
});
21+
22+
it('should render the graph', () => {
23+
const svg = container.querySelector('svg');
24+
expect(svg).toBeInTheDocument();
25+
});
26+
27+
it('renders correctly with empty data', () => {
28+
renderWithMockContext(<SatsFlowGraph satsFlowData={{ periods: [] }} width={900} />, {
29+
providerProps,
30+
});
31+
const svg = container.querySelector('svg');
32+
expect(svg).toBeInTheDocument();
33+
});
34+
35+
it('renders correct number of bars for the periods', () => {
36+
const bars = container.querySelectorAll('g.bar-group');
37+
expect(bars.length).toBe(2);
38+
});
39+
40+
it('displays tooltip with correct content on hover', async () => {
41+
const bar = container.querySelector('rect.bar');
42+
let tooltip = container.querySelector('.sats-flow-tooltip');
43+
44+
expect(tooltip).toBeNull();
45+
expect(bar).not.toBeNull();
46+
47+
await act(async () => fireEvent.mouseOver(bar));
48+
49+
tooltip = await waitFor(() => {
50+
const tooltipElement = document.querySelector('.sats-flow-tooltip');
51+
if (!tooltipElement) throw new Error('Tooltip not found');
52+
return tooltipElement;
53+
});
54+
55+
expect(tooltip).toBeVisible();
56+
57+
const tooltipText = tooltip.textContent?.replace(/\s+/g, ' ').trim();
58+
const expectedText = `
59+
Event Tag: deposit
60+
Net Inflow: 800.000
61+
Credits: 1,000.000
62+
Debits: 200.000
63+
Volume: 1,200.000
64+
Period Inflow: 1,500.000
65+
Period Outflow: 200.000
66+
Period Net Inflow: 1,300.000
67+
Period Volume: 1,700.000
68+
`
69+
.replace(/\s+/g, ' ')
70+
.trim();
71+
expect(tooltipText).toContain(expectedText);
72+
});
73+
74+
it('hides tooltip on mouseout', async () => {
75+
const bar = container.querySelector('rect.bar');
76+
let tooltip = container.querySelector('.sats-flow-tooltip');
77+
78+
await act(async () => fireEvent.mouseOver(bar));
79+
80+
tooltip = await waitFor(() => {
81+
const tooltipElement = document.querySelector('.sats-flow-tooltip');
82+
if (!tooltipElement) throw new Error('Tooltip not found');
83+
return tooltipElement;
84+
});
85+
86+
expect(tooltip).toBeVisible();
87+
88+
await act(async () => fireEvent.mouseOut(bar));
89+
90+
tooltip = await waitFor(() => {
91+
const tooltipElement = document.querySelector('.sats-flow-tooltip');
92+
if (!tooltipElement) throw new Error('Tooltip not found');
93+
return tooltipElement;
94+
});
95+
96+
expect(tooltip).not.toBeVisible();
97+
});
98+
99+
it('renders the x-axis and y-axis correctly', () => {
100+
const xAxisLabels = container.querySelectorAll('.x-axis-labels text');
101+
const yAxisLabels = container.querySelectorAll('.y-axis text');
102+
103+
expect(xAxisLabels.length).toBe(2);
104+
expect(yAxisLabels.length).toBeGreaterThan(0);
105+
});
106+
});

apps/frontend/src/components/bookkeeper/SatsFlow/SatsFlowGraph/SatsFlowGraph.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ function SatsFlowGraph({ satsFlowData, width }: { satsFlowData: SatsFlow, width:
160160
//set up y axis
161161
const yAxisTickFormat = d => `${d3.format(",")(d)}`;
162162
svg.append("g")
163+
.attr("class", "y-axis")
163164
.call(d3.axisLeft(yScale)
164165
.tickSizeInner(0)
165166
.tickSizeOuter(0)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { render, screen } from '@testing-library/react';
2+
import SatsFlowRoot from './SatsFlowRoot';
3+
4+
jest.mock('react-router-dom', () => ({
5+
...jest.requireActual('react-router-dom'),
6+
useNavigate: jest.fn(),
7+
}));
8+
9+
describe('Sats Flow component ', () => {
10+
beforeEach(() => render(<SatsFlowRoot />));
11+
12+
it('should be in the document', () => {
13+
expect(screen.getByTestId('satsflow-container')).not.toBeEmptyDOMElement();
14+
});
15+
});

0 commit comments

Comments
 (0)