@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
package/components/IconOrSvg.vue
CHANGED
|
@@ -18,9 +18,9 @@
|
|
|
18
18
|
*/
|
|
19
19
|
import { Solver } from '@shell/utils/svg-filter';
|
|
20
20
|
import { colorToRgb, mapStandardColors, normalizeHex } from '@shell/utils/color';
|
|
21
|
+
import { mapGetters } from 'vuex';
|
|
21
22
|
|
|
22
23
|
const filterCache = {};
|
|
23
|
-
const cssCache = {};
|
|
24
24
|
|
|
25
25
|
const colors = {
|
|
26
26
|
header: {
|
|
@@ -33,7 +33,7 @@ const colors = {
|
|
|
33
33
|
},
|
|
34
34
|
primary: {
|
|
35
35
|
color: '--on-tertiary',
|
|
36
|
-
hover: '--
|
|
36
|
+
hover: '--tertiary-hover-app-bar',
|
|
37
37
|
colorFallback: '--on-tertiary',
|
|
38
38
|
hoverFallback: '--primary-hover-text',
|
|
39
39
|
active: '--on-active',
|
|
@@ -63,7 +63,12 @@ export default {
|
|
|
63
63
|
},
|
|
64
64
|
|
|
65
65
|
data() {
|
|
66
|
-
return {
|
|
66
|
+
return {
|
|
67
|
+
className: '',
|
|
68
|
+
mainFilter: null,
|
|
69
|
+
hoverFilter: null,
|
|
70
|
+
activeFilter: null,
|
|
71
|
+
};
|
|
67
72
|
},
|
|
68
73
|
|
|
69
74
|
created() {
|
|
@@ -72,6 +77,18 @@ export default {
|
|
|
72
77
|
}
|
|
73
78
|
},
|
|
74
79
|
|
|
80
|
+
computed: {
|
|
81
|
+
...mapGetters({
|
|
82
|
+
brand: 'management/brand',
|
|
83
|
+
theme: 'prefs/theme',
|
|
84
|
+
})
|
|
85
|
+
},
|
|
86
|
+
|
|
87
|
+
watch: {
|
|
88
|
+
brand: 'recomputeColor',
|
|
89
|
+
theme: 'recomputeColor',
|
|
90
|
+
},
|
|
91
|
+
|
|
75
92
|
methods: {
|
|
76
93
|
getComputedStyleFor(cssVar, fallback) {
|
|
77
94
|
const value = window.getComputedStyle(document.body).getPropertyValue(cssVar).trim();
|
|
@@ -86,11 +103,11 @@ export default {
|
|
|
86
103
|
|
|
87
104
|
const solver = new Solver(rgb);
|
|
88
105
|
const res = solver.solve();
|
|
89
|
-
const
|
|
106
|
+
const filterVal = res?.filterVal;
|
|
90
107
|
|
|
91
|
-
filterCache[cacheKey] =
|
|
108
|
+
filterCache[cacheKey] = filterVal;
|
|
92
109
|
|
|
93
|
-
return
|
|
110
|
+
return filterVal;
|
|
94
111
|
},
|
|
95
112
|
|
|
96
113
|
setColor() {
|
|
@@ -111,43 +128,23 @@ export default {
|
|
|
111
128
|
|
|
112
129
|
const className = `svg-icon-${ uiColorStr }-${ hoverColorStr }`;
|
|
113
130
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
const activeFilter = this.resolveColorFilter(activeColor, activeColorRGB);
|
|
118
|
-
|
|
119
|
-
// Add stylesheet (added as global styles)
|
|
120
|
-
const styles = `
|
|
121
|
-
img.${ className } {
|
|
122
|
-
${ mainFilter };
|
|
123
|
-
}
|
|
124
|
-
img.${ className }:hover {
|
|
125
|
-
${ hoverFilter };
|
|
126
|
-
}
|
|
127
|
-
button:hover > img.${ className } {
|
|
128
|
-
${ hoverFilter };
|
|
129
|
-
}
|
|
130
|
-
li:hover > img.${ className } {
|
|
131
|
-
${ hoverFilter };
|
|
132
|
-
}
|
|
133
|
-
a.option:hover > img.${ className } {
|
|
134
|
-
${ hoverFilter };
|
|
135
|
-
}
|
|
136
|
-
a.option.active-menu-link > img.${ className } {
|
|
137
|
-
${ activeFilter };
|
|
138
|
-
}
|
|
139
|
-
`;
|
|
140
|
-
|
|
141
|
-
const styleSheet = document.createElement('style');
|
|
142
|
-
|
|
143
|
-
styleSheet.innerText = styles;
|
|
144
|
-
document.head.appendChild(styleSheet);
|
|
145
|
-
|
|
146
|
-
cssCache[className] = true;
|
|
147
|
-
}
|
|
131
|
+
this.hoverFilter = this.resolveColorFilter(hoverColor, hoverColorRGB);
|
|
132
|
+
this.mainFilter = this.resolveColorFilter(uiColor, uiColorRGB);
|
|
133
|
+
this.activeFilter = this.resolveColorFilter(activeColor, activeColorRGB);
|
|
148
134
|
|
|
149
135
|
this['className'] = className;
|
|
150
|
-
}
|
|
136
|
+
},
|
|
137
|
+
|
|
138
|
+
recomputeColor() {
|
|
139
|
+
if (!this.src) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
this.mainFilter = null;
|
|
144
|
+
this.hoverFilter = null;
|
|
145
|
+
this.activeFilter = null;
|
|
146
|
+
this.setColor();
|
|
147
|
+
},
|
|
151
148
|
}
|
|
152
149
|
};
|
|
153
150
|
</script>
|
|
@@ -172,8 +169,30 @@ export default {
|
|
|
172
169
|
</template>
|
|
173
170
|
|
|
174
171
|
<style lang="scss" scoped>
|
|
175
|
-
.svg-icon {
|
|
172
|
+
img.svg-icon {
|
|
173
|
+
filter: v-bind(mainFilter);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
button:hover > img.svg-icon,
|
|
177
|
+
li:hover > img.svg-icon {
|
|
178
|
+
filter: v-bind(hoverFilter);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.side-menu .category div a > img.svg-icon {
|
|
176
182
|
height: 24px;
|
|
177
183
|
width: 24px;
|
|
184
|
+
filter: v-bind(mainFilter);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.side-menu .category div a:hover > img.svg-icon {
|
|
188
|
+
filter: v-bind(hoverFilter);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.side-menu .category div a.active-menu-link > img.svg-icon {
|
|
192
|
+
filter: v-bind(activeFilter);
|
|
193
|
+
|
|
194
|
+
&:hover {
|
|
195
|
+
filter: v-bind(activeFilter);
|
|
196
|
+
}
|
|
178
197
|
}
|
|
179
198
|
</style>
|
|
@@ -2099,13 +2099,13 @@ export default {
|
|
|
2099
2099
|
|
|
2100
2100
|
$header-padding: 20px;
|
|
2101
2101
|
.sub-header-row {
|
|
2102
|
-
padding: 0 0 $header-padding / 2 0;
|
|
2102
|
+
padding: 0 0 calc($header-padding / 2) 0;
|
|
2103
2103
|
}
|
|
2104
2104
|
|
|
2105
2105
|
.fixed-header-actions {
|
|
2106
2106
|
padding: 0 0 $header-padding 0;
|
|
2107
2107
|
&.with-sub-header {
|
|
2108
|
-
padding: 0 0 $header-padding / 4 0;
|
|
2108
|
+
padding: 0 0 calc($header-padding / 4) 0;
|
|
2109
2109
|
}
|
|
2110
2110
|
|
|
2111
2111
|
width: 100%;
|
|
@@ -9,7 +9,7 @@ import { ToggleSwitch } from '@components/Form/ToggleSwitch';
|
|
|
9
9
|
import { TextAreaAutoGrow } from '@components/Form/TextArea';
|
|
10
10
|
import { Banner } from '@components/Banner';
|
|
11
11
|
|
|
12
|
-
export default
|
|
12
|
+
export default {
|
|
13
13
|
name: 'BannerSettings',
|
|
14
14
|
|
|
15
15
|
props: {
|
|
@@ -112,7 +112,7 @@ export default ({
|
|
|
112
112
|
return this.bannerType === 'bannerConsent';
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
|
-
}
|
|
115
|
+
};
|
|
116
116
|
</script>
|
|
117
117
|
|
|
118
118
|
<template>
|
|
@@ -3,7 +3,7 @@ import { LabeledInput } from '@components/Form/LabeledInput';
|
|
|
3
3
|
import { Checkbox } from '@components/Form/Checkbox';
|
|
4
4
|
import { _EDIT, _VIEW } from '@shell/config/query-params';
|
|
5
5
|
|
|
6
|
-
export default
|
|
6
|
+
export default {
|
|
7
7
|
|
|
8
8
|
name: 'NotificationSettings',
|
|
9
9
|
|
|
@@ -29,7 +29,7 @@ export default ({
|
|
|
29
29
|
},
|
|
30
30
|
},
|
|
31
31
|
|
|
32
|
-
}
|
|
32
|
+
};
|
|
33
33
|
</script>
|
|
34
34
|
|
|
35
35
|
<template>
|
|
@@ -6,7 +6,7 @@ import ResourceTabs from '@shell/components/form/ResourceTabs';
|
|
|
6
6
|
import Tab from '@shell/components/Tabbed/Tab';
|
|
7
7
|
import { MANAGEMENT, FLEET, SCHEMA } from '@shell/config/types';
|
|
8
8
|
import { FLEET as FLEET_LABELS } from '@shell/config/labels-annotations';
|
|
9
|
-
import { allHash } from 'utils/promise';
|
|
9
|
+
import { allHash } from '@shell/utils/promise';
|
|
10
10
|
|
|
11
11
|
export default {
|
|
12
12
|
name: 'FleetDetailCluster',
|
|
@@ -134,7 +134,7 @@ export default {
|
|
|
134
134
|
this.waiting = false;
|
|
135
135
|
this.close();
|
|
136
136
|
|
|
137
|
-
await this.$store.dispatch('management/findAll', { type: this.
|
|
137
|
+
await this.$store.dispatch('management/findAll', { type: this.update.type, opt: { force: true } });
|
|
138
138
|
}
|
|
139
139
|
} catch (e) {}
|
|
140
140
|
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { shallowMount } from '@vue/test-utils';
|
|
2
|
+
import Auth from '@shell/edit/monitoring.coreos.com.alertmanagerconfig/auth.vue';
|
|
3
|
+
import LabeledSelect from '@shell/components/form/LabeledSelect.vue';
|
|
4
|
+
import SimpleSecretSelector from '@shell/components/form/SimpleSecretSelector';
|
|
5
|
+
|
|
6
|
+
describe('component: Auth.vue', () => {
|
|
7
|
+
const defaultProps = {
|
|
8
|
+
mode: 'edit',
|
|
9
|
+
value: {},
|
|
10
|
+
namespace: 'test-namespace'
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
it('should render correctly with initial props', () => {
|
|
14
|
+
const wrapper = shallowMount(Auth, {
|
|
15
|
+
props: defaultProps,
|
|
16
|
+
global: { mocks: { $fetchState: { pending: false, error: null } } }
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
expect(wrapper.find('h3').text()).toBe('%monitoringReceiver.auth.label%');
|
|
20
|
+
expect(wrapper.findComponent(LabeledSelect).exists()).toBe(true);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('should initialize with basic auth type if present', () => {
|
|
24
|
+
const wrapper = shallowMount(Auth, {
|
|
25
|
+
props: { ...defaultProps, value: { basicAuth: { username: { name: 'test' } } } },
|
|
26
|
+
global: { mocks: { $fetchState: { pending: false, error: null } } }
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
expect(wrapper.vm.authType).toBe('basicAuth');
|
|
30
|
+
expect(wrapper.findAllComponents(SimpleSecretSelector)).toHaveLength(2);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('should initialize with bearer token auth type if present', () => {
|
|
34
|
+
const wrapper = shallowMount(Auth, {
|
|
35
|
+
props: { ...defaultProps, value: { bearerTokenSecret: { name: 'test' } } },
|
|
36
|
+
global: { mocks: { $fetchState: { pending: false, error: null } } }
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
expect(wrapper.vm.authType).toBe('bearerTokenSecret');
|
|
40
|
+
expect(wrapper.findAllComponents(SimpleSecretSelector)).toHaveLength(1);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('should switch to basic auth and clear other types', async() => {
|
|
44
|
+
const value = { bearerTokenSecret: { name: 'b', key: 'k' } };
|
|
45
|
+
const wrapper = shallowMount(Auth, {
|
|
46
|
+
props: { ...defaultProps, value },
|
|
47
|
+
global: { mocks: { $fetchState: { pending: false, error: null } } }
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
await wrapper.findComponent(LabeledSelect).vm.$emit('update:value', 'basicAuth');
|
|
51
|
+
expect(wrapper.vm.authType).toBe('basicAuth');
|
|
52
|
+
expect(wrapper.props('value').bearerTokenSecret).toBeUndefined();
|
|
53
|
+
expect(wrapper.props('value').basicAuth).toBeDefined();
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('should switch to bearer token and clear other types', async() => {
|
|
57
|
+
const value = { basicAuth: { username: { name: 'u' } } };
|
|
58
|
+
const wrapper = shallowMount(Auth, {
|
|
59
|
+
props: { ...defaultProps, value },
|
|
60
|
+
global: { mocks: { $fetchState: { pending: false, error: null } } }
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
await wrapper.findComponent(LabeledSelect).vm.$emit('update:value', 'bearerTokenSecret');
|
|
64
|
+
expect(wrapper.vm.authType).toBe('bearerTokenSecret');
|
|
65
|
+
expect(wrapper.props('value').basicAuth).toBeUndefined();
|
|
66
|
+
expect(wrapper.props('value').bearerTokenSecret).toBeDefined();
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('should switch to none and clear other types', async() => {
|
|
70
|
+
const value = { basicAuth: { username: { name: 'u' } } };
|
|
71
|
+
const wrapper = shallowMount(Auth, {
|
|
72
|
+
props: { ...defaultProps, value },
|
|
73
|
+
global: { mocks: { $fetchState: { pending: false, error: null } } }
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
await wrapper.findComponent(LabeledSelect).vm.$emit('update:value', 'none');
|
|
77
|
+
expect(wrapper.vm.authType).toBe('none');
|
|
78
|
+
expect(wrapper.props('value').basicAuth).toBeUndefined();
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('should update basic auth username and password', async() => {
|
|
82
|
+
const wrapper = shallowMount(Auth, {
|
|
83
|
+
props: { ...defaultProps, value: { basicAuth: { username: { name: 'test' } } } },
|
|
84
|
+
global: { mocks: { $fetchState: { pending: false, error: null } } }
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
await wrapper.vm.$nextTick();
|
|
88
|
+
|
|
89
|
+
const selectors = wrapper.findAllComponents(SimpleSecretSelector);
|
|
90
|
+
|
|
91
|
+
expect(selectors).toHaveLength(2);
|
|
92
|
+
|
|
93
|
+
const usernameSelector = selectors[0];
|
|
94
|
+
const passwordSelector = selectors[1];
|
|
95
|
+
|
|
96
|
+
await usernameSelector.vm.$emit('updateSecretName', 'user-secret');
|
|
97
|
+
await usernameSelector.vm.$emit('updateSecretKey', 'user-key');
|
|
98
|
+
await passwordSelector.vm.$emit('updateSecretName', 'pass-secret');
|
|
99
|
+
await passwordSelector.vm.$emit('updateSecretKey', 'pass-key');
|
|
100
|
+
|
|
101
|
+
const basicAuth = wrapper.props('value').basicAuth;
|
|
102
|
+
|
|
103
|
+
expect(basicAuth.username.name).toBe('user-secret');
|
|
104
|
+
expect(basicAuth.username.key).toBe('user-key');
|
|
105
|
+
expect(basicAuth.password.name).toBe('pass-secret');
|
|
106
|
+
expect(basicAuth.password.key).toBe('pass-key');
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('should update bearer token secret', async() => {
|
|
110
|
+
const wrapper = shallowMount(Auth, {
|
|
111
|
+
props: { ...defaultProps, value: { bearerTokenSecret: { name: 'test' } } },
|
|
112
|
+
global: { mocks: { $fetchState: { pending: false, error: null } } }
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
await wrapper.vm.$nextTick();
|
|
116
|
+
|
|
117
|
+
const selector = wrapper.findComponent(SimpleSecretSelector);
|
|
118
|
+
|
|
119
|
+
expect(selector.exists()).toBe(true);
|
|
120
|
+
|
|
121
|
+
await selector.vm.$emit('updateSecretName', 'bearer-name');
|
|
122
|
+
await selector.vm.$emit('updateSecretKey', 'bearer-key');
|
|
123
|
+
|
|
124
|
+
const bearerToken = wrapper.props('value').bearerTokenSecret;
|
|
125
|
+
|
|
126
|
+
expect(bearerToken.name).toBe('bearer-name');
|
|
127
|
+
expect(bearerToken.key).toBe('bearer-key');
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it('should render in view mode', () => {
|
|
131
|
+
const wrapper = shallowMount(Auth, {
|
|
132
|
+
props: {
|
|
133
|
+
mode: 'view', value: { basicAuth: {} }, namespace: 'ns'
|
|
134
|
+
},
|
|
135
|
+
global: { mocks: { $fetchState: { pending: false, error: null } } }
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
expect(wrapper.findComponent(LabeledSelect).attributes('disabled')).toBe('true');
|
|
139
|
+
const selectors = wrapper.findAllComponents(SimpleSecretSelector);
|
|
140
|
+
|
|
141
|
+
selectors.forEach((selector) => {
|
|
142
|
+
expect(selector.props('disabled')).toBe(true);
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
});
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/* eslint-disable import/first */
|
|
2
|
+
global.PointerEvent = class PointerEvent extends Event {};
|
|
3
|
+
|
|
4
|
+
import { shallowMount } from '@vue/test-utils';
|
|
5
|
+
import { EDITOR_MODES } from '@shell/components/YamlEditor.vue';
|
|
6
|
+
import { _EDIT, _VIEW } from '@shell/config/query-params';
|
|
7
|
+
import Index from '../index.vue';
|
|
8
|
+
|
|
9
|
+
describe('monitoring.coreos.com.alertmanagerconfig/index.vue', () => {
|
|
10
|
+
it('should render correctly', () => {
|
|
11
|
+
const valueMock = {
|
|
12
|
+
applyDefaults: jest.fn(),
|
|
13
|
+
spec: {
|
|
14
|
+
receivers: [
|
|
15
|
+
{ name: 'receiver1', type: 'webhook' },
|
|
16
|
+
{ name: 'receiver2', type: 'email' },
|
|
17
|
+
],
|
|
18
|
+
},
|
|
19
|
+
getCreateReceiverRoute: jest.fn(() => ({ name: 'create-receiver' })),
|
|
20
|
+
getReceiverDetailLink: jest.fn((name) => `detail-${ name }`),
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const wrapper = shallowMount(Index, {
|
|
24
|
+
propsData: {
|
|
25
|
+
value: valueMock,
|
|
26
|
+
mode: 'create',
|
|
27
|
+
},
|
|
28
|
+
global: {
|
|
29
|
+
mocks: {
|
|
30
|
+
$store: {
|
|
31
|
+
getters: { currentProduct: { inStore: 'test' } },
|
|
32
|
+
dispatch: jest.fn(() => Promise.resolve({ receiverSchema: {} })),
|
|
33
|
+
},
|
|
34
|
+
$router: { push: jest.fn() },
|
|
35
|
+
$route: { name: 'test-route' },
|
|
36
|
+
$fetchState: { pending: false },
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
stubs: {
|
|
40
|
+
CruResource: true,
|
|
41
|
+
NameNsDescription: true,
|
|
42
|
+
Tabbed: true,
|
|
43
|
+
Tab: true,
|
|
44
|
+
RouteConfig: true,
|
|
45
|
+
ResourceTable: true,
|
|
46
|
+
ActionMenu: true,
|
|
47
|
+
Loading: true,
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
// Ensure the component is rendered
|
|
52
|
+
expect(wrapper.exists()).toBe(true);
|
|
53
|
+
|
|
54
|
+
// Assert that applyDefaults is called
|
|
55
|
+
expect(valueMock.applyDefaults).toHaveBeenCalledTimes(1);
|
|
56
|
+
|
|
57
|
+
// Assert receiverOptions are correctly populated from value.spec.receivers
|
|
58
|
+
expect(wrapper.vm.receiverOptions).toStrictEqual(['receiver1', 'receiver2']);
|
|
59
|
+
|
|
60
|
+
// Assert createReceiverLink is correctly set
|
|
61
|
+
expect(wrapper.vm.createReceiverLink).toStrictEqual({ name: 'create-receiver' });
|
|
62
|
+
|
|
63
|
+
// Assert that receiverTableHeaders has the expected structure (basic check)
|
|
64
|
+
expect(wrapper.vm.receiverTableHeaders.length).toBeGreaterThan(0);
|
|
65
|
+
expect(wrapper.vm.receiverTableHeaders[0].name).toBe('name');
|
|
66
|
+
expect(wrapper.vm.receiverTableHeaders[1].name).toBe('type');
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// Additional test for editorMode computed property
|
|
70
|
+
it('editorMode should return VIEW_CODE when mode is _VIEW', () => {
|
|
71
|
+
const valueMock = {
|
|
72
|
+
applyDefaults: jest.fn(),
|
|
73
|
+
spec: { receivers: [] },
|
|
74
|
+
getCreateReceiverRoute: jest.fn(),
|
|
75
|
+
getReceiverDetailLink: jest.fn(),
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const wrapper = shallowMount(Index, {
|
|
79
|
+
propsData: {
|
|
80
|
+
value: valueMock,
|
|
81
|
+
mode: _VIEW, // Set mode to _VIEW
|
|
82
|
+
},
|
|
83
|
+
global: {
|
|
84
|
+
mocks: {
|
|
85
|
+
$store: {
|
|
86
|
+
getters: { currentProduct: { inStore: 'test' } },
|
|
87
|
+
dispatch: jest.fn(() => Promise.resolve({ receiverSchema: {} })),
|
|
88
|
+
},
|
|
89
|
+
$router: { push: jest.fn() },
|
|
90
|
+
$route: { name: 'test-route' },
|
|
91
|
+
$fetchState: { pending: false },
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
stubs: {
|
|
95
|
+
CruResource: true,
|
|
96
|
+
NameNsDescription: true,
|
|
97
|
+
Tabbed: true,
|
|
98
|
+
Tab: true,
|
|
99
|
+
RouteConfig: true,
|
|
100
|
+
ResourceTable: true,
|
|
101
|
+
ActionMenu: true,
|
|
102
|
+
Loading: true,
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
expect(wrapper.vm.editorMode).toBe(EDITOR_MODES.VIEW_CODE);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('editorMode should return EDIT_CODE when mode is not _VIEW', () => {
|
|
110
|
+
const valueMock = {
|
|
111
|
+
applyDefaults: jest.fn(),
|
|
112
|
+
spec: { receivers: [] },
|
|
113
|
+
getCreateReceiverRoute: jest.fn(),
|
|
114
|
+
getReceiverDetailLink: jest.fn(),
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const wrapper = shallowMount(Index, {
|
|
118
|
+
propsData: {
|
|
119
|
+
value: valueMock,
|
|
120
|
+
mode: _EDIT, // Set mode to _EDIT
|
|
121
|
+
},
|
|
122
|
+
global: {
|
|
123
|
+
mocks: {
|
|
124
|
+
$store: {
|
|
125
|
+
getters: { currentProduct: { inStore: 'test' } },
|
|
126
|
+
dispatch: jest.fn(() => Promise.resolve({ receiverSchema: {} })),
|
|
127
|
+
},
|
|
128
|
+
$router: { push: jest.fn() },
|
|
129
|
+
$route: { name: 'test-route' },
|
|
130
|
+
$fetchState: { pending: false },
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
stubs: {
|
|
134
|
+
CruResource: true,
|
|
135
|
+
NameNsDescription: true,
|
|
136
|
+
Tabbed: true,
|
|
137
|
+
Tab: true,
|
|
138
|
+
RouteConfig: true,
|
|
139
|
+
ResourceTable: true,
|
|
140
|
+
ActionMenu: true,
|
|
141
|
+
Loading: true,
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
expect(wrapper.vm.editorMode).toBe(EDITOR_MODES.EDIT_CODE);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it('translateReceiverTypes method translates receiver types', () => {
|
|
149
|
+
const valueMock = {
|
|
150
|
+
applyDefaults: jest.fn(),
|
|
151
|
+
spec: { receivers: [] },
|
|
152
|
+
getCreateReceiverRoute: jest.fn(),
|
|
153
|
+
getReceiverDetailLink: jest.fn(),
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
const wrapper = shallowMount(Index, {
|
|
157
|
+
propsData: {
|
|
158
|
+
value: valueMock,
|
|
159
|
+
mode: 'create',
|
|
160
|
+
},
|
|
161
|
+
global: {
|
|
162
|
+
mocks: {
|
|
163
|
+
$store: {
|
|
164
|
+
getters: { currentProduct: { inStore: 'test' } },
|
|
165
|
+
dispatch: jest.fn(() => Promise.resolve({ receiverSchema: {} })),
|
|
166
|
+
},
|
|
167
|
+
$router: { push: jest.fn() },
|
|
168
|
+
$route: { name: 'test-route' },
|
|
169
|
+
$fetchState: { pending: false },
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
stubs: {
|
|
173
|
+
CruResource: true,
|
|
174
|
+
NameNsDescription: true,
|
|
175
|
+
Tabbed: true,
|
|
176
|
+
Tab: true,
|
|
177
|
+
RouteConfig: true,
|
|
178
|
+
ResourceTable: true,
|
|
179
|
+
ActionMenu: true,
|
|
180
|
+
Loading: true,
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// Ensure receiverTypes is initialized, then call the method
|
|
185
|
+
const originalReceiverTypes = [
|
|
186
|
+
{ label: 'alertmanagerConfigReceiver.alerta', value: 'alerta' },
|
|
187
|
+
{ label: 'alertmanagerConfigReceiver.dingtalk', value: 'dingtalk' }
|
|
188
|
+
];
|
|
189
|
+
|
|
190
|
+
// Manually set receiverTypes for the test (it's normally populated from an import)
|
|
191
|
+
// In a real scenario, you'd mock the import or ensure it's loaded before the test.
|
|
192
|
+
// For this test, we'll directly manipulate the vm.
|
|
193
|
+
wrapper.setData({ receiverTypes: originalReceiverTypes });
|
|
194
|
+
|
|
195
|
+
const translatedTypes = wrapper.vm.translateReceiverTypes();
|
|
196
|
+
|
|
197
|
+
expect(translatedTypes).toStrictEqual([
|
|
198
|
+
{ label: '%alertmanagerConfigReceiver.alerta%', value: 'alerta' },
|
|
199
|
+
{ label: '%alertmanagerConfigReceiver.dingtalk%', value: 'dingtalk' }
|
|
200
|
+
]);
|
|
201
|
+
});
|
|
202
|
+
});
|