@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.
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,4 +1,4 @@
1
- import { mount as enzymeMount } from 'enzyme';
1
+ import { fireEvent, render, screen, waitFor } from '@testing-library/react';
2
2
  import React from 'react';
3
3
 
4
4
  import {
@@ -8,13 +8,11 @@ import {
8
8
  ErrorModalService,
9
9
  InfrastructureCaches,
10
10
  LoadBalancerWriter,
11
- ManagedMenuItem,
12
11
  nativePromiseService,
13
12
  ProviderServiceDelegate,
14
13
  Registry,
15
14
  ServerGroupReader,
16
15
  ServerGroupWarningMessageService,
17
- SubmitButton,
18
16
  TaskExecutor,
19
17
  } from '@spinnaker/core';
20
18
 
@@ -34,11 +32,7 @@ import { GceSecurityGroupReader } from './securityGroup/securityGroup.reader';
34
32
  import { GceSecurityGroupTransformer } from './securityGroup/securityGroup.transformer';
35
33
  import { GceServerGroupCommandBuilder } from './serverGroup/configure/serverGroupCommandBuilder.service';
36
34
  import { GceServerGroupConfigurationService } from './serverGroup/configure/serverGroupConfiguration.service';
37
- import {
38
- cloneGceServerGroup,
39
- GceServerGroupActions,
40
- gceServerGroupDetailsGetter,
41
- } from './serverGroup/details/gceServerGroupDetails';
35
+ import { cloneGceServerGroup, GceServerGroupActions } from './serverGroup/details/gceServerGroupDetails';
42
36
  import { GceServerGroupTransformer } from './serverGroup/serverGroup.transformer';
43
37
  import { GceSubnetRenderer } from './subnet/subnet.renderer';
44
38
 
@@ -46,7 +40,8 @@ describe('Google provider registration', () => {
46
40
  let runtimeServices: any;
47
41
  const RuntimeWrapper = ({ children }: React.PropsWithChildren<{}>) =>
48
42
  React.createElement(DeckRuntimeContext.Provider, { value: { services: runtimeServices } as any }, children);
49
- const mount = (component: React.ReactElement) => enzymeMount(component, { wrappingComponent: RuntimeWrapper });
43
+ const renderWithRuntime = (component: React.ReactElement) =>
44
+ render(React.createElement(RuntimeWrapper, undefined, component));
50
45
 
51
46
  beforeEach(() => {
52
47
  runtimeServices = {
@@ -152,8 +147,8 @@ describe('Google provider registration', () => {
152
147
  'serverGroup.commandBuilder',
153
148
  );
154
149
 
155
- expect(commandBuilder.buildNewServerGroupCommand).toEqual(jasmine.any(Function));
156
- expect(commandBuilder.buildServerGroupCommandFromExisting).toEqual(jasmine.any(Function));
150
+ expect(commandBuilder.buildNewServerGroupCommand).toEqual(expect.any(Function));
151
+ expect(commandBuilder.buildServerGroupCommandFromExisting).toEqual(expect.any(Function));
157
152
  });
158
153
 
159
154
  it('normalizes HTTP load balancers without constructor dependencies', () => {
@@ -185,30 +180,20 @@ describe('Google provider registration', () => {
185
180
  runtimeServices.securityGroupReader = {
186
181
  getAllSecurityGroups: () => Promise.resolve({}),
187
182
  };
188
- const wrapper = mount(
183
+ renderWithRuntime(
189
184
  React.createElement(GceSecurityGroupModal, {
190
185
  application: { name: 'fnord', securityGroups: { data: [] } },
191
186
  credentials: 'test-account',
192
187
  }),
193
188
  );
194
189
 
195
- wrapper.setState({
196
- securityGroup: {
197
- ...(wrapper.state() as any).securityGroup,
198
- ipIngress: [{ type: 'tcp', startPort: 443, endPort: 443 }],
199
- name: 'fnord-firewall',
200
- network: 'default',
201
- sourceRanges: ['10.0.0.0/8'],
202
- sourceTags: [],
203
- targetTags: [],
204
- },
205
- } as any);
206
-
207
- await Promise.resolve();
208
- await Promise.resolve();
209
- wrapper.update();
190
+ fireEvent.change(screen.getByRole('textbox', { name: 'Name' }), { target: { value: 'fnord-firewall' } });
191
+ fireEvent.change(screen.getByRole('textbox', { name: 'Network' }), { target: { value: 'default' } });
192
+ fireEvent.change(screen.getByRole('textbox', { name: 'Source CIDRs' }), { target: { value: '10.0.0.0/8' } });
193
+ fireEvent.change(screen.getByRole('spinbutton', { name: 'Start port 1' }), { target: { value: '443' } });
194
+ fireEvent.change(screen.getByRole('spinbutton', { name: 'End port 1' }), { target: { value: '443' } });
210
195
 
211
- expect(wrapper.find(SubmitButton).prop('isDisabled')).toBe(false);
196
+ await waitFor(() => expect(screen.getByRole('button', { name: 'Create' })).toBeEnabled());
212
197
  });
213
198
 
214
199
  it('loads and enriches GCE load balancer details through the Core reader', async () => {
@@ -230,9 +215,9 @@ describe('Google provider registration', () => {
230
215
  defaultService: { name: 'backend-default', healthCheck: { name: 'hc-default' } },
231
216
  };
232
217
  const loadBalancerReader = {
233
- getLoadBalancerDetails: jasmine
234
- .createSpy('getLoadBalancerDetails')
235
- .and.callFake((_provider: string, _account: string, _region: string, name: string) =>
218
+ getLoadBalancerDetails: vi
219
+ .fn()
220
+ .mockImplementation((_provider: string, _account: string, _region: string, name: string) =>
236
221
  Promise.resolve([
237
222
  {
238
223
  name,
@@ -244,11 +229,9 @@ describe('Google provider registration', () => {
244
229
  ),
245
230
  };
246
231
  const accountService = {
247
- getAccountDetails: jasmine
248
- .createSpy('getAccountDetails')
249
- .and.returnValue(Promise.resolve({ project: 'gce-project' })),
232
+ getAccountDetails: vi.fn().mockReturnValue(Promise.resolve({ project: 'gce-project' })),
250
233
  };
251
- const autoClose = jasmine.createSpy('autoClose');
234
+ const autoClose = vi.fn();
252
235
 
253
236
  const loadBalancer = await loadGceLoadBalancerDetails({
254
237
  app: { loadBalancers: { data: [summary] } } as any,
@@ -298,10 +281,10 @@ describe('Google provider registration', () => {
298
281
  });
299
282
 
300
283
  it('deletes HTTP load balancers by forwarding rule and preserves delete params', async () => {
301
- const confirmSpy = spyOn(ConfirmationModalService, 'confirm').and.returnValue(Promise.resolve({}) as any);
302
- spyOn(LoadBalancerWriter, 'deleteLoadBalancer').and.returnValue(Promise.resolve({}) as any);
303
- const clearCacheSpy = spyOn(InfrastructureCaches, 'clearCache');
304
- const executeTaskSpy = spyOn(TaskExecutor, 'executeTask').and.returnValue(Promise.resolve({}) as any);
284
+ const confirmSpy = vi.spyOn(ConfirmationModalService, 'confirm').mockReturnValue(Promise.resolve({}) as any);
285
+ vi.spyOn(LoadBalancerWriter, 'deleteLoadBalancer').mockReturnValue(Promise.resolve({}) as any);
286
+ const clearCacheSpy = vi.spyOn(InfrastructureCaches, 'clearCache').mockReturnValue(undefined);
287
+ const executeTaskSpy = vi.spyOn(TaskExecutor, 'executeTask').mockReturnValue(Promise.resolve({}) as any);
305
288
  const app = { name: 'fnord' };
306
289
  const loadBalancer = {
307
290
  account: 'test-account',
@@ -313,12 +296,10 @@ describe('Google provider registration', () => {
313
296
  urlMapName: 'frontend-map',
314
297
  };
315
298
 
316
- const wrapper = mount(React.createElement(GceLoadBalancerActions, { app, loadBalancer }));
317
- wrapper
318
- .find(ManagedMenuItem)
319
- .filterWhere((item) => item.prop('children') === 'Delete Load Balancer')
320
- .prop('onClick')();
321
- const modalParams = confirmSpy.calls.mostRecent().args[0] as any;
299
+ render(React.createElement(GceLoadBalancerActions, { app, loadBalancer }));
300
+ fireEvent.click(screen.getByText('Delete Load Balancer'));
301
+ await waitFor(() => expect(confirmSpy).toHaveBeenCalled());
302
+ const modalParams = confirmSpy.mock.lastCall[0] as any;
322
303
  await modalParams.submitMethod({ deleteHealthChecks: true, reason: 'cleanup' });
323
304
 
324
305
  expect(LoadBalancerWriter.deleteLoadBalancer).not.toHaveBeenCalled();
@@ -328,7 +309,7 @@ describe('Google provider registration', () => {
328
309
  application: app,
329
310
  description: 'Delete load balancer: frontend-map in test-account:global',
330
311
  job: [
331
- jasmine.objectContaining({
312
+ expect.objectContaining({
332
313
  cloudProvider: 'gce',
333
314
  credentials: 'test-account',
334
315
  deleteHealthChecks: true,
@@ -343,79 +324,85 @@ describe('Google provider registration', () => {
343
324
  });
344
325
  });
345
326
 
346
- it('loads GCE server group details even when the app summary is not loaded yet', (done) => {
347
- const autoClose = jasmine.createSpy('autoClose');
348
- spyOn(ServerGroupReader, 'getServerGroup').and.returnValue(
349
- Promise.resolve({
350
- account: 'test-account',
351
- launchConfig: {
352
- instanceTemplate: {
353
- properties: { networkInterfaces: [] },
354
- selfLink:
355
- 'https://compute.googleapis.com/compute/beta/projects/gce-project/global/instanceTemplates/fnord-v001',
327
+ it('loads GCE server group details even when the app summary is not loaded yet', () =>
328
+ new Promise((done, reject) => {
329
+ googlePackage.registerGoogleProvider();
330
+ const registeredDetailsGetter = CloudProviderRegistry.getValue('gce', 'serverGroup.detailsGetter');
331
+ const autoClose = vi.fn();
332
+ vi.spyOn(ServerGroupReader, 'getServerGroup').mockReturnValue(
333
+ Promise.resolve({
334
+ account: 'test-account',
335
+ launchConfig: {
336
+ instanceTemplate: {
337
+ properties: { networkInterfaces: [] },
338
+ selfLink:
339
+ 'https://compute.googleapis.com/compute/beta/projects/gce-project/global/instanceTemplates/fnord-v001',
340
+ },
356
341
  },
357
- },
358
- name: 'fnord-v001',
359
- region: 'us-central1',
360
- zones: ['us-central1-b', 'us-central1-a'],
361
- }) as any,
362
- );
342
+ name: 'fnord-v001',
343
+ region: 'us-central1',
344
+ zones: ['us-central1-b', 'us-central1-a'],
345
+ }) as any,
346
+ );
363
347
 
364
- gceServerGroupDetailsGetter(
365
- {
366
- app: { loadBalancers: { data: [] }, name: 'fnord', serverGroups: { data: [] } },
367
- serverGroup: { accountId: 'test-account', name: 'fnord-v001', region: 'us-central1' },
368
- },
369
- autoClose,
370
- ).subscribe({
371
- error: done.fail,
372
- next: (serverGroup: any) => {
373
- expect(serverGroup.name).toBe('fnord-v001');
374
- expect(serverGroup.account).toBe('test-account');
375
- expect(serverGroup.zones).toEqual(['us-central1-a', 'us-central1-b']);
376
- },
377
- complete: () => {
378
- expect(autoClose).not.toHaveBeenCalled();
379
- expect(ServerGroupReader.getServerGroup).toHaveBeenCalledWith(
380
- 'fnord',
381
- 'test-account',
382
- 'us-central1',
383
- 'fnord-v001',
384
- );
385
- done();
386
- },
387
- });
388
- });
389
-
390
- it('loads GCE server group details when the launch template is missing', (done) => {
391
- const autoClose = jasmine.createSpy('autoClose');
392
- spyOn(ServerGroupReader, 'getServerGroup').and.returnValue(
393
- Promise.resolve({
394
- account: 'test-account',
395
- name: 'fnord-v001',
396
- region: 'us-central1',
397
- zones: ['us-central1-a'],
398
- }) as any,
399
- );
400
-
401
- gceServerGroupDetailsGetter(
402
- {
403
- app: { loadBalancers: { data: [] }, name: 'fnord', serverGroups: { data: [] } },
404
- serverGroup: { accountId: 'test-account', name: 'fnord-v001', region: 'us-central1' },
405
- },
406
- autoClose,
407
- ).subscribe({
408
- error: done.fail,
409
- next: (serverGroup: any) => {
410
- expect(serverGroup.name).toBe('fnord-v001');
411
- expect(serverGroup.logsLink).toBeUndefined();
412
- },
413
- complete: () => {
414
- expect(autoClose).not.toHaveBeenCalled();
415
- done();
416
- },
417
- });
418
- });
348
+ registeredDetailsGetter(
349
+ {
350
+ app: { loadBalancers: { data: [] }, name: 'fnord', serverGroups: { data: [] } },
351
+ serverGroup: { accountId: 'test-account', name: 'fnord-v001', region: 'us-central1' },
352
+ },
353
+ autoClose,
354
+ ).subscribe({
355
+ error: reject,
356
+ next: (serverGroup: any) => {
357
+ expect(serverGroup.name).toBe('fnord-v001');
358
+ expect(serverGroup.account).toBe('test-account');
359
+ expect(serverGroup.zones).toEqual(['us-central1-a', 'us-central1-b']);
360
+ },
361
+ complete: () => {
362
+ expect(autoClose).not.toHaveBeenCalled();
363
+ expect(ServerGroupReader.getServerGroup).toHaveBeenCalledWith(
364
+ 'fnord',
365
+ 'test-account',
366
+ 'us-central1',
367
+ 'fnord-v001',
368
+ );
369
+ done();
370
+ },
371
+ });
372
+ }));
373
+
374
+ it('loads GCE server group details when the launch template is missing', () =>
375
+ new Promise((done, reject) => {
376
+ googlePackage.registerGoogleProvider();
377
+ const registeredDetailsGetter = CloudProviderRegistry.getValue('gce', 'serverGroup.detailsGetter');
378
+ const autoClose = vi.fn();
379
+ vi.spyOn(ServerGroupReader, 'getServerGroup').mockReturnValue(
380
+ Promise.resolve({
381
+ account: 'test-account',
382
+ name: 'fnord-v001',
383
+ region: 'us-central1',
384
+ zones: ['us-central1-a'],
385
+ }) as any,
386
+ );
387
+
388
+ registeredDetailsGetter(
389
+ {
390
+ app: { loadBalancers: { data: [] }, name: 'fnord', serverGroups: { data: [] } },
391
+ serverGroup: { accountId: 'test-account', name: 'fnord-v001', region: 'us-central1' },
392
+ },
393
+ autoClose,
394
+ ).subscribe({
395
+ error: reject,
396
+ next: (serverGroup: any) => {
397
+ expect(serverGroup.name).toBe('fnord-v001');
398
+ expect(serverGroup.logsLink).toBeUndefined();
399
+ },
400
+ complete: () => {
401
+ expect(autoClose).not.toHaveBeenCalled();
402
+ done();
403
+ },
404
+ });
405
+ }));
419
406
 
420
407
  it('builds GCE instance logs links with the expected resource type', async () => {
421
408
  const instance = decorateInstance({
@@ -430,64 +417,56 @@ describe('Google provider registration', () => {
430
417
  });
431
418
 
432
419
  it('does not force Google health provider params when platform-health override is disabled', async () => {
433
- const confirmSpy = spyOn(ConfirmationModalService, 'confirm').and.returnValue(Promise.resolve({}) as any);
434
- const writer = { enableServerGroup: jasmine.createSpy('enableServerGroup').and.returnValue(Promise.resolve({})) };
420
+ const confirmSpy = vi.spyOn(ConfirmationModalService, 'confirm').mockReturnValue(Promise.resolve({}) as any);
421
+ const writer = { enableServerGroup: vi.fn().mockReturnValue(Promise.resolve({})) };
435
422
  runtimeServices.serverGroupWriter = writer;
436
423
 
437
- mount(
424
+ renderWithRuntime(
438
425
  React.createElement(GceServerGroupActions, {
439
426
  app: { attributes: { platformHealthOnly: true, platformHealthOnlyShowOverride: false }, name: 'fnord' },
440
427
  serverGroup: { account: 'test-account', isDisabled: true, name: 'fnord-v001', region: 'us-central1' },
441
428
  }),
442
- )
443
- .find('a')
444
- .filterWhere((link) => link.text() === 'Enable')
445
- .simulate('click');
429
+ );
430
+ fireEvent.click(screen.getByText('Enable', { selector: 'a' }));
446
431
 
447
- const modalParams = confirmSpy.calls.mostRecent().args[0] as any;
432
+ const modalParams = confirmSpy.mock.lastCall[0] as any;
448
433
  expect(modalParams.platformHealthOnlyShowOverride).toBe(false);
449
434
  await modalParams.submitMethod({ reason: 'not forced' });
450
- expect(writer.enableServerGroup.calls.mostRecent().args[2].interestingHealthProviderNames).toBeUndefined();
435
+ expect(writer.enableServerGroup.mock.lastCall[2].interestingHealthProviderNames).toBeUndefined();
451
436
  });
452
437
 
453
438
  it('adds Google health provider params to GCE server group actions when platform health only is enabled', async () => {
454
- const confirmSpy = spyOn(ConfirmationModalService, 'confirm').and.returnValue(Promise.resolve({}) as any);
455
- spyOn(ServerGroupWarningMessageService, 'addDisableWarningMessage');
456
- spyOn(ServerGroupWarningMessageService, 'addDestroyWarningMessage');
439
+ const confirmSpy = vi.spyOn(ConfirmationModalService, 'confirm').mockReturnValue(Promise.resolve({}) as any);
440
+ vi.spyOn(ServerGroupWarningMessageService, 'addDisableWarningMessage').mockReturnValue(undefined);
441
+ vi.spyOn(ServerGroupWarningMessageService, 'addDestroyWarningMessage').mockReturnValue(undefined);
457
442
  const writer = {
458
- destroyServerGroup: jasmine.createSpy('destroyServerGroup').and.returnValue(Promise.resolve({})),
459
- disableServerGroup: jasmine.createSpy('disableServerGroup').and.returnValue(Promise.resolve({})),
443
+ destroyServerGroup: vi.fn().mockReturnValue(Promise.resolve({})),
444
+ disableServerGroup: vi.fn().mockReturnValue(Promise.resolve({})),
460
445
  };
461
446
  runtimeServices.serverGroupWriter = writer;
462
447
  const app = { attributes: { platformHealthOnly: true, platformHealthOnlyShowOverride: true }, name: 'fnord' };
463
448
  const serverGroup = { account: 'test-account', isDisabled: false, name: 'fnord-v001', region: 'us-central1' };
464
449
 
465
- const wrapper = mount(React.createElement(GceServerGroupActions, { app, serverGroup }));
466
- wrapper
467
- .find('a')
468
- .filterWhere((link) => link.text() === 'Disable')
469
- .simulate('click');
470
- let modalParams = confirmSpy.calls.mostRecent().args[0] as any;
450
+ renderWithRuntime(React.createElement(GceServerGroupActions, { app, serverGroup }));
451
+ fireEvent.click(screen.getByText('Disable', { selector: 'a' }));
452
+ let modalParams = confirmSpy.mock.lastCall[0] as any;
471
453
  expect(modalParams.platformHealthOnlyShowOverride).toBe(true);
472
454
  await modalParams.submitMethod({ reason: 'platform health only' });
473
- expect(writer.disableServerGroup.calls.mostRecent().args[2].interestingHealthProviderNames).toEqual(['Google']);
455
+ expect(writer.disableServerGroup.mock.lastCall[2].interestingHealthProviderNames).toEqual(['Google']);
474
456
 
475
- wrapper
476
- .find('a')
477
- .filterWhere((link) => link.text() === 'Destroy')
478
- .simulate('click');
479
- modalParams = confirmSpy.calls.mostRecent().args[0] as any;
457
+ fireEvent.click(screen.getByText('Destroy', { selector: 'a' }));
458
+ modalParams = confirmSpy.mock.lastCall[0] as any;
480
459
  expect(modalParams.platformHealthOnlyShowOverride).toBe(true);
481
460
  await modalParams.submitMethod({ reason: 'platform health only' });
482
- expect(writer.destroyServerGroup.calls.mostRecent().args[2].interestingHealthProviderNames).toEqual(['Google']);
461
+ expect(writer.destroyServerGroup.mock.lastCall[2].interestingHealthProviderNames).toEqual(['Google']);
483
462
  });
484
463
 
485
464
  it('shows an error when the GCE clone command cannot be built', async () => {
486
- const errorSpy = spyOn(ErrorModalService, 'error').and.returnValue(Promise.resolve({}) as any);
465
+ const errorSpy = vi.spyOn(ErrorModalService, 'error').mockReturnValue(Promise.resolve({}) as any);
487
466
  const commandBuilder = {
488
- buildServerGroupCommandFromExisting: jasmine
489
- .createSpy('buildServerGroupCommandFromExisting')
490
- .and.returnValue(Promise.reject({ data: { message: 'missing launch template' } })),
467
+ buildServerGroupCommandFromExisting: vi
468
+ .fn()
469
+ .mockReturnValue(Promise.reject({ data: { message: 'missing launch template' } })),
491
470
  };
492
471
 
493
472
  await cloneGceServerGroup(
@@ -508,8 +487,8 @@ describe('Google provider registration', () => {
508
487
  });
509
488
 
510
489
  it('closes GCE load balancer details when no matching summary exists', async () => {
511
- const loadBalancerReader = { getLoadBalancerDetails: jasmine.createSpy('getLoadBalancerDetails') };
512
- const autoClose = jasmine.createSpy('autoClose');
490
+ const loadBalancerReader = { getLoadBalancerDetails: vi.fn() };
491
+ const autoClose = vi.fn();
513
492
 
514
493
  const loadBalancer = await loadGceLoadBalancerDetails({
515
494
  app: { loadBalancers: { data: [] } } as any,
@@ -555,8 +534,8 @@ describe('Google provider registration', () => {
555
534
 
556
535
  expectedStages.forEach((provides) => {
557
536
  const stage = gceStages.find((candidate: any) => candidate.provides === provides);
558
- expect(stage).withContext(`gce ${provides} stage`).toBeDefined();
559
- expect(stage?.component).withContext(`gce ${provides} stage component`).toBeDefined();
537
+ expect(stage, `gce ${provides} stage`).toBeDefined();
538
+ expect(stage?.component, `gce ${provides} stage component`).toBeDefined();
560
539
  });
561
540
  } finally {
562
541
  Registry.pipeline = previousPipeline;
@@ -591,7 +570,7 @@ describe('Google provider registration', () => {
591
570
 
592
571
  expectedStages.forEach((provides) => {
593
572
  const registrations = gceStages.filter((stage: any) => stage.provides === provides);
594
- expect(registrations.length).withContext(`gce ${provides} registration count`).toBe(1);
573
+ expect(registrations.length, `gce ${provides} registration count`).toBe(1);
595
574
  });
596
575
  } finally {
597
576
  Registry.pipeline = previousPipeline;