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
+ await clickByRole ( 'button' , 'Host type' )
89
+ await clickByRole ( 'option' , 'Instance' )
88
90
typeByRole ( 'textbox' , 'Value' , 'my-target-instance' )
89
- clickByRole ( 'button' , 'Add host filter' )
91
+ await clickByRole ( 'button' , 'Add host filter' )
90
92
91
93
// host is added to hosts table
92
94
screen . getByRole ( 'cell' , { name : 'my-target-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,88 @@ 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
+
118
+ // TODO: assert the target and host show up in the row
119
+
115
120
for ( const { name } of defaultFirewallRules ) {
116
121
screen . getByText ( name )
117
122
}
118
123
} , 10000 )
124
+
125
+ it ( 'edit works' , async ( ) => {
126
+ renderAppAt ( '/orgs/maze-war/projects/mock-project/vpcs/mock-vpc' )
127
+ await clickByRole ( 'tab' , 'Firewall Rules' )
128
+
129
+ // default rules show up in the table
130
+ for ( const { name } of defaultFirewallRules ) {
131
+ await screen . findByText ( name )
132
+ }
133
+ // the one we'll be adding is not there
134
+ expect ( screen . queryByRole ( 'cell' , { name : 'new-rule-name' } ) ) . toBeNull ( )
135
+
136
+ // modal is not already open
137
+ expect (
138
+ screen . queryByRole ( 'dialog' , { name : 'Edit firewall rule' } )
139
+ ) . toBeNull ( )
140
+
141
+ // click more button on allow-icmp row to get menu, then click Edit
142
+ const allowIcmpRow = screen . getByRole ( 'row' , { name : / a l l o w - i c m p / } )
143
+ const more = getByRole ( allowIcmpRow , 'button' , { name : 'More' } )
144
+ await userEvent . click ( more )
145
+ await clickByRole ( 'menuitem' , 'Edit' )
146
+
147
+ // now the modal is open
148
+ screen . getByRole ( 'dialog' , { name : 'Edit firewall rule' } )
149
+
150
+ // name is populated
151
+ const name = screen . getByRole ( 'textbox' , {
152
+ name : 'Name' ,
153
+ } ) as HTMLInputElement
154
+ expect ( name . value ) . toEqual ( 'allow-icmp' )
155
+
156
+ // priority is populated
157
+ const priority = screen . getByRole ( 'spinbutton' , {
158
+ name : 'Priority' ,
159
+ } ) as HTMLInputElement
160
+ expect ( priority . value ) . toEqual ( '65534' )
161
+
162
+ // protocol is populated
163
+ expect ( screen . getByRole ( 'checkbox' , { name : / I C M P / } ) ) . toBeChecked ( )
164
+ expect ( screen . getByRole ( 'checkbox' , { name : / T C P / } ) ) . not . toBeChecked ( )
165
+ expect ( screen . getByRole ( 'checkbox' , { name : / U D P / } ) ) . not . toBeChecked ( )
166
+
167
+ // targets default vpc
168
+ screen . getByRole ( 'cell' , { name : 'vpc' } )
169
+ screen . getByRole ( 'cell' , { name : 'default' } )
170
+
171
+ // update name
172
+ await userEvent . clear ( name )
173
+ await userEvent . type ( name , 'new-rule-name' )
174
+
175
+ // TODO: update more things in the form
176
+
177
+ // submit the form
178
+ await clickByRole ( 'button' , 'Update rule' )
179
+
180
+ // wait for modal to close
181
+ await waitForElementToBeRemoved (
182
+ ( ) => screen . queryByText ( 'Edit firewall rule' ) ,
183
+ // fails in CI without a longer timeout (default 1000). boo
184
+ { timeout : 2000 }
185
+ )
186
+
187
+ // table refetches and now includes the updated rule name, not the old name
188
+ await screen . findByText ( 'new-rule-name' )
189
+ expect ( screen . queryByRole ( 'cell' , { name : 'allow-icmp' } ) ) . toBeNull ( )
190
+
191
+ // TODO: assert other stuff is in the row
192
+ // const updatedRow = screen.getByRole('row', { name: /new-rule-name/ })
193
+
194
+ // other 3 rules are still there
195
+ const rest = defaultFirewallRules . filter ( ( r ) => r . name !== 'allow-icmp' )
196
+ for ( const { name } of rest ) {
197
+ screen . getByRole ( 'cell' , { name } )
198
+ }
199
+ } , 10000 )
119
200
} )
120
201
} )
0 commit comments