@spinnaker/google 2026.3.2 → 2026.4.1

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.
Files changed (108) hide show
  1. package/dist/autoscalingPolicy/GceAutoScalingFieldLayout.d.ts +2 -2
  2. package/dist/domain/loadBalancer.d.ts +6 -3
  3. package/dist/image/ImageSelect.d.ts +1 -1
  4. package/dist/index.js +159 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/loadBalancer/configure/common/gceLoadBalancerModels.d.ts +13 -2
  7. package/dist/loadBalancer/configure/http/GceHttpLoadBalancerEditor.d.ts +3 -0
  8. package/dist/loadBalancer/configure/http/GceHttpLoadBalancerModal.d.ts +1 -1
  9. package/dist/loadBalancer/configure/network/GceRegionalExternalNetworkLoadBalancerEditor.d.ts +30 -0
  10. package/dist/loadBalancer/configure/network/GceRegionalExternalNetworkLoadBalancerModal.d.ts +53 -0
  11. package/dist/loadBalancer/httpLoadBalancerUtils.service.d.ts +3 -1
  12. package/dist/serverGroup/configure/wizard/GceCloneServerGroupModal.d.ts +3 -0
  13. package/dist/serverGroup/configure/wizard/GceServerGroupWizard.types.d.ts +1 -0
  14. package/dist/serverGroup/configure/wizard/customInstance/CustomInstanceConfigurer.d.ts +1 -1
  15. package/dist/serverGroup/configure/wizard/customInstance/GceCustomInstanceBuilder.d.ts +2 -2
  16. package/dist/serverGroup/configure/wizard/pages/AdvancedSettings.d.ts +3 -0
  17. package/dist/serverGroup/configure/wizard/pages/GceServerGroupLoadBalancers.d.ts +1 -0
  18. package/dist/serverGroup/configure/wizard/pages/Policies.d.ts +21 -3
  19. package/dist/serverGroup/configure/wizard/pages/ServerGroupBasicSettings.d.ts +1 -0
  20. package/dist/serverGroup/configure/wizard/pages/ServerGroupCapacity.d.ts +1 -0
  21. package/dist/serverGroup/configure/wizard/pages/ServerGroupImageSettings.d.ts +1 -0
  22. package/dist/serverGroup/configure/wizard/pages/ServerGroupInstanceType.d.ts +1 -0
  23. package/dist/serverGroup/configure/wizard/zones/GceInstanceFlexibilityConfigurer.d.ts +2 -2
  24. package/dist/serverGroup/details/GceInstanceFlexibilityPolicyDetails.d.ts +2 -2
  25. package/dist/serverGroup/details/stateful/MarkDiskStatefulButton.d.ts +2 -2
  26. package/dist/serverGroup/details/stateful/UpdateBootImageButton.d.ts +2 -2
  27. package/package.json +5 -5
  28. package/src/autoHealingPolicy/GceAutoHealingPolicyEditor.spec.tsx +68 -52
  29. package/src/autoscalingPolicy/GceAutoscalingPolicyEditor.spec.tsx +43 -50
  30. package/src/autoscalingPolicy/GceAutoscalingPolicyEditor.tsx +1 -1
  31. package/src/autoscalingPolicy/GceAutoscalingPolicyWriter.spec.ts +1 -1
  32. package/src/domain/loadBalancer.ts +6 -3
  33. package/src/gce.module.spec.ts +132 -153
  34. package/src/instance/details/GceInstanceDetails.spec.tsx +86 -83
  35. package/src/loadBalancer/configure/choice/GceLoadBalancerChoiceModal.spec.tsx +162 -121
  36. package/src/loadBalancer/configure/choice/GceLoadBalancerChoiceModal.tsx +13 -1
  37. package/src/loadBalancer/configure/common/GceProxyLoadBalancerEditor.spec.tsx +47 -30
  38. package/src/loadBalancer/configure/common/GceProxyLoadBalancerEditor.tsx +2 -1
  39. package/src/loadBalancer/configure/common/GceProxyLoadBalancerModal.spec.tsx +85 -57
  40. package/src/loadBalancer/configure/common/gceLoadBalancerData.spec.ts +17 -16
  41. package/src/loadBalancer/configure/common/gceLoadBalancerModels.spec.ts +230 -5
  42. package/src/loadBalancer/configure/common/gceLoadBalancerModels.ts +186 -22
  43. package/src/loadBalancer/configure/common/gceLoadBalancerSubmission.spec.ts +298 -2
  44. package/src/loadBalancer/configure/common/gceLoadBalancerSubmission.ts +35 -5
  45. package/src/loadBalancer/configure/common/useGceLoadBalancerData.spec.tsx +37 -46
  46. package/src/loadBalancer/configure/http/GceHttpLoadBalancerEditor.spec.tsx +399 -58
  47. package/src/loadBalancer/configure/http/GceHttpLoadBalancerEditor.tsx +148 -41
  48. package/src/loadBalancer/configure/http/GceHttpLoadBalancerListenerEditor.spec.tsx +169 -36
  49. package/src/loadBalancer/configure/http/GceHttpLoadBalancerListenerEditor.tsx +80 -12
  50. package/src/loadBalancer/configure/http/GceHttpLoadBalancerModal.spec.tsx +224 -124
  51. package/src/loadBalancer/configure/http/GceHttpLoadBalancerModal.tsx +8 -2
  52. package/src/loadBalancer/configure/http/GceHttpLoadBalancerResourceEditors.spec.tsx +57 -22
  53. package/src/loadBalancer/configure/http/GceHttpLoadBalancerResourceEditors.tsx +21 -0
  54. package/src/loadBalancer/configure/http/GceHttpLoadBalancerRoutingEditor.spec.tsx +24 -20
  55. package/src/loadBalancer/configure/network/GceNetworkLoadBalancerEditor.spec.tsx +41 -32
  56. package/src/loadBalancer/configure/network/GceNetworkLoadBalancerModal.spec.tsx +35 -30
  57. package/src/loadBalancer/configure/network/GceRegionalExternalNetworkLoadBalancerEditor.spec.tsx +443 -0
  58. package/src/loadBalancer/configure/network/GceRegionalExternalNetworkLoadBalancerEditor.tsx +401 -0
  59. package/src/loadBalancer/configure/network/GceRegionalExternalNetworkLoadBalancerModal.spec.tsx +330 -0
  60. package/src/loadBalancer/configure/network/GceRegionalExternalNetworkLoadBalancerModal.tsx +348 -0
  61. package/src/loadBalancer/details/gceLoadBalancerDetails.spec.tsx +439 -35
  62. package/src/loadBalancer/details/gceLoadBalancerDetails.tsx +104 -21
  63. package/src/loadBalancer/httpLoadBalancerUtils.service.spec.ts +126 -0
  64. package/src/loadBalancer/httpLoadBalancerUtils.service.ts +27 -11
  65. package/src/loadBalancer/loadBalancer.setTransformer.spec.ts +165 -0
  66. package/src/loadBalancer/loadBalancer.setTransformer.ts +15 -2
  67. package/src/pipeline/stages/googleStageConfig.spec.js +22 -16
  68. package/src/securityGroup/configure/GceSecurityGroupModal.spec.tsx +177 -193
  69. package/src/securityGroup/configure/GceSecurityGroupModal.tsx +14 -2
  70. package/src/securityGroup/details/GceSecurityGroupDetails.spec.tsx +69 -78
  71. package/src/serverGroup/configure/serverGroupCommandBuilder.service.spec.js +35 -15
  72. package/src/serverGroup/configure/serverGroupConfiguration.service.js +7 -1
  73. package/src/serverGroup/configure/serverGroupConfiguration.service.spec.js +74 -4
  74. package/src/serverGroup/configure/wizard/GceCloneServerGroupModal.spec.tsx +593 -855
  75. package/src/serverGroup/configure/wizard/GceCloneServerGroupModal.tsx +120 -38
  76. package/src/serverGroup/configure/wizard/GceServerGroupWizard.types.ts +1 -0
  77. package/src/serverGroup/configure/wizard/GceServerGroupWizardPage.spec.tsx +53 -50
  78. package/src/serverGroup/configure/wizard/customInstance/GceCustomInstanceBuilder.spec.tsx +65 -49
  79. package/src/serverGroup/configure/wizard/hiddenMetadataKeys.value.js +1 -0
  80. package/src/serverGroup/configure/wizard/pages/AdvancedSettings.spec.tsx +101 -108
  81. package/src/serverGroup/configure/wizard/pages/AdvancedSettings.tsx +32 -28
  82. package/src/serverGroup/configure/wizard/pages/GceServerGroupFirewalls.spec.tsx +60 -59
  83. package/src/serverGroup/configure/wizard/pages/GceServerGroupLoadBalancers.spec.tsx +240 -114
  84. package/src/serverGroup/configure/wizard/pages/GceServerGroupLoadBalancers.tsx +152 -63
  85. package/src/serverGroup/configure/wizard/pages/Policies.spec.tsx +93 -48
  86. package/src/serverGroup/configure/wizard/pages/Policies.tsx +80 -55
  87. package/src/serverGroup/configure/wizard/pages/ServerGroupBasicSettings.spec.tsx +123 -94
  88. package/src/serverGroup/configure/wizard/pages/ServerGroupBasicSettings.tsx +24 -18
  89. package/src/serverGroup/configure/wizard/pages/ServerGroupCapacity.spec.tsx +152 -133
  90. package/src/serverGroup/configure/wizard/pages/ServerGroupCapacity.tsx +40 -37
  91. package/src/serverGroup/configure/wizard/pages/ServerGroupImageSettings.spec.tsx +66 -60
  92. package/src/serverGroup/configure/wizard/pages/ServerGroupImageSettings.tsx +8 -2
  93. package/src/serverGroup/configure/wizard/pages/ServerGroupInstanceType.spec.tsx +131 -101
  94. package/src/serverGroup/configure/wizard/pages/ServerGroupInstanceType.tsx +29 -28
  95. package/src/serverGroup/configure/wizard/zones/GceInstanceFlexibilityConfigurer.spec.tsx +104 -81
  96. package/src/serverGroup/details/GceInstanceFlexibilityPolicyDetails.spec.tsx +10 -11
  97. package/src/serverGroup/details/autoHealingPolicy/GceAutoHealingPolicyDetails.spec.tsx +51 -59
  98. package/src/serverGroup/details/autoHealingPolicy/modal/GceUpsertAutoHealingPolicyModal.spec.tsx +3 -3
  99. package/src/serverGroup/details/autoscalingPolicy/GceAutoscalingPolicyDetails.spec.tsx +49 -58
  100. package/src/serverGroup/details/autoscalingPolicy/modal/GceUpsertAutoscalingPolicyModal.spec.tsx +3 -3
  101. package/src/serverGroup/details/gceServerGroupDetails.spec.tsx +162 -141
  102. package/src/serverGroup/details/resize/GceResizeServerGroupModal.spec.tsx +102 -86
  103. package/src/serverGroup/details/resize/GceResizeServerGroupModal.tsx +4 -0
  104. package/src/serverGroup/details/rollback/GceRollbackServerGroupModal.spec.tsx +40 -31
  105. package/src/serverGroup/serverGroup.transformer.js +1 -0
  106. package/src/serverGroup/serverGroup.transformer.spec.js +48 -0
  107. package/src/validation/ApplicationNameValidator.spec.ts +1 -1
  108. /package/dist/{gce.logo2ae85d8704b1d6b8.png → gce.logoChI3w_A5.png} +0 -0
@@ -1,9 +1,10 @@
1
- import { shallow } from 'enzyme';
2
1
  import type { FormikProps } from 'formik';
2
+ import type { Mocked } from 'vitest';
3
+ import { fireEvent, render, screen, waitFor, within } from '@testing-library/react';
3
4
  import React from 'react';
4
5
 
5
- import { GceServerGroupFirewalls } from './GceServerGroupFirewalls';
6
6
  import type { IGceServerGroupCommand, IGceServerGroupWizardAdapter } from '../GceServerGroupWizard.types';
7
+ import { GceServerGroupFirewalls } from './GceServerGroupFirewalls';
7
8
 
8
9
  describe('GCE server group Firewalls page', () => {
9
10
  it('separates network scoped explicit and implicit firewalls and preserves unavailable selections', () => {
@@ -12,22 +13,21 @@ describe('GCE server group Firewalls page', () => {
12
13
  viewState: { mode: 'clone', dirty: {}, listImplicitSecurityGroups: true },
13
14
  });
14
15
  const { formik } = testProps(values);
15
- const wrapper = shallow(<GceServerGroupFirewalls app={{} as any} formik={formik} />);
16
+ render(<GceServerGroupFirewalls app={{} as any} formik={formik} />);
16
17
 
17
- expect(selectOptions(wrapper)).toEqual([
18
+ expect(selectOptions()).toEqual([
18
19
  ['api-firewall', 'api-firewall (api-firewall)'],
19
20
  ['web-firewall', 'web-firewall (web-firewall)'],
20
21
  ['persisted-firewall', 'persisted-firewall (unavailable)'],
21
22
  ]);
22
- expect(wrapper.find('select[aria-label="Firewalls"]').prop('value')).toEqual([
23
- 'web-firewall',
24
- 'persisted-firewall',
25
- ]);
26
- expect(wrapper.find('label[htmlFor="gce-server-group-firewalls"]').text()).toBe('Firewalls');
27
- expect(wrapper.find('label[htmlFor="gce-show-implicit-firewalls"]').text()).toContain('Show implicit firewalls');
28
- expect(wrapper.find('ul[aria-label="Implicit firewalls"] li').map((item) => item.text())).toEqual([
29
- 'implicit-firewall',
30
- ]);
23
+ expect(selectedValues(screen.getByLabelText('Firewalls'))).toEqual(['web-firewall', 'persisted-firewall']);
24
+ expect(screen.getByText('Firewalls', { selector: 'label' })).toHaveAttribute('for', 'gce-server-group-firewalls');
25
+ expect(screen.getByText(/Show implicit firewalls/, { selector: 'label' })).toHaveAttribute(
26
+ 'for',
27
+ 'gce-show-implicit-firewalls',
28
+ );
29
+ expect(within(screen.getByRole('list', { name: 'Implicit firewalls' })).getAllByRole('listitem')).toHaveLength(1);
30
+ expect(screen.getByRole('listitem')).toHaveTextContent('implicit-firewall');
31
31
  });
32
32
 
33
33
  it('routes explicit firewall changes through networkChanged without losing selections or tags', async () => {
@@ -36,24 +36,20 @@ describe('GCE server group Firewalls page', () => {
36
36
  tags: [{ value: 'existing-tag' }],
37
37
  });
38
38
  const { adapter, formik } = testProps(values);
39
- adapter.applyCommandHandler.and.callFake(async (nextCommand) => ({
39
+ adapter.applyCommandHandler.mockImplementation(async (nextCommand) => ({
40
40
  command: { ...nextCommand, securityGroups: [], tags: [] },
41
41
  result: { dirty: { securityGroups: ['persisted-firewall'] } },
42
42
  }));
43
- const wrapper = shallow(<GceServerGroupFirewalls app={{} as any} formik={formik} adapter={adapter} />);
43
+ render(<GceServerGroupFirewalls app={{} as any} adapter={adapter} formik={formik} />);
44
44
 
45
- wrapper.find('select[aria-label="Firewalls"]').simulate('change', {
46
- target: {
47
- selectedOptions: [{ value: 'web-firewall' }, { value: 'persisted-firewall' }, { value: 'web-firewall' }],
48
- },
49
- });
50
- await flush();
45
+ changeMultiSelect(screen.getByLabelText('Firewalls'), ['web-firewall', 'persisted-firewall']);
51
46
 
52
- const changedCommand = adapter.applyCommandHandler.calls.mostRecent().args[0];
47
+ await waitFor(() => expect(formik.setValues).toHaveBeenCalled());
48
+ const changedCommand = adapter.applyCommandHandler.mock.lastCall[0];
53
49
  expect(changedCommand.securityGroups).toEqual(['web-firewall', 'persisted-firewall']);
54
50
  expect(adapter.applyCommandHandler).toHaveBeenCalledWith(changedCommand, 'networkChanged');
55
51
  expect(formik.setValues).toHaveBeenCalledWith(
56
- jasmine.objectContaining({
52
+ expect.objectContaining({
57
53
  securityGroups: ['web-firewall', 'persisted-firewall'],
58
54
  tags: [{ value: 'existing-tag' }],
59
55
  }),
@@ -66,19 +62,17 @@ describe('GCE server group Firewalls page', () => {
66
62
  tags: [{ value: 'existing-tag' }, { value: 'existing-tag' }],
67
63
  });
68
64
  const { adapter, formik } = testProps(values);
69
- const wrapper = shallow(<GceServerGroupFirewalls app={{} as any} formik={formik} adapter={adapter} />);
65
+ render(<GceServerGroupFirewalls app={{} as any} adapter={adapter} formik={formik} />);
70
66
 
71
- wrapper
72
- .find('input[aria-label="Target tag shared for firewall web-firewall"]')
73
- .simulate('change', { target: { checked: true } });
74
- await flush();
67
+ fireEvent.click(screen.getByLabelText('Target tag shared for firewall web-firewall'));
75
68
 
76
- const changedCommand = adapter.applyCommandHandler.calls.mostRecent().args[0];
69
+ await waitFor(() => expect(formik.setValues).toHaveBeenCalled());
70
+ const changedCommand = adapter.applyCommandHandler.mock.lastCall[0];
77
71
  expect(changedCommand.securityGroups).toEqual(['web-firewall', 'api-firewall']);
78
72
  expect(changedCommand.tags).toEqual([{ value: 'existing-tag' }, { value: 'shared' }]);
79
73
  expect(adapter.applyCommandHandler).toHaveBeenCalledWith(changedCommand, 'networkChanged');
80
74
  expect(formik.setValues).toHaveBeenCalledWith(
81
- jasmine.objectContaining({
75
+ expect.objectContaining({
82
76
  securityGroups: ['web-firewall', 'api-firewall'],
83
77
  tags: [{ value: 'existing-tag' }, { value: 'shared' }],
84
78
  }),
@@ -91,14 +85,12 @@ describe('GCE server group Firewalls page', () => {
91
85
  tags: [{ value: 'existing-tag' }, { value: 'shared' }],
92
86
  });
93
87
  const { adapter, formik } = testProps(values);
94
- const wrapper = shallow(<GceServerGroupFirewalls app={{} as any} formik={formik} adapter={adapter} />);
88
+ render(<GceServerGroupFirewalls app={{} as any} adapter={adapter} formik={formik} />);
95
89
 
96
- wrapper
97
- .find('input[aria-label="Target tag shared for firewall web-firewall"]')
98
- .simulate('change', { target: { checked: false } });
99
- await flush();
90
+ fireEvent.click(screen.getByLabelText('Target tag shared for firewall web-firewall'));
100
91
 
101
- const changedCommand = adapter.applyCommandHandler.calls.mostRecent().args[0];
92
+ await waitFor(() => expect(formik.setValues).toHaveBeenCalled());
93
+ const changedCommand = adapter.applyCommandHandler.mock.lastCall[0];
102
94
  expect(changedCommand.securityGroups).toEqual(['persisted-firewall']);
103
95
  expect(changedCommand.tags).toEqual([{ value: 'existing-tag' }]);
104
96
  });
@@ -109,7 +101,7 @@ describe('GCE server group Firewalls page', () => {
109
101
  tags: [{ value: 'existing-tag' }],
110
102
  });
111
103
  const { adapter, formik } = testProps(values);
112
- adapter.applyConfigurationRefresh.and.resolveTo({
104
+ adapter.applyConfigurationRefresh.mockResolvedValue({
113
105
  command: {
114
106
  ...values,
115
107
  backingData: { ...values.backingData, refreshed: true },
@@ -118,15 +110,15 @@ describe('GCE server group Firewalls page', () => {
118
110
  },
119
111
  result: { dirty: {} },
120
112
  });
121
- const wrapper = shallow(<GceServerGroupFirewalls app={{} as any} formik={formik} adapter={adapter} />);
113
+ render(<GceServerGroupFirewalls app={{} as any} adapter={adapter} formik={formik} />);
122
114
 
123
- wrapper.find('button[aria-label="Refresh firewalls"]').simulate('click');
124
- await flush();
115
+ fireEvent.click(screen.getByRole('button', { name: 'Refresh firewalls' }));
125
116
 
117
+ await waitFor(() => expect(formik.setValues).toHaveBeenCalled());
126
118
  expect(adapter.applyConfigurationRefresh).toHaveBeenCalledWith(values, 'refreshSecurityGroups');
127
119
  expect(formik.setValues).toHaveBeenCalledWith(
128
- jasmine.objectContaining({
129
- backingData: jasmine.objectContaining({ refreshed: true }),
120
+ expect.objectContaining({
121
+ backingData: expect.objectContaining({ refreshed: true }),
130
122
  securityGroups: ['persisted-firewall'],
131
123
  tags: [{ value: 'existing-tag' }],
132
124
  }),
@@ -134,26 +126,39 @@ describe('GCE server group Firewalls page', () => {
134
126
  });
135
127
  });
136
128
 
137
- function selectOptions(wrapper: ReturnType<typeof shallow>): string[][] {
138
- return wrapper
139
- .find('select[aria-label="Firewalls"] option')
140
- .map((option) => [option.prop('value') as string, option.text()]);
129
+ function selectOptions(): string[][] {
130
+ return within(screen.getByLabelText('Firewalls'))
131
+ .getAllByRole('option')
132
+ .map((option) => [(option as HTMLOptionElement).value, option.textContent || '']);
133
+ }
134
+
135
+ function selectedValues(select: HTMLElement): string[] {
136
+ return Array.from((select as HTMLSelectElement).selectedOptions).map((option) => option.value);
137
+ }
138
+
139
+ function changeMultiSelect(select: HTMLElement, values: string[]): void {
140
+ Array.from((select as HTMLSelectElement).options).forEach((option) => {
141
+ option.selected = values.includes(option.value);
142
+ });
143
+ fireEvent.change(select);
141
144
  }
142
145
 
143
146
  function testProps(values = command()) {
144
147
  const formik = ({
145
148
  values,
146
- setFieldValue: jasmine.createSpy('setFieldValue'),
147
- setValues: jasmine.createSpy('setValues'),
149
+ setFieldValue: vi.fn(),
150
+ setValues: vi.fn(),
148
151
  } as unknown) as FormikProps<IGceServerGroupCommand>;
149
152
  const adapter = ({
150
- applyCommandHandler: jasmine
151
- .createSpy('applyCommandHandler')
152
- .and.callFake(async (nextCommand: IGceServerGroupCommand) => ({ command: nextCommand, result: { dirty: {} } })),
153
- applyConfigurationRefresh: jasmine
154
- .createSpy('applyConfigurationRefresh')
155
- .and.callFake(async (nextCommand: IGceServerGroupCommand) => ({ command: nextCommand, result: { dirty: {} } })),
156
- } as unknown) as jasmine.SpyObj<IGceServerGroupWizardAdapter>;
153
+ applyCommandHandler: vi.fn().mockImplementation(async (nextCommand: IGceServerGroupCommand) => ({
154
+ command: nextCommand,
155
+ result: { dirty: {} },
156
+ })),
157
+ applyConfigurationRefresh: vi.fn().mockImplementation(async (nextCommand: IGceServerGroupCommand) => ({
158
+ command: nextCommand,
159
+ result: { dirty: {} },
160
+ })),
161
+ } as unknown) as Mocked<IGceServerGroupWizardAdapter>;
157
162
  return { adapter, formik };
158
163
  }
159
164
 
@@ -190,7 +195,3 @@ function command(overrides: Partial<IGceServerGroupCommand> = {}): IGceServerGro
190
195
  ...overrides,
191
196
  };
192
197
  }
193
-
194
- function flush(): Promise<void> {
195
- return new Promise((resolve) => setTimeout(resolve));
196
- }