@rancher/shell 0.5.2 → 0.5.3
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/assets/translations/en-us.yaml +8 -4
- package/components/ClusterIconMenu.vue +24 -9
- package/components/CodeMirror.vue +79 -18
- package/components/FixedBanner.vue +1 -0
- package/components/ResourceDetail/index.vue +1 -4
- package/components/ResourceYaml.vue +29 -5
- package/components/SideNav.vue +42 -64
- package/components/SortableTable/index.vue +1 -1
- package/components/YamlEditor.vue +1 -0
- package/components/__tests__/CodeMirror.spec.ts +99 -0
- package/components/form/BannerSettings.vue +3 -0
- package/components/form/FileSelector.vue +1 -0
- package/components/form/KeyValue.vue +1 -0
- package/components/formatter/WorkloadDetailEndpoints.vue +12 -22
- package/components/formatter/__tests__/WorkloadDetailEndpoints.test.ts +81 -0
- package/components/nav/Header.vue +1 -0
- package/components/nav/Jump.vue +19 -9
- package/components/nav/TopLevelMenu.vue +37 -15
- package/components/nav/Type.vue +15 -4
- package/components/nav/__tests__/TopLevelMenu.test.ts +1 -1
- package/components/nav/__tests__/Type.test.ts +30 -0
- package/detail/__tests__/provisioning.cattle.io.cluster.test.ts +77 -0
- package/detail/fleet.cattle.io.bundle.vue +1 -1
- package/detail/provisioning.cattle.io.cluster.vue +19 -4
- package/edit/management.cattle.io.setting.vue +1 -0
- package/edit/monitoring.coreos.com.alertmanagerconfig/types/opsgenie.vue +1 -1
- package/edit/monitoring.coreos.com.alertmanagerconfig/types/pagerduty.vue +1 -2
- package/edit/monitoring.coreos.com.alertmanagerconfig/types/slack.vue +1 -1
- package/edit/provisioning.cattle.io.cluster/index.vue +14 -7
- package/edit/provisioning.cattle.io.cluster/rke2.vue +22 -50
- package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +9 -11
- package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue +3 -1
- package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +3 -0
- package/edit/token.vue +1 -0
- package/list/catalog.cattle.io.app.vue +1 -0
- package/list/management.cattle.io.setting.vue +1 -0
- package/machine-config/amazonec2.vue +1 -0
- package/models/__tests__/provisioning.cattle.io.cluster.test.ts +151 -0
- package/models/__tests__/secret.test.ts +37 -0
- package/models/__tests__/storage.k8s.io.storageclass.test.ts +22 -0
- package/models/provisioning.cattle.io.cluster.js +36 -1
- package/models/secret.js +9 -0
- package/models/storage.k8s.io.storageclass.js +1 -1
- package/package.json +1 -1
- package/pages/c/_cluster/settings/DefaultLinksEditor.vue +1 -0
- package/pages/c/_cluster/settings/brand.vue +3 -0
- package/pages/c/_cluster/uiplugins/AddExtensionRepos.vue +4 -4
- package/pages/c/_cluster/uiplugins/SetupUIPlugins.vue +5 -2
- package/pages/c/_cluster/uiplugins/__tests__/AddExtensionRepos.test.ts +96 -0
- package/pages/c/_cluster/uiplugins/__tests__/SetupUIPlugins.test.ts +128 -0
- package/plugins/dashboard-store/__tests__/actions.test.ts +196 -111
- package/plugins/dashboard-store/actions.js +4 -6
- package/plugins/dashboard-store/getters.js +60 -2
- package/plugins/dashboard-store/resource-class.js +6 -2
- package/plugins/steve/__tests__/getters.spec.ts +10 -0
- package/plugins/steve/__tests__/resource-utils.test.ts +159 -0
- package/plugins/steve/actions.js +3 -37
- package/plugins/steve/getters.js +6 -0
- package/plugins/steve/resource-utils.ts +38 -0
- package/store/__tests__/type-map.test.ts +1122 -0
- package/store/index.js +3 -2
- package/store/type-map.js +145 -75
- package/types/shell/index.d.ts +2 -0
- package/utils/__tests__/create-yaml.test.ts +10 -0
- package/utils/create-yaml.js +5 -1
- package/utils/object.js +10 -0
package/package.json
CHANGED
|
@@ -238,6 +238,7 @@ export default {
|
|
|
238
238
|
<label class="text-muted">{{ t('branding.logos.lightPreview') }}</label>
|
|
239
239
|
<img
|
|
240
240
|
class="logo-preview"
|
|
241
|
+
data-testid="branding-logo-light-preview"
|
|
241
242
|
:src="uiLogoLight ? uiLogoLight : uiLogoDark"
|
|
242
243
|
>
|
|
243
244
|
</SimpleBox>
|
|
@@ -262,6 +263,7 @@ export default {
|
|
|
262
263
|
<label class="text-muted">{{ t('branding.logos.darkPreview') }}</label>
|
|
263
264
|
<img
|
|
264
265
|
class="logo-preview"
|
|
266
|
+
data-testid="branding-logo-dark-preview"
|
|
265
267
|
:src="uiLogoDark ? uiLogoDark : uiLogoLight"
|
|
266
268
|
>
|
|
267
269
|
</SimpleBox>
|
|
@@ -304,6 +306,7 @@ export default {
|
|
|
304
306
|
<label class="text-muted">{{ t('branding.favicon.preview') }}</label>
|
|
305
307
|
<img
|
|
306
308
|
class="logo-preview"
|
|
309
|
+
data-testid="branding-favicon-preview"
|
|
307
310
|
:src="uiFavicon"
|
|
308
311
|
>
|
|
309
312
|
</SimpleBox>
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
UI_PLUGINS_PARTNERS_REPO_URL,
|
|
11
11
|
UI_PLUGINS_PARTNERS_REPO_BRANCH,
|
|
12
12
|
} from '@shell/config/uiplugins';
|
|
13
|
+
import { isRancherPrime } from '@shell/config/version';
|
|
13
14
|
|
|
14
15
|
export default {
|
|
15
16
|
components: {
|
|
@@ -27,6 +28,7 @@ export default {
|
|
|
27
28
|
return {
|
|
28
29
|
errors: [],
|
|
29
30
|
repos: [],
|
|
31
|
+
prime: isRancherPrime(),
|
|
30
32
|
addRepos: {
|
|
31
33
|
official: true,
|
|
32
34
|
partners: true
|
|
@@ -54,16 +56,13 @@ export default {
|
|
|
54
56
|
},
|
|
55
57
|
hasRancherUIPartnersPluginsRepo() {
|
|
56
58
|
return !!this.repos.find((r) => r.urlDisplay === UI_PLUGINS_PARTNERS_REPO_URL);
|
|
57
|
-
},
|
|
58
|
-
isAnyRepoAvailableForInstall() {
|
|
59
|
-
return !this.hasRancherUIPluginsRepo || !this.hasRancherUIPartnersPluginsRepo;
|
|
60
59
|
}
|
|
61
60
|
},
|
|
62
61
|
|
|
63
62
|
methods: {
|
|
64
63
|
showDialog() {
|
|
65
64
|
this.addRepos = {
|
|
66
|
-
official: !this.hasRancherUIPluginsRepo,
|
|
65
|
+
official: isRancherPrime() && !this.hasRancherUIPluginsRepo,
|
|
67
66
|
partners: !this.hasRancherUIPartnersPluginsRepo,
|
|
68
67
|
};
|
|
69
68
|
this.$modal.show('add-extensions-repos');
|
|
@@ -121,6 +120,7 @@ export default {
|
|
|
121
120
|
</p>
|
|
122
121
|
<!-- Official repo -->
|
|
123
122
|
<div
|
|
123
|
+
v-if="prime"
|
|
124
124
|
class="mb-15"
|
|
125
125
|
>
|
|
126
126
|
<Checkbox
|
|
@@ -7,6 +7,7 @@ import { CATALOG as CATALOG_ANNOTATIONS } from '@shell/config/labels-annotations
|
|
|
7
7
|
import Dialog from '@shell/components/Dialog.vue';
|
|
8
8
|
import Checkbox from '@components/Form/Checkbox/Checkbox.vue';
|
|
9
9
|
import Banner from '@components/Banner/Banner.vue';
|
|
10
|
+
import { isRancherPrime } from '@shell/config/version';
|
|
10
11
|
|
|
11
12
|
import {
|
|
12
13
|
UI_PLUGIN_NAMESPACE,
|
|
@@ -68,6 +69,7 @@ export default {
|
|
|
68
69
|
haveCharts: false,
|
|
69
70
|
installCharts: [],
|
|
70
71
|
errors: [],
|
|
72
|
+
prime: isRancherPrime(),
|
|
71
73
|
addRepos: {
|
|
72
74
|
official: true,
|
|
73
75
|
partners: true,
|
|
@@ -98,7 +100,7 @@ export default {
|
|
|
98
100
|
return !!this.repos.find((r) => r.urlDisplay === UI_PLUGINS_PARTNERS_REPO_URL);
|
|
99
101
|
},
|
|
100
102
|
isAnyRepoAvailableForInstall() {
|
|
101
|
-
return !this.hasRancherUIPluginsRepo || !this.hasRancherUIPartnersPluginsRepo;
|
|
103
|
+
return (isRancherPrime() && !this.hasRancherUIPluginsRepo) || !this.hasRancherUIPartnersPluginsRepo;
|
|
102
104
|
}
|
|
103
105
|
},
|
|
104
106
|
|
|
@@ -155,7 +157,7 @@ export default {
|
|
|
155
157
|
|
|
156
158
|
// Reset checkbox based on if the repo is already installed
|
|
157
159
|
this.addRepos = {
|
|
158
|
-
official: !this.hasRancherUIPluginsRepo,
|
|
160
|
+
official: isRancherPrime() && !this.hasRancherUIPluginsRepo,
|
|
159
161
|
partners: !this.hasRancherUIPartnersPluginsRepo,
|
|
160
162
|
};
|
|
161
163
|
|
|
@@ -286,6 +288,7 @@ export default {
|
|
|
286
288
|
</Banner>
|
|
287
289
|
<!-- Official rancher repo -->
|
|
288
290
|
<div
|
|
291
|
+
v-if="prime"
|
|
289
292
|
class="mb-15"
|
|
290
293
|
>
|
|
291
294
|
<Checkbox
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { mount } from '@vue/test-utils';
|
|
2
|
+
import {
|
|
3
|
+
UI_PLUGINS_REPO_URL,
|
|
4
|
+
UI_PLUGINS_PARTNERS_REPO_URL,
|
|
5
|
+
} from '@shell/config/uiplugins';
|
|
6
|
+
import AddExtensionRepos from '@shell/pages/c/_cluster/uiplugins/AddExtensionRepos.vue';
|
|
7
|
+
const mockedStore = () => {
|
|
8
|
+
return {
|
|
9
|
+
getters: {
|
|
10
|
+
'i18n/t': (text: string) => text,
|
|
11
|
+
'i18n/exists': (text: string) => text,
|
|
12
|
+
t: (text: string) => text,
|
|
13
|
+
'management/schemaFor': () => true,
|
|
14
|
+
'management/findAll': () => [
|
|
15
|
+
{ urlDisplay: UI_PLUGINS_REPO_URL },
|
|
16
|
+
{ urlDisplay: UI_PLUGINS_PARTNERS_REPO_URL },
|
|
17
|
+
]
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const requiredSetup = () => {
|
|
23
|
+
return {
|
|
24
|
+
mocks: {
|
|
25
|
+
$store: mockedStore(),
|
|
26
|
+
$fetchState: {},
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
describe('component: AddExtensionRepos', () => {
|
|
32
|
+
it('should NOT SHOW a checkbox to install official Rancher repo if NOT prime', async() => {
|
|
33
|
+
jest.useFakeTimers();
|
|
34
|
+
|
|
35
|
+
const wrapper = mount(AddExtensionRepos, {
|
|
36
|
+
...requiredSetup(),
|
|
37
|
+
// since vue-js-modal uses transitions, we need disable
|
|
38
|
+
// the default behaviour of transition-stubbing that vue-test-utils has...
|
|
39
|
+
stubs: { transition: false }
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
wrapper.vm.showDialog();
|
|
43
|
+
|
|
44
|
+
// these couple of nextTick + advanceTimersByTime are needed for
|
|
45
|
+
// the dialog content to be rendered!
|
|
46
|
+
await wrapper.vm.$nextTick();
|
|
47
|
+
|
|
48
|
+
jest.advanceTimersByTime(1);
|
|
49
|
+
|
|
50
|
+
await wrapper.vm.$nextTick();
|
|
51
|
+
|
|
52
|
+
jest.advanceTimersByTime(1);
|
|
53
|
+
|
|
54
|
+
const rancherCheckbox = wrapper.find('[data-testid="add-extensions-repos-modal-add-official-repo"]');
|
|
55
|
+
const partnersCheckbox = wrapper.find('[data-testid="add-extensions-repos-modal-add-partners-repo"]');
|
|
56
|
+
|
|
57
|
+
expect(rancherCheckbox.exists()).toBe(false);
|
|
58
|
+
expect(partnersCheckbox.exists()).toBe(true);
|
|
59
|
+
|
|
60
|
+
jest.clearAllTimers();
|
|
61
|
+
wrapper.destroy();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('should SHOW a checkbox to install official Rancher repo if IS prime', async() => {
|
|
65
|
+
jest.useFakeTimers();
|
|
66
|
+
|
|
67
|
+
const wrapper = mount(AddExtensionRepos, {
|
|
68
|
+
...requiredSetup(),
|
|
69
|
+
// since vue-js-modal uses transitions, we need disable
|
|
70
|
+
// the default behaviour of transition-stubbing that vue-test-utils has...
|
|
71
|
+
stubs: { transition: false }
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
wrapper.vm.prime = true;
|
|
75
|
+
wrapper.vm.showDialog();
|
|
76
|
+
|
|
77
|
+
// these couple of nextTick + advanceTimersByTime are needed for
|
|
78
|
+
// the dialog content to be rendered!
|
|
79
|
+
await wrapper.vm.$nextTick();
|
|
80
|
+
|
|
81
|
+
jest.advanceTimersByTime(1);
|
|
82
|
+
|
|
83
|
+
await wrapper.vm.$nextTick();
|
|
84
|
+
|
|
85
|
+
jest.advanceTimersByTime(1);
|
|
86
|
+
|
|
87
|
+
const rancherCheckbox = wrapper.find('[data-testid="add-extensions-repos-modal-add-official-repo"]');
|
|
88
|
+
const partnersCheckbox = wrapper.find('[data-testid="add-extensions-repos-modal-add-partners-repo"]');
|
|
89
|
+
|
|
90
|
+
expect(rancherCheckbox.exists()).toBe(true);
|
|
91
|
+
expect(partnersCheckbox.exists()).toBe(true);
|
|
92
|
+
|
|
93
|
+
jest.clearAllTimers();
|
|
94
|
+
wrapper.destroy();
|
|
95
|
+
});
|
|
96
|
+
});
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { mount, createLocalVue } from '@vue/test-utils';
|
|
2
|
+
import Vuex from 'vuex';
|
|
3
|
+
import {
|
|
4
|
+
UI_PLUGINS_REPO_URL,
|
|
5
|
+
UI_PLUGINS_PARTNERS_REPO_URL,
|
|
6
|
+
} from '@shell/config/uiplugins';
|
|
7
|
+
import SetupUIPlugins from '@shell/pages/c/_cluster/uiplugins/SetupUIPlugins.vue';
|
|
8
|
+
|
|
9
|
+
describe('component: SetupUIPlugins', () => {
|
|
10
|
+
const localVue = createLocalVue();
|
|
11
|
+
|
|
12
|
+
localVue.use(Vuex);
|
|
13
|
+
|
|
14
|
+
it('should NOT SHOW a checkbox to install official Rancher repo if NOT prime', async() => {
|
|
15
|
+
const store = new Vuex.Store({
|
|
16
|
+
modules: {
|
|
17
|
+
catalog: {
|
|
18
|
+
namespaced: true,
|
|
19
|
+
getters: {
|
|
20
|
+
repos: () => [
|
|
21
|
+
{ urlDisplay: UI_PLUGINS_REPO_URL },
|
|
22
|
+
{ urlDisplay: UI_PLUGINS_PARTNERS_REPO_URL },
|
|
23
|
+
],
|
|
24
|
+
repo: () => {},
|
|
25
|
+
rawCharts: () => [],
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
getters: {
|
|
30
|
+
'i18n/t': () => jest.fn(),
|
|
31
|
+
'i18n/exists': () => jest.fn(),
|
|
32
|
+
t: () => jest.fn(),
|
|
33
|
+
'management/schemaFor': () => true,
|
|
34
|
+
'management/findAll': () => [],
|
|
35
|
+
'management/find': () => {}
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
jest.useFakeTimers();
|
|
40
|
+
|
|
41
|
+
const wrapper = mount(SetupUIPlugins, {
|
|
42
|
+
store,
|
|
43
|
+
localVue,
|
|
44
|
+
// since vue-js-modal uses transitions, we need disable
|
|
45
|
+
// the default behaviour of transition-stubbing that vue-test-utils has...
|
|
46
|
+
stubs: { transition: false }
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
wrapper.vm.enable();
|
|
50
|
+
|
|
51
|
+
// these couple of nextTick + advanceTimersByTime are needed for
|
|
52
|
+
// the dialog content to be rendered!
|
|
53
|
+
await wrapper.vm.$nextTick();
|
|
54
|
+
|
|
55
|
+
jest.advanceTimersByTime(1);
|
|
56
|
+
|
|
57
|
+
await wrapper.vm.$nextTick();
|
|
58
|
+
|
|
59
|
+
jest.advanceTimersByTime(1);
|
|
60
|
+
|
|
61
|
+
const rancherCheckbox = wrapper.find('[data-testid="extension-enable-operator-official-repo"]');
|
|
62
|
+
const partnersCheckbox = wrapper.find('[data-testid="extension-enable-operator-partners-repo"]');
|
|
63
|
+
|
|
64
|
+
expect(rancherCheckbox.exists()).toBe(false);
|
|
65
|
+
expect(partnersCheckbox.exists()).toBe(true);
|
|
66
|
+
|
|
67
|
+
jest.clearAllTimers();
|
|
68
|
+
wrapper.destroy();
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('should SHOW a checkbox to install official Rancher repo if IS prime', async() => {
|
|
72
|
+
const store = new Vuex.Store({
|
|
73
|
+
modules: {
|
|
74
|
+
catalog: {
|
|
75
|
+
namespaced: true,
|
|
76
|
+
getters: {
|
|
77
|
+
repos: () => [
|
|
78
|
+
{ urlDisplay: UI_PLUGINS_REPO_URL },
|
|
79
|
+
{ urlDisplay: UI_PLUGINS_PARTNERS_REPO_URL },
|
|
80
|
+
],
|
|
81
|
+
repo: () => {},
|
|
82
|
+
rawCharts: () => [],
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
getters: {
|
|
87
|
+
'i18n/t': () => jest.fn(),
|
|
88
|
+
'i18n/exists': () => jest.fn(),
|
|
89
|
+
t: () => jest.fn(),
|
|
90
|
+
'management/schemaFor': () => true,
|
|
91
|
+
'management/findAll': () => [],
|
|
92
|
+
'management/find': () => {}
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
jest.useFakeTimers();
|
|
97
|
+
|
|
98
|
+
const wrapper = mount(SetupUIPlugins, {
|
|
99
|
+
store,
|
|
100
|
+
localVue,
|
|
101
|
+
// since vue-js-modal uses transitions, we need disable
|
|
102
|
+
// the default behaviour of transition-stubbing that vue-test-utils has...
|
|
103
|
+
stubs: { transition: false }
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
wrapper.vm.prime = true;
|
|
107
|
+
wrapper.vm.enable();
|
|
108
|
+
|
|
109
|
+
// these couple of nextTick + advanceTimersByTime are needed for
|
|
110
|
+
// the dialog content to be rendered!
|
|
111
|
+
await wrapper.vm.$nextTick();
|
|
112
|
+
|
|
113
|
+
jest.advanceTimersByTime(1);
|
|
114
|
+
|
|
115
|
+
await wrapper.vm.$nextTick();
|
|
116
|
+
|
|
117
|
+
jest.advanceTimersByTime(1);
|
|
118
|
+
|
|
119
|
+
const rancherCheckbox = wrapper.find('[data-testid="extension-enable-operator-official-repo"]');
|
|
120
|
+
const partnersCheckbox = wrapper.find('[data-testid="extension-enable-operator-partners-repo"]');
|
|
121
|
+
|
|
122
|
+
expect(rancherCheckbox.exists()).toBe(true);
|
|
123
|
+
expect(partnersCheckbox.exists()).toBe(true);
|
|
124
|
+
|
|
125
|
+
jest.clearAllTimers();
|
|
126
|
+
wrapper.destroy();
|
|
127
|
+
});
|
|
128
|
+
});
|
|
@@ -1,127 +1,127 @@
|
|
|
1
1
|
import _actions from '@shell/plugins/dashboard-store/actions';
|
|
2
2
|
|
|
3
|
-
const { findAll } = _actions;
|
|
3
|
+
const { findAll, findMatching } = _actions;
|
|
4
4
|
|
|
5
5
|
describe('dashboard-store: actions', () => {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
6
|
+
describe('findAll', () => {
|
|
7
|
+
// Note - there are TS errors alll over this describe and should not have merged with them in.
|
|
8
|
+
const setupContext = () => {
|
|
9
|
+
const commit = jest.fn();
|
|
10
|
+
const dispatch = jest.fn((...args) => {
|
|
11
|
+
switch (args[0]) {
|
|
12
|
+
case 'request':
|
|
13
|
+
return { data: ['requestData'] };
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
const state = { config: { namespace: 'unitTest' } };
|
|
17
|
+
const getters = {
|
|
18
|
+
normalizeType: jest.fn(() => 'getters.normalizeType'),
|
|
19
|
+
typeRegistered: jest.fn(() => false),
|
|
20
|
+
haveAll: jest.fn(() => false),
|
|
21
|
+
haveAllNamespace: jest.fn(() => false),
|
|
22
|
+
all: jest.fn(() => 'getters.all'),
|
|
23
|
+
urlFor: jest.fn(() => 'getters.urlFor'), // we're not testing the urlFor getter so we don't need to do anything with opt here
|
|
24
|
+
};
|
|
25
|
+
const rootGetters = {
|
|
26
|
+
'type-map/optionsFor': jest.fn(),
|
|
27
|
+
'auth/fromHeader': 'foo'
|
|
28
|
+
};
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
// we're not testing function output based off of state or getter inputs here since they are dependencies and should be tested independently
|
|
31
|
+
return {
|
|
32
|
+
state,
|
|
33
|
+
getters,
|
|
34
|
+
rootGetters,
|
|
35
|
+
commit,
|
|
36
|
+
dispatch
|
|
37
|
+
};
|
|
35
38
|
};
|
|
36
|
-
};
|
|
37
39
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
{
|
|
40
|
+
const standardAssertions = {
|
|
41
|
+
returnsPromise: {
|
|
41
42
|
assertionLabel: 'returns a promise',
|
|
42
43
|
valueGetter: ({ findAllPromise }) => typeof findAllPromise.then,
|
|
43
44
|
valueExpected: 'function'
|
|
44
45
|
},
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
},
|
|
55
|
-
firstDispatchAction: {
|
|
56
|
-
assertionLabel: 'first dispatch should be the "request" action',
|
|
57
|
-
valueGetter: ({ dispatch }) => dispatch.mock.calls[0][0],
|
|
58
|
-
valueExpected: 'request'
|
|
59
|
-
},
|
|
60
|
-
firstDispatchParams: {
|
|
61
|
-
assertionLabel: 'first dispatch parameters should be provided a normalized type and a url, streaming, and "metadata.managedFields" excluded under opt',
|
|
62
|
-
valueGetter: ({ dispatch }) => dispatch.mock.calls[0][1],
|
|
63
|
-
valueExpected: {
|
|
64
|
-
type: 'getters.normalizeType',
|
|
65
|
-
opt: {
|
|
66
|
-
url: 'getters.urlFor',
|
|
67
|
-
stream: true
|
|
68
|
-
}
|
|
46
|
+
callsAll: {
|
|
47
|
+
assertionLabel: 'calls the "all" getter with the normalizedType',
|
|
48
|
+
valueGetter: ({ getters }) => getters.all.mock.calls[0][0],
|
|
49
|
+
valueExpected: 'getters.normalizeType'
|
|
50
|
+
},
|
|
51
|
+
returnsFromAll: {
|
|
52
|
+
assertionLabel: 'returns the value expected from the "all" getter',
|
|
53
|
+
valueGetter: ({ findAllReturnValue }) => findAllReturnValue,
|
|
54
|
+
valueExpected: 'getters.all'
|
|
69
55
|
},
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
56
|
+
firstDispatchAction: {
|
|
57
|
+
assertionLabel: 'first dispatch should be the "request" action',
|
|
58
|
+
valueGetter: ({ dispatch }) => dispatch.mock.calls[0][0],
|
|
59
|
+
valueExpected: 'request'
|
|
60
|
+
},
|
|
61
|
+
firstDispatchParams: {
|
|
62
|
+
assertionLabel: 'first dispatch parameters should be provided a normalized type and a url, streaming, and "metadata.managedFields" excluded under opt',
|
|
63
|
+
valueGetter: ({ dispatch }) => dispatch.mock.calls[0][1],
|
|
64
|
+
valueExpected: {
|
|
65
|
+
type: 'getters.normalizeType',
|
|
66
|
+
opt: {
|
|
67
|
+
url: 'getters.urlFor',
|
|
68
|
+
stream: true
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
assertionMethod: 'toMatchObject'
|
|
72
|
+
},
|
|
73
|
+
secondDispatchAction: {
|
|
74
|
+
assertionLabel: 'second dispatch should be the "watch" action',
|
|
75
|
+
valueGetter: ({ dispatch }) => dispatch.mock.calls[1][0],
|
|
76
|
+
valueExpected: 'watch'
|
|
77
|
+
},
|
|
78
|
+
secondDispatchParams: {
|
|
79
|
+
assertionLabel: 'second dispatch parameters should have a normalized type and force set to false',
|
|
80
|
+
valueGetter: ({ dispatch }) => dispatch.mock.calls[1][1],
|
|
81
|
+
valueExpected: { type: 'getters.normalizeType', force: false },
|
|
82
|
+
assertionMethod: 'toMatchObject'
|
|
83
|
+
},
|
|
84
|
+
countDispatches: {
|
|
85
|
+
assertionLabel: 'should only make two dispatches',
|
|
86
|
+
valueGetter: ({ dispatch }) => dispatch.mock.calls,
|
|
87
|
+
valueExpected: 2,
|
|
88
|
+
assertionMethod: 'toHaveLength'
|
|
89
|
+
},
|
|
90
|
+
firstCommitMutation: {
|
|
91
|
+
assertionLabel: 'first commit should be the "registerType" mutation',
|
|
92
|
+
valueGetter: ({ commit }) => commit.mock.calls[0][0],
|
|
93
|
+
valueExpected: 'registerType'
|
|
94
|
+
},
|
|
95
|
+
firstCommitParams: {
|
|
96
|
+
assertionLabel: 'first commit parameter should be a normalized type',
|
|
97
|
+
valueGetter: ({ commit }) => commit.mock.calls[0][1],
|
|
98
|
+
valueExpected: 'getters.normalizeType'
|
|
99
|
+
},
|
|
100
|
+
secondCommitMutation: {
|
|
101
|
+
assertionLabel: 'second commit should be the "loadAll" mutation',
|
|
102
|
+
valueGetter: ({ commit }) => commit.mock.calls[1][0],
|
|
103
|
+
valueExpected: 'loadAll'
|
|
104
|
+
},
|
|
105
|
+
secondCommitParams: {
|
|
106
|
+
assertionLabel: 'second commit parameters should have a normalized type, ctx.state.config.namespace, data returned by request, and skipHaveAll set to false',
|
|
107
|
+
valueGetter: ({ commit }) => commit.mock.calls[1][1],
|
|
108
|
+
valueExpected: {
|
|
109
|
+
type: 'getters.normalizeType',
|
|
110
|
+
ctx: { state: { config: { namespace: 'unitTest' } } },
|
|
111
|
+
data: ['requestData'],
|
|
112
|
+
skipHaveAll: false,
|
|
113
|
+
},
|
|
114
|
+
assertionMethod: 'toMatchObject'
|
|
112
115
|
},
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
describe('dashboard-store > actions > findAll', () => {
|
|
116
|
+
countCommits: {
|
|
117
|
+
assertionLabel: 'should only make two commits',
|
|
118
|
+
valueGetter: ({ commit }) => commit.mock.calls,
|
|
119
|
+
valueExpected: 2,
|
|
120
|
+
assertionMethod: 'toHaveLength'
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
};
|
|
124
|
+
|
|
125
125
|
describe('called without a cache for the type in the second param', () => {
|
|
126
126
|
const {
|
|
127
127
|
dispatch, commit, getters, rootGetters, state
|
|
@@ -162,4 +162,89 @@ describe('dashboard-store: actions', () => {
|
|
|
162
162
|
);
|
|
163
163
|
});
|
|
164
164
|
});
|
|
165
|
+
|
|
166
|
+
describe('findMatching', () => {
|
|
167
|
+
const setupContext = () => {
|
|
168
|
+
const commit = jest.fn();
|
|
169
|
+
const dispatch = jest.fn(() => 'dispatch');
|
|
170
|
+
|
|
171
|
+
const state = { config: { namespace: 'unitTest' } };
|
|
172
|
+
const getters = {
|
|
173
|
+
normalizeType: jest.fn((type) => type),
|
|
174
|
+
typeRegistered: jest.fn(() => true),
|
|
175
|
+
haveSelector: jest.fn(() => false),
|
|
176
|
+
matching: jest.fn(() => 'getters.all'),
|
|
177
|
+
urlFor: jest.fn(() => 'getters.urlFor'),
|
|
178
|
+
urlOptions: jest.fn(() => 'getters.urlOptions')
|
|
179
|
+
};
|
|
180
|
+
const rootGetters = { 'type-map/optionsFor': jest.fn() };
|
|
181
|
+
|
|
182
|
+
// we're not testing function output based off of state or getter inputs here since they are dependencies and should be tested independently
|
|
183
|
+
return {
|
|
184
|
+
state,
|
|
185
|
+
getters,
|
|
186
|
+
rootGetters,
|
|
187
|
+
commit,
|
|
188
|
+
dispatch
|
|
189
|
+
};
|
|
190
|
+
};
|
|
191
|
+
const genericType = 'services';
|
|
192
|
+
const genericSelector = 'a=b';
|
|
193
|
+
const genericOpt = {};
|
|
194
|
+
|
|
195
|
+
const assertionChain = [{
|
|
196
|
+
assertionLabel: 'Basic Selector',
|
|
197
|
+
input: {
|
|
198
|
+
type: genericType,
|
|
199
|
+
selector: genericSelector,
|
|
200
|
+
opt: { ...genericOpt },
|
|
201
|
+
namespace: undefined
|
|
202
|
+
},
|
|
203
|
+
output: {
|
|
204
|
+
getters: {
|
|
205
|
+
urlFor: [
|
|
206
|
+
genericType,
|
|
207
|
+
null,
|
|
208
|
+
{
|
|
209
|
+
...genericOpt,
|
|
210
|
+
depaginate: undefined,
|
|
211
|
+
labelSelector: genericSelector,
|
|
212
|
+
url: 'getters.urlFor',
|
|
213
|
+
}
|
|
214
|
+
]
|
|
215
|
+
},
|
|
216
|
+
actions: {
|
|
217
|
+
request: {
|
|
218
|
+
opt: {},
|
|
219
|
+
type: genericType
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}];
|
|
224
|
+
|
|
225
|
+
const {
|
|
226
|
+
dispatch,
|
|
227
|
+
commit,
|
|
228
|
+
getters,
|
|
229
|
+
rootGetters,
|
|
230
|
+
state
|
|
231
|
+
} = setupContext();
|
|
232
|
+
|
|
233
|
+
it.each(assertionChain)(
|
|
234
|
+
'$assertionLabel',
|
|
235
|
+
async({ input, output }) => {
|
|
236
|
+
await findMatching(
|
|
237
|
+
{
|
|
238
|
+
dispatch,
|
|
239
|
+
getters,
|
|
240
|
+
rootGetters,
|
|
241
|
+
state,
|
|
242
|
+
commit,
|
|
243
|
+
},
|
|
244
|
+
input
|
|
245
|
+
);
|
|
246
|
+
expect(getters.urlFor).toHaveBeenCalledWith(...output.getters.urlFor);
|
|
247
|
+
}
|
|
248
|
+
);
|
|
249
|
+
});
|
|
165
250
|
});
|