Skip to content

Commit 9bfc017

Browse files
Add Custom Fee Rate for Withdrawal
Closes #36
1 parent d54556d commit 9bfc017

2 files changed

Lines changed: 269 additions & 113 deletions

File tree

apps/frontend/src/components/cln/BTCWithdraw/BTCWithdraw.test.tsx

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { fireEvent, screen, waitFor } from '@testing-library/react';
2+
import { CLNService } from '../../../services/http.service';
23
import { mockAppStore } from '../../../utilities/test-utilities/mockData';
34
import { renderWithProviders } from '../../../utilities/test-utilities/mockStore';
45
import BTCWithdraw from './BTCWithdraw';
@@ -18,4 +19,80 @@ describe('BTCWithdraw component ', () => {
1819
expect(screen.getByTestId('button-withdraw')).toBeInTheDocument();
1920
});
2021
});
22+
23+
it('should show custom fee rate input when checkbox is checked', async () => {
24+
await renderWithProviders(<BTCWithdraw />, { preloadedState: mockAppStore, initialRoute: ['/cln'] });
25+
26+
// Open the channel open card
27+
fireEvent.click(screen.getByTestId('button-open-channel'));
28+
await waitFor(() => expect(screen.getByTestId('channel-open-card')).toBeInTheDocument());
29+
30+
// Custom fee rate input should be hidden initially
31+
const customFeeRateCheckbox = screen.getByTestId('show-custom-fee-rate');
32+
expect(customFeeRateCheckbox).not.toBeChecked();
33+
34+
// Check the checkbox
35+
fireEvent.click(customFeeRateCheckbox);
36+
await waitFor(() => {
37+
expect(customFeeRateCheckbox).toBeChecked();
38+
expect(screen.getByLabelText('feeRate')).toBeVisible();
39+
expect(screen.getByTestId('fee-rate-unit')).toHaveTextContent('perkw');
40+
});
41+
});
42+
43+
it('should use custom fee rate value suffixed with perkw on submit', async () => {
44+
const mockOpenChannel = jest.spyOn(CLNService, 'openChannel').mockResolvedValue({ channel_id: 'abc123' });
45+
46+
await renderWithProviders(<BTCWithdraw />, { preloadedState: mockAppStore, initialRoute: ['/cln'] });
47+
48+
fireEvent.click(screen.getByTestId('button-open-channel'));
49+
await waitFor(() => expect(screen.getByTestId('channel-open-card')).toBeInTheDocument());
50+
51+
// Fill pubkey and amount
52+
fireEvent.change(screen.getByLabelText('pubkey'), { target: { value: 'pubkey@host:port' } });
53+
fireEvent.change(screen.getByLabelText('amount'), { target: { value: '100000' } });
54+
55+
// Enable custom fee rate and enter a value
56+
fireEvent.click(screen.getByTestId('show-custom-fee-rate'));
57+
const feeRateInput = await screen.findByLabelText('feeRate');
58+
fireEvent.change(feeRateInput, { target: { value: '500' } });
59+
60+
fireEvent.click(screen.getByTestId('button-open-channel-submit'));
61+
await waitFor(() => {
62+
expect(mockOpenChannel).toHaveBeenCalledWith(
63+
'pubkey@host:port',
64+
100000,
65+
'500perkw', // custom fee rate suffixed
66+
true
67+
);
68+
});
69+
70+
mockOpenChannel.mockRestore();
71+
});
72+
73+
it('should use slider fee rate when custom fee rate checkbox is unchecked', async () => {
74+
const mockOpenChannel = jest.spyOn(CLNService, 'openChannel').mockResolvedValue({ channel_id: 'abc123' });
75+
76+
await renderWithProviders(<BTCWithdraw />, { preloadedState: mockAppStore, initialRoute: ['/cln'] });
77+
78+
fireEvent.click(screen.getByTestId('button-open-channel'));
79+
await waitFor(() => expect(screen.getByTestId('channel-open-card')).toBeInTheDocument());
80+
81+
fireEvent.change(screen.getByLabelText('pubkey'), { target: { value: 'pubkey@host:port' } });
82+
fireEvent.change(screen.getByLabelText('amount'), { target: { value: '100000' } });
83+
84+
// Submit WITHOUT checking custom fee rate checkbox → should use default selFeeRate ('normal')
85+
fireEvent.click(screen.getByTestId('button-open-channel-submit'));
86+
await waitFor(() => {
87+
expect(mockOpenChannel).toHaveBeenCalledWith(
88+
'pubkey@host:port',
89+
100000,
90+
'normal',
91+
true
92+
);
93+
});
94+
95+
mockOpenChannel.mockRestore();
96+
});
97+
2198
});

0 commit comments

Comments
 (0)