Skip to content

Commit fb8a16c

Browse files
committed
test: add unit tests for processing swap updates
1 parent 7b6e062 commit fb8a16c

File tree

4 files changed

+170
-8
lines changed

4 files changed

+170
-8
lines changed

app/src/__stories__/ProcessingSwaps.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ const mockSwap = (type: number, state: number, id?: string) => {
4747
swap.id = `${id || ''}${swap.id}`;
4848
swap.type = type;
4949
swap.state = state;
50-
swap.initiationTime = Date.now() * 1000 * 1000;
50+
swap.lastUpdateTime = Date.now() * 1000 * 1000;
5151
return swap;
5252
};
5353
// create a list of swaps to use for stories
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
import React from 'react';
2+
import * as LOOP from 'types/generated/loop_pb';
3+
import { fireEvent } from '@testing-library/react';
4+
import { ellipseInside } from 'util/strings';
5+
import { renderWithProviders } from 'util/tests';
6+
import { loopListSwaps } from 'util/tests/sampleData';
7+
import { createStore, Store } from 'store';
8+
import { Swap } from 'store/models';
9+
import ProcessingSwaps from 'components/loop/processing/ProcessingSwaps';
10+
11+
const { LOOP_IN, LOOP_OUT } = LOOP.SwapType;
12+
const {
13+
INITIATED,
14+
PREIMAGE_REVEALED,
15+
HTLC_PUBLISHED,
16+
SUCCESS,
17+
INVOICE_SETTLED,
18+
FAILED,
19+
} = LOOP.SwapState;
20+
const width = (el: any) => window.getComputedStyle(el).width;
21+
22+
describe('ProcessingSwaps component', () => {
23+
let store: Store;
24+
25+
const addSwap = (type: number, state: number, id?: string) => {
26+
const swap = new Swap(loopListSwaps.swapsList[0]);
27+
swap.id = `${id || ''}${swap.id}`;
28+
swap.type = type;
29+
swap.state = state;
30+
swap.lastUpdateTime = Date.now() * 1000 * 1000;
31+
store.swapStore.swaps.set(swap.id, swap);
32+
return swap;
33+
};
34+
35+
beforeEach(async () => {
36+
store = createStore();
37+
});
38+
39+
const render = () => {
40+
return renderWithProviders(<ProcessingSwaps />, store);
41+
};
42+
43+
it('should display the title', async () => {
44+
const { getByText } = render();
45+
expect(getByText('Processing Loops')).toBeInTheDocument();
46+
});
47+
48+
it('should display an INITIATED Loop In', () => {
49+
const { getByText, getByTitle } = render();
50+
const swap = addSwap(LOOP_IN, INITIATED);
51+
expect(getByText('dot.svg')).toHaveClass('warn');
52+
expect(getByText(ellipseInside(swap.id))).toBeInTheDocument();
53+
expect(getByTitle(swap.stateLabel)).toBeInTheDocument();
54+
expect(width(getByTitle(swap.stateLabel))).toBe('25%');
55+
});
56+
57+
it('should display an HTLC_PUBLISHED Loop In', () => {
58+
const { getByText, getByTitle } = render();
59+
const swap = addSwap(LOOP_IN, HTLC_PUBLISHED);
60+
expect(getByText('dot.svg')).toHaveClass('warn');
61+
expect(getByText(ellipseInside(swap.id))).toBeInTheDocument();
62+
expect(getByTitle(swap.stateLabel)).toBeInTheDocument();
63+
expect(width(getByTitle(swap.stateLabel))).toBe('50%');
64+
});
65+
66+
it('should display an INVOICE_SETTLED Loop In', () => {
67+
const { getByText, getByTitle } = render();
68+
const swap = addSwap(LOOP_IN, INVOICE_SETTLED);
69+
expect(getByText('dot.svg')).toHaveClass('warn');
70+
expect(getByText(ellipseInside(swap.id))).toBeInTheDocument();
71+
expect(getByTitle(swap.stateLabel)).toBeInTheDocument();
72+
expect(width(getByTitle(swap.stateLabel))).toBe('75%');
73+
});
74+
75+
it('should display an SUCCESS Loop In', () => {
76+
const { getByText, getByTitle } = render();
77+
const swap = addSwap(LOOP_IN, SUCCESS);
78+
expect(getByText(ellipseInside(swap.id))).toBeInTheDocument();
79+
expect(getByTitle(swap.stateLabel)).toBeInTheDocument();
80+
expect(width(getByTitle(swap.stateLabel))).toBe('100%');
81+
});
82+
83+
it('should display an FAILED Loop In', () => {
84+
const { getByText } = render();
85+
const swap = addSwap(LOOP_IN, FAILED);
86+
expect(getByText(ellipseInside(swap.id))).toBeInTheDocument();
87+
expect(getByText(swap.stateLabel)).toBeInTheDocument();
88+
expect(getByText('close.svg')).toBeInTheDocument();
89+
});
90+
91+
it('should display an INITIATED Loop Out', () => {
92+
const { getByText, getByTitle } = render();
93+
const swap = addSwap(LOOP_OUT, INITIATED);
94+
expect(getByText('dot.svg')).toHaveClass('warn');
95+
expect(getByText(ellipseInside(swap.id))).toBeInTheDocument();
96+
expect(getByTitle(swap.stateLabel)).toBeInTheDocument();
97+
expect(width(getByTitle(swap.stateLabel))).toBe('33%');
98+
});
99+
100+
it('should display an PREIMAGE_REVEALED Loop Out', () => {
101+
const { getByText, getByTitle } = render();
102+
const swap = addSwap(LOOP_OUT, PREIMAGE_REVEALED);
103+
expect(getByText('dot.svg')).toHaveClass('warn');
104+
expect(getByText(ellipseInside(swap.id))).toBeInTheDocument();
105+
expect(getByTitle(swap.stateLabel)).toBeInTheDocument();
106+
expect(width(getByTitle(swap.stateLabel))).toBe('66%');
107+
});
108+
109+
it('should display an SUCCESS Loop Out', () => {
110+
const { getByText, getByTitle } = render();
111+
const swap = addSwap(LOOP_OUT, SUCCESS);
112+
expect(getByText('dot.svg')).toHaveClass('success');
113+
expect(getByText(ellipseInside(swap.id))).toBeInTheDocument();
114+
expect(getByTitle(swap.stateLabel)).toBeInTheDocument();
115+
expect(width(getByTitle(swap.stateLabel))).toBe('100%');
116+
});
117+
118+
it('should display an FAILED Loop Out', () => {
119+
const { getByText } = render();
120+
const swap = addSwap(LOOP_OUT, FAILED);
121+
expect(getByText(ellipseInside(swap.id))).toBeInTheDocument();
122+
expect(getByText(swap.stateLabel)).toBeInTheDocument();
123+
expect(getByText('close.svg')).toBeInTheDocument();
124+
});
125+
126+
it('should dismiss a failed Loop', () => {
127+
const { getByText } = render();
128+
addSwap(LOOP_OUT, FAILED);
129+
expect(store.swapStore.dismissedSwapIds).toHaveLength(0);
130+
fireEvent.click(getByText('close.svg'));
131+
expect(store.swapStore.dismissedSwapIds).toHaveLength(1);
132+
});
133+
});

app/src/__tests__/store/swapStore.spec.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as LOOP from 'types/generated/loop_pb';
2+
import { waitFor } from '@testing-library/react';
23
import { loopListSwaps } from 'util/tests/sampleData';
34
import { createStore, SwapStore } from 'store';
45

@@ -55,4 +56,37 @@ describe('SwapStore', () => {
5556
swap.type = type;
5657
expect(swap.typeName).toEqual(label);
5758
});
59+
60+
it('should poll for swap updates', async () => {
61+
await store.fetchSwaps();
62+
const swap = store.sortedSwaps[0];
63+
// create a pending swap to trigger auto-polling
64+
swap.state = LOOP.SwapState.INITIATED;
65+
expect(store.pendingSwaps).toHaveLength(1);
66+
// wait for polling to start
67+
await waitFor(() => {
68+
expect(store.pollingInterval).toBeDefined();
69+
});
70+
// change the swap to complete
71+
swap.state = LOOP.SwapState.SUCCESS;
72+
expect(store.pendingSwaps).toHaveLength(0);
73+
// confirm polling has stopped
74+
await waitFor(() => {
75+
expect(store.pollingInterval).toBeUndefined();
76+
});
77+
});
78+
79+
it('should handle startPolling when polling is already running', () => {
80+
expect(store.pollingInterval).toBeUndefined();
81+
store.startPolling();
82+
expect(store.pollingInterval).toBeDefined();
83+
store.startPolling();
84+
expect(store.pollingInterval).toBeDefined();
85+
});
86+
87+
it('should handle stopPolling when polling is already stopped', () => {
88+
expect(store.pollingInterval).toBeUndefined();
89+
store.stopPolling();
90+
expect(store.pollingInterval).toBeUndefined();
91+
});
5892
});

app/src/store/stores/swapStore.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
toJS,
1010
values,
1111
} from 'mobx';
12-
import { IS_PROD } from 'config';
12+
import { IS_PROD, IS_TEST } from 'config';
1313
import { Store } from 'store';
1414
import { Swap } from '../models';
1515

@@ -69,11 +69,6 @@ export default class SwapStore {
6969
return this.sortedSwaps.filter(s => s.isPending);
7070
}
7171

72-
/** swaps that were completed in the past 5 minutes */
73-
@computed get recentSwaps() {
74-
return this.sortedSwaps.filter(s => s.isRecent);
75-
}
76-
7772
@action.bound
7873
dismissSwap(swapId: string) {
7974
this.dismissedSwapIds.push(swapId);
@@ -113,7 +108,7 @@ export default class SwapStore {
113108
startPolling() {
114109
if (this.pollingInterval) this.stopPolling();
115110
this._store.log.info('start polling for swap updates');
116-
const ms = IS_PROD ? 60 * 1000 : 1000;
111+
const ms = IS_PROD ? 60 * 1000 : IS_TEST ? 100 : 1000;
117112
this.pollingInterval = setInterval(this.fetchSwaps, ms);
118113
}
119114

0 commit comments

Comments
 (0)