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