1
1
import {
2
+ clickByRole ,
2
3
renderAppAt ,
3
4
screen ,
4
- waitForElementToBeRemoved ,
5
- clickByRole ,
6
5
typeByRole ,
6
+ waitForElementToBeRemoved ,
7
+ userEvent ,
8
+ getByRole ,
7
9
} from 'app/test-utils'
8
10
import { defaultFirewallRules } from '@oxide/api-mocks'
11
+ import { logRoles } from '@testing-library/react'
9
12
10
13
describe ( 'VpcPage' , ( ) => {
11
14
describe ( 'subnet' , ( ) => {
@@ -22,7 +25,7 @@ describe('VpcPage', () => {
22
25
expect ( screen . queryByTestId ( 'create-vpc-subnet-modal' ) ) . toBeNull ( )
23
26
24
27
// click button to open modal
25
- clickByRole ( 'button' , 'New subnet' )
28
+ await clickByRole ( 'button' , 'New subnet' )
26
29
27
30
// modal is open
28
31
screen . getByRole ( 'dialog' , { name : 'Create subnet' } )
@@ -32,7 +35,7 @@ describe('VpcPage', () => {
32
35
typeByRole ( 'textbox' , 'Name' , 'mock-subnet-2' )
33
36
34
37
// submit the form
35
- clickByRole ( 'button' , 'Create subnet' )
38
+ await clickByRole ( 'button' , 'Create subnet' )
36
39
37
40
// wait for modal to close
38
41
await waitForElementToBeRemoved ( ( ) =>
@@ -48,7 +51,7 @@ describe('VpcPage', () => {
48
51
describe ( 'firewall rule' , ( ) => {
49
52
it ( 'create works' , async ( ) => {
50
53
renderAppAt ( '/orgs/maze-war/projects/mock-project/vpcs/mock-vpc' )
51
- clickByRole ( 'tab' , 'Firewall Rules' )
54
+ await clickByRole ( 'tab' , 'Firewall Rules' )
52
55
53
56
// default rules show up in the table
54
57
for ( const { name } of defaultFirewallRules ) {
@@ -63,45 +66,45 @@ describe('VpcPage', () => {
63
66
) . toBeNull ( )
64
67
65
68
// click button to open modal
66
- clickByRole ( 'button' , 'New rule' )
69
+ await clickByRole ( 'button' , 'New rule' )
67
70
68
71
// modal is open
69
- await screen . findByText ( ' Create firewall rule')
72
+ screen . getByRole ( 'dialog' , { name : ' Create firewall rule' } )
70
73
71
74
typeByRole ( 'textbox' , 'Name' , 'my-new-rule' )
72
75
73
- clickByRole ( 'radio' , 'Outgoing' )
76
+ await clickByRole ( 'radio' , 'Outgoing' )
74
77
75
78
// input type="number" becomes spinbutton for some reason
76
79
typeByRole ( 'spinbutton' , 'Priority' , '5' )
77
80
78
- clickByRole ( 'button' , 'Target type' )
79
- clickByRole ( 'option' , 'VPC' )
81
+ await clickByRole ( 'button' , 'Target type' )
82
+ await clickByRole ( 'option' , 'VPC' )
80
83
typeByRole ( 'textbox' , 'Target name' , 'my-target-vpc' )
81
- clickByRole ( 'button' , 'Add target' )
84
+ await clickByRole ( 'button' , 'Add target' )
82
85
83
86
// target is added to targets table
84
87
screen . getByRole ( 'cell' , { name : 'my-target-vpc' } )
85
88
86
- clickByRole ( 'button' , 'Host type' )
87
- clickByRole ( 'option' , 'Instance' )
88
- typeByRole ( 'textbox' , 'Value' , 'my-target -instance' )
89
- clickByRole ( 'button' , 'Add host filter' )
89
+ await clickByRole ( 'button' , 'Host type' )
90
+ await clickByRole ( 'option' , 'Instance' )
91
+ typeByRole ( 'textbox' , 'Value' , 'host-filter -instance' )
92
+ await clickByRole ( 'button' , 'Add host filter' )
90
93
91
94
// host is added to hosts table
92
- screen . getByRole ( 'cell' , { name : 'my-target -instance' } )
95
+ screen . getByRole ( 'cell' , { name : 'host-filter -instance' } )
93
96
94
97
// TODO: test invalid port range once I put an error message in there
95
98
typeByRole ( 'textbox' , 'Port filter' , '123-456' )
96
- clickByRole ( 'button' , 'Add port filter' )
99
+ await clickByRole ( 'button' , 'Add port filter' )
97
100
98
101
// port range is added to port ranges table
99
102
screen . getByRole ( 'cell' , { name : '123-456' } )
100
103
101
- clickByRole ( 'checkbox' , 'UDP' )
104
+ await clickByRole ( 'checkbox' , 'UDP' )
102
105
103
106
// submit the form
104
- clickByRole ( 'button' , 'Create rule' )
107
+ await clickByRole ( 'button' , 'Create rule' )
105
108
106
109
// wait for modal to close
107
110
await waitForElementToBeRemoved (
@@ -112,9 +115,99 @@ describe('VpcPage', () => {
112
115
113
116
// table refetches and now includes the new rule as well as the originals
114
117
await screen . findByText ( 'my-new-rule' )
118
+ screen . getByRole ( 'cell' , {
119
+ name : 'instance host-filter-instance UDP 123-456' ,
120
+ } )
121
+
115
122
for ( const { name } of defaultFirewallRules ) {
116
123
screen . getByText ( name )
117
124
}
118
125
} , 10000 )
126
+
127
+ it ( 'edit works' , async ( ) => {
128
+ renderAppAt ( '/orgs/maze-war/projects/mock-project/vpcs/mock-vpc' )
129
+ await clickByRole ( 'tab' , 'Firewall Rules' )
130
+
131
+ // default rules show up in the table
132
+ for ( const { name } of defaultFirewallRules ) {
133
+ await screen . findByText ( name )
134
+ }
135
+ expect ( screen . getAllByRole ( 'row' ) . length ) . toEqual ( 5 ) // 4 + header
136
+
137
+ // the one we'll be adding is not there
138
+ expect ( screen . queryByRole ( 'cell' , { name : 'new-rule-name' } ) ) . toBeNull ( )
139
+
140
+ // modal is not already open
141
+ expect (
142
+ screen . queryByRole ( 'dialog' , { name : 'Edit firewall rule' } )
143
+ ) . toBeNull ( )
144
+
145
+ // click more button on allow-icmp row to get menu, then click Edit
146
+ const allowIcmpRow = screen . getByRole ( 'row' , { name : / a l l o w - i c m p / } )
147
+ const more = getByRole ( allowIcmpRow , 'button' , { name : 'More' } )
148
+ await userEvent . click ( more )
149
+ await clickByRole ( 'menuitem' , 'Edit' )
150
+
151
+ // now the modal is open
152
+ screen . getByRole ( 'dialog' , { name : 'Edit firewall rule' } )
153
+
154
+ // name is populated
155
+ const name = screen . getByRole ( 'textbox' , {
156
+ name : 'Name' ,
157
+ } ) as HTMLInputElement
158
+ expect ( name . value ) . toEqual ( 'allow-icmp' )
159
+
160
+ // priority is populated
161
+ const priority = screen . getByRole ( 'spinbutton' , {
162
+ name : 'Priority' ,
163
+ } ) as HTMLInputElement
164
+ expect ( priority . value ) . toEqual ( '65534' )
165
+
166
+ // protocol is populated
167
+ expect ( screen . getByRole ( 'checkbox' , { name : / I C M P / } ) ) . toBeChecked ( )
168
+ expect ( screen . getByRole ( 'checkbox' , { name : / T C P / } ) ) . not . toBeChecked ( )
169
+ expect ( screen . getByRole ( 'checkbox' , { name : / U D P / } ) ) . not . toBeChecked ( )
170
+
171
+ // targets default vpc
172
+ screen . getByRole ( 'cell' , { name : 'vpc' } )
173
+ screen . getByRole ( 'cell' , { name : 'default' } )
174
+
175
+ // update name
176
+ await userEvent . clear ( name )
177
+ await userEvent . type ( name , 'new-rule-name' )
178
+
179
+ await clickByRole ( 'button' , 'Host type' )
180
+ await clickByRole ( 'option' , 'Instance' )
181
+ typeByRole ( 'textbox' , 'Value' , 'edit-filter-instance' )
182
+ await clickByRole ( 'button' , 'Add host filter' )
183
+
184
+ // host is added to hosts table
185
+ screen . getByRole ( 'cell' , { name : 'edit-filter-instance' } )
186
+
187
+ // submit the form
188
+ await clickByRole ( 'button' , 'Update rule' )
189
+
190
+ // wait for modal to close
191
+ await waitForElementToBeRemoved (
192
+ ( ) => screen . queryByText ( 'Edit firewall rule' ) ,
193
+ // fails in CI without a longer timeout (default 1000). boo
194
+ { timeout : 2000 }
195
+ )
196
+
197
+ // table refetches and now includes the updated rule name, not the old name
198
+ await screen . findByText ( 'new-rule-name' )
199
+ expect ( screen . queryByRole ( 'cell' , { name : 'allow-icmp' } ) ) . toBeNull ( )
200
+ expect ( screen . getAllByRole ( 'row' ) . length ) . toEqual ( 5 ) // 4 + header
201
+
202
+ screen . getByRole ( 'cell' , {
203
+ name : 'instance edit-filter-instance ICMP' ,
204
+ } )
205
+
206
+ // other 3 rules are still there
207
+ const rest = defaultFirewallRules . filter ( ( r ) => r . name !== 'allow-icmp' )
208
+ for ( const { name } of rest ) {
209
+ screen . getByRole ( 'cell' , { name } )
210
+ }
211
+ } , 15000 )
119
212
} )
120
213
} )
0 commit comments