1+ import { h } from 'preact' ;
2+ import { fireEvent , act , screen } from '@testing-library/preact' ;
3+ import '@testing-library/jest-dom' ;
4+ import waitForExpect from 'wait-for-expect' ;
5+
6+ import NetworkNodesPage from './src/networkNodesPage' ;
7+ import DeleteNodesPage from './src/containers/deleteNodesPage' ;
8+ import queryCache from 'utils/queryCache' ;
9+ import { getNodes , markNodesAsGone } from './src/networkNodesApi' ;
10+ import { render } from 'utils/test_utils' ;
11+
12+ jest . mock ( './src/networkNodesApi' ) ;
13+
14+ beforeEach ( ( ) => {
15+ getNodes . mockImplementation ( async ( ) => [
16+ { hostname : 'node1' , status : 'connected' } ,
17+ { hostname : 'node2' , status : 'connected' } ,
18+ { hostname : 'node3' , status : 'connected' } ,
19+ { hostname : 'node4' , status : 'disconnected' } ,
20+ { hostname : 'node5' , status : 'disconnected' } ,
21+ { hostname : 'node6' , status : 'disconnected' } ,
22+ { hostname : 'node7' , status : 'disconnected' } ,
23+ { hostname : 'node8' , status : 'gone' } ,
24+ { hostname : 'node9' , status : 'gone' } ,
25+ ] ) ;
26+ markNodesAsGone . mockImplementation ( async ( ) => [ ] ) ;
27+ } ) ;
28+
29+ afterEach ( ( ) => {
30+ act ( ( ) => queryCache . clear ( ) ) ;
31+ } ) ;
32+
33+ describe ( 'network nodes screen' , ( ) => {
34+ it ( 'shows one tab for connected nodes and one for discconected nodes with length' , async ( ) => {
35+ render ( < NetworkNodesPage /> ) ;
36+ expect ( await screen . findByRole ( 'tab' , { name : / ^ c o n n e c t e d \( 3 \) / i } ) ) . toBeVisible ( ) ;
37+ expect ( await screen . findByRole ( 'tab' , { name : / ^ d i s c o n n e c t e d \( 4 \) / i } ) ) . toBeVisible ( ) ;
38+ } )
39+
40+ it ( 'shows one row with the hostname for each connect node' , async ( ) => {
41+ render ( < NetworkNodesPage /> ) ;
42+ expect ( await screen . findByText ( 'node1' ) ) . toBeVisible ( ) ;
43+ expect ( await screen . findByText ( 'node2' ) ) . toBeVisible ( ) ;
44+ expect ( await screen . findByText ( 'node3' ) ) . toBeVisible ( ) ;
45+ } )
46+
47+ it ( 'shows one row with the hostname for each disconnect node' , async ( ) => {
48+ render ( < NetworkNodesPage /> ) ;
49+ const tabDisconnected = await screen . findByRole ( 'tab' , { name : / ^ d i s c o n n e c t e d \( 4 \) / i } ) ;
50+ fireEvent . click ( tabDisconnected ) ;
51+ expect ( await screen . findByText ( 'node4' ) ) . toBeVisible ( ) ;
52+ expect ( await screen . findByText ( 'node5' ) ) . toBeVisible ( ) ;
53+ expect ( await screen . findByText ( 'node6' ) ) . toBeVisible ( ) ;
54+ expect ( await screen . findByText ( 'node7' ) ) . toBeVisible ( ) ;
55+ } )
56+
57+ it ( 'shows a link to go to delete nodes page' , async ( ) => {
58+ render ( < NetworkNodesPage /> ) ;
59+ const tabDisconnected = await screen . findByRole ( 'tab' , { name : / ^ d i s c o n n e c t e d \( 4 \) / i } ) ;
60+ fireEvent . click ( tabDisconnected ) ;
61+ expect ( await screen . findByRole ( 'link' , { name : / g o t o d e l e t e n o d e s / i } ) ) . toBeVisible ( ) ;
62+ } )
63+
64+ it ( 'does not show a link to go to delete nodes page if there are no disconnected nodes' , async ( ) => {
65+ getNodes . mockImplementation ( async ( ) => [
66+ { hostname : 'node1' , status : 'connected' } ,
67+ { hostname : 'node2' , status : 'connected' } ,
68+ { hostname : 'node3' , status : 'connected' } ,
69+ ] ) ;
70+ render ( < NetworkNodesPage /> ) ;
71+ const tabDisconnected = await screen . findByRole ( 'tab' , { name : / ^ d i s c o n n e c t e d \( 0 \) / i } ) ;
72+ fireEvent . click ( tabDisconnected ) ;
73+ expect ( screen . queryByRole ( 'link' , { name : / g o t o d e l e t e n o d e s / i } ) ) . toBeNull ( ) ;
74+ } )
75+
76+ it ( 'shows help message when clicking on help button' , async ( ) => {
77+ render ( < NetworkNodesPage /> ) ;
78+ const helpButton = await screen . findByLabelText ( 'help' ) ;
79+ fireEvent . click ( helpButton ) ;
80+ expect ( await screen . findByText ( "Connected Nodes" ) ) . toBeVisible ( ) ;
81+ expect ( await screen . findByText ( "These are the nodes with which you have connectivity, "
82+ + "i.e. there is a working path from your node to each of them." ) ) . toBeVisible ( ) ;
83+ expect ( await screen . findByText ( "Disconnected Nodes" ) ) . toBeVisible ( ) ;
84+ expect ( await screen . findByText ( "These are the nodes with which you do not have connectivity, "
85+ + "it is possible that they are not turned on or a link to reach them is down." ) ) . toBeVisible ( ) ;
86+ } )
87+ } ) ;
88+
89+
90+ describe ( 'delete nodes page' , ( ) => {
91+ it ( 'shows the list of disconnected nodes only' , async ( ) => {
92+ render ( < DeleteNodesPage /> ) ;
93+ expect ( await screen . findByText ( 'node4' ) ) . toBeVisible ( ) ;
94+ expect ( await screen . findByText ( 'node5' ) ) . toBeVisible ( ) ;
95+ expect ( await screen . findByText ( 'node6' ) ) . toBeVisible ( ) ;
96+ expect ( await screen . findByText ( 'node7' ) ) . toBeVisible ( ) ;
97+ expect ( screen . queryByText ( 'node1' ) ) . toBeNull ( ) ;
98+ expect ( screen . queryByText ( 'node2' ) ) . toBeNull ( ) ;
99+ expect ( screen . queryByText ( 'node3' ) ) . toBeNull ( ) ;
100+ expect ( screen . queryByText ( 'node8' ) ) . toBeNull ( ) ;
101+ expect ( screen . queryByText ( 'node9' ) ) . toBeNull ( ) ;
102+ } )
103+
104+ it ( 'calls the markNodesAsGone api when deleting' , async ( ) => {
105+ markNodesAsGone . mockImplementation ( async ( ) => [ 'node6' ] ) ;
106+ render ( < DeleteNodesPage /> ) ;
107+ fireEvent . click ( await screen . findByText ( 'node6' ) ) ;
108+ fireEvent . click ( await screen . findByRole ( 'button' , { name : / d e l e t e / i } ) ) ;
109+ await waitForExpect ( ( ) => {
110+ expect ( markNodesAsGone ) . toBeCalledWith ( [ 'node6' ] ) ;
111+ } )
112+ } )
113+
114+ it ( 'hide nodes from the list after deletion' , async ( ) => {
115+ markNodesAsGone . mockImplementation ( async ( ) => [ 'node6' , 'node7' ] ) ;
116+ render ( < DeleteNodesPage /> ) ;
117+ fireEvent . click ( await screen . findByText ( 'node6' ) ) ;
118+ fireEvent . click ( await screen . findByText ( 'node7' ) ) ;
119+ fireEvent . click ( await screen . findByRole ( 'button' , { name : / d e l e t e / i } ) ) ;
120+ expect ( await screen . findByText ( 'node4' ) ) . toBeVisible ( ) ;
121+ expect ( await screen . queryByText ( 'node5' ) ) . toBeVisible ( ) ;
122+ expect ( await screen . queryByText ( 'node6' ) ) . toBeNull ( ) ;
123+ expect ( await screen . queryByText ( 'node7' ) ) . toBeNull ( ) ;
124+ } )
125+
126+ it ( 'show success message after deletion' , async ( ) => {
127+ markNodesAsGone . mockImplementation ( async ( ) => [ 'node6' , 'node7' ] ) ;
128+ render ( < DeleteNodesPage /> ) ;
129+ fireEvent . click ( await screen . findByText ( 'node6' ) ) ;
130+ fireEvent . click ( await screen . findByText ( 'node7' ) ) ;
131+ fireEvent . click ( await screen . findByRole ( 'button' , { name : / d e l e t e / i } ) ) ;
132+ expect ( await screen . findByText ( / s u c c e s s f u l l y d e l e t e d / i) ) . toBeVisible ( ) ;
133+ } )
134+ } )
0 commit comments