@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,226 @@
|
|
|
1
|
+
|
|
2
|
+
import Tls from '@shell/edit/monitoring.coreos.com.alertmanagerconfig/tls.vue';
|
|
3
|
+
import { shallowMount } from '@vue/test-utils';
|
|
4
|
+
import { _EDIT, _VIEW } from '@shell/config/query-params';
|
|
5
|
+
import SimpleSecretSelector from '@shell/components/form/SimpleSecretSelector.vue';
|
|
6
|
+
import { LabeledInput } from '@components/Form/LabeledInput';
|
|
7
|
+
import { Banner } from '@components/Banner';
|
|
8
|
+
|
|
9
|
+
describe('component: Tls', () => {
|
|
10
|
+
const mockStore = {
|
|
11
|
+
getters: {
|
|
12
|
+
'i18n/t': (key: string) => key,
|
|
13
|
+
'i18n/exists': () => true,
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const requiredProps = {
|
|
18
|
+
value: { tlsConfig: {} },
|
|
19
|
+
namespace: 'test-namespace',
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
it('should render all child components', () => {
|
|
23
|
+
const wrapper = shallowMount(Tls, {
|
|
24
|
+
props: { ...requiredProps, mode: _EDIT },
|
|
25
|
+
global: { mocks: mockStore },
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const secretSelectors = wrapper.findAllComponents(SimpleSecretSelector);
|
|
29
|
+
const labeledInput = wrapper.findComponent(LabeledInput);
|
|
30
|
+
|
|
31
|
+
expect(secretSelectors).toHaveLength(3);
|
|
32
|
+
expect(labeledInput.exists()).toBe(true);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('should show a banner if namespace is not provided', () => {
|
|
36
|
+
const wrapper = shallowMount(Tls, {
|
|
37
|
+
props: {
|
|
38
|
+
...requiredProps,
|
|
39
|
+
namespace: undefined,
|
|
40
|
+
mode: _EDIT,
|
|
41
|
+
},
|
|
42
|
+
global: { mocks: mockStore },
|
|
43
|
+
});
|
|
44
|
+
const banner = wrapper.findComponent(Banner);
|
|
45
|
+
|
|
46
|
+
expect(banner.exists()).toBe(true);
|
|
47
|
+
expect(banner.props().color).toBe('error');
|
|
48
|
+
expect(banner.vm.$slots.default()[0].children).toBe('%alertmanagerConfigReceiver.namespaceWarning%');
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('should not show a banner if namespace is provided', () => {
|
|
52
|
+
const wrapper = shallowMount(Tls, {
|
|
53
|
+
props: { ...requiredProps, mode: _EDIT },
|
|
54
|
+
global: { mocks: mockStore },
|
|
55
|
+
});
|
|
56
|
+
const banner = wrapper.findComponent(Banner);
|
|
57
|
+
|
|
58
|
+
expect(banner.exists()).toBe(false);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('should disable inputs when in view mode', () => {
|
|
62
|
+
const wrapper = shallowMount(Tls, {
|
|
63
|
+
props: { ...requiredProps, mode: _VIEW },
|
|
64
|
+
global: { mocks: mockStore },
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const secretSelectors = wrapper.findAllComponents(SimpleSecretSelector);
|
|
68
|
+
const labeledInput = wrapper.findComponent(LabeledInput);
|
|
69
|
+
|
|
70
|
+
secretSelectors.forEach((s) => expect(s.props().disabled).toBe(true));
|
|
71
|
+
expect(labeledInput.props().mode).toBe(_VIEW);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('should initialize tlsConfig if not present', () => {
|
|
75
|
+
const value = {};
|
|
76
|
+
const wrapper = shallowMount(Tls, {
|
|
77
|
+
props: {
|
|
78
|
+
...requiredProps,
|
|
79
|
+
value,
|
|
80
|
+
mode: _EDIT,
|
|
81
|
+
},
|
|
82
|
+
global: { mocks: mockStore },
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
expect(wrapper.props().value.tlsConfig).toBeDefined();
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it('should correctly initialize data from props', () => {
|
|
89
|
+
const value = {
|
|
90
|
+
tlsConfig: {
|
|
91
|
+
ca: {
|
|
92
|
+
secret: {
|
|
93
|
+
key: 'ca-key',
|
|
94
|
+
name: 'ca-name'
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
cert: {
|
|
98
|
+
secret: {
|
|
99
|
+
key: 'cert-key',
|
|
100
|
+
name: 'cert-name'
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
keySecret: {
|
|
104
|
+
key: 'key-key',
|
|
105
|
+
name: 'key-name'
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const wrapper = shallowMount(Tls, {
|
|
111
|
+
props: {
|
|
112
|
+
...requiredProps,
|
|
113
|
+
value,
|
|
114
|
+
mode: _EDIT,
|
|
115
|
+
},
|
|
116
|
+
global: { mocks: mockStore },
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const data = wrapper.vm.$data;
|
|
120
|
+
|
|
121
|
+
expect(data.initialCaSecretKey).toBe('ca-key');
|
|
122
|
+
expect(data.initialCaSecretName).toBe('ca-name');
|
|
123
|
+
expect(data.initialClientCertSecretKey).toBe('cert-key');
|
|
124
|
+
expect(data.initialClientCertSecretName).toBe('cert-name');
|
|
125
|
+
expect(data.initialClientKeySecretKey).toBe('key-key');
|
|
126
|
+
expect(data.initialClientKeySecretName).toBe('key-name');
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
describe('event handling', () => {
|
|
130
|
+
it.each([
|
|
131
|
+
['ca', 0, 'ca', 'updateCaSecretName', 'updateCaSecretKey'],
|
|
132
|
+
['cert', 1, 'cert', 'updateClientCertSecretName', 'updateClientCertSecretKey'],
|
|
133
|
+
['key', 2, 'keySecret', 'updateClientKeySecretName', 'updateClientKeySecretKey'],
|
|
134
|
+
])('should handle %p secret selector events', async(secretType, index, tlsConfigKey, nameHandler, keyHandler) => {
|
|
135
|
+
const value = { tlsConfig: {} };
|
|
136
|
+
const wrapper = shallowMount(Tls, {
|
|
137
|
+
props: {
|
|
138
|
+
...requiredProps, value, mode: _EDIT
|
|
139
|
+
},
|
|
140
|
+
global: { mocks: mockStore },
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
const secretSelector = wrapper.findAllComponents(SimpleSecretSelector)[index];
|
|
144
|
+
const name = `${ secretType }-secret-name`;
|
|
145
|
+
const key = `${ secretType }-secret-key`;
|
|
146
|
+
|
|
147
|
+
await secretSelector.vm.$emit('updateSecretName', name);
|
|
148
|
+
await wrapper.vm.$nextTick();
|
|
149
|
+
|
|
150
|
+
const nameValue = tlsConfigKey === 'keySecret' ? value.tlsConfig[tlsConfigKey].name : value.tlsConfig[tlsConfigKey].secret.name;
|
|
151
|
+
|
|
152
|
+
expect(nameValue).toBe(name);
|
|
153
|
+
|
|
154
|
+
await secretSelector.vm.$emit('updateSecretKey', key);
|
|
155
|
+
await wrapper.vm.$nextTick();
|
|
156
|
+
|
|
157
|
+
const keyValue = tlsConfigKey === 'keySecret' ? value.tlsConfig[tlsConfigKey].key : value.tlsConfig[tlsConfigKey].secret.key;
|
|
158
|
+
|
|
159
|
+
expect(keyValue).toBe(key);
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
describe('secret updates', () => {
|
|
164
|
+
it.each([
|
|
165
|
+
['Ca', 'updateCaSecretName', 'ca', 'name'],
|
|
166
|
+
['Ca', 'updateCaSecretKey', 'ca', 'key'],
|
|
167
|
+
['ClientCert', 'updateClientCertSecretName', 'cert', 'name'],
|
|
168
|
+
['ClientCert', 'updateClientCertSecretKey', 'cert', 'key'],
|
|
169
|
+
['ClientKey', 'updateClientKeySecretName', 'keySecret', 'name'],
|
|
170
|
+
['ClientKey', 'updateClientKeySecretKey', 'keySecret', 'key'],
|
|
171
|
+
])('should update %p secret %p', (secret, handler, obj, field) => {
|
|
172
|
+
const value = { tlsConfig: {} };
|
|
173
|
+
const wrapper = shallowMount(Tls, {
|
|
174
|
+
props: {
|
|
175
|
+
...requiredProps,
|
|
176
|
+
value,
|
|
177
|
+
mode: _EDIT
|
|
178
|
+
},
|
|
179
|
+
global: { mocks: mockStore },
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
const data = 'test-data';
|
|
183
|
+
|
|
184
|
+
(wrapper.vm as any)[handler](data);
|
|
185
|
+
|
|
186
|
+
const dataValue = obj === 'keySecret' ? value.tlsConfig[obj][field] : value.tlsConfig[obj].secret[field];
|
|
187
|
+
|
|
188
|
+
expect(dataValue).toBe(data);
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
it.each([
|
|
192
|
+
['Ca', 'updateCaSecretName', 'ca'],
|
|
193
|
+
['ClientCert', 'updateClientCertSecretName', 'cert'],
|
|
194
|
+
])('should remove %p secret', (secret, handler, obj) => {
|
|
195
|
+
const value = { tlsConfig: { [obj]: { secret: { name: 'test-name', key: 'test-key' } } } };
|
|
196
|
+
const wrapper = shallowMount(Tls, {
|
|
197
|
+
props: {
|
|
198
|
+
...requiredProps,
|
|
199
|
+
value,
|
|
200
|
+
mode: _EDIT
|
|
201
|
+
},
|
|
202
|
+
global: { mocks: mockStore },
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
(wrapper.vm as any)[handler]('__[[NONE]]__');
|
|
206
|
+
|
|
207
|
+
expect(value.tlsConfig[obj]).toStrictEqual({});
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
it('should remove "ClientKey" secret', () => {
|
|
211
|
+
const value = { tlsConfig: { keySecret: { name: 'test-name', key: 'test-key' } } };
|
|
212
|
+
const wrapper = shallowMount(Tls, {
|
|
213
|
+
props: {
|
|
214
|
+
...requiredProps,
|
|
215
|
+
value,
|
|
216
|
+
mode: _EDIT
|
|
217
|
+
},
|
|
218
|
+
global: { mocks: mockStore },
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
(wrapper.vm as any).updateClientKeySecretName('__[[NONE]]__');
|
|
222
|
+
|
|
223
|
+
expect(value.tlsConfig.keySecret).toStrictEqual({});
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
});
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import LabeledSelect from '@shell/components/form/LabeledSelect';
|
|
3
3
|
import SimpleSecretSelector from '@shell/components/form/SimpleSecretSelector';
|
|
4
|
+
import Banner from '@components/Banner/Banner.vue';
|
|
4
5
|
import isEmpty from 'lodash/isEmpty';
|
|
5
6
|
import { _VIEW } from '@shell/config/query-params';
|
|
6
7
|
|
|
7
8
|
export default {
|
|
8
|
-
components: {
|
|
9
|
-
|
|
9
|
+
components: {
|
|
10
|
+
Banner, LabeledSelect, SimpleSecretSelector
|
|
11
|
+
},
|
|
12
|
+
props: {
|
|
10
13
|
mode: {
|
|
11
14
|
type: String,
|
|
12
15
|
required: true,
|
|
@@ -64,7 +67,7 @@ export default {
|
|
|
64
67
|
initializeType(authOptions, type) {
|
|
65
68
|
authOptions.forEach((authOption) => {
|
|
66
69
|
if (authOption.value === type && type !== 'none') {
|
|
67
|
-
this.value
|
|
70
|
+
this.value[authOption.value] = this.value[authOption.value] || authOption.default;
|
|
68
71
|
} else if (typeof this.value[authOption.value] !== 'undefined') {
|
|
69
72
|
delete this.value[authOption.value];
|
|
70
73
|
}
|
|
@@ -248,9 +251,9 @@ export default {
|
|
|
248
251
|
/>
|
|
249
252
|
</div>
|
|
250
253
|
</div>
|
|
251
|
-
<div
|
|
252
|
-
v-if="authType === 'basicAuth'"
|
|
253
|
-
class="row mb-20"
|
|
254
|
+
<div
|
|
255
|
+
v-if="authType === 'basicAuth'"
|
|
256
|
+
class="row mb-20"
|
|
254
257
|
>
|
|
255
258
|
<SimpleSecretSelector
|
|
256
259
|
v-if="namespace"
|
|
@@ -265,16 +268,16 @@ export default {
|
|
|
265
268
|
@updateSecretName="updateBasicAuthUsernameSecretName"
|
|
266
269
|
@updateSecretKey="updateBasicAuthUsernameSecretKey"
|
|
267
270
|
/>
|
|
268
|
-
<Banner
|
|
269
|
-
v-else
|
|
270
|
-
color="error"
|
|
271
|
+
<Banner
|
|
272
|
+
v-else
|
|
273
|
+
color="error"
|
|
271
274
|
>
|
|
272
275
|
{{ t("alertmanagerConfigReceiver.namespaceWarning") }}
|
|
273
276
|
</Banner>
|
|
274
277
|
</div>
|
|
275
|
-
<div
|
|
276
|
-
v-if="authType === 'basicAuth'"
|
|
277
|
-
class="row mb-20"
|
|
278
|
+
<div
|
|
279
|
+
v-if="authType === 'basicAuth'"
|
|
280
|
+
class="row mb-20"
|
|
278
281
|
>
|
|
279
282
|
<SimpleSecretSelector
|
|
280
283
|
v-if="namespace"
|
|
@@ -289,16 +292,16 @@ export default {
|
|
|
289
292
|
@updateSecretName="updateBasicAuthPasswordSecretName"
|
|
290
293
|
@updateSecretKey="updateBasicAuthPasswordSecretKey"
|
|
291
294
|
/>
|
|
292
|
-
<Banner
|
|
293
|
-
v-else
|
|
294
|
-
color="error"
|
|
295
|
+
<Banner
|
|
296
|
+
v-else
|
|
297
|
+
color="error"
|
|
295
298
|
>
|
|
296
299
|
{{ t("alertmanagerConfigReceiver.namespaceWarning") }}
|
|
297
300
|
</Banner>
|
|
298
301
|
</div>
|
|
299
|
-
<div
|
|
300
|
-
v-if="authType === 'bearerTokenSecret'"
|
|
301
|
-
class="row mb-20"
|
|
302
|
+
<div
|
|
303
|
+
v-if="authType === 'bearerTokenSecret'"
|
|
304
|
+
class="row mb-20"
|
|
302
305
|
>
|
|
303
306
|
<SimpleSecretSelector
|
|
304
307
|
v-if="namespace"
|
|
@@ -313,9 +316,9 @@ export default {
|
|
|
313
316
|
@updateSecretName="updateBearerTokenSecretName"
|
|
314
317
|
@updateSecretKey="updateBearerTokenSecretKey"
|
|
315
318
|
/>
|
|
316
|
-
<Banner
|
|
317
|
-
v-else
|
|
318
|
-
color="error"
|
|
319
|
+
<Banner
|
|
320
|
+
v-else
|
|
321
|
+
color="error"
|
|
319
322
|
>
|
|
320
323
|
{{ t("alertmanagerConfigReceiver.namespaceWarning") }}
|
|
321
324
|
</Banner>
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { shallowMount } from '@vue/test-utils';
|
|
2
|
+
import Opsgenie from '@shell/edit/monitoring.coreos.com.alertmanagerconfig/types/opsgenie.vue';
|
|
3
|
+
import { Checkbox } from '@components/Form/Checkbox';
|
|
4
|
+
|
|
5
|
+
describe('component: Opsgenie.vue', () => {
|
|
6
|
+
const defaultProps = {
|
|
7
|
+
mode: 'edit',
|
|
8
|
+
value: { responders: [] },
|
|
9
|
+
namespace: 'test-namespace'
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
it('should render correctly with initial props', () => {
|
|
13
|
+
const wrapper = shallowMount(Opsgenie, {
|
|
14
|
+
props: defaultProps,
|
|
15
|
+
global: { mocks: { $fetchState: { pending: false, error: null } } }
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const headings = wrapper.findAll('h3');
|
|
19
|
+
|
|
20
|
+
expect(headings[0].text()).toBe('Target');
|
|
21
|
+
expect(headings[1].text()).toBe('Responders');
|
|
22
|
+
expect(wrapper.findComponent({ name: 'SimpleSecretSelector' }).exists()).toBe(true);
|
|
23
|
+
expect(wrapper.findComponent({ name: 'LabeledInput' }).exists()).toBe(true);
|
|
24
|
+
expect(wrapper.findComponent(Checkbox).exists()).toBe(true);
|
|
25
|
+
expect(wrapper.findComponent({ name: 'ArrayList' }).exists()).toBe(true);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('should update proxy URL', async() => {
|
|
29
|
+
const wrapper = shallowMount(Opsgenie, {
|
|
30
|
+
props: defaultProps,
|
|
31
|
+
global: { mocks: { $fetchState: { pending: false, error: null } } }
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const labeledInput = wrapper.findComponent({ name: 'LabeledInput' });
|
|
35
|
+
|
|
36
|
+
await labeledInput.vm.$emit('update:value', 'http://my-proxy.com');
|
|
37
|
+
|
|
38
|
+
expect(wrapper.props('value').httpConfig.proxyURL).toBe('http://my-proxy.com');
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('should toggle send resolved alerts checkbox', async() => {
|
|
42
|
+
const wrapper = shallowMount(Opsgenie, {
|
|
43
|
+
props: defaultProps,
|
|
44
|
+
global: { mocks: { $fetchState: { pending: false, error: null } } }
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const checkbox = wrapper.findComponent(Checkbox);
|
|
48
|
+
|
|
49
|
+
await checkbox.vm.$emit('update:value', false);
|
|
50
|
+
expect(wrapper.props('value').sendResolved).toBe(false);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('should handle API key secret updates', async() => {
|
|
54
|
+
const wrapper = shallowMount(Opsgenie, {
|
|
55
|
+
props: defaultProps,
|
|
56
|
+
global: { mocks: { $fetchState: { pending: false, error: null } } }
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const secretSelector = wrapper.findComponent({ name: 'SimpleSecretSelector' });
|
|
60
|
+
|
|
61
|
+
await secretSelector.vm.$emit('updateSecretName', 'my-secret-name');
|
|
62
|
+
await secretSelector.vm.$emit('updateSecretKey', 'my-secret-key');
|
|
63
|
+
|
|
64
|
+
expect(wrapper.props('value').apiKey.name).toBe('my-secret-name');
|
|
65
|
+
expect(wrapper.props('value').apiKey.key).toBe('my-secret-key');
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('should add and update a responder', async() => {
|
|
69
|
+
const wrapper = shallowMount(Opsgenie, {
|
|
70
|
+
props: defaultProps,
|
|
71
|
+
global: { mocks: { $fetchState: { pending: false, error: null } } }
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const arrayList = wrapper.findComponent({ name: 'ArrayList' });
|
|
75
|
+
|
|
76
|
+
await arrayList.vm.$emit('update:value', [wrapper.vm.defaultResponder]);
|
|
77
|
+
|
|
78
|
+
const responders = wrapper.vm.responders;
|
|
79
|
+
|
|
80
|
+
expect(responders).toHaveLength(1);
|
|
81
|
+
expect(responders[0].type).toBe('team');
|
|
82
|
+
expect(responders[0].target).toBe('id');
|
|
83
|
+
|
|
84
|
+
// Manually change responder type and check if watch updates the value prop
|
|
85
|
+
responders[0].type = 'user';
|
|
86
|
+
await wrapper.vm.$nextTick();
|
|
87
|
+
expect(wrapper.props('value').responders[0].type).toBe('user');
|
|
88
|
+
|
|
89
|
+
// Test updateResponder method
|
|
90
|
+
wrapper.vm.updateResponder({ selected: 'username', text: 'test-user' }, responders[0]);
|
|
91
|
+
await wrapper.vm.$nextTick();
|
|
92
|
+
expect(responders[0].target).toBe('username');
|
|
93
|
+
expect(responders[0].value).toBe('test-user');
|
|
94
|
+
// Check that the watcher has updated the value prop correctly
|
|
95
|
+
expect(wrapper.props('value').responders[0]).toStrictEqual({ type: 'user', username: 'test-user' });
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('should remove a responder', async() => {
|
|
99
|
+
const wrapper = shallowMount(Opsgenie, {
|
|
100
|
+
props: {
|
|
101
|
+
...defaultProps,
|
|
102
|
+
value: {
|
|
103
|
+
responders: [
|
|
104
|
+
{
|
|
105
|
+
type: 'team',
|
|
106
|
+
id: 'team-id'
|
|
107
|
+
}
|
|
108
|
+
]
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
global: { mocks: { $fetchState: { pending: false, error: null } } }
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// Simulate the internal workings of ArrayList for removing an item
|
|
115
|
+
wrapper.vm.responders.splice(0, 1);
|
|
116
|
+
await wrapper.vm.$nextTick();
|
|
117
|
+
|
|
118
|
+
expect(wrapper.vm.responders).toHaveLength(0);
|
|
119
|
+
expect(wrapper.props('value').responders).toHaveLength(0);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it('should render in view mode', () => {
|
|
123
|
+
const wrapper = shallowMount(Opsgenie, {
|
|
124
|
+
props: {
|
|
125
|
+
mode: 'view',
|
|
126
|
+
value: {
|
|
127
|
+
httpConfig: { proxyURL: 'http://view-proxy.com' },
|
|
128
|
+
sendResolved: false,
|
|
129
|
+
responders: [
|
|
130
|
+
{
|
|
131
|
+
type: 'user',
|
|
132
|
+
name: 'view-user'
|
|
133
|
+
}
|
|
134
|
+
]
|
|
135
|
+
},
|
|
136
|
+
namespace: 'test-namespace'
|
|
137
|
+
},
|
|
138
|
+
global: { mocks: { $fetchState: { pending: false, error: null } } }
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
const labeledInput = wrapper.findComponent({ name: 'LabeledInput' });
|
|
142
|
+
const checkbox = wrapper.findComponent(Checkbox);
|
|
143
|
+
const arrayList = wrapper.findComponent({ name: 'ArrayList' });
|
|
144
|
+
|
|
145
|
+
expect(labeledInput.props('mode')).toBe('view');
|
|
146
|
+
expect(checkbox.props('mode')).toBe('view');
|
|
147
|
+
expect(arrayList.props('mode')).toBe('view');
|
|
148
|
+
|
|
149
|
+
const responder = wrapper.vm.responders[0];
|
|
150
|
+
|
|
151
|
+
expect(responder.type).toBe('user');
|
|
152
|
+
expect(responder.target).toBe('name');
|
|
153
|
+
expect(responder.value).toBe('view-user');
|
|
154
|
+
expect(wrapper.vm.typeLabel(responder.type)).toBe('User');
|
|
155
|
+
expect(wrapper.vm.targetLabel(responder.target)).toBe('Name');
|
|
156
|
+
});
|
|
157
|
+
});
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { shallowMount } from '@vue/test-utils';
|
|
2
|
+
import PagerDuty from '@shell/edit/monitoring.coreos.com.alertmanagerconfig/types/pagerduty.vue';
|
|
3
|
+
import { Checkbox } from '@components/Form/Checkbox';
|
|
4
|
+
|
|
5
|
+
describe('component: PagerDuty.vue', () => {
|
|
6
|
+
const defaultProps = {
|
|
7
|
+
mode: 'edit',
|
|
8
|
+
value: {},
|
|
9
|
+
namespace: 'test-namespace'
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
it('should render correctly with initial props', () => {
|
|
13
|
+
const wrapper = shallowMount(PagerDuty, {
|
|
14
|
+
props: defaultProps,
|
|
15
|
+
global: { mocks: { $fetchState: { pending: false, error: null } } }
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const headings = wrapper.findAll('h3');
|
|
19
|
+
|
|
20
|
+
expect(headings[0].text()).toBe('Target');
|
|
21
|
+
|
|
22
|
+
expect(wrapper.findComponent({ name: 'LabeledSelect' }).exists()).toBe(true);
|
|
23
|
+
expect(wrapper.findComponent({ name: 'SimpleSecretSelector' }).exists()).toBe(true);
|
|
24
|
+
expect(wrapper.findComponent({ name: 'LabeledInput' }).exists()).toBe(true);
|
|
25
|
+
expect(wrapper.findComponent(Checkbox).exists()).toBe(true);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('should show routing key selector for "Events API v2"', () => {
|
|
29
|
+
const wrapper = shallowMount(PagerDuty, {
|
|
30
|
+
props: defaultProps,
|
|
31
|
+
global: { mocks: { $fetchState: { pending: false, error: null } } }
|
|
32
|
+
});
|
|
33
|
+
const selector = wrapper.findComponent({ name: 'SimpleSecretSelector' });
|
|
34
|
+
|
|
35
|
+
expect(selector.props('secretNameLabel')).toContain('monitoring.alertmanagerConfig.pagerDuty.routingKey');
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should show service key selector for "Prometheus"', async() => {
|
|
39
|
+
const wrapper = shallowMount(PagerDuty, {
|
|
40
|
+
props: { ...defaultProps, value: { serviceKey: { name: 's', key: 'k' } } },
|
|
41
|
+
global: { mocks: { $fetchState: { pending: false, error: null } } }
|
|
42
|
+
});
|
|
43
|
+
const selector = wrapper.findComponent({ name: 'SimpleSecretSelector' });
|
|
44
|
+
|
|
45
|
+
expect(selector.props('secretNameLabel')).toContain('monitoring.alertmanagerConfig.pagerDuty.serviceKey');
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('should clear other key when integration type changes', async() => {
|
|
49
|
+
const wrapper = shallowMount(PagerDuty, {
|
|
50
|
+
props: { ...defaultProps, value: { routingKey: { name: 'r', key: 'k' } } },
|
|
51
|
+
global: { mocks: { $fetchState: { pending: false, error: null } } }
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
wrapper.vm.integrationType = 'Prometheus';
|
|
55
|
+
await wrapper.vm.$nextTick();
|
|
56
|
+
|
|
57
|
+
expect(wrapper.props('value').routingKey).toBeNull();
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('should update routing key secret', async() => {
|
|
61
|
+
const wrapper = shallowMount(PagerDuty, {
|
|
62
|
+
props: defaultProps,
|
|
63
|
+
global: { mocks: { $fetchState: { pending: false, error: null } } }
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const secretSelector = wrapper.findComponent({ name: 'SimpleSecretSelector' });
|
|
67
|
+
|
|
68
|
+
await secretSelector.vm.$emit('updateSecretName', 'routing-name');
|
|
69
|
+
await secretSelector.vm.$emit('updateSecretKey', 'routing-key');
|
|
70
|
+
|
|
71
|
+
expect(wrapper.props('value').routingKey.name).toBe('routing-name');
|
|
72
|
+
expect(wrapper.props('value').routingKey.key).toBe('routing-key');
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('should update service key secret', async() => {
|
|
76
|
+
const wrapper = shallowMount(PagerDuty, {
|
|
77
|
+
props: { ...defaultProps, value: { serviceKey: {} } },
|
|
78
|
+
global: { mocks: { $fetchState: { pending: false, error: null } } }
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const secretSelector = wrapper.findComponent({ name: 'SimpleSecretSelector' });
|
|
82
|
+
|
|
83
|
+
await secretSelector.vm.$emit('updateSecretName', 'service-name');
|
|
84
|
+
await secretSelector.vm.$emit('updateSecretKey', 'service-key');
|
|
85
|
+
|
|
86
|
+
expect(wrapper.props('value').serviceKey.name).toBe('service-name');
|
|
87
|
+
expect(wrapper.props('value').serviceKey.key).toBe('service-key');
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('should update proxy URL', async() => {
|
|
91
|
+
const wrapper = shallowMount(PagerDuty, {
|
|
92
|
+
props: defaultProps,
|
|
93
|
+
global: { mocks: { $fetchState: { pending: false, error: null } } }
|
|
94
|
+
});
|
|
95
|
+
const labeledInput = wrapper.findComponent({ name: 'LabeledInput' });
|
|
96
|
+
|
|
97
|
+
await labeledInput.vm.$emit('update:value', 'http://proxy.com');
|
|
98
|
+
expect(wrapper.props('value').httpConfig.proxyURL).toBe('http://proxy.com');
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('should toggle send resolved alerts', async() => {
|
|
102
|
+
const wrapper = shallowMount(PagerDuty, {
|
|
103
|
+
props: defaultProps,
|
|
104
|
+
global: { mocks: { $fetchState: { pending: false, error: null } } }
|
|
105
|
+
});
|
|
106
|
+
const checkbox = wrapper.findComponent(Checkbox);
|
|
107
|
+
|
|
108
|
+
await checkbox.vm.$emit('update:value', false);
|
|
109
|
+
expect(wrapper.props('value').sendResolved).toBe(false);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it('should render in view mode', () => {
|
|
113
|
+
const wrapper = shallowMount(PagerDuty, {
|
|
114
|
+
props: { ...defaultProps, mode: 'view' },
|
|
115
|
+
global: { mocks: { $fetchState: { pending: false, error: null } } }
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
expect(wrapper.findComponent({ name: 'LabeledSelect' }).attributes('mode')).toBe('view');
|
|
119
|
+
expect(wrapper.findComponent({ name: 'SimpleSecretSelector' }).props('disabled')).toBe(true);
|
|
120
|
+
expect(wrapper.findComponent({ name: 'LabeledInput' }).attributes('mode')).toBe('view');
|
|
121
|
+
expect(wrapper.findComponent(Checkbox).attributes('mode')).toBe('view');
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it('should show banner if no namespace is provided', () => {
|
|
125
|
+
const wrapper = shallowMount(PagerDuty, {
|
|
126
|
+
props: { ...defaultProps, namespace: '' },
|
|
127
|
+
global: { mocks: { $fetchState: { pending: false, error: null } } }
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
expect(wrapper.findComponent({ name: 'Banner' }).exists()).toBe(true);
|
|
131
|
+
});
|
|
132
|
+
});
|