@spinnaker/google 2026.3.1 → 2026.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/autoscalingPolicy/GceAutoScalingFieldLayout.d.ts +2 -2
- package/dist/domain/loadBalancer.d.ts +6 -3
- package/dist/image/ImageSelect.d.ts +1 -1
- package/dist/index.js +159 -1
- package/dist/index.js.map +1 -1
- package/dist/loadBalancer/configure/common/gceLoadBalancerModels.d.ts +13 -2
- package/dist/loadBalancer/configure/http/GceHttpLoadBalancerEditor.d.ts +3 -0
- package/dist/loadBalancer/configure/http/GceHttpLoadBalancerModal.d.ts +1 -1
- package/dist/loadBalancer/configure/network/GceRegionalExternalNetworkLoadBalancerEditor.d.ts +30 -0
- package/dist/loadBalancer/configure/network/GceRegionalExternalNetworkLoadBalancerModal.d.ts +53 -0
- package/dist/loadBalancer/httpLoadBalancerUtils.service.d.ts +3 -1
- package/dist/serverGroup/configure/wizard/GceCloneServerGroupModal.d.ts +3 -0
- package/dist/serverGroup/configure/wizard/GceServerGroupWizard.types.d.ts +1 -0
- package/dist/serverGroup/configure/wizard/customInstance/CustomInstanceConfigurer.d.ts +1 -1
- package/dist/serverGroup/configure/wizard/customInstance/GceCustomInstanceBuilder.d.ts +2 -2
- package/dist/serverGroup/configure/wizard/pages/AdvancedSettings.d.ts +3 -0
- package/dist/serverGroup/configure/wizard/pages/GceServerGroupLoadBalancers.d.ts +1 -0
- package/dist/serverGroup/configure/wizard/pages/Policies.d.ts +21 -3
- package/dist/serverGroup/configure/wizard/pages/ServerGroupBasicSettings.d.ts +1 -0
- package/dist/serverGroup/configure/wizard/pages/ServerGroupCapacity.d.ts +1 -0
- package/dist/serverGroup/configure/wizard/pages/ServerGroupImageSettings.d.ts +1 -0
- package/dist/serverGroup/configure/wizard/pages/ServerGroupInstanceType.d.ts +1 -0
- package/dist/serverGroup/configure/wizard/zones/GceInstanceFlexibilityConfigurer.d.ts +2 -2
- package/dist/serverGroup/details/GceInstanceFlexibilityPolicyDetails.d.ts +2 -2
- package/dist/serverGroup/details/stateful/MarkDiskStatefulButton.d.ts +2 -2
- package/dist/serverGroup/details/stateful/UpdateBootImageButton.d.ts +2 -2
- package/package.json +5 -5
- package/src/autoHealingPolicy/GceAutoHealingPolicyEditor.spec.tsx +68 -52
- package/src/autoscalingPolicy/GceAutoscalingPolicyEditor.spec.tsx +43 -50
- package/src/autoscalingPolicy/GceAutoscalingPolicyEditor.tsx +1 -1
- package/src/autoscalingPolicy/GceAutoscalingPolicyWriter.spec.ts +1 -1
- package/src/domain/loadBalancer.ts +6 -3
- package/src/gce.module.spec.ts +132 -153
- package/src/instance/details/GceInstanceDetails.spec.tsx +86 -83
- package/src/loadBalancer/configure/choice/GceLoadBalancerChoiceModal.spec.tsx +162 -121
- package/src/loadBalancer/configure/choice/GceLoadBalancerChoiceModal.tsx +13 -1
- package/src/loadBalancer/configure/common/GceProxyLoadBalancerEditor.spec.tsx +47 -30
- package/src/loadBalancer/configure/common/GceProxyLoadBalancerEditor.tsx +2 -1
- package/src/loadBalancer/configure/common/GceProxyLoadBalancerModal.spec.tsx +85 -57
- package/src/loadBalancer/configure/common/gceLoadBalancerData.spec.ts +17 -16
- package/src/loadBalancer/configure/common/gceLoadBalancerModels.spec.ts +230 -5
- package/src/loadBalancer/configure/common/gceLoadBalancerModels.ts +186 -22
- package/src/loadBalancer/configure/common/gceLoadBalancerSubmission.spec.ts +298 -2
- package/src/loadBalancer/configure/common/gceLoadBalancerSubmission.ts +35 -5
- package/src/loadBalancer/configure/common/useGceLoadBalancerData.spec.tsx +37 -46
- package/src/loadBalancer/configure/http/GceHttpLoadBalancerEditor.spec.tsx +399 -58
- package/src/loadBalancer/configure/http/GceHttpLoadBalancerEditor.tsx +148 -41
- package/src/loadBalancer/configure/http/GceHttpLoadBalancerListenerEditor.spec.tsx +169 -36
- package/src/loadBalancer/configure/http/GceHttpLoadBalancerListenerEditor.tsx +80 -12
- package/src/loadBalancer/configure/http/GceHttpLoadBalancerModal.spec.tsx +224 -124
- package/src/loadBalancer/configure/http/GceHttpLoadBalancerModal.tsx +8 -2
- package/src/loadBalancer/configure/http/GceHttpLoadBalancerResourceEditors.spec.tsx +57 -22
- package/src/loadBalancer/configure/http/GceHttpLoadBalancerResourceEditors.tsx +21 -0
- package/src/loadBalancer/configure/http/GceHttpLoadBalancerRoutingEditor.spec.tsx +24 -20
- package/src/loadBalancer/configure/network/GceNetworkLoadBalancerEditor.spec.tsx +41 -32
- package/src/loadBalancer/configure/network/GceNetworkLoadBalancerModal.spec.tsx +35 -30
- package/src/loadBalancer/configure/network/GceRegionalExternalNetworkLoadBalancerEditor.spec.tsx +443 -0
- package/src/loadBalancer/configure/network/GceRegionalExternalNetworkLoadBalancerEditor.tsx +401 -0
- package/src/loadBalancer/configure/network/GceRegionalExternalNetworkLoadBalancerModal.spec.tsx +330 -0
- package/src/loadBalancer/configure/network/GceRegionalExternalNetworkLoadBalancerModal.tsx +348 -0
- package/src/loadBalancer/details/gceLoadBalancerDetails.spec.tsx +439 -35
- package/src/loadBalancer/details/gceLoadBalancerDetails.tsx +104 -21
- package/src/loadBalancer/httpLoadBalancerUtils.service.spec.ts +126 -0
- package/src/loadBalancer/httpLoadBalancerUtils.service.ts +27 -11
- package/src/loadBalancer/loadBalancer.setTransformer.spec.ts +165 -0
- package/src/loadBalancer/loadBalancer.setTransformer.ts +15 -2
- package/src/pipeline/stages/googleStageConfig.spec.js +22 -16
- package/src/securityGroup/configure/GceSecurityGroupModal.spec.tsx +177 -193
- package/src/securityGroup/configure/GceSecurityGroupModal.tsx +14 -2
- package/src/securityGroup/details/GceSecurityGroupDetails.spec.tsx +69 -78
- package/src/serverGroup/configure/serverGroupCommandBuilder.service.spec.js +35 -15
- package/src/serverGroup/configure/serverGroupConfiguration.service.js +7 -1
- package/src/serverGroup/configure/serverGroupConfiguration.service.spec.js +74 -4
- package/src/serverGroup/configure/wizard/GceCloneServerGroupModal.spec.tsx +593 -855
- package/src/serverGroup/configure/wizard/GceCloneServerGroupModal.tsx +120 -38
- package/src/serverGroup/configure/wizard/GceServerGroupWizard.types.ts +1 -0
- package/src/serverGroup/configure/wizard/GceServerGroupWizardPage.spec.tsx +53 -50
- package/src/serverGroup/configure/wizard/customInstance/GceCustomInstanceBuilder.spec.tsx +65 -49
- package/src/serverGroup/configure/wizard/hiddenMetadataKeys.value.js +1 -0
- package/src/serverGroup/configure/wizard/pages/AdvancedSettings.spec.tsx +101 -108
- package/src/serverGroup/configure/wizard/pages/AdvancedSettings.tsx +32 -28
- package/src/serverGroup/configure/wizard/pages/GceServerGroupFirewalls.spec.tsx +60 -59
- package/src/serverGroup/configure/wizard/pages/GceServerGroupLoadBalancers.spec.tsx +240 -114
- package/src/serverGroup/configure/wizard/pages/GceServerGroupLoadBalancers.tsx +152 -63
- package/src/serverGroup/configure/wizard/pages/Policies.spec.tsx +93 -48
- package/src/serverGroup/configure/wizard/pages/Policies.tsx +80 -55
- package/src/serverGroup/configure/wizard/pages/ServerGroupBasicSettings.spec.tsx +123 -94
- package/src/serverGroup/configure/wizard/pages/ServerGroupBasicSettings.tsx +24 -18
- package/src/serverGroup/configure/wizard/pages/ServerGroupCapacity.spec.tsx +152 -133
- package/src/serverGroup/configure/wizard/pages/ServerGroupCapacity.tsx +40 -37
- package/src/serverGroup/configure/wizard/pages/ServerGroupImageSettings.spec.tsx +66 -60
- package/src/serverGroup/configure/wizard/pages/ServerGroupImageSettings.tsx +8 -2
- package/src/serverGroup/configure/wizard/pages/ServerGroupInstanceType.spec.tsx +131 -101
- package/src/serverGroup/configure/wizard/pages/ServerGroupInstanceType.tsx +29 -28
- package/src/serverGroup/configure/wizard/zones/GceInstanceFlexibilityConfigurer.spec.tsx +104 -81
- package/src/serverGroup/details/GceInstanceFlexibilityPolicyDetails.spec.tsx +10 -11
- package/src/serverGroup/details/autoHealingPolicy/GceAutoHealingPolicyDetails.spec.tsx +51 -59
- package/src/serverGroup/details/autoHealingPolicy/modal/GceUpsertAutoHealingPolicyModal.spec.tsx +3 -3
- package/src/serverGroup/details/autoscalingPolicy/GceAutoscalingPolicyDetails.spec.tsx +49 -58
- package/src/serverGroup/details/autoscalingPolicy/modal/GceUpsertAutoscalingPolicyModal.spec.tsx +3 -3
- package/src/serverGroup/details/gceServerGroupDetails.spec.tsx +162 -141
- package/src/serverGroup/details/resize/GceResizeServerGroupModal.spec.tsx +102 -86
- package/src/serverGroup/details/resize/GceResizeServerGroupModal.tsx +4 -0
- package/src/serverGroup/details/rollback/GceRollbackServerGroupModal.spec.tsx +40 -31
- package/src/serverGroup/serverGroup.transformer.js +1 -0
- package/src/serverGroup/serverGroup.transformer.spec.js +48 -0
- package/src/validation/ApplicationNameValidator.spec.ts +1 -1
- /package/dist/{gce.logo2ae85d8704b1d6b8.png → gce.logoChI3w_A5.png} +0 -0
|
@@ -1,30 +1,35 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { fireEvent, render } from '@testing-library/react';
|
|
2
|
+
import type { RenderResult } from '@testing-library/react';
|
|
2
3
|
import type { FormikProps } from 'formik';
|
|
3
4
|
import React from 'react';
|
|
5
|
+
import type { Mocked } from 'vitest';
|
|
4
6
|
|
|
5
|
-
import { GceServerGroupLoadBalancers } from './GceServerGroupLoadBalancers';
|
|
7
|
+
import { GceServerGroupLoadBalancers, validateGceServerGroupLoadBalancers } from './GceServerGroupLoadBalancers';
|
|
6
8
|
import type { IGceServerGroupCommand, IGceServerGroupWizardAdapter } from '../GceServerGroupWizard.types';
|
|
7
9
|
|
|
8
10
|
describe('GCE server group Load Balancers page', () => {
|
|
9
11
|
it('shows only account and region scoped load balancers without duplicate references', () => {
|
|
10
12
|
const values = command({ loadBalancers: ['regional-lb', 'persisted-lb', 'persisted-lb'] });
|
|
11
13
|
const { formik } = testProps(values);
|
|
12
|
-
const wrapper =
|
|
14
|
+
const wrapper = renderPage(<GceServerGroupLoadBalancers app={{} as any} formik={formik} />);
|
|
13
15
|
|
|
14
16
|
expect(selectOptions(wrapper)).toEqual([
|
|
15
17
|
['global-lb', 'global-lb'],
|
|
16
18
|
['regional-lb', 'regional-lb'],
|
|
17
19
|
['persisted-lb', 'persisted-lb (unavailable)'],
|
|
18
20
|
]);
|
|
19
|
-
expect(wrapper.
|
|
20
|
-
|
|
21
|
+
expect(wrapper.getByText('Load Balancers', { selector: 'label' })).toHaveAttribute(
|
|
22
|
+
'for',
|
|
23
|
+
'gce-server-group-load-balancers',
|
|
24
|
+
);
|
|
25
|
+
expect(selectedValues(wrapper.getByLabelText('Load balancers'))).toEqual(['regional-lb', 'persisted-lb']);
|
|
21
26
|
});
|
|
22
27
|
|
|
23
28
|
it('does not fall back to stale filtered load balancers when raw data has no scoped matches', () => {
|
|
24
29
|
const values = command({ credentials: 'account-c' });
|
|
25
30
|
values.backingData.filtered.loadBalancers = ['stale-lb'];
|
|
26
31
|
const { formik } = testProps(values);
|
|
27
|
-
const wrapper =
|
|
32
|
+
const wrapper = renderPage(<GceServerGroupLoadBalancers app={{} as any} formik={formik} />);
|
|
28
33
|
|
|
29
34
|
expect(selectOptions(wrapper)).toEqual([]);
|
|
30
35
|
});
|
|
@@ -32,22 +37,20 @@ describe('GCE server group Load Balancers page', () => {
|
|
|
32
37
|
it('runs load-balancer configuration and preserves selected unavailable references', async () => {
|
|
33
38
|
const values = command({ loadBalancers: ['persisted-lb'] });
|
|
34
39
|
const { adapter, formik } = testProps(values);
|
|
35
|
-
adapter.applyConfigurationUpdate.
|
|
40
|
+
adapter.applyConfigurationUpdate.mockImplementation(async (nextCommand) => ({
|
|
36
41
|
command: { ...nextCommand, loadBalancers: ['regional-lb'], backendServices: { 'regional-lb': ['backend'] } },
|
|
37
42
|
result: { dirty: { loadBalancers: ['persisted-lb'] } },
|
|
38
43
|
}));
|
|
39
|
-
const wrapper =
|
|
44
|
+
const wrapper = renderPage(<GceServerGroupLoadBalancers app={{} as any} formik={formik} adapter={adapter} />);
|
|
40
45
|
|
|
41
|
-
wrapper.
|
|
42
|
-
target: { selectedOptions: [{ value: 'regional-lb' }, { value: 'persisted-lb' }, { value: 'regional-lb' }] },
|
|
43
|
-
});
|
|
46
|
+
changeMultiSelect(wrapper.getByLabelText('Load balancers'), ['regional-lb', 'persisted-lb']);
|
|
44
47
|
await flush();
|
|
45
48
|
|
|
46
|
-
const changedCommand = adapter.applyConfigurationUpdate.
|
|
49
|
+
const changedCommand = adapter.applyConfigurationUpdate.mock.lastCall[0];
|
|
47
50
|
expect(changedCommand.loadBalancers).toEqual(['regional-lb']);
|
|
48
51
|
expect(adapter.applyConfigurationUpdate).toHaveBeenCalledWith(changedCommand, 'configureLoadBalancerOptions');
|
|
49
52
|
expect(formik.setValues).toHaveBeenCalledWith(
|
|
50
|
-
|
|
53
|
+
expect.objectContaining({
|
|
51
54
|
backendServices: { 'regional-lb': ['backend'] },
|
|
52
55
|
loadBalancers: ['regional-lb', 'persisted-lb'],
|
|
53
56
|
}),
|
|
@@ -57,25 +60,23 @@ describe('GCE server group Load Balancers page', () => {
|
|
|
57
60
|
it('initializes the backend-compatible default policy when selecting the first supported load balancer', async () => {
|
|
58
61
|
const values = command();
|
|
59
62
|
const { adapter, formik } = testProps(values);
|
|
60
|
-
adapter.applyConfigurationUpdate.
|
|
63
|
+
adapter.applyConfigurationUpdate.mockImplementation(async (nextCommand) => ({
|
|
61
64
|
command: { ...nextCommand, loadBalancingPolicy: undefined },
|
|
62
65
|
result: { dirty: {} },
|
|
63
66
|
}));
|
|
64
|
-
const wrapper =
|
|
67
|
+
const wrapper = renderPage(<GceServerGroupLoadBalancers app={{} as any} formik={formik} adapter={adapter} />);
|
|
65
68
|
|
|
66
|
-
wrapper.
|
|
67
|
-
target: { selectedOptions: [{ value: 'regional-lb' }] },
|
|
68
|
-
});
|
|
69
|
+
changeMultiSelect(wrapper.getByLabelText('Load balancers'), ['regional-lb']);
|
|
69
70
|
await flush();
|
|
70
71
|
|
|
71
|
-
expect(adapter.applyConfigurationUpdate.
|
|
72
|
+
expect(adapter.applyConfigurationUpdate.mock.lastCall[0].loadBalancingPolicy).toEqual({
|
|
72
73
|
balancingMode: 'UTILIZATION',
|
|
73
74
|
capacityScaler: 1,
|
|
74
75
|
maxUtilization: 0.8,
|
|
75
76
|
namedPorts: [{ name: 'http', port: 80 }],
|
|
76
77
|
});
|
|
77
78
|
expect(formik.setValues).toHaveBeenCalledWith(
|
|
78
|
-
|
|
79
|
+
expect.objectContaining({
|
|
79
80
|
loadBalancingPolicy: {
|
|
80
81
|
balancingMode: 'UTILIZATION',
|
|
81
82
|
capacityScaler: 1,
|
|
@@ -89,7 +90,7 @@ describe('GCE server group Load Balancers page', () => {
|
|
|
89
90
|
it('refreshes backing data while preserving selected load balancers', async () => {
|
|
90
91
|
const values = command({ loadBalancers: ['persisted-lb'] });
|
|
91
92
|
const { adapter, formik } = testProps(values);
|
|
92
|
-
adapter.applyConfigurationRefresh.
|
|
93
|
+
adapter.applyConfigurationRefresh.mockResolvedValue({
|
|
93
94
|
command: {
|
|
94
95
|
...values,
|
|
95
96
|
backingData: { ...values.backingData, refreshed: true },
|
|
@@ -97,15 +98,15 @@ describe('GCE server group Load Balancers page', () => {
|
|
|
97
98
|
},
|
|
98
99
|
result: { dirty: {} },
|
|
99
100
|
});
|
|
100
|
-
const wrapper =
|
|
101
|
+
const wrapper = renderPage(<GceServerGroupLoadBalancers app={{} as any} formik={formik} adapter={adapter} />);
|
|
101
102
|
|
|
102
|
-
wrapper.
|
|
103
|
+
fireEvent.click(wrapper.getByRole('button', { name: 'Refresh load balancers' }));
|
|
103
104
|
await flush();
|
|
104
105
|
|
|
105
106
|
expect(adapter.applyConfigurationRefresh).toHaveBeenCalledWith(values, 'refreshLoadBalancers');
|
|
106
107
|
expect(formik.setValues).toHaveBeenCalledWith(
|
|
107
|
-
|
|
108
|
-
backingData:
|
|
108
|
+
expect.objectContaining({
|
|
109
|
+
backingData: expect.objectContaining({ refreshed: true }),
|
|
109
110
|
loadBalancers: ['persisted-lb'],
|
|
110
111
|
}),
|
|
111
112
|
);
|
|
@@ -126,7 +127,7 @@ describe('GCE server group Load Balancers page', () => {
|
|
|
126
127
|
},
|
|
127
128
|
});
|
|
128
129
|
const { formik } = testProps(values);
|
|
129
|
-
const wrapper =
|
|
130
|
+
const wrapper = renderPage(<GceServerGroupLoadBalancers app={{} as any} formik={formik} />);
|
|
130
131
|
|
|
131
132
|
expect(selectOptions(wrapper, 'Backend services for regional-lb')).toEqual([
|
|
132
133
|
['backend-a', 'backend-a'],
|
|
@@ -146,8 +147,8 @@ describe('GCE server group Load Balancers page', () => {
|
|
|
146
147
|
['RATE', 'RATE'],
|
|
147
148
|
['UTILIZATION', 'UTILIZATION'],
|
|
148
149
|
]);
|
|
149
|
-
expect(wrapper.
|
|
150
|
-
expect(wrapper.
|
|
150
|
+
expect(wrapper.getByLabelText('Capacity scaler')).toHaveValue(80);
|
|
151
|
+
expect(wrapper.getByLabelText('Max rate per instance')).toHaveValue(50);
|
|
151
152
|
});
|
|
152
153
|
|
|
153
154
|
it('round-trips load-balancer metadata without dropping unavailable or unrelated references', async () => {
|
|
@@ -159,24 +160,22 @@ describe('GCE server group Load Balancers page', () => {
|
|
|
159
160
|
},
|
|
160
161
|
});
|
|
161
162
|
const { adapter, formik } = testProps(values);
|
|
162
|
-
adapter.applyConfigurationUpdate.
|
|
163
|
+
adapter.applyConfigurationUpdate.mockImplementation(async (nextCommand) => ({
|
|
163
164
|
command: { ...nextCommand, loadBalancers: ['global-lb'], loadBalancerMetadata: {} },
|
|
164
165
|
result: { dirty: { loadBalancers: ['persisted-lb'] } },
|
|
165
166
|
}));
|
|
166
|
-
const wrapper =
|
|
167
|
+
const wrapper = renderPage(<GceServerGroupLoadBalancers app={{} as any} formik={formik} adapter={adapter} />);
|
|
167
168
|
|
|
168
|
-
wrapper.
|
|
169
|
-
target: { selectedOptions: [{ value: 'global-lb' }, { value: 'persisted-lb' }] },
|
|
170
|
-
});
|
|
169
|
+
changeMultiSelect(wrapper.getByLabelText('Load balancers'), ['global-lb', 'persisted-lb']);
|
|
171
170
|
await flush();
|
|
172
171
|
|
|
173
|
-
const changedCommand = adapter.applyConfigurationUpdate.
|
|
172
|
+
const changedCommand = adapter.applyConfigurationUpdate.mock.lastCall[0];
|
|
174
173
|
expect(changedCommand.loadBalancerMetadata).toEqual({
|
|
175
174
|
'global-load-balancer-names': ['persisted-listener', 'global-lb'],
|
|
176
175
|
'load-balancer-names': ['unrelated-regional-listener'],
|
|
177
176
|
});
|
|
178
177
|
expect(formik.setValues).toHaveBeenCalledWith(
|
|
179
|
-
|
|
178
|
+
expect.objectContaining({
|
|
180
179
|
loadBalancers: ['global-lb', 'persisted-lb'],
|
|
181
180
|
loadBalancerMetadata: {
|
|
182
181
|
'global-load-balancer-names': ['persisted-listener', 'global-lb'],
|
|
@@ -197,7 +196,7 @@ describe('GCE server group Load Balancers page', () => {
|
|
|
197
196
|
backendServiceMetadata: ['old-backend', 'persisted-backend', 'other-backend'],
|
|
198
197
|
});
|
|
199
198
|
const { adapter, formik } = testProps(values);
|
|
200
|
-
adapter.applyConfigurationUpdate.
|
|
199
|
+
adapter.applyConfigurationUpdate.mockImplementation(async (nextCommand) => ({
|
|
201
200
|
command: {
|
|
202
201
|
...nextCommand,
|
|
203
202
|
backendServices: { 'global-lb': ['configured-backend'] },
|
|
@@ -205,16 +204,14 @@ describe('GCE server group Load Balancers page', () => {
|
|
|
205
204
|
},
|
|
206
205
|
result: { dirty: {} },
|
|
207
206
|
}));
|
|
208
|
-
const wrapper =
|
|
207
|
+
const wrapper = renderPage(<GceServerGroupLoadBalancers app={{} as any} formik={formik} adapter={adapter} />);
|
|
209
208
|
|
|
210
|
-
wrapper.
|
|
211
|
-
target: { selectedOptions: [{ value: 'global-lb' }, { value: 'persisted-lb' }] },
|
|
212
|
-
});
|
|
209
|
+
changeMultiSelect(wrapper.getByLabelText('Load balancers'), ['global-lb', 'persisted-lb']);
|
|
213
210
|
await flush();
|
|
214
211
|
|
|
215
|
-
expect(adapter.applyConfigurationUpdate.
|
|
212
|
+
expect(adapter.applyConfigurationUpdate.mock.lastCall[0].loadBalancers).toEqual(['global-lb']);
|
|
216
213
|
expect(formik.setValues).toHaveBeenCalledWith(
|
|
217
|
-
|
|
214
|
+
expect.objectContaining({
|
|
218
215
|
loadBalancers: ['global-lb', 'persisted-lb'],
|
|
219
216
|
backendServices: {
|
|
220
217
|
'persisted-lb': ['persisted-backend'],
|
|
@@ -236,7 +233,7 @@ describe('GCE server group Load Balancers page', () => {
|
|
|
236
233
|
backendServiceMetadata: ['backend-a', 'persisted-backend', 'other-backend'],
|
|
237
234
|
});
|
|
238
235
|
const { adapter, formik } = testProps(values);
|
|
239
|
-
adapter.applyConfigurationUpdate.
|
|
236
|
+
adapter.applyConfigurationUpdate.mockImplementation(async (nextCommand) => ({
|
|
240
237
|
command: {
|
|
241
238
|
...nextCommand,
|
|
242
239
|
backendServices: { 'regional-lb': ['backend-b'] },
|
|
@@ -244,21 +241,19 @@ describe('GCE server group Load Balancers page', () => {
|
|
|
244
241
|
},
|
|
245
242
|
result: { dirty: {} },
|
|
246
243
|
}));
|
|
247
|
-
const wrapper =
|
|
244
|
+
const wrapper = renderPage(<GceServerGroupLoadBalancers app={{} as any} formik={formik} adapter={adapter} />);
|
|
248
245
|
|
|
249
|
-
wrapper.
|
|
250
|
-
target: { selectedOptions: [{ value: 'backend-b' }, { value: 'persisted-backend' }] },
|
|
251
|
-
});
|
|
246
|
+
changeMultiSelect(wrapper.getByLabelText('Backend services for regional-lb'), ['backend-b', 'persisted-backend']);
|
|
252
247
|
await flush();
|
|
253
248
|
|
|
254
|
-
const changedCommand = adapter.applyConfigurationUpdate.
|
|
249
|
+
const changedCommand = adapter.applyConfigurationUpdate.mock.lastCall[0];
|
|
255
250
|
expect(changedCommand.backendServices).toEqual({
|
|
256
251
|
'regional-lb': ['backend-b', 'persisted-backend'],
|
|
257
252
|
'other-lb': ['other-backend'],
|
|
258
253
|
});
|
|
259
254
|
expect(changedCommand.backendServiceMetadata).toEqual(['backend-b', 'persisted-backend', 'other-backend']);
|
|
260
255
|
expect(formik.setValues).toHaveBeenCalledWith(
|
|
261
|
-
|
|
256
|
+
expect.objectContaining({
|
|
262
257
|
backendServices: {
|
|
263
258
|
'regional-lb': ['backend-b', 'persisted-backend'],
|
|
264
259
|
'other-lb': ['other-backend'],
|
|
@@ -281,12 +276,12 @@ describe('GCE server group Load Balancers page', () => {
|
|
|
281
276
|
},
|
|
282
277
|
});
|
|
283
278
|
const { adapter, formik } = testProps(values);
|
|
284
|
-
const wrapper =
|
|
279
|
+
const wrapper = renderPage(<GceServerGroupLoadBalancers app={{} as any} formik={formik} adapter={adapter} />);
|
|
285
280
|
|
|
286
|
-
wrapper.
|
|
281
|
+
fireEvent.change(wrapper.getByLabelText('Balancing mode'), { target: { value: 'UTILIZATION' } });
|
|
287
282
|
await flush();
|
|
288
283
|
|
|
289
|
-
const changedCommand = adapter.applyConfigurationUpdate.
|
|
284
|
+
const changedCommand = adapter.applyConfigurationUpdate.mock.lastCall[0];
|
|
290
285
|
expect(changedCommand.loadBalancingPolicy).toEqual({
|
|
291
286
|
balancingMode: 'UTILIZATION',
|
|
292
287
|
capacityScaler: 1,
|
|
@@ -294,7 +289,7 @@ describe('GCE server group Load Balancers page', () => {
|
|
|
294
289
|
unknownField: 'keep',
|
|
295
290
|
});
|
|
296
291
|
expect(adapter.applyConfigurationUpdate).toHaveBeenCalledWith(changedCommand, 'configureLoadBalancerOptions');
|
|
297
|
-
expect(formik.setValues).toHaveBeenCalledWith(
|
|
292
|
+
expect(formik.setValues).toHaveBeenCalledWith(expect.objectContaining(changedCommand));
|
|
298
293
|
});
|
|
299
294
|
|
|
300
295
|
it('derives balancing modes from selected load-balancer types and renders the active limit', () => {
|
|
@@ -307,14 +302,14 @@ describe('GCE server group Load Balancers page', () => {
|
|
|
307
302
|
namedPorts: [],
|
|
308
303
|
},
|
|
309
304
|
});
|
|
310
|
-
const connectionWrapper =
|
|
305
|
+
const connectionWrapper = renderPage(
|
|
311
306
|
<GceServerGroupLoadBalancers app={{} as any} formik={testProps(connectionValues).formik} />,
|
|
312
307
|
);
|
|
313
308
|
expect(selectOptions(connectionWrapper, 'Balancing mode')).toEqual([
|
|
314
309
|
['CONNECTION', 'CONNECTION'],
|
|
315
310
|
['UTILIZATION', 'UTILIZATION'],
|
|
316
311
|
]);
|
|
317
|
-
expect(connectionWrapper.
|
|
312
|
+
expect(connectionWrapper.getByLabelText('Max connections per instance')).toHaveValue(25);
|
|
318
313
|
|
|
319
314
|
const mixedValues = command({
|
|
320
315
|
loadBalancers: ['regional-lb', 'global-lb'],
|
|
@@ -325,11 +320,11 @@ describe('GCE server group Load Balancers page', () => {
|
|
|
325
320
|
namedPorts: [],
|
|
326
321
|
},
|
|
327
322
|
});
|
|
328
|
-
const mixedWrapper =
|
|
323
|
+
const mixedWrapper = renderPage(
|
|
329
324
|
<GceServerGroupLoadBalancers app={{} as any} formik={testProps(mixedValues).formik} />,
|
|
330
325
|
);
|
|
331
326
|
expect(selectOptions(mixedWrapper, 'Balancing mode')).toEqual([['UTILIZATION', 'UTILIZATION']]);
|
|
332
|
-
expect(mixedWrapper.
|
|
327
|
+
expect(mixedWrapper.getByLabelText('Max utilization')).toHaveValue(70);
|
|
333
328
|
});
|
|
334
329
|
|
|
335
330
|
it('round-trips named-port and percentage edits and supports adding and removing mappings', async () => {
|
|
@@ -343,51 +338,47 @@ describe('GCE server group Load Balancers page', () => {
|
|
|
343
338
|
},
|
|
344
339
|
});
|
|
345
340
|
const nameProps = testProps(values);
|
|
346
|
-
const nameWrapper =
|
|
341
|
+
const nameWrapper = renderPage(
|
|
347
342
|
<GceServerGroupLoadBalancers app={{} as any} formik={nameProps.formik} adapter={nameProps.adapter} />,
|
|
348
343
|
);
|
|
349
|
-
nameWrapper.
|
|
344
|
+
fireEvent.change(nameWrapper.getByLabelText('Named port name 1'), { target: { value: 'metrics' } });
|
|
350
345
|
await flush();
|
|
351
|
-
expect(
|
|
352
|
-
|
|
353
|
-
|
|
346
|
+
expect(nameProps.adapter.applyConfigurationUpdate.mock.lastCall[0].loadBalancingPolicy.namedPorts).toEqual([
|
|
347
|
+
{ name: 'metrics', port: 8080 },
|
|
348
|
+
]);
|
|
354
349
|
|
|
355
350
|
const capacityProps = testProps(values);
|
|
356
|
-
const capacityWrapper =
|
|
351
|
+
const capacityWrapper = renderPage(
|
|
357
352
|
<GceServerGroupLoadBalancers app={{} as any} formik={capacityProps.formik} adapter={capacityProps.adapter} />,
|
|
358
353
|
);
|
|
359
|
-
capacityWrapper.
|
|
354
|
+
fireEvent.change(capacityWrapper.getByLabelText('Capacity scaler'), { target: { value: '75' } });
|
|
360
355
|
await flush();
|
|
361
|
-
expect(
|
|
362
|
-
|
|
363
|
-
)
|
|
356
|
+
expect(capacityProps.adapter.applyConfigurationUpdate.mock.lastCall[0].loadBalancingPolicy.capacityScaler).toBe(
|
|
357
|
+
0.75,
|
|
358
|
+
);
|
|
364
359
|
|
|
365
360
|
const addProps = testProps(values);
|
|
366
|
-
const addWrapper =
|
|
361
|
+
const addWrapper = renderPage(
|
|
367
362
|
<GceServerGroupLoadBalancers app={{} as any} formik={addProps.formik} adapter={addProps.adapter} />,
|
|
368
363
|
);
|
|
369
|
-
addWrapper.
|
|
364
|
+
fireEvent.click(addWrapper.getByRole('button', { name: 'Add named port' }));
|
|
370
365
|
await flush();
|
|
371
|
-
expect(addProps.adapter.applyConfigurationUpdate.
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
],
|
|
376
|
-
);
|
|
366
|
+
expect(addProps.adapter.applyConfigurationUpdate.mock.lastCall[0].loadBalancingPolicy.namedPorts).toEqual([
|
|
367
|
+
{ name: 'http', port: 8080 },
|
|
368
|
+
{ name: '', port: 80 },
|
|
369
|
+
]);
|
|
377
370
|
|
|
378
371
|
const removeProps = testProps(values);
|
|
379
|
-
const removeWrapper =
|
|
372
|
+
const removeWrapper = renderPage(
|
|
380
373
|
<GceServerGroupLoadBalancers app={{} as any} formik={removeProps.formik} adapter={removeProps.adapter} />,
|
|
381
374
|
);
|
|
382
|
-
removeWrapper.
|
|
375
|
+
fireEvent.click(removeWrapper.getByRole('button', { name: 'Remove named port 1' }));
|
|
383
376
|
await flush();
|
|
384
|
-
expect(
|
|
385
|
-
removeProps.adapter.applyConfigurationUpdate.calls.mostRecent().args[0].loadBalancingPolicy.namedPorts,
|
|
386
|
-
).toEqual([]);
|
|
377
|
+
expect(removeProps.adapter.applyConfigurationUpdate.mock.lastCall[0].loadBalancingPolicy.namedPorts).toEqual([]);
|
|
387
378
|
});
|
|
388
379
|
|
|
389
380
|
it('renders policy validation errors and associates them with the invalid controls', () => {
|
|
390
|
-
const rateWrapper =
|
|
381
|
+
const rateWrapper = renderPage(
|
|
391
382
|
<GceServerGroupLoadBalancers
|
|
392
383
|
app={{} as any}
|
|
393
384
|
formik={
|
|
@@ -426,7 +417,7 @@ describe('GCE server group Load Balancers page', () => {
|
|
|
426
417
|
'Max rate must be',
|
|
427
418
|
);
|
|
428
419
|
|
|
429
|
-
const modeWrapper =
|
|
420
|
+
const modeWrapper = renderPage(
|
|
430
421
|
<GceServerGroupLoadBalancers
|
|
431
422
|
app={{} as any}
|
|
432
423
|
formik={
|
|
@@ -441,7 +432,7 @@ describe('GCE server group Load Balancers page', () => {
|
|
|
441
432
|
);
|
|
442
433
|
expectPolicyError(modeWrapper, 'select[aria-label="Balancing mode"]', 'balancing-mode', 'Select a balancing mode');
|
|
443
434
|
|
|
444
|
-
const connectionWrapper =
|
|
435
|
+
const connectionWrapper = renderPage(
|
|
445
436
|
<GceServerGroupLoadBalancers
|
|
446
437
|
app={{} as any}
|
|
447
438
|
formik={
|
|
@@ -466,7 +457,7 @@ describe('GCE server group Load Balancers page', () => {
|
|
|
466
457
|
'Max connections must be',
|
|
467
458
|
);
|
|
468
459
|
|
|
469
|
-
const utilizationWrapper =
|
|
460
|
+
const utilizationWrapper = renderPage(
|
|
470
461
|
<GceServerGroupLoadBalancers
|
|
471
462
|
app={{} as any}
|
|
472
463
|
formik={
|
|
@@ -503,11 +494,7 @@ describe('GCE server group Load Balancers page', () => {
|
|
|
503
494
|
},
|
|
504
495
|
});
|
|
505
496
|
const { formik } = testProps(invalid);
|
|
506
|
-
|
|
507
|
-
<GceServerGroupLoadBalancers app={{} as any} formik={formik} />,
|
|
508
|
-
).instance() as GceServerGroupLoadBalancers;
|
|
509
|
-
|
|
510
|
-
expect(page.validate(invalid)).toEqual({
|
|
497
|
+
expect(validateGceServerGroupLoadBalancers(invalid)).toEqual({
|
|
511
498
|
loadBalancingPolicy: {
|
|
512
499
|
capacityScaler: 'Capacity must be between 0 and 100%.',
|
|
513
500
|
maxRatePerInstance: 'Max rate must be a finite number greater than or equal to zero.',
|
|
@@ -525,8 +512,8 @@ describe('GCE server group Load Balancers page', () => {
|
|
|
525
512
|
namedPorts: [{ name: 'http', port: '${ parameters.port }' }],
|
|
526
513
|
},
|
|
527
514
|
});
|
|
528
|
-
expect(
|
|
529
|
-
expect(
|
|
515
|
+
expect(validateGceServerGroupLoadBalancers(pipeline)).toEqual({});
|
|
516
|
+
expect(validateGceServerGroupLoadBalancers({ ...pipeline, viewState: { mode: 'create', dirty: {} } })).toEqual({
|
|
530
517
|
loadBalancingPolicy: {
|
|
531
518
|
capacityScaler: 'Capacity must be between 0 and 100%.',
|
|
532
519
|
maxRatePerInstance: 'Max rate must be a finite number greater than or equal to zero.',
|
|
@@ -543,47 +530,181 @@ describe('GCE server group Load Balancers page', () => {
|
|
|
543
530
|
namedPorts: [],
|
|
544
531
|
},
|
|
545
532
|
});
|
|
546
|
-
expect(
|
|
533
|
+
expect(validateGceServerGroupLoadBalancers(blank)).toEqual({
|
|
547
534
|
loadBalancingPolicy: {
|
|
548
535
|
capacityScaler: 'Capacity must be between 0 and 100%.',
|
|
549
536
|
maxRatePerInstance: 'Max rate must be a finite number greater than or equal to zero.',
|
|
550
537
|
},
|
|
551
538
|
});
|
|
552
539
|
});
|
|
540
|
+
|
|
541
|
+
it('rejects ambiguous cross-scope names and mixed passthrough attachments', () => {
|
|
542
|
+
const ambiguous = command({
|
|
543
|
+
loadBalancers: ['shared-name'],
|
|
544
|
+
backingData: {
|
|
545
|
+
...command().backingData,
|
|
546
|
+
loadBalancers: [
|
|
547
|
+
{
|
|
548
|
+
accounts: [
|
|
549
|
+
{
|
|
550
|
+
name: 'account-a',
|
|
551
|
+
regions: [
|
|
552
|
+
{
|
|
553
|
+
loadBalancers: [
|
|
554
|
+
{ loadBalancerType: 'TCP', name: 'shared-name', region: 'global' },
|
|
555
|
+
{
|
|
556
|
+
loadBalancerType: 'REGIONAL_EXTERNAL_NETWORK',
|
|
557
|
+
name: 'shared-name',
|
|
558
|
+
region: 'us-central1',
|
|
559
|
+
},
|
|
560
|
+
],
|
|
561
|
+
},
|
|
562
|
+
],
|
|
563
|
+
},
|
|
564
|
+
],
|
|
565
|
+
},
|
|
566
|
+
],
|
|
567
|
+
},
|
|
568
|
+
});
|
|
569
|
+
const ambiguousMessage =
|
|
570
|
+
'The selected load balancer name is ambiguous across regions or load balancer types. Rename it or select an unambiguous load balancer.';
|
|
571
|
+
expect(validateGceServerGroupLoadBalancers(ambiguous).loadBalancers).toBe(ambiguousMessage);
|
|
572
|
+
const ambiguousWrapper = renderPage(
|
|
573
|
+
<GceServerGroupLoadBalancers app={{} as any} formik={testProps(ambiguous).formik} />,
|
|
574
|
+
);
|
|
575
|
+
expect(ambiguousWrapper.getByRole('alert')).toHaveTextContent(ambiguousMessage);
|
|
576
|
+
ambiguousWrapper.unmount();
|
|
577
|
+
|
|
578
|
+
const mixedPassthrough = command({
|
|
579
|
+
loadBalancers: ['regional-network', 'regional-lb'],
|
|
580
|
+
backingData: {
|
|
581
|
+
...command().backingData,
|
|
582
|
+
filtered: {
|
|
583
|
+
loadBalancerIndex: {
|
|
584
|
+
'regional-lb': command().backingData.filtered.loadBalancerIndex['regional-lb'],
|
|
585
|
+
'regional-network': {
|
|
586
|
+
loadBalancerType: 'REGIONAL_EXTERNAL_NETWORK',
|
|
587
|
+
name: 'regional-network',
|
|
588
|
+
},
|
|
589
|
+
},
|
|
590
|
+
},
|
|
591
|
+
},
|
|
592
|
+
});
|
|
593
|
+
const mixedMessage =
|
|
594
|
+
'REGIONAL_EXTERNAL_NETWORK load balancers cannot be combined with other load balancer families in this editor.';
|
|
595
|
+
expect(validateGceServerGroupLoadBalancers(mixedPassthrough).loadBalancers).toBe(mixedMessage);
|
|
596
|
+
const mixedWrapper = renderPage(
|
|
597
|
+
<GceServerGroupLoadBalancers app={{} as any} formik={testProps(mixedPassthrough).formik} />,
|
|
598
|
+
);
|
|
599
|
+
expect(
|
|
600
|
+
mixedWrapper.container.querySelector('#gce-server-group-load-balancers-error[role="alert"]'),
|
|
601
|
+
).toHaveTextContent(mixedMessage);
|
|
602
|
+
});
|
|
603
|
+
|
|
604
|
+
it('treats EXTERNAL_MANAGED as HTTP and REGIONAL_EXTERNAL_NETWORK as policy-free', () => {
|
|
605
|
+
const externalManaged = command({
|
|
606
|
+
loadBalancers: ['external-managed'],
|
|
607
|
+
loadBalancingPolicy: {
|
|
608
|
+
balancingMode: 'RATE',
|
|
609
|
+
capacityScaler: 1,
|
|
610
|
+
maxRatePerInstance: 50,
|
|
611
|
+
namedPorts: [{ name: 'http', port: 80 }],
|
|
612
|
+
},
|
|
613
|
+
backingData: {
|
|
614
|
+
...command().backingData,
|
|
615
|
+
filtered: {
|
|
616
|
+
loadBalancerIndex: {
|
|
617
|
+
'external-managed': {
|
|
618
|
+
backendServices: [{ name: 'backend-a', portName: 'http' }],
|
|
619
|
+
listeners: [{ name: 'frontend' }],
|
|
620
|
+
loadBalancerType: 'EXTERNAL_MANAGED',
|
|
621
|
+
name: 'external-managed',
|
|
622
|
+
},
|
|
623
|
+
},
|
|
624
|
+
},
|
|
625
|
+
},
|
|
626
|
+
});
|
|
627
|
+
const externalWrapper = renderPage(
|
|
628
|
+
<GceServerGroupLoadBalancers app={{} as any} formik={testProps(externalManaged).formik} />,
|
|
629
|
+
);
|
|
630
|
+
expect(selectOptions(externalWrapper, 'Balancing mode')).toEqual([
|
|
631
|
+
['RATE', 'RATE'],
|
|
632
|
+
['UTILIZATION', 'UTILIZATION'],
|
|
633
|
+
]);
|
|
634
|
+
externalWrapper.unmount();
|
|
635
|
+
|
|
636
|
+
const passthrough = command({
|
|
637
|
+
loadBalancers: ['regional-network'],
|
|
638
|
+
loadBalancingPolicy: {
|
|
639
|
+
balancingMode: 'UTILIZATION',
|
|
640
|
+
capacityScaler: 1,
|
|
641
|
+
maxUtilization: 0.8,
|
|
642
|
+
namedPorts: [{ name: 'http', port: 80 }],
|
|
643
|
+
},
|
|
644
|
+
backingData: {
|
|
645
|
+
...command().backingData,
|
|
646
|
+
filtered: {
|
|
647
|
+
loadBalancerIndex: {
|
|
648
|
+
'regional-network': {
|
|
649
|
+
backendServices: ['backend-a'],
|
|
650
|
+
loadBalancerType: 'REGIONAL_EXTERNAL_NETWORK',
|
|
651
|
+
name: 'regional-network',
|
|
652
|
+
},
|
|
653
|
+
},
|
|
654
|
+
},
|
|
655
|
+
},
|
|
656
|
+
});
|
|
657
|
+
const passthroughWrapper = renderPage(
|
|
658
|
+
<GceServerGroupLoadBalancers app={{} as any} formik={testProps(passthrough).formik} />,
|
|
659
|
+
);
|
|
660
|
+
expect(passthroughWrapper.queryByLabelText('Balancing mode')).not.toBeInTheDocument();
|
|
661
|
+
expect(passthroughWrapper.queryByLabelText('Backend services for regional-network')).not.toBeInTheDocument();
|
|
662
|
+
expect(passthroughWrapper.queryByRole('alert')).not.toBeInTheDocument();
|
|
663
|
+
expect(validateGceServerGroupLoadBalancers(passthrough)).toEqual({});
|
|
664
|
+
});
|
|
553
665
|
});
|
|
554
666
|
|
|
555
|
-
function selectOptions(wrapper:
|
|
556
|
-
return wrapper
|
|
557
|
-
.
|
|
558
|
-
.
|
|
667
|
+
function selectOptions(wrapper: RenderResult, ariaLabel = 'Load balancers'): string[][] {
|
|
668
|
+
return Array.from(wrapper.getByLabelText(ariaLabel).querySelectorAll('option')).map((option) => [
|
|
669
|
+
option.value,
|
|
670
|
+
option.textContent || '',
|
|
671
|
+
]);
|
|
559
672
|
}
|
|
560
673
|
|
|
561
|
-
function expectPolicyError(
|
|
562
|
-
wrapper: ReturnType<typeof shallow>,
|
|
563
|
-
selector: string,
|
|
564
|
-
errorName: string,
|
|
565
|
-
message: string,
|
|
566
|
-
): void {
|
|
674
|
+
function expectPolicyError(wrapper: RenderResult, selector: string, errorName: string, message: string): void {
|
|
567
675
|
const id = `gce-load-balancing-policy-${errorName}-error`;
|
|
568
|
-
expect(wrapper.
|
|
569
|
-
expect(wrapper.
|
|
570
|
-
expect(wrapper.
|
|
676
|
+
expect(wrapper.container.querySelector(selector)).toHaveAttribute('aria-invalid', 'true');
|
|
677
|
+
expect(wrapper.container.querySelector(selector)).toHaveAttribute('aria-describedby', id);
|
|
678
|
+
expect(wrapper.container.querySelector(`#${id}[role="alert"]`)).toHaveTextContent(message);
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
function selectedValues(select: HTMLElement): string[] {
|
|
682
|
+
return Array.from((select as HTMLSelectElement).selectedOptions).map((option) => option.value);
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
function changeMultiSelect(select: HTMLElement, values: string[]): void {
|
|
686
|
+
Array.from((select as HTMLSelectElement).options).forEach((option) => {
|
|
687
|
+
option.selected = values.includes(option.value);
|
|
688
|
+
});
|
|
689
|
+
fireEvent.change(select);
|
|
571
690
|
}
|
|
572
691
|
|
|
573
692
|
function testProps(values = command()) {
|
|
574
693
|
const formik = ({
|
|
575
694
|
values,
|
|
576
|
-
setFieldValue:
|
|
577
|
-
setValues:
|
|
695
|
+
setFieldValue: vi.fn(),
|
|
696
|
+
setValues: vi.fn(),
|
|
578
697
|
} as unknown) as FormikProps<IGceServerGroupCommand>;
|
|
579
698
|
const adapter = ({
|
|
580
|
-
applyConfigurationRefresh:
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
699
|
+
applyConfigurationRefresh: vi.fn().mockImplementation(async (nextCommand: IGceServerGroupCommand) => ({
|
|
700
|
+
command: nextCommand,
|
|
701
|
+
result: { dirty: {} },
|
|
702
|
+
})),
|
|
703
|
+
applyConfigurationUpdate: vi.fn().mockImplementation(async (nextCommand: IGceServerGroupCommand) => ({
|
|
704
|
+
command: nextCommand,
|
|
705
|
+
result: { dirty: {} },
|
|
706
|
+
})),
|
|
707
|
+
} as unknown) as Mocked<IGceServerGroupWizardAdapter>;
|
|
587
708
|
return { adapter, formik };
|
|
588
709
|
}
|
|
589
710
|
|
|
@@ -641,3 +762,8 @@ function command(overrides: Partial<IGceServerGroupCommand> = {}): IGceServerGro
|
|
|
641
762
|
function flush(): Promise<void> {
|
|
642
763
|
return new Promise((resolve) => setTimeout(resolve));
|
|
643
764
|
}
|
|
765
|
+
|
|
766
|
+
function renderPage(component: React.ReactElement): RenderResult {
|
|
767
|
+
const container = document.body.appendChild(document.createElement('div'));
|
|
768
|
+
return render(component, { baseElement: container, container });
|
|
769
|
+
}
|