@rancher/shell 3.0.9-rc.6 → 3.0.9
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/components/IconOrSvg.vue +61 -42
- package/components/SortableTable/index.vue +2 -2
- package/components/form/BannerSettings.vue +2 -2
- package/components/form/NotificationSettings.vue +2 -2
- package/config/product/manager.js +0 -1
- package/detail/fleet.cattle.io.cluster.vue +1 -1
- package/dialog/FeatureFlagListDialog.vue +1 -1
- package/edit/catalog.cattle.io.clusterrepo.vue +1 -1
- package/edit/monitoring.coreos.com.alertmanagerconfig/__tests__/auth.spec.ts +145 -0
- package/edit/monitoring.coreos.com.alertmanagerconfig/__tests__/index.test.ts +202 -0
- package/edit/monitoring.coreos.com.alertmanagerconfig/__tests__/tls.spec.ts +226 -0
- package/edit/monitoring.coreos.com.alertmanagerconfig/auth.vue +24 -21
- package/edit/monitoring.coreos.com.alertmanagerconfig/types/__tests__/opsgenie.spec.ts +157 -0
- package/edit/monitoring.coreos.com.alertmanagerconfig/types/__tests__/pagerduty.spec.ts +132 -0
- package/edit/monitoring.coreos.com.alertmanagerconfig/types/__tests__/slack.spec.ts +108 -0
- package/edit/monitoring.coreos.com.alertmanagerconfig/types/pagerduty.vue +2 -1
- package/edit/monitoring.coreos.com.receiver/__tests__/auth.spec.ts +165 -0
- package/edit/monitoring.coreos.com.receiver/__tests__/index.test.ts +153 -0
- package/edit/monitoring.coreos.com.receiver/__tests__/tls.spec.ts +115 -0
- package/edit/monitoring.coreos.com.receiver/types/__tests__/email.spec.ts +86 -0
- package/edit/monitoring.coreos.com.receiver/types/__tests__/opsgenie.spec.ts +209 -0
- package/edit/monitoring.coreos.com.receiver/types/__tests__/pagerduty.spec.ts +105 -0
- package/edit/monitoring.coreos.com.receiver/types/__tests__/slack.spec.ts +92 -0
- package/edit/monitoring.coreos.com.receiver/types/__tests__/webhook.spec.ts +131 -0
- package/edit/provisioning.cattle.io.cluster/ingress/IngressCards.vue +14 -12
- package/edit/provisioning.cattle.io.cluster/rke2.vue +4 -5
- package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +18 -3
- package/edit/provisioning.cattle.io.cluster/tabs/Ingress.vue +100 -76
- package/list/provisioning.cattle.io.cluster.vue +2 -2
- package/models/__tests__/chart.test.ts +2 -2
- package/models/chart.js +3 -3
- package/package.json +1 -1
- package/pages/c/_cluster/apps/charts/AppChartCardFooter.vue +45 -18
- package/pages/c/_cluster/apps/charts/index.vue +1 -11
- package/pages/c/_cluster/explorer/tools/index.vue +1 -1
- package/pages/c/_cluster/manager/cloudCredential/index.vue +1 -1
- package/pages/c/_cluster/uiplugins/index.vue +1 -1
- package/rancher-components/RcItemCard/RcItemCard.vue +8 -1
- package/types/shell/index.d.ts +1 -0
- package/utils/svg-filter.js +4 -3
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
|
|
2
|
+
import { shallowMount } from '@vue/test-utils';
|
|
3
|
+
import Opsgenie, { TARGETS, TYPES } from '@shell/edit/monitoring.coreos.com.receiver/types/opsgenie.vue';
|
|
4
|
+
import { LabeledInput } from '@components/Form/LabeledInput';
|
|
5
|
+
import { Checkbox } from '@components/Form/Checkbox';
|
|
6
|
+
import ArrayList from '@shell/components/form/ArrayList.vue';
|
|
7
|
+
import { _EDIT, _VIEW } from '@shell/config/query-params';
|
|
8
|
+
|
|
9
|
+
describe('component: Opsgenie', () => {
|
|
10
|
+
const mockStore = {
|
|
11
|
+
getters: {
|
|
12
|
+
'i18n/t': (key: string) => key,
|
|
13
|
+
'i18n/exists': () => true,
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const requiredProps = {
|
|
18
|
+
mode: _EDIT,
|
|
19
|
+
value: { responders: [] },
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
it('should render all child components', () => {
|
|
23
|
+
const wrapper = shallowMount(Opsgenie, {
|
|
24
|
+
props: requiredProps,
|
|
25
|
+
global: { mocks: mockStore },
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const labeledInputs = wrapper.findAllComponents(LabeledInput);
|
|
29
|
+
const checkbox = wrapper.findComponent(Checkbox);
|
|
30
|
+
const arrayList = wrapper.findComponent(ArrayList);
|
|
31
|
+
|
|
32
|
+
expect(labeledInputs).toHaveLength(2);
|
|
33
|
+
expect(checkbox.exists()).toBe(true);
|
|
34
|
+
expect(arrayList.exists()).toBe(true);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('should pass down the mode prop to child components', () => {
|
|
38
|
+
const wrapper = shallowMount(Opsgenie, {
|
|
39
|
+
props: requiredProps,
|
|
40
|
+
global: { mocks: mockStore },
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const labeledInputs = wrapper.findAllComponents(LabeledInput);
|
|
44
|
+
const checkbox = wrapper.findComponent(Checkbox);
|
|
45
|
+
const arrayList = wrapper.findComponent(ArrayList);
|
|
46
|
+
|
|
47
|
+
labeledInputs.forEach((input) => {
|
|
48
|
+
expect(input.props().mode).toBe(_EDIT);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
expect(checkbox.props().mode).toBe(_EDIT);
|
|
52
|
+
expect(arrayList.props().mode).toBe(_EDIT);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
describe('data initialization', () => {
|
|
56
|
+
it('should initialize http_config, send_resolved, and responders', () => {
|
|
57
|
+
const value = {};
|
|
58
|
+
const wrapper = shallowMount(Opsgenie, {
|
|
59
|
+
props: {
|
|
60
|
+
...requiredProps,
|
|
61
|
+
value,
|
|
62
|
+
},
|
|
63
|
+
global: { mocks: mockStore },
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
expect(wrapper.props().value.http_config).toBeDefined();
|
|
67
|
+
expect(wrapper.props().value.send_resolved).toBe(true);
|
|
68
|
+
expect(wrapper.props().value.responders).toBeDefined();
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('should correctly transform responders from props', () => {
|
|
72
|
+
const value = {
|
|
73
|
+
responders: [
|
|
74
|
+
{ type: 'team', id: 'team-id' },
|
|
75
|
+
{ type: 'user', name: 'user-name' },
|
|
76
|
+
],
|
|
77
|
+
};
|
|
78
|
+
const wrapper = shallowMount(Opsgenie, {
|
|
79
|
+
props: {
|
|
80
|
+
...requiredProps,
|
|
81
|
+
value,
|
|
82
|
+
},
|
|
83
|
+
global: { mocks: mockStore },
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
expect(wrapper.vm.responders).toStrictEqual([
|
|
87
|
+
{
|
|
88
|
+
type: 'team', target: 'id', value: 'team-id'
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
type: 'user', target: 'name', value: 'user-name'
|
|
92
|
+
},
|
|
93
|
+
]);
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
describe('watchers', () => {
|
|
98
|
+
it('should update value.responders when responders data changes', async() => {
|
|
99
|
+
const value = { responders: [] };
|
|
100
|
+
const wrapper = shallowMount(Opsgenie, {
|
|
101
|
+
props: {
|
|
102
|
+
...requiredProps,
|
|
103
|
+
value,
|
|
104
|
+
},
|
|
105
|
+
global: { mocks: mockStore },
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
wrapper.vm.responders = [
|
|
109
|
+
{
|
|
110
|
+
type: 'team', target: 'id', value: 'team-id'
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
type: 'user', target: 'name', value: 'user-name'
|
|
114
|
+
},
|
|
115
|
+
];
|
|
116
|
+
|
|
117
|
+
await wrapper.vm.$nextTick();
|
|
118
|
+
|
|
119
|
+
expect(value.responders).toStrictEqual([
|
|
120
|
+
{ type: 'team', id: 'team-id' },
|
|
121
|
+
{ type: 'user', name: 'user-name' },
|
|
122
|
+
]);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
describe('methods', () => {
|
|
127
|
+
it('should update a responder with updateResponder', () => {
|
|
128
|
+
const wrapper = shallowMount(Opsgenie, {
|
|
129
|
+
props: requiredProps,
|
|
130
|
+
global: { mocks: mockStore },
|
|
131
|
+
});
|
|
132
|
+
const responder = {
|
|
133
|
+
type: 'team',
|
|
134
|
+
target: 'id',
|
|
135
|
+
value: 'old-value',
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
wrapper.vm.updateResponder({ selected: 'name', text: 'new-value' }, responder);
|
|
139
|
+
|
|
140
|
+
expect(responder.target).toBe('name');
|
|
141
|
+
expect(responder.value).toBe('new-value');
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
it('should return the correct label with typeLabel', () => {
|
|
145
|
+
const wrapper = shallowMount(Opsgenie, {
|
|
146
|
+
props: requiredProps,
|
|
147
|
+
global: { mocks: mockStore },
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
TYPES.forEach((type) => {
|
|
151
|
+
expect(wrapper.vm.typeLabel(type.value)).toBe(type.label);
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it('should return the correct label with targetLabel', () => {
|
|
156
|
+
const wrapper = shallowMount(Opsgenie, {
|
|
157
|
+
props: requiredProps,
|
|
158
|
+
global: { mocks: mockStore },
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
TARGETS.forEach((target) => {
|
|
162
|
+
expect(wrapper.vm.targetLabel(target.value)).toBe(target.label);
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
describe('template', () => {
|
|
168
|
+
describe('responders', () => {
|
|
169
|
+
it('should render responders correctly in edit mode', async() => {
|
|
170
|
+
const value = { responders: [{ type: 'team', id: 'team-id' }] };
|
|
171
|
+
const wrapper = shallowMount(Opsgenie, {
|
|
172
|
+
props: {
|
|
173
|
+
...requiredProps,
|
|
174
|
+
value,
|
|
175
|
+
},
|
|
176
|
+
global: { mocks: mockStore },
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
const arrayList = wrapper.findComponent(ArrayList);
|
|
180
|
+
|
|
181
|
+
expect(arrayList.props().value).toStrictEqual([{
|
|
182
|
+
type: 'team',
|
|
183
|
+
target: 'id',
|
|
184
|
+
value: 'team-id'
|
|
185
|
+
}]);
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
it('should render responders correctly in view mode', async() => {
|
|
189
|
+
const value = { responders: [{ type: 'team', id: 'team-id' }] };
|
|
190
|
+
const wrapper = shallowMount(Opsgenie, {
|
|
191
|
+
props: {
|
|
192
|
+
...requiredProps,
|
|
193
|
+
value,
|
|
194
|
+
mode: _VIEW,
|
|
195
|
+
},
|
|
196
|
+
global: { mocks: mockStore },
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
const arrayList = wrapper.findComponent(ArrayList);
|
|
200
|
+
|
|
201
|
+
expect(arrayList.props().value).toStrictEqual([{
|
|
202
|
+
type: 'team',
|
|
203
|
+
target: 'id',
|
|
204
|
+
value: 'team-id'
|
|
205
|
+
}]);
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
});
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
|
|
2
|
+
import { shallowMount } from '@vue/test-utils';
|
|
3
|
+
import Pagerduty from '@shell/edit/monitoring.coreos.com.receiver/types/pagerduty.vue';
|
|
4
|
+
import { LabeledInput } from '@components/Form/LabeledInput';
|
|
5
|
+
import { Checkbox } from '@components/Form/Checkbox';
|
|
6
|
+
import LabeledSelect from '@shell/components/form/LabeledSelect.vue';
|
|
7
|
+
import { _EDIT } from '@shell/config/query-params';
|
|
8
|
+
|
|
9
|
+
describe('component: Pagerduty', () => {
|
|
10
|
+
const mockStore = {
|
|
11
|
+
getters: {
|
|
12
|
+
'i18n/t': (key: string) => key,
|
|
13
|
+
'i18n/exists': () => true,
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const requiredProps = {
|
|
18
|
+
mode: _EDIT,
|
|
19
|
+
value: {},
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
it('should render all child components', () => {
|
|
23
|
+
const wrapper = shallowMount(Pagerduty, {
|
|
24
|
+
props: requiredProps,
|
|
25
|
+
global: { mocks: mockStore },
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const labeledInputs = wrapper.findAllComponents(LabeledInput);
|
|
29
|
+
const checkbox = wrapper.findComponent(Checkbox);
|
|
30
|
+
const labeledSelect = wrapper.findComponent(LabeledSelect);
|
|
31
|
+
|
|
32
|
+
expect(labeledInputs).toHaveLength(2);
|
|
33
|
+
expect(checkbox.exists()).toBe(true);
|
|
34
|
+
expect(labeledSelect.exists()).toBe(true);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('should pass down the mode prop to child components', () => {
|
|
38
|
+
const wrapper = shallowMount(Pagerduty, {
|
|
39
|
+
props: requiredProps,
|
|
40
|
+
global: { mocks: mockStore },
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const labeledInputs = wrapper.findAllComponents(LabeledInput);
|
|
44
|
+
const checkbox = wrapper.findComponent(Checkbox);
|
|
45
|
+
const labeledSelect = wrapper.findComponent(LabeledSelect);
|
|
46
|
+
|
|
47
|
+
labeledInputs.forEach((input) => {
|
|
48
|
+
expect(input.props().mode).toBe(_EDIT);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
expect(checkbox.props().mode).toBe(_EDIT);
|
|
52
|
+
expect(labeledSelect.attributes().mode).toBe(_EDIT);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
describe('data initialization', () => {
|
|
56
|
+
it('should initialize http_config and send_resolved', () => {
|
|
57
|
+
const value = {};
|
|
58
|
+
const wrapper = shallowMount(Pagerduty, {
|
|
59
|
+
props: {
|
|
60
|
+
...requiredProps,
|
|
61
|
+
value,
|
|
62
|
+
},
|
|
63
|
+
global: { mocks: mockStore },
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
expect(wrapper.props().value.http_config).toBeDefined();
|
|
67
|
+
expect(wrapper.props().value.send_resolved).toBe(true);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it.each([
|
|
71
|
+
['Events API v2', { routing_key: 'test-key' }],
|
|
72
|
+
['Prometheus', { service_key: 'test-key' }],
|
|
73
|
+
['Events API v2', {}],
|
|
74
|
+
])('should set integrationType to %p', (expectedType, value) => {
|
|
75
|
+
const wrapper = shallowMount(Pagerduty, {
|
|
76
|
+
props: {
|
|
77
|
+
...requiredProps,
|
|
78
|
+
value,
|
|
79
|
+
},
|
|
80
|
+
global: { mocks: mockStore },
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
expect(wrapper.vm.integrationType).toBe(expectedType);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
describe('watchers', () => {
|
|
88
|
+
it('should clear old integration key when integrationType changes', async() => {
|
|
89
|
+
const value = { routing_key: 'test-key' };
|
|
90
|
+
const wrapper = shallowMount(Pagerduty, {
|
|
91
|
+
props: {
|
|
92
|
+
...requiredProps,
|
|
93
|
+
value,
|
|
94
|
+
},
|
|
95
|
+
global: { mocks: mockStore },
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
wrapper.vm.integrationType = 'Prometheus';
|
|
99
|
+
|
|
100
|
+
await wrapper.vm.$nextTick();
|
|
101
|
+
|
|
102
|
+
expect(value.routing_key).toBeNull();
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
});
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
|
|
2
|
+
import { shallowMount } from '@vue/test-utils';
|
|
3
|
+
import Slack from '@shell/edit/monitoring.coreos.com.receiver/types/slack.vue';
|
|
4
|
+
import { LabeledInput } from '@components/Form/LabeledInput';
|
|
5
|
+
import { Checkbox } from '@components/Form/Checkbox';
|
|
6
|
+
import { _CREATE, _EDIT } from '@shell/config/query-params';
|
|
7
|
+
|
|
8
|
+
describe('component: Slack', () => {
|
|
9
|
+
const mockStore = {
|
|
10
|
+
getters: {
|
|
11
|
+
'i18n/t': (key: string) => key,
|
|
12
|
+
'i18n/exists': () => true,
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const requiredProps = {
|
|
17
|
+
mode: _EDIT,
|
|
18
|
+
value: {},
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
it('should render all child components', () => {
|
|
22
|
+
const wrapper = shallowMount(Slack, {
|
|
23
|
+
props: requiredProps,
|
|
24
|
+
global: { mocks: mockStore },
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const labeledInputs = wrapper.findAllComponents(LabeledInput);
|
|
28
|
+
const checkbox = wrapper.findComponent(Checkbox);
|
|
29
|
+
|
|
30
|
+
expect(labeledInputs).toHaveLength(3);
|
|
31
|
+
expect(checkbox.exists()).toBe(true);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('should pass down the mode prop to child components', () => {
|
|
35
|
+
const wrapper = shallowMount(Slack, {
|
|
36
|
+
props: requiredProps,
|
|
37
|
+
global: { mocks: mockStore },
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const labeledInputs = wrapper.findAllComponents(LabeledInput);
|
|
41
|
+
const checkbox = wrapper.findComponent(Checkbox);
|
|
42
|
+
|
|
43
|
+
labeledInputs.forEach((input) => {
|
|
44
|
+
expect(input.props().mode).toBe(_EDIT);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
expect(checkbox.props().mode).toBe(_EDIT);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
describe('data initialization', () => {
|
|
51
|
+
it('should initialize http_config and send_resolved', () => {
|
|
52
|
+
const value = {};
|
|
53
|
+
const wrapper = shallowMount(Slack, {
|
|
54
|
+
props: {
|
|
55
|
+
...requiredProps,
|
|
56
|
+
value,
|
|
57
|
+
},
|
|
58
|
+
global: { mocks: mockStore },
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
expect(wrapper.props().value.http_config).toBeDefined();
|
|
62
|
+
expect(wrapper.props().value.send_resolved).toBe(false);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('should set default text when mode is create', () => {
|
|
66
|
+
const value = {};
|
|
67
|
+
const wrapper = shallowMount(Slack, {
|
|
68
|
+
props: {
|
|
69
|
+
...requiredProps,
|
|
70
|
+
value,
|
|
71
|
+
mode: _CREATE,
|
|
72
|
+
},
|
|
73
|
+
global: { mocks: mockStore },
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
expect(wrapper.props().value.text).toBe('{{ template "slack.rancher.text" . }}');
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('should not set default text when mode is not create', () => {
|
|
80
|
+
const value = {};
|
|
81
|
+
const wrapper = shallowMount(Slack, {
|
|
82
|
+
props: {
|
|
83
|
+
...requiredProps,
|
|
84
|
+
value,
|
|
85
|
+
},
|
|
86
|
+
global: { mocks: mockStore },
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
expect(wrapper.props().value.text).toBeUndefined();
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
});
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
|
|
2
|
+
import { shallowMount } from '@vue/test-utils';
|
|
3
|
+
import Webhook from '@shell/edit/monitoring.coreos.com.receiver/types/webhook.vue';
|
|
4
|
+
import { LabeledInput } from '@components/Form/LabeledInput';
|
|
5
|
+
import { Checkbox } from '@components/Form/Checkbox';
|
|
6
|
+
import TLS from '@shell/edit/monitoring.coreos.com.receiver/tls.vue';
|
|
7
|
+
import Auth from '@shell/edit/monitoring.coreos.com.receiver/auth.vue';
|
|
8
|
+
import { Banner } from '@components/Banner';
|
|
9
|
+
import { _CREATE, _EDIT, _VIEW } from '@shell/config/query-params';
|
|
10
|
+
import { ALIBABA_CLOUD_SMS_URL, MS_TEAMS_URL } from '@shell/edit/monitoring.coreos.com.receiver/types/webhook.add.vue';
|
|
11
|
+
|
|
12
|
+
describe('component: Webhook', () => {
|
|
13
|
+
const mockStore = {
|
|
14
|
+
getters: {
|
|
15
|
+
'i18n/t': (key: string) => key,
|
|
16
|
+
'i18n/exists': () => true,
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const requiredProps = {
|
|
21
|
+
mode: _EDIT,
|
|
22
|
+
value: {},
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
it('should render all child components', () => {
|
|
26
|
+
const wrapper = shallowMount(Webhook, {
|
|
27
|
+
props: requiredProps,
|
|
28
|
+
global: { mocks: mockStore },
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const labeledInputs = wrapper.findAllComponents(LabeledInput);
|
|
32
|
+
const checkbox = wrapper.findComponent(Checkbox);
|
|
33
|
+
const tls = wrapper.findComponent(TLS);
|
|
34
|
+
const auth = wrapper.findComponent(Auth);
|
|
35
|
+
|
|
36
|
+
expect(labeledInputs).toHaveLength(2);
|
|
37
|
+
expect(checkbox.exists()).toBe(true);
|
|
38
|
+
expect(tls.exists()).toBe(true);
|
|
39
|
+
expect(auth.exists()).toBe(true);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('should pass down the mode prop to child components', () => {
|
|
43
|
+
const wrapper = shallowMount(Webhook, {
|
|
44
|
+
props: requiredProps,
|
|
45
|
+
global: { mocks: mockStore },
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const labeledInputs = wrapper.findAllComponents(LabeledInput);
|
|
49
|
+
const checkbox = wrapper.findComponent(Checkbox);
|
|
50
|
+
const tls = wrapper.findComponent(TLS);
|
|
51
|
+
const auth = wrapper.findComponent(Auth);
|
|
52
|
+
|
|
53
|
+
labeledInputs.forEach((input) => {
|
|
54
|
+
expect(input.props().mode).toBe(_EDIT);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
expect(checkbox.props().mode).toBe(_EDIT);
|
|
58
|
+
expect(tls.props().mode).toBe(_EDIT);
|
|
59
|
+
expect(auth.props().mode).toBe(_EDIT);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
describe('data initialization', () => {
|
|
63
|
+
it('should initialize http_config and send_resolved', () => {
|
|
64
|
+
const value = {};
|
|
65
|
+
const wrapper = shallowMount(Webhook, {
|
|
66
|
+
props: {
|
|
67
|
+
...requiredProps,
|
|
68
|
+
value,
|
|
69
|
+
},
|
|
70
|
+
global: { mocks: mockStore },
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
expect(wrapper.props().value.http_config).toBeDefined();
|
|
74
|
+
expect(wrapper.props().value.send_resolved).toBe(false);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it.each([
|
|
78
|
+
[true, _CREATE, MS_TEAMS_URL],
|
|
79
|
+
[true, _EDIT, MS_TEAMS_URL],
|
|
80
|
+
[false, _VIEW, MS_TEAMS_URL],
|
|
81
|
+
[true, _CREATE, ALIBABA_CLOUD_SMS_URL],
|
|
82
|
+
[true, _EDIT, ALIBABA_CLOUD_SMS_URL],
|
|
83
|
+
[false, _VIEW, ALIBABA_CLOUD_SMS_URL],
|
|
84
|
+
[false, _CREATE, 'https://some.other.url/'],
|
|
85
|
+
])('should set showNamespaceBanner to %p when mode is %p and url is %p', (expected, mode, url) => {
|
|
86
|
+
const value = { url };
|
|
87
|
+
const wrapper = shallowMount(Webhook, {
|
|
88
|
+
props: {
|
|
89
|
+
...requiredProps,
|
|
90
|
+
value,
|
|
91
|
+
mode,
|
|
92
|
+
},
|
|
93
|
+
global: { mocks: mockStore },
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
expect(wrapper.vm.showNamespaceBanner).toBe(expected);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
describe('banner', () => {
|
|
101
|
+
it('should show banner when showNamespaceBanner is true', () => {
|
|
102
|
+
const wrapper = shallowMount(Webhook, {
|
|
103
|
+
props: {
|
|
104
|
+
...requiredProps,
|
|
105
|
+
value: { url: MS_TEAMS_URL },
|
|
106
|
+
mode: _CREATE,
|
|
107
|
+
},
|
|
108
|
+
global: { mocks: mockStore },
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
const banner = wrapper.findComponent(Banner);
|
|
112
|
+
|
|
113
|
+
expect(banner.exists()).toBe(true);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('should not show banner when showNamespaceBanner is false', () => {
|
|
117
|
+
const wrapper = shallowMount(Webhook, {
|
|
118
|
+
props: {
|
|
119
|
+
...requiredProps,
|
|
120
|
+
value: { url: 'https://some.other.url/' },
|
|
121
|
+
mode: _CREATE,
|
|
122
|
+
},
|
|
123
|
+
global: { mocks: mockStore },
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
const banner = wrapper.findComponent(Banner);
|
|
127
|
+
|
|
128
|
+
expect(banner.exists()).toBe(false);
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
});
|
|
@@ -60,18 +60,20 @@ const { t } = useI18n(store);
|
|
|
60
60
|
v-once
|
|
61
61
|
#item-card-footer
|
|
62
62
|
>
|
|
63
|
-
<
|
|
64
|
-
<
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
63
|
+
<div class="mmt-2">
|
|
64
|
+
<rc-item-card-action>
|
|
65
|
+
<a
|
|
66
|
+
:href="card.doc.url"
|
|
67
|
+
rel="nofollow noopener noreferrer"
|
|
68
|
+
target="_blank"
|
|
69
|
+
class="ingress-card-footer-button secondary-text-link"
|
|
70
|
+
>
|
|
71
|
+
{{ t('cluster.ingress.learnMore.label') }}
|
|
72
|
+
<i class="icon icon-external-link" />
|
|
73
|
+
<span class="sr-only">{{ t('generic.opensInNewTab') }}</span>
|
|
74
|
+
</a>
|
|
75
|
+
</rc-item-card-action>
|
|
76
|
+
</div>
|
|
75
77
|
</template>
|
|
76
78
|
</rc-item-card>
|
|
77
79
|
</div>
|
|
@@ -978,8 +978,7 @@ export default {
|
|
|
978
978
|
);
|
|
979
979
|
}
|
|
980
980
|
|
|
981
|
-
|
|
982
|
-
|
|
981
|
+
this.versionInfo = {}; // Invalidate cache such that version info relevant to selected kube version is updated
|
|
983
982
|
// Allow time for addonNames to update... then fetch any missing addons
|
|
984
983
|
this.$nextTick(() => this.initAddons());
|
|
985
984
|
if (this.mode === _CREATE) {
|
|
@@ -1864,11 +1863,11 @@ export default {
|
|
|
1864
1863
|
versionName: entry.version,
|
|
1865
1864
|
});
|
|
1866
1865
|
|
|
1867
|
-
this.
|
|
1866
|
+
this.versionInfo[chartName] = res;
|
|
1868
1867
|
const key = this.chartVersionKey(chartName);
|
|
1869
1868
|
|
|
1870
1869
|
if (!this.userChartValues[key]) {
|
|
1871
|
-
this.
|
|
1870
|
+
this.userChartValues[key] = {};
|
|
1872
1871
|
}
|
|
1873
1872
|
} catch (e) {
|
|
1874
1873
|
console.error(`Failed to fetch or process chart info for ${ chartName }`); // eslint-disable-line no-console
|
|
@@ -1940,7 +1939,7 @@ export default {
|
|
|
1940
1939
|
const fromUser = this.userChartValuesTemp[name];
|
|
1941
1940
|
const different = diff(fromChart, fromUser);
|
|
1942
1941
|
|
|
1943
|
-
this.
|
|
1942
|
+
this.userChartValues[this.chartVersionKey(name)] = different;
|
|
1944
1943
|
}, 250, { leading: true }),
|
|
1945
1944
|
|
|
1946
1945
|
initYamlEditor(name) {
|
|
@@ -12,7 +12,7 @@ import { LEGACY } from '@shell/store/features';
|
|
|
12
12
|
import semver from 'semver';
|
|
13
13
|
import Ingress from '@shell/edit/provisioning.cattle.io.cluster/tabs/Ingress';
|
|
14
14
|
import {
|
|
15
|
-
HARVESTER, RKE2_INGRESS_NGINX, RKE2_TRAEFIK, INGRESS_CONTROLLER, INGRESS_NGINX
|
|
15
|
+
HARVESTER, RKE2_INGRESS_NGINX, RKE2_TRAEFIK, INGRESS_CONTROLLER, INGRESS_NGINX, INGRESS_NONE
|
|
16
16
|
} from '@shell/edit/provisioning.cattle.io.cluster/shared';
|
|
17
17
|
|
|
18
18
|
export default {
|
|
@@ -173,7 +173,17 @@ export default {
|
|
|
173
173
|
},
|
|
174
174
|
ingressController: {
|
|
175
175
|
get() {
|
|
176
|
-
|
|
176
|
+
if (this.serverConfig) {
|
|
177
|
+
if (this.serverConfig[INGRESS_CONTROLLER]) {
|
|
178
|
+
return this.serverConfig[INGRESS_CONTROLLER];
|
|
179
|
+
} else {
|
|
180
|
+
if (this.serverConfig.disable && this.serverConfig.disable.includes(RKE2_INGRESS_NGINX)) {
|
|
181
|
+
return INGRESS_NONE;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return INGRESS_NGINX;
|
|
177
187
|
},
|
|
178
188
|
|
|
179
189
|
set(neu) {
|
|
@@ -253,12 +263,16 @@ export default {
|
|
|
253
263
|
});
|
|
254
264
|
},
|
|
255
265
|
nginxSupported() {
|
|
256
|
-
if (this.serverArgs?.disable?.options.includes(RKE2_INGRESS_NGINX)) {
|
|
266
|
+
if (Object.keys(this.serverArgs).length === 0 || this.serverArgs?.disable?.options.includes(RKE2_INGRESS_NGINX)) {
|
|
257
267
|
return true;
|
|
258
268
|
}
|
|
259
269
|
|
|
260
270
|
return false;
|
|
261
271
|
},
|
|
272
|
+
// If version is too old and we couldn't get serverArgs, it has to be NGINX
|
|
273
|
+
traefikSupported() {
|
|
274
|
+
return Object.keys(this.serverArgs).length > 0;
|
|
275
|
+
},
|
|
262
276
|
|
|
263
277
|
serverArgs() {
|
|
264
278
|
return this.selectedVersion?.serverArgs || {};
|
|
@@ -680,6 +694,7 @@ export default {
|
|
|
680
694
|
v-model:value="ingressController"
|
|
681
695
|
:mode="mode"
|
|
682
696
|
:nginx-supported="nginxSupported"
|
|
697
|
+
:traefik-supported="traefikSupported"
|
|
683
698
|
:nginx-chart="nginxChart"
|
|
684
699
|
:traefik-chart="traefikChart"
|
|
685
700
|
:user-chart-values="userChartValues"
|