@spinnaker/ecs 2026.2.3 → 2026.3.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/ecs.module.d.ts +3 -1
- package/dist/ecsCluster/ecsCluster.read.service.d.ts +2 -3
- package/dist/iamRoles/iamRole.read.service.d.ts +1 -2
- package/dist/index.d.ts +5 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/instance/details/EcsInstanceDetails.d.ts +50 -0
- package/dist/loadBalancer/loadBalancer.transformer.d.ts +1 -5
- package/dist/loadBalancer/targetGroup.states.d.ts +2 -1
- package/dist/metricAlarm/metricAlarm.read.service.d.ts +1 -2
- package/dist/pipeline/stages/cloneServerGroup/ecsCloneServerGroupStage.d.ts +1 -0
- package/dist/pipeline/stages/common/EcsServerGroupStepLabel.d.ts +7 -0
- package/dist/pipeline/stages/common/EcsStageConfigs.d.ts +11 -0
- package/dist/pipeline/stages/destroyAsg/ecsDestroyAsgStage.d.ts +1 -2
- package/dist/pipeline/stages/disableAsg/ecsDisableAsgStage.d.ts +1 -2
- package/dist/pipeline/stages/disableCluster/ecsDisableClusterStage.d.ts +1 -2
- package/dist/pipeline/stages/enableAsg/ecsEnableAsgStage.d.ts +1 -2
- package/dist/pipeline/stages/findImageFromTags/EcsFindImageFromTagsExecutionDetails.d.ts +5 -0
- package/dist/pipeline/stages/findImageFromTags/ecsFindImageFromTagStage.d.ts +1 -2
- package/dist/pipeline/stages/resizeAsg/ecsResizeAsgStage.d.ts +1 -2
- package/dist/pipeline/stages/scaleDownCluster/ecsScaleDownClusterStage.d.ts +1 -2
- package/dist/pipeline/stages/shrinkCluster/ecsShrinkClusterStage.d.ts +1 -2
- package/dist/placementStrategy/placementStrategy.service.d.ts +0 -1
- package/dist/secrets/secret.read.service.d.ts +1 -2
- package/dist/securityGroup/details/EcsSecurityGroupDetails.d.ts +45 -0
- package/dist/securityGroup/securityGroup.reader.d.ts +0 -1
- package/dist/securityGroup/securityGroup.transformer.d.ts +3 -2
- package/dist/serverGroup/configure/dockerImage.util.d.ts +3 -0
- package/dist/serverGroup/configure/serverGroupCommandBuilder.service.d.ts +111 -2
- package/dist/serverGroup/configure/serverGroupConfiguration.service.d.ts +13 -63
- package/dist/serverGroup/configure/wizard/EcsCloneServerGroupModal.d.ts +64 -0
- package/dist/serverGroup/configure/wizard/capacityProvider/CapacityProvider.d.ts +29 -4
- package/dist/serverGroup/configure/wizard/container/Container.d.ts +3 -3
- package/dist/serverGroup/configure/wizard/networking/Networking.d.ts +3 -3
- package/dist/serverGroup/configure/wizard/pages/AdvancedSettings.d.ts +3 -0
- package/dist/serverGroup/configure/wizard/pages/BasicSettings.d.ts +3 -0
- package/dist/serverGroup/configure/wizard/pages/ContainerSettings.d.ts +3 -0
- package/dist/serverGroup/configure/wizard/pages/HorizontalScalingSettings.d.ts +3 -0
- package/dist/serverGroup/configure/wizard/pages/LoggingSettings.d.ts +3 -0
- package/dist/serverGroup/configure/wizard/pages/NetworkingSettings.d.ts +3 -0
- package/dist/serverGroup/configure/wizard/pages/ServiceDiscoverySettings.d.ts +3 -0
- package/dist/serverGroup/configure/wizard/pages/TaskDefinitionSettings.d.ts +3 -0
- package/dist/serverGroup/configure/wizard/pages/common.d.ts +8 -0
- package/dist/serverGroup/configure/wizard/pages/validation.d.ts +22 -0
- package/dist/serverGroup/configure/wizard/serviceDiscovery/ServiceDiscovery.d.ts +5 -3
- package/dist/serverGroup/configure/wizard/taskDefinition/TaskDefinition.d.ts +3 -3
- package/dist/serverGroup/details/EcsServerGroupActions.d.ts +6 -0
- package/dist/serverGroup/details/ecsServerGroupDetailsGetter.d.ts +3 -0
- package/dist/serverGroup/details/resize/EcsResizeServerGroupModal.d.ts +43 -0
- package/dist/serverGroup/details/resize/index.d.ts +1 -0
- package/dist/serverGroup/details/rollback/EcsRollbackServerGroupModal.d.ts +46 -0
- package/dist/serverGroup/details/rollback/index.d.ts +1 -0
- package/dist/serverGroup/details/sections/EcsServerGroupDetailsSections.d.ts +9 -0
- package/dist/serverGroup/details/sections/EcsServerGroupEventsSection.d.ts +3 -0
- package/dist/serverGroup/details/sections/EcsServerGroupInformationSection.d.ts +3 -0
- package/dist/serverGroup/events/EcsServerGroupEventsModal.d.ts +22 -0
- package/dist/serverGroup/events/EventsLink.d.ts +2 -0
- package/dist/serverGroup/events/serverGroupEventsReader.service.d.ts +1 -1
- package/dist/serverGroup/serverGroup.transformer.d.ts +1 -2
- package/dist/serviceDiscovery/serviceDiscovery.read.service.d.ts +1 -1
- package/package.json +3 -9
- package/src/ecs.module.spec.ts +86 -0
- package/src/ecs.module.ts +68 -84
- package/src/ecsCluster/ecsCluster.read.service.ts +3 -9
- package/src/iamRoles/iamRole.read.service.ts +1 -7
- package/src/index.ts +6 -0
- package/src/instance/details/EcsInstanceDetails.spec.tsx +426 -0
- package/src/instance/details/EcsInstanceDetails.tsx +474 -0
- package/src/loadBalancer/details/loadBalancerDetails.tsx +1 -1
- package/src/loadBalancer/details/targetGroupDetails.tsx +1 -1
- package/src/loadBalancer/loadBalancer.transformer.ts +2 -7
- package/src/loadBalancer/targetGroup.states.ts +55 -53
- package/src/metricAlarm/metricAlarm.read.service.ts +1 -7
- package/src/pipeline/stages/cloneServerGroup/ecsCloneServerGroupStage.js +22 -94
- package/src/pipeline/stages/common/EcsServerGroupStepLabel.tsx +16 -0
- package/src/pipeline/stages/common/EcsStageConfigs.tsx +587 -0
- package/src/pipeline/stages/destroyAsg/ecsDestroyAsgStage.js +29 -65
- package/src/pipeline/stages/disableAsg/ecsDisableAsgStage.js +27 -70
- package/src/pipeline/stages/disableCluster/ecsDisableClusterStage.js +21 -84
- package/src/pipeline/stages/enableAsg/ecsEnableAsgStage.js +22 -73
- package/src/pipeline/stages/findImageFromTags/EcsFindImageFromTagsExecutionDetails.tsx +40 -0
- package/src/pipeline/stages/findImageFromTags/ecsFindImageFromTagStage.js +12 -24
- package/src/pipeline/stages/resizeAsg/ecsResizeAsgStage.js +30 -128
- package/src/pipeline/stages/scaleDownCluster/ecsScaleDownClusterStage.js +24 -78
- package/src/pipeline/stages/shrinkCluster/ecsShrinkClusterStage.js +19 -73
- package/src/placementStrategy/placementStrategy.service.ts +0 -6
- package/src/secrets/secret.read.service.ts +1 -7
- package/src/securityGroup/details/EcsSecurityGroupDetails.spec.tsx +245 -0
- package/src/securityGroup/details/EcsSecurityGroupDetails.tsx +285 -0
- package/src/securityGroup/securityGroup.reader.ts +0 -5
- package/src/securityGroup/securityGroup.transformer.js +5 -13
- package/src/serverGroup/configure/dockerImage.util.ts +29 -0
- package/src/serverGroup/configure/serverGroupCommandBuilder.service.js +215 -278
- package/src/serverGroup/configure/serverGroupCommandBuilder.service.spec.ts +83 -0
- package/src/serverGroup/configure/serverGroupConfiguration.service.ts +16 -633
- package/src/serverGroup/configure/wizard/EcsCloneServerGroupModal.spec.tsx +2078 -0
- package/src/serverGroup/configure/wizard/EcsCloneServerGroupModal.tsx +712 -0
- package/src/serverGroup/configure/wizard/capacityProvider/CapacityProvider.tsx +98 -49
- package/src/serverGroup/configure/wizard/container/Container.spec.tsx +20 -8
- package/src/serverGroup/configure/wizard/container/Container.tsx +53 -24
- package/src/serverGroup/configure/wizard/networking/Networking.tsx +60 -38
- package/src/serverGroup/configure/wizard/pages/AdvancedSettings.tsx +290 -0
- package/src/serverGroup/configure/wizard/pages/BasicSettings.tsx +101 -0
- package/src/serverGroup/configure/wizard/pages/ContainerSettings.tsx +10 -0
- package/src/serverGroup/configure/wizard/pages/HorizontalScalingSettings.tsx +137 -0
- package/src/serverGroup/configure/wizard/pages/LoggingSettings.tsx +60 -0
- package/src/serverGroup/configure/wizard/pages/NetworkingSettings.tsx +10 -0
- package/src/serverGroup/configure/wizard/pages/ServiceDiscoverySettings.tsx +10 -0
- package/src/serverGroup/configure/wizard/pages/TaskDefinitionSettings.tsx +59 -0
- package/src/serverGroup/configure/wizard/pages/common.ts +10 -0
- package/src/serverGroup/configure/wizard/pages/validation.tsx +190 -0
- package/src/serverGroup/configure/wizard/serviceDiscovery/ServiceDiscovery.tsx +83 -34
- package/src/serverGroup/configure/wizard/taskDefinition/TaskDefinition.spec.tsx +21 -8
- package/src/serverGroup/configure/wizard/taskDefinition/TaskDefinition.tsx +63 -33
- package/src/serverGroup/details/EcsServerGroupActions.spec.tsx +244 -0
- package/src/serverGroup/details/EcsServerGroupActions.tsx +152 -0
- package/src/serverGroup/details/ecsServerGroupDetailsGetter.spec.ts +110 -0
- package/src/serverGroup/details/ecsServerGroupDetailsGetter.ts +73 -0
- package/src/serverGroup/details/resize/EcsResizeServerGroupModal.spec.tsx +130 -0
- package/src/serverGroup/details/resize/EcsResizeServerGroupModal.tsx +263 -0
- package/src/serverGroup/details/resize/index.ts +1 -0
- package/src/serverGroup/details/rollback/EcsRollbackServerGroupModal.spec.tsx +173 -0
- package/src/serverGroup/details/rollback/EcsRollbackServerGroupModal.tsx +285 -0
- package/src/serverGroup/details/rollback/index.ts +1 -0
- package/src/serverGroup/details/sections/EcsServerGroupDetailsSections.spec.tsx +130 -0
- package/src/serverGroup/details/sections/EcsServerGroupDetailsSections.tsx +172 -0
- package/src/serverGroup/details/sections/EcsServerGroupEventsSection.tsx +14 -0
- package/src/serverGroup/details/sections/EcsServerGroupInformationSection.tsx +25 -0
- package/src/serverGroup/events/EcsServerGroupEventsModal.spec.tsx +109 -0
- package/src/serverGroup/events/EcsServerGroupEventsModal.tsx +112 -0
- package/src/serverGroup/events/EventsLink.tsx +18 -0
- package/src/serverGroup/events/serverGroupEventsReader.service.spec.ts +41 -0
- package/src/serverGroup/events/serverGroupEventsReader.service.ts +2 -8
- package/src/serverGroup/serverGroup.transformer.spec.ts +10 -24
- package/src/serverGroup/serverGroup.transformer.ts +1 -5
- package/src/serviceDiscovery/serviceDiscovery.read.service.ts +1 -1
- package/dist/common/common.module.d.ts +0 -1
- package/dist/common/footer.component.d.ts +0 -1
- package/dist/instance/details/instance.details.controller.d.ts +0 -2
- package/dist/securityGroup/details/securityGroupDetail.controller.d.ts +0 -2
- package/dist/securityGroup/securityGroup.module.d.ts +0 -1
- package/dist/serverGroup/configure/wizard/CloneServerGroup.ecs.controller.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/advancedSettings/advancedSettings.component.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/horizontalScaling/horizontalScaling.component.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/location/ServerGroupBasicSettings.controller.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/logging/logging.component.d.ts +0 -1
- package/dist/serverGroup/details/resize/resizeCapacity.component.d.ts +0 -1
- package/dist/serverGroup/details/resize/resizeServerGroup.controller.d.ts +0 -2
- package/dist/serverGroup/details/rollback/rollbackServerGroup.controller.d.ts +0 -2
- package/dist/serverGroup/details/serverGroupDetails.ecs.controller.d.ts +0 -2
- package/dist/serverGroup/details/serverGroupDetails.module.d.ts +0 -1
- package/dist/serverGroup/events/events.component.d.ts +0 -3
- package/dist/serverGroup/events/events.controller.d.ts +0 -19
- package/dist/serverGroup/serverGroup.module.d.ts +0 -1
- package/src/common/common.module.ts +0 -6
- package/src/common/footer.component.ts +0 -29
- package/src/instance/details/instance.details.controller.js +0 -356
- package/src/instance/details/instanceDetails.html +0 -204
- package/src/pipeline/stages/cloneServerGroup/cloneServerGroupStage.html +0 -101
- package/src/pipeline/stages/cloneServerGroup/cloneServerGroupStepLabel.html +0 -1
- package/src/pipeline/stages/destroyAsg/destroyAsgStage.html +0 -9
- package/src/pipeline/stages/destroyAsg/destroyAsgStepLabel.html +0 -1
- package/src/pipeline/stages/disableAsg/disableAsgStage.html +0 -11
- package/src/pipeline/stages/disableAsg/disableAsgStepLabel.html +0 -1
- package/src/pipeline/stages/disableCluster/disableClusterStage.html +0 -26
- package/src/pipeline/stages/enableAsg/enableAsgStage.html +0 -11
- package/src/pipeline/stages/enableAsg/enableAsgStepLabel.html +0 -1
- package/src/pipeline/stages/findImageFromTags/findImageFromTagsExecutionDetails.html +0 -36
- package/src/pipeline/stages/findImageFromTags/findImageFromTagsStage.html +0 -9
- package/src/pipeline/stages/resizeAsg/resizeAsgStage.html +0 -87
- package/src/pipeline/stages/resizeAsg/resizeAsgStepLabel.html +0 -1
- package/src/pipeline/stages/scaleDownCluster/scaleDownClusterStage.html +0 -35
- package/src/pipeline/stages/shrinkCluster/shrinkClusterStage.html +0 -34
- package/src/securityGroup/details/securityGroupDetail.controller.js +0 -147
- package/src/securityGroup/details/securityGroupDetail.html +0 -104
- package/src/securityGroup/securityGroup.module.ts +0 -12
- package/src/serverGroup/configure/wizard/CloneServerGroup.ecs.controller.js +0 -259
- package/src/serverGroup/configure/wizard/advancedSettings/advancedSettings.component.html +0 -194
- package/src/serverGroup/configure/wizard/advancedSettings/advancedSettings.component.js +0 -17
- package/src/serverGroup/configure/wizard/advancedSettings/advancedSettings.html +0 -10
- package/src/serverGroup/configure/wizard/capacityProvider/capacityProvider.html +0 -11
- package/src/serverGroup/configure/wizard/container/container.html +0 -9
- package/src/serverGroup/configure/wizard/horizontalScaling/horizontalScaling.component.html +0 -118
- package/src/serverGroup/configure/wizard/horizontalScaling/horizontalScaling.component.js +0 -20
- package/src/serverGroup/configure/wizard/horizontalScaling/horizontalScaling.html +0 -13
- package/src/serverGroup/configure/wizard/location/ServerGroupBasicSettings.controller.js +0 -41
- package/src/serverGroup/configure/wizard/location/basicSettings.html +0 -137
- package/src/serverGroup/configure/wizard/logging/logging.component.html +0 -29
- package/src/serverGroup/configure/wizard/logging/logging.component.ts +0 -12
- package/src/serverGroup/configure/wizard/logging/logging.html +0 -7
- package/src/serverGroup/configure/wizard/networking/networking.html +0 -9
- package/src/serverGroup/configure/wizard/serverGroupWizard.html +0 -55
- package/src/serverGroup/configure/wizard/serviceDiscovery/serviceDiscovery.html +0 -11
- package/src/serverGroup/configure/wizard/taskDefinition/taskDefinition.html +0 -51
- package/src/serverGroup/configure/wizard/templateSelection/templateSelection.html +0 -9
- package/src/serverGroup/configure/wizard/verticalScaling/verticalScaling.html +0 -10
- package/src/serverGroup/details/resize/resizeCapacity.component.html +0 -94
- package/src/serverGroup/details/resize/resizeCapacity.component.ts +0 -14
- package/src/serverGroup/details/resize/resizeServerGroup.controller.js +0 -85
- package/src/serverGroup/details/resize/resizeServerGroup.html +0 -28
- package/src/serverGroup/details/rollback/rollbackServerGroup.controller.js +0 -97
- package/src/serverGroup/details/rollback/rollbackServerGroup.html +0 -67
- package/src/serverGroup/details/serverGroupDetails.ecs.controller.js +0 -366
- package/src/serverGroup/details/serverGroupDetails.html +0 -216
- package/src/serverGroup/details/serverGroupDetails.module.ts +0 -5
- package/src/serverGroup/events/events.component.ts +0 -35
- package/src/serverGroup/events/events.controller.ts +0 -45
- package/src/serverGroup/events/events.html +0 -36
- package/src/serverGroup/serverGroup.module.ts +0 -6
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { shallow } from 'enzyme';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
PlatformHealthOverride,
|
|
6
|
+
ReactModal,
|
|
7
|
+
SpinFormik,
|
|
8
|
+
TaskMonitorWrapper,
|
|
9
|
+
TaskReason,
|
|
10
|
+
UserVerification,
|
|
11
|
+
} from '@spinnaker/core';
|
|
12
|
+
|
|
13
|
+
import { EcsResizeServerGroupModal, validateEcsResizeValues } from './index';
|
|
14
|
+
|
|
15
|
+
describe('EcsResizeServerGroupModal', () => {
|
|
16
|
+
const serverGroup = {
|
|
17
|
+
account: 'test-account',
|
|
18
|
+
capacity: { desired: 4, max: 8, min: 2 },
|
|
19
|
+
name: 'fnord-main-v004',
|
|
20
|
+
region: 'eu-west-1',
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
function application(attributes: any = {}) {
|
|
24
|
+
return {
|
|
25
|
+
attributes,
|
|
26
|
+
serverGroups: { refresh: jasmine.createSpy('refresh') },
|
|
27
|
+
} as any;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function props(app = application()) {
|
|
31
|
+
return {
|
|
32
|
+
application: app,
|
|
33
|
+
closeModal: jasmine.createSpy('closeModal'),
|
|
34
|
+
dismissModal: jasmine.createSpy('dismissModal'),
|
|
35
|
+
serverGroup: serverGroup as any,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
it('validates non-negative min, max, and desired capacities in range', () => {
|
|
40
|
+
expect(validateEcsResizeValues({ capacity: { desired: 4, max: 8, min: -1 } })).toEqual({
|
|
41
|
+
capacity: { min: 'Min cannot be negative' },
|
|
42
|
+
});
|
|
43
|
+
expect(validateEcsResizeValues({ capacity: { desired: 4, max: 1, min: 2 } })).toEqual({
|
|
44
|
+
capacity: { max: 'Max cannot be smaller than Min', min: 'Min cannot be larger than Max' },
|
|
45
|
+
});
|
|
46
|
+
expect(validateEcsResizeValues({ capacity: { desired: 1, max: 8, min: 2 } })).toEqual({
|
|
47
|
+
capacity: { desired: 'Desired cannot be smaller than Min' },
|
|
48
|
+
});
|
|
49
|
+
expect(validateEcsResizeValues({ capacity: { desired: 9, max: 8, min: 2 } })).toEqual({
|
|
50
|
+
capacity: { desired: 'Desired cannot be larger than Max' },
|
|
51
|
+
});
|
|
52
|
+
expect(validateEcsResizeValues({ capacity: { desired: 4, max: 8, min: 2 } })).toEqual({});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('submits the exact shared resize writer contract through its task monitor', () => {
|
|
56
|
+
const app = application({ platformHealthOnly: true, platformHealthOnlyShowOverride: true });
|
|
57
|
+
const writer = { resizeServerGroup: jasmine.createSpy('resizeServerGroup').and.returnValue(Promise.resolve()) };
|
|
58
|
+
const component = new EcsResizeServerGroupModal(props(app));
|
|
59
|
+
(component as any).context = { services: { serverGroupWriter: writer } };
|
|
60
|
+
component.setState = ((update: any) => {
|
|
61
|
+
component.state = { ...component.state, ...(typeof update === 'function' ? update(component.state) : update) };
|
|
62
|
+
}) as any;
|
|
63
|
+
component.setState({ verified: true });
|
|
64
|
+
spyOn(component.state.taskMonitor, 'submit').and.callFake((submitMethod: any) => submitMethod());
|
|
65
|
+
|
|
66
|
+
(component as any).submit({
|
|
67
|
+
capacity: { desired: 6, max: 10, min: 3 },
|
|
68
|
+
interestingHealthProviderNames: ['Ecs'],
|
|
69
|
+
reason: ' preserve this resize reason exactly ',
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
expect(component.state.taskMonitor.submit).toHaveBeenCalled();
|
|
73
|
+
expect(writer.resizeServerGroup).toHaveBeenCalledOnceWith(serverGroup, app, {
|
|
74
|
+
capacity: { desired: 6, max: 10, min: 3 },
|
|
75
|
+
interestingHealthProviderNames: ['Ecs'],
|
|
76
|
+
reason: ' preserve this resize reason exactly ',
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('does not submit invalid or unverified resize commands', () => {
|
|
81
|
+
const writer = { resizeServerGroup: jasmine.createSpy('resizeServerGroup') };
|
|
82
|
+
const component = new EcsResizeServerGroupModal(props());
|
|
83
|
+
(component as any).context = { services: { serverGroupWriter: writer } };
|
|
84
|
+
spyOn(component.state.taskMonitor, 'submit');
|
|
85
|
+
|
|
86
|
+
(component as any).submit({ capacity: { desired: 9, max: 8, min: 2 } });
|
|
87
|
+
component.state.verified = true;
|
|
88
|
+
(component as any).submit({ capacity: { desired: 9, max: 8, min: 2 } });
|
|
89
|
+
|
|
90
|
+
expect(component.state.taskMonitor.submit).not.toHaveBeenCalled();
|
|
91
|
+
expect(writer.resizeServerGroup).not.toHaveBeenCalled();
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('renders task, capacity, verification, reason, and ECS platform-health controls', () => {
|
|
95
|
+
const app = application({ platformHealthOnly: true, platformHealthOnlyShowOverride: true });
|
|
96
|
+
const wrapper = shallow(<EcsResizeServerGroupModal {...props(app)} />);
|
|
97
|
+
const formik = wrapper.find(SpinFormik);
|
|
98
|
+
expect(wrapper.find(TaskMonitorWrapper).prop('monitor')).toBe((wrapper.instance() as any).state.taskMonitor);
|
|
99
|
+
|
|
100
|
+
const content = shallow(
|
|
101
|
+
<div>
|
|
102
|
+
{(formik.prop('render') as any)({
|
|
103
|
+
errors: {},
|
|
104
|
+
isValid: true,
|
|
105
|
+
setFieldValue: jasmine.createSpy('setFieldValue'),
|
|
106
|
+
values: formik.prop('initialValues'),
|
|
107
|
+
})}
|
|
108
|
+
</div>,
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
expect(content.find(UserVerification).prop('account')).toBe('test-account');
|
|
112
|
+
expect(content.find(TaskReason).exists()).toBe(true);
|
|
113
|
+
expect(content.find('[name="capacity.min"]').exists()).toBe(true);
|
|
114
|
+
expect(content.find('[name="capacity.max"]').exists()).toBe(true);
|
|
115
|
+
expect(content.find('[name="capacity.desired"]').exists()).toBe(true);
|
|
116
|
+
expect(content.find(PlatformHealthOverride).props()).toEqual(
|
|
117
|
+
jasmine.objectContaining({ interestingHealthProviderNames: ['Ecs'], platformHealthType: 'Ecs' }),
|
|
118
|
+
);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it('exports a show primitive for later actions integration', () => {
|
|
122
|
+
const show = spyOn(ReactModal, 'show').and.returnValue(Promise.resolve() as any);
|
|
123
|
+
const modalProps = props();
|
|
124
|
+
const runtimeServices = {} as any;
|
|
125
|
+
|
|
126
|
+
EcsResizeServerGroupModal.show(modalProps, runtimeServices);
|
|
127
|
+
|
|
128
|
+
expect(show).toHaveBeenCalledOnceWith(EcsResizeServerGroupModal, modalProps, undefined, runtimeServices);
|
|
129
|
+
});
|
|
130
|
+
});
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Modal } from 'react-bootstrap';
|
|
3
|
+
|
|
4
|
+
import type {
|
|
5
|
+
Application,
|
|
6
|
+
DeckRuntimeServices,
|
|
7
|
+
IModalComponentProps,
|
|
8
|
+
IServerGroup,
|
|
9
|
+
IServerGroupJob,
|
|
10
|
+
} from '@spinnaker/core';
|
|
11
|
+
import {
|
|
12
|
+
DeckRuntimeContext,
|
|
13
|
+
FormikFormField,
|
|
14
|
+
MinMaxDesiredChanges,
|
|
15
|
+
ModalClose,
|
|
16
|
+
noop,
|
|
17
|
+
NumberInput,
|
|
18
|
+
PlatformHealthOverride,
|
|
19
|
+
ReactModal,
|
|
20
|
+
SpinFormik,
|
|
21
|
+
TaskMonitor,
|
|
22
|
+
TaskMonitorWrapper,
|
|
23
|
+
TaskReason,
|
|
24
|
+
UserVerification,
|
|
25
|
+
ValidationMessage,
|
|
26
|
+
} from '@spinnaker/core';
|
|
27
|
+
|
|
28
|
+
export interface IEcsResizeServerGroupModalProps extends IModalComponentProps {
|
|
29
|
+
application: Application;
|
|
30
|
+
serverGroup: IServerGroup;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface IEcsResizeCapacity {
|
|
34
|
+
desired: number;
|
|
35
|
+
max: number;
|
|
36
|
+
min: number;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface IEcsResizeServerGroupValues {
|
|
40
|
+
capacity: IEcsResizeCapacity;
|
|
41
|
+
interestingHealthProviderNames?: string[];
|
|
42
|
+
reason?: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface IEcsResizeServerGroupJob extends IServerGroupJob {
|
|
46
|
+
capacity: IEcsResizeCapacity;
|
|
47
|
+
interestingHealthProviderNames?: string[];
|
|
48
|
+
reason?: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface IEcsResizeServerGroupErrors {
|
|
52
|
+
capacity?: Partial<Record<keyof IEcsResizeCapacity, string>>;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
interface IEcsResizeServerGroupModalState {
|
|
56
|
+
initialValues: IEcsResizeServerGroupValues;
|
|
57
|
+
taskMonitor: TaskMonitor;
|
|
58
|
+
verified: boolean;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function validateEcsResizeValues(values: IEcsResizeServerGroupValues): IEcsResizeServerGroupErrors {
|
|
62
|
+
const { desired, max, min } = values.capacity;
|
|
63
|
+
const capacity: IEcsResizeServerGroupErrors['capacity'] = {};
|
|
64
|
+
|
|
65
|
+
if (!Number.isFinite(min) || min < 0) {
|
|
66
|
+
capacity.min = 'Min cannot be negative';
|
|
67
|
+
}
|
|
68
|
+
if (!Number.isFinite(max) || max < 0) {
|
|
69
|
+
capacity.max = 'Max cannot be negative';
|
|
70
|
+
}
|
|
71
|
+
if (!Number.isFinite(desired) || desired < 0) {
|
|
72
|
+
capacity.desired = 'Desired cannot be negative';
|
|
73
|
+
}
|
|
74
|
+
if (Object.keys(capacity).length > 0) {
|
|
75
|
+
return { capacity };
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (min > max) {
|
|
79
|
+
capacity.min = 'Min cannot be larger than Max';
|
|
80
|
+
capacity.max = 'Max cannot be smaller than Min';
|
|
81
|
+
} else if (desired < min) {
|
|
82
|
+
capacity.desired = 'Desired cannot be smaller than Min';
|
|
83
|
+
} else if (desired > max) {
|
|
84
|
+
capacity.desired = 'Desired cannot be larger than Max';
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return Object.keys(capacity).length > 0 ? { capacity } : {};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export class EcsResizeServerGroupModal extends React.Component<
|
|
91
|
+
IEcsResizeServerGroupModalProps,
|
|
92
|
+
IEcsResizeServerGroupModalState
|
|
93
|
+
> {
|
|
94
|
+
public static contextType = DeckRuntimeContext;
|
|
95
|
+
public declare context: React.ContextType<typeof DeckRuntimeContext>;
|
|
96
|
+
|
|
97
|
+
public static defaultProps: Partial<IEcsResizeServerGroupModalProps> = {
|
|
98
|
+
closeModal: noop,
|
|
99
|
+
dismissModal: noop,
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
public static show(
|
|
103
|
+
props: IEcsResizeServerGroupModalProps,
|
|
104
|
+
runtimeServices: DeckRuntimeServices,
|
|
105
|
+
): Promise<IEcsResizeServerGroupJob> {
|
|
106
|
+
return ReactModal.show(EcsResizeServerGroupModal, props, undefined, runtimeServices);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
public constructor(props: IEcsResizeServerGroupModalProps) {
|
|
110
|
+
super(props);
|
|
111
|
+
const { application, serverGroup } = props;
|
|
112
|
+
const attributes = application.attributes || {};
|
|
113
|
+
this.state = {
|
|
114
|
+
initialValues: {
|
|
115
|
+
capacity: {
|
|
116
|
+
desired: Number(serverGroup.capacity.desired),
|
|
117
|
+
max: Number(serverGroup.capacity.max),
|
|
118
|
+
min: Number(serverGroup.capacity.min),
|
|
119
|
+
},
|
|
120
|
+
interestingHealthProviderNames:
|
|
121
|
+
attributes.platformHealthOnlyShowOverride && attributes.platformHealthOnly ? ['Ecs'] : undefined,
|
|
122
|
+
},
|
|
123
|
+
taskMonitor: new TaskMonitor({
|
|
124
|
+
application,
|
|
125
|
+
title: `Resizing ${serverGroup.name}`,
|
|
126
|
+
onDismiss: () => this.props.dismissModal(),
|
|
127
|
+
onTaskComplete: () => application.serverGroups.refresh(),
|
|
128
|
+
}),
|
|
129
|
+
verified: false,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
private close = (): void => this.props.dismissModal();
|
|
134
|
+
|
|
135
|
+
private submit = (values: IEcsResizeServerGroupValues): void => {
|
|
136
|
+
if (!this.state.verified || Object.keys(validateEcsResizeValues(values)).length > 0) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const { application, serverGroup } = this.props;
|
|
141
|
+
const command: IEcsResizeServerGroupJob = {
|
|
142
|
+
capacity: values.capacity,
|
|
143
|
+
interestingHealthProviderNames: values.interestingHealthProviderNames,
|
|
144
|
+
reason: values.reason,
|
|
145
|
+
};
|
|
146
|
+
this.state.taskMonitor.submit(() =>
|
|
147
|
+
this.context.services.serverGroupWriter.resizeServerGroup(serverGroup, application, command),
|
|
148
|
+
);
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
private capacityError(errors: IEcsResizeServerGroupErrors): string | undefined {
|
|
152
|
+
const capacity = errors.capacity;
|
|
153
|
+
return capacity && ([capacity.min, capacity.max, capacity.desired].find(Boolean) as string);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
public render(): JSX.Element {
|
|
157
|
+
const { application, serverGroup } = this.props;
|
|
158
|
+
|
|
159
|
+
return (
|
|
160
|
+
<>
|
|
161
|
+
<TaskMonitorWrapper monitor={this.state.taskMonitor} />
|
|
162
|
+
<SpinFormik<IEcsResizeServerGroupValues>
|
|
163
|
+
initialValues={this.state.initialValues}
|
|
164
|
+
onSubmit={this.submit}
|
|
165
|
+
validate={validateEcsResizeValues}
|
|
166
|
+
render={(formik) => {
|
|
167
|
+
const error = this.capacityError(formik.errors as IEcsResizeServerGroupErrors);
|
|
168
|
+
return (
|
|
169
|
+
<>
|
|
170
|
+
<ModalClose dismiss={this.close} />
|
|
171
|
+
<Modal.Header>
|
|
172
|
+
<Modal.Title>Resize {serverGroup.name}</Modal.Title>
|
|
173
|
+
</Modal.Header>
|
|
174
|
+
<Modal.Body>
|
|
175
|
+
<form className="form-horizontal">
|
|
176
|
+
<div className="form-group bold">
|
|
177
|
+
<div className="col-sm-2 col-sm-offset-3">Min</div>
|
|
178
|
+
<div className="col-sm-2">Max</div>
|
|
179
|
+
<div className="col-sm-2">Desired</div>
|
|
180
|
+
</div>
|
|
181
|
+
<div className="form-group">
|
|
182
|
+
<div className="col-sm-3 sm-label-right">Current</div>
|
|
183
|
+
{(['min', 'max', 'desired'] as Array<keyof IEcsResizeCapacity>).map((field) => (
|
|
184
|
+
<div className="col-sm-2" key={field}>
|
|
185
|
+
<input
|
|
186
|
+
className="form-control input-sm"
|
|
187
|
+
disabled={true}
|
|
188
|
+
type="number"
|
|
189
|
+
value={serverGroup.capacity[field]}
|
|
190
|
+
/>
|
|
191
|
+
</div>
|
|
192
|
+
))}
|
|
193
|
+
</div>
|
|
194
|
+
<div className="form-group">
|
|
195
|
+
<div className="col-sm-3 sm-label-right">Resize to</div>
|
|
196
|
+
{(['min', 'max', 'desired'] as Array<keyof IEcsResizeCapacity>).map((field) => (
|
|
197
|
+
<div className="col-sm-2" key={field}>
|
|
198
|
+
<FormikFormField
|
|
199
|
+
name={`capacity.${field}`}
|
|
200
|
+
input={(props) => <NumberInput {...props} min={0} />}
|
|
201
|
+
layout={({ input }) => <>{input}</>}
|
|
202
|
+
touched={true}
|
|
203
|
+
/>
|
|
204
|
+
</div>
|
|
205
|
+
))}
|
|
206
|
+
</div>
|
|
207
|
+
{error && (
|
|
208
|
+
<div className="col-sm-9 col-sm-offset-3">
|
|
209
|
+
<ValidationMessage message={error} type="error" />
|
|
210
|
+
</div>
|
|
211
|
+
)}
|
|
212
|
+
|
|
213
|
+
<div className="form-group">
|
|
214
|
+
<div className="col-sm-3 sm-label-right">Changes</div>
|
|
215
|
+
<div className="col-sm-9 sm-control-field">
|
|
216
|
+
<MinMaxDesiredChanges current={serverGroup.capacity} next={formik.values.capacity} />
|
|
217
|
+
</div>
|
|
218
|
+
</div>
|
|
219
|
+
|
|
220
|
+
{application.attributes?.platformHealthOnlyShowOverride && (
|
|
221
|
+
<div className="form-group">
|
|
222
|
+
<div className="col-sm-10 col-sm-offset-1">
|
|
223
|
+
<PlatformHealthOverride
|
|
224
|
+
interestingHealthProviderNames={formik.values.interestingHealthProviderNames}
|
|
225
|
+
onChange={(names) => formik.setFieldValue('interestingHealthProviderNames', names)}
|
|
226
|
+
platformHealthType="Ecs"
|
|
227
|
+
showHelpDetails={true}
|
|
228
|
+
/>
|
|
229
|
+
</div>
|
|
230
|
+
</div>
|
|
231
|
+
)}
|
|
232
|
+
|
|
233
|
+
<TaskReason
|
|
234
|
+
reason={formik.values.reason}
|
|
235
|
+
onChange={(reason) => formik.setFieldValue('reason', reason)}
|
|
236
|
+
/>
|
|
237
|
+
</form>
|
|
238
|
+
</Modal.Body>
|
|
239
|
+
<Modal.Footer>
|
|
240
|
+
<UserVerification
|
|
241
|
+
account={serverGroup.account}
|
|
242
|
+
onValidChange={(verified) => this.setState({ verified })}
|
|
243
|
+
/>
|
|
244
|
+
<button className="btn btn-default" onClick={this.close} type="button">
|
|
245
|
+
Cancel
|
|
246
|
+
</button>
|
|
247
|
+
<button
|
|
248
|
+
className="btn btn-primary"
|
|
249
|
+
disabled={!this.state.verified || !formik.isValid}
|
|
250
|
+
onClick={() => this.submit(formik.values)}
|
|
251
|
+
type="submit"
|
|
252
|
+
>
|
|
253
|
+
Submit
|
|
254
|
+
</button>
|
|
255
|
+
</Modal.Footer>
|
|
256
|
+
</>
|
|
257
|
+
);
|
|
258
|
+
}}
|
|
259
|
+
/>
|
|
260
|
+
</>
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './EcsResizeServerGroupModal';
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { shallow } from 'enzyme';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
PlatformHealthOverride,
|
|
6
|
+
ReactModal,
|
|
7
|
+
SpinFormik,
|
|
8
|
+
TaskMonitorWrapper,
|
|
9
|
+
TaskReason,
|
|
10
|
+
UserVerification,
|
|
11
|
+
} from '@spinnaker/core';
|
|
12
|
+
|
|
13
|
+
import { EcsRollbackServerGroupModal, getEcsRollbackTargets, validateEcsRollbackValues } from './index';
|
|
14
|
+
|
|
15
|
+
describe('EcsRollbackServerGroupModal', () => {
|
|
16
|
+
const serverGroup = {
|
|
17
|
+
account: 'test-account',
|
|
18
|
+
capacity: { desired: 4, max: 8, min: 2 },
|
|
19
|
+
cluster: 'fnord-main',
|
|
20
|
+
moniker: { app: 'fnord', cluster: 'fnord-main' },
|
|
21
|
+
name: 'fnord-main-v004',
|
|
22
|
+
region: 'eu-west-1',
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
function application(attributes: any = {}) {
|
|
26
|
+
return {
|
|
27
|
+
attributes,
|
|
28
|
+
name: 'fnord',
|
|
29
|
+
serverGroups: {
|
|
30
|
+
data: [
|
|
31
|
+
target('fnord-main-v003'),
|
|
32
|
+
target('fnord-main-v002', { isDisabled: false }),
|
|
33
|
+
target('other-main-v003', { cluster: 'other-main', moniker: { app: 'fnord', cluster: 'other-main' } }),
|
|
34
|
+
target('fnord-main-v003-other-account', { account: 'other-account' }),
|
|
35
|
+
target('fnord-main-v003-other-region', { region: 'us-east-1' }),
|
|
36
|
+
target('fnord-main-v003-other-app', { moniker: { app: 'other', cluster: 'fnord-main' } }),
|
|
37
|
+
],
|
|
38
|
+
refresh: jasmine.createSpy('refresh'),
|
|
39
|
+
},
|
|
40
|
+
} as any;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function target(name: string, overrides: any = {}) {
|
|
44
|
+
return {
|
|
45
|
+
account: 'test-account',
|
|
46
|
+
cluster: 'fnord-main',
|
|
47
|
+
isDisabled: true,
|
|
48
|
+
moniker: { app: 'fnord', cluster: 'fnord-main' },
|
|
49
|
+
name,
|
|
50
|
+
region: 'eu-west-1',
|
|
51
|
+
...overrides,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function props(app = application()) {
|
|
56
|
+
return {
|
|
57
|
+
application: app,
|
|
58
|
+
closeModal: jasmine.createSpy('closeModal'),
|
|
59
|
+
dismissModal: jasmine.createSpy('dismissModal'),
|
|
60
|
+
serverGroup: serverGroup as any,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
it('finds only disabled rollback targets in the same application, cluster, account, and region', () => {
|
|
65
|
+
expect(getEcsRollbackTargets(application(), serverGroup as any).map((candidate) => candidate.name)).toEqual([
|
|
66
|
+
'fnord-main-v003',
|
|
67
|
+
]);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('requires a target and a health threshold from 0 through 100 while keeping reason optional', () => {
|
|
71
|
+
expect(validateEcsRollbackValues({ restoreServerGroupName: '', targetHealthyRollbackPercentage: 100 })).toEqual({
|
|
72
|
+
restoreServerGroupName: 'Select a server group to restore',
|
|
73
|
+
});
|
|
74
|
+
expect(
|
|
75
|
+
validateEcsRollbackValues({ restoreServerGroupName: 'fnord-main-v003', targetHealthyRollbackPercentage: -1 }),
|
|
76
|
+
).toEqual({ targetHealthyRollbackPercentage: 'Healthy threshold must be between 0 and 100' });
|
|
77
|
+
expect(
|
|
78
|
+
validateEcsRollbackValues({ restoreServerGroupName: 'fnord-main-v003', targetHealthyRollbackPercentage: 101 }),
|
|
79
|
+
).toEqual({ targetHealthyRollbackPercentage: 'Healthy threshold must be between 0 and 100' });
|
|
80
|
+
expect(
|
|
81
|
+
validateEcsRollbackValues({ restoreServerGroupName: 'fnord-main-v003', targetHealthyRollbackPercentage: 95 }),
|
|
82
|
+
).toEqual({});
|
|
83
|
+
expect(
|
|
84
|
+
validateEcsRollbackValues({ restoreServerGroupName: 'fnord-main-v999', targetHealthyRollbackPercentage: 95 }, [
|
|
85
|
+
'fnord-main-v003',
|
|
86
|
+
]),
|
|
87
|
+
).toEqual({ restoreServerGroupName: 'Select an eligible server group to restore' });
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('does not submit a rollback target outside the eligible disabled set', () => {
|
|
91
|
+
const app = application();
|
|
92
|
+
const writer = { rollbackServerGroup: jasmine.createSpy('rollbackServerGroup') };
|
|
93
|
+
const component = new EcsRollbackServerGroupModal(props(app));
|
|
94
|
+
(component as any).context = { services: { serverGroupWriter: writer } };
|
|
95
|
+
component.state.verified = true;
|
|
96
|
+
spyOn(component.state.taskMonitor, 'submit');
|
|
97
|
+
|
|
98
|
+
(component as any).submit({
|
|
99
|
+
restoreServerGroupName: 'fnord-main-v999',
|
|
100
|
+
targetHealthyRollbackPercentage: 95,
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
expect(component.state.taskMonitor.submit).not.toHaveBeenCalled();
|
|
104
|
+
expect(writer.rollbackServerGroup).not.toHaveBeenCalled();
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('submits the exact shared rollback writer contract through its task monitor', () => {
|
|
108
|
+
const app = application({ platformHealthOnly: true, platformHealthOnlyShowOverride: true });
|
|
109
|
+
const writer = { rollbackServerGroup: jasmine.createSpy('rollbackServerGroup').and.returnValue(Promise.resolve()) };
|
|
110
|
+
const component = new EcsRollbackServerGroupModal(props(app));
|
|
111
|
+
(component as any).context = { services: { serverGroupWriter: writer } };
|
|
112
|
+
component.setState = ((update: any) => {
|
|
113
|
+
component.state = { ...component.state, ...(typeof update === 'function' ? update(component.state) : update) };
|
|
114
|
+
}) as any;
|
|
115
|
+
component.setState({ verified: true });
|
|
116
|
+
spyOn(component.state.taskMonitor, 'submit').and.callFake((submitMethod: any) => submitMethod());
|
|
117
|
+
|
|
118
|
+
(component as any).submit({
|
|
119
|
+
interestingHealthProviderNames: ['Ecs'],
|
|
120
|
+
reason: ' preserve this reason exactly ',
|
|
121
|
+
restoreServerGroupName: 'fnord-main-v003',
|
|
122
|
+
targetHealthyRollbackPercentage: 95,
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
expect(component.state.taskMonitor.submit).toHaveBeenCalled();
|
|
126
|
+
expect(writer.rollbackServerGroup).toHaveBeenCalledOnceWith(serverGroup, app, {
|
|
127
|
+
interestingHealthProviderNames: ['Ecs'],
|
|
128
|
+
platformHealthOnlyShowOverride: true,
|
|
129
|
+
reason: ' preserve this reason exactly ',
|
|
130
|
+
rollbackContext: {
|
|
131
|
+
restoreServerGroupName: 'fnord-main-v003',
|
|
132
|
+
rollbackServerGroupName: 'fnord-main-v004',
|
|
133
|
+
targetHealthyRollbackPercentage: 95,
|
|
134
|
+
},
|
|
135
|
+
rollbackType: 'EXPLICIT',
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it('renders task, verification, reason, threshold, and ECS platform-health controls', () => {
|
|
140
|
+
const app = application({ platformHealthOnly: true, platformHealthOnlyShowOverride: true });
|
|
141
|
+
const wrapper = shallow(<EcsRollbackServerGroupModal {...props(app)} />);
|
|
142
|
+
const formik = wrapper.find(SpinFormik);
|
|
143
|
+
expect(wrapper.find(TaskMonitorWrapper).prop('monitor')).toBe((wrapper.instance() as any).state.taskMonitor);
|
|
144
|
+
|
|
145
|
+
const content = shallow(
|
|
146
|
+
<div>
|
|
147
|
+
{(formik.prop('render') as any)({
|
|
148
|
+
errors: {},
|
|
149
|
+
isValid: true,
|
|
150
|
+
setFieldValue: jasmine.createSpy('setFieldValue'),
|
|
151
|
+
values: formik.prop('initialValues'),
|
|
152
|
+
})}
|
|
153
|
+
</div>,
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
expect(content.find(UserVerification).prop('account')).toBe('test-account');
|
|
157
|
+
expect(content.find(TaskReason).exists()).toBe(true);
|
|
158
|
+
expect(content.find('input[name="targetHealthyRollbackPercentage"]').exists()).toBe(true);
|
|
159
|
+
expect(content.find(PlatformHealthOverride).props()).toEqual(
|
|
160
|
+
jasmine.objectContaining({ interestingHealthProviderNames: ['Ecs'], platformHealthType: 'Ecs' }),
|
|
161
|
+
);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it('exports a show primitive for later actions integration', () => {
|
|
165
|
+
const show = spyOn(ReactModal, 'show').and.returnValue(Promise.resolve() as any);
|
|
166
|
+
const modalProps = props();
|
|
167
|
+
const runtimeServices = {} as any;
|
|
168
|
+
|
|
169
|
+
EcsRollbackServerGroupModal.show(modalProps, runtimeServices);
|
|
170
|
+
|
|
171
|
+
expect(show).toHaveBeenCalledOnceWith(EcsRollbackServerGroupModal, modalProps, undefined, runtimeServices);
|
|
172
|
+
});
|
|
173
|
+
});
|