dashboard/shell/components/__tests__/ConfigMapSettings.test.ts

377 lines
12 KiB
TypeScript

import { mount } from '@vue/test-utils';
import ConfigMapSettings, { Setting } from '@shell/components/ConfigMapSettings/index.vue';
import { _EDIT } from '@shell/config/query-params';
import { CONFIG_MAP } from '@shell/config/types';
import jsyaml from 'js-yaml';
const mockedStore = () => {
return {
getters: {
'cluster/schemaFor': jest.fn(),
'management/schemaFor': jest.fn(),
'i18n/t': (text: string, v = {}) => {
return `${ text }${ Object.values(v) }`;
},
},
};
};
const mockedRoute = { query: {} };
const requiredSetup = () => {
return {
global: {
mocks: {
$store: mockedStore(),
$route: mockedRoute,
$fetchState: {},
},
stubs: { AsyncButton: true }
}
};
};
const settings = {
garbageCollectionInterval: {
weight: 0,
type: 'string',
path: 'garbageCollectionInterval',
default: '15m',
},
garbageCollectionIntervalNumber: {
weight: 0,
type: 'number',
handler: 'UnitInput',
path: 'garbageCollectionIntervalNumber',
default: '15m',
},
gitClientTimeout: {
weight: 1,
type: 'string',
path: 'gitClientTimeout',
default: '30s',
},
gitClientTimeoutNumber: {
weight: 1,
type: 'number',
handler: 'UnitInput',
path: 'gitClientTimeoutNumber',
default: '30s',
},
gitjobReplicas: {
weight: 1,
type: 'number',
path: 'gitjob.replicas',
default: 1,
},
multiSelect: {
weight: 4,
type: 'array',
path: 'multiSelect',
default: 'foo',
items: [{
type: 'string',
value: 'foo'
}, {
type: 'string',
value: 'bar'
}],
},
singleSelect: {
weight: 1,
type: 'string',
items: [{
type: 'string',
value: 'strict'
}, {
type: 'string',
value: 'system-store'
}],
path: 'agentTLSMode',
default: 'system-store',
},
nodeSelector: {
weight: 1,
type: 'object',
handler: 'Textarea',
path: 'nodeSelector',
default: {},
},
nodeSelectorKeyValue: {
weight: 1,
type: 'object',
handler: 'KeyValue',
path: 'nodeSelectorKeyValue',
default: { foo: 'val' },
},
debug: {
weight: 1,
type: 'boolean',
path: 'debug',
default: false,
},
tolerationsTaints: {
weight: 2,
type: 'object',
handler: 'Taints',
path: 'tolerationsTaints',
default: [{
key: 'foo1',
value: 'bar1',
effect: 'PreferNoSchedule'
}],
},
} as Record<string, Setting>;
const groups = [{
name: 'general',
children: [
'garbageCollectionInterval',
'gitClientTimeout'
],
expanded: true,
weight: 0
}];
const configMap = {
type: CONFIG_MAP,
metadata: {
namespace: 'ns',
name: 'name'
},
data: {
fleet: jsyaml.dump({
foo: 'bar',
garbageCollectionInterval: '1h',
gitjob: { replicas: 5 },
debug: true,
nodeSelector: { key: 'value1' },
garbageCollectionIntervalNumber: '14m',
gitClientTimeoutNumber: '3m',
nodeSelectorKeyValue: { foo: 'bar' },
tolerationsTaints: [{
key: 'foo',
value: 'bar',
effect: 'PreferNoSchedule'
}]
}),
foo: { bar: 'value' }
},
save: () => {},
};
describe('component: ConfigMapSettings', () => {
it('should init values from settings descriptor default values, having ConfigMap === null', async() => {
const wrapper = mount(ConfigMapSettings, {
...requiredSetup(),
props: {
settings,
groups,
name: 'cm-name',
namespace: 'cm-namespace',
dataKey: 'fleet'
},
computed: {
mode: () => _EDIT,
canEdit: () => true,
fetchState: () => ({ $fetchState: false }),
},
});
wrapper.vm.initValues();
await wrapper.vm.$nextTick();
const generalGroup = wrapper.find('[data-testid="cm-settings-group-body-general"]');
const garbageCollectionInterval = wrapper.find('[data-testid="cm-settings-field-string-garbageCollectionInterval"]').element as HTMLInputElement;
const garbageCollectionIntervalNumber = wrapper.find('[data-testid="cm-settings-field-number-UnitInput-garbageCollectionIntervalNumber"]').element as HTMLInputElement;
const gitClientTimeout = wrapper.find('[data-testid="cm-settings-field-string-gitClientTimeout"]').element as HTMLInputElement;
const gitClientTimeoutNumber = wrapper.find('[data-testid="cm-settings-field-number-UnitInput-gitClientTimeoutNumber"]').element as HTMLInputElement;
const gitjobReplicas = wrapper.find('[data-testid="cm-settings-field-number-gitjobReplicas"]').element as HTMLInputElement;
const multiSelect = wrapper.find('[data-testid="cm-settings-field-array-multiSelect"]').element as HTMLInputElement;
const nodeSelector = wrapper.find('[data-testid="cm-settings-field-object-Textarea-nodeSelector"]').element as HTMLInputElement;
const nodeSelectorKeyValue = wrapper.find('[data-testid="cm-settings-field-object-KeyValue-nodeSelectorKeyValue"]').find('[data-testid="input-kv-item-key-0"]').element as HTMLInputElement;
const tolerationsTaints = wrapper.find('[data-testid="cm-settings-field-object-Taints-tolerationsTaints"]').find('[data-testid="input-kv-item-key-0"]').element as HTMLInputElement;
const singleSelect = wrapper.find('[data-testid="cm-settings-field-string-singleSelect"]').element as HTMLInputElement;
const debug = wrapper.find('[data-testid="cm-settings-field-boolean-debug"]').find('input[type="checkbox"]').element as HTMLInputElement;
expect(generalGroup.exists()).toBe(true);
expect(garbageCollectionInterval.value).toBe('15m');
expect(garbageCollectionIntervalNumber.value).toBe('900');
expect(gitClientTimeout.value).toBe('30s');
expect(gitClientTimeoutNumber.value).toBe('30');
expect(multiSelect.textContent).toContain('foo');
expect(singleSelect.textContent).toContain('system-store');
expect(nodeSelector.value).toBe('{}');
expect(nodeSelectorKeyValue.value).toBe('foo');
expect(tolerationsTaints.value).toBe('foo1');
expect(gitjobReplicas.value).toBe('1');
expect(debug.checked).toBe(false);
});
it('should display error when parsing malformed values', async() => {
const wrapper = mount(ConfigMapSettings, {
...requiredSetup(),
props: {
settings,
groups,
name: 'cm-name',
namespace: 'cm-namespace',
dataKey: 'fleet'
},
computed: {
mode: () => _EDIT,
canEdit: () => true,
fetchState: () => ({ $fetchState: false }),
},
});
wrapper.setData({
configMap: {
type: CONFIG_MAP,
metadata: {
namespace: 'ns',
name: 'name'
},
data: {
fleet: { foo: 'bar' },
foo: { bar: 'value' }
}
}
});
wrapper.vm.initValues();
await wrapper.vm.$nextTick();
const error = wrapper.find('[data-testid="cm-settings-error"]');
expect(error.text()).toContain('parseError');
});
it('should merge settings descriptor default values with ConfigMap values', async() => {
const wrapper = mount(ConfigMapSettings, {
...requiredSetup(),
props: {
settings,
groups,
name: 'cm-name',
namespace: 'cm-namespace',
dataKey: 'fleet'
},
computed: {
mode: () => _EDIT,
canEdit: () => true,
fetchState: () => ({ $fetchState: false }),
},
});
wrapper.setData({ configMap });
wrapper.vm.initValues();
await wrapper.vm.$nextTick();
const garbageCollectionInterval = wrapper.find('[data-testid="cm-settings-field-string-garbageCollectionInterval"]').element as HTMLInputElement;
const gitClientTimeout = wrapper.find('[data-testid="cm-settings-field-string-gitClientTimeout"]').element as HTMLInputElement;
const gitjobReplicas = wrapper.find('[data-testid="cm-settings-field-number-gitjobReplicas"]').element as HTMLInputElement;
const multiSelect = wrapper.find('[data-testid="cm-settings-field-array-multiSelect"]').element as HTMLInputElement;
const nodeSelector = wrapper.find('[data-testid="cm-settings-field-object-Textarea-nodeSelector"]').element as HTMLInputElement;
const singleSelect = wrapper.find('[data-testid="cm-settings-field-string-singleSelect"]').element as HTMLInputElement;
const debug = wrapper.find('[data-testid="cm-settings-field-boolean-debug"]').find('input[type="checkbox"]').element as HTMLInputElement;
const garbageCollectionIntervalNumber = wrapper.find('[data-testid="cm-settings-field-number-UnitInput-garbageCollectionIntervalNumber"]').element as HTMLInputElement;
const gitClientTimeoutNumber = wrapper.find('[data-testid="cm-settings-field-number-UnitInput-gitClientTimeoutNumber"]').element as HTMLInputElement;
const nodeSelectorKeyValue = wrapper.find('[data-testid="cm-settings-field-object-KeyValue-nodeSelectorKeyValue"]').find('[data-testid="input-kv-item-key-0"]').element as HTMLInputElement;
const tolerationsTaints = wrapper.find('[data-testid="cm-settings-field-object-Taints-tolerationsTaints"]').find('[data-testid="input-kv-item-key-0"]').element as HTMLInputElement;
expect(garbageCollectionInterval.value).toBe('1h');
expect(gitClientTimeout.value).toBe('30s');
expect(multiSelect.textContent).toContain('foo');
expect(singleSelect.textContent).toContain('system-store');
expect(nodeSelector.value).toBe('{\"key\":\"value1\"}');
expect(gitjobReplicas.value).toBe('5');
expect(debug.checked).toBe(true);
expect(garbageCollectionIntervalNumber.value).toBe('840');
expect(gitClientTimeoutNumber.value).toBe('180');
expect(nodeSelectorKeyValue.value).toBe('foo');
expect(tolerationsTaints.value).toBe('foo');
});
it('should save ConfigMap values preserving extraneous values', async() => {
const wrapper = mount(ConfigMapSettings, {
...requiredSetup(),
props: {
settings,
groups,
name: 'cm-name',
namespace: 'cm-namespace',
dataKey: 'fleet'
},
computed: {
mode: () => _EDIT,
canEdit: () => true,
fetchState: () => ({ $fetchState: false }),
},
});
wrapper.setData({ configMap });
wrapper.vm.initValues();
await wrapper.vm.$nextTick();
await wrapper.vm.save(() => {});
const cm = wrapper.vm.configMap as any;
expect(cm.data).toStrictEqual({
fleet: 'foo: bar\ngarbageCollectionInterval: 1h\ngitjob:\n replicas: 5\ndebug: true\nnodeSelector:\n key: value1\ngarbageCollectionIntervalNumber: 840s\ngitClientTimeoutNumber: 180s\nnodeSelectorKeyValue:\n foo: bar\ntolerationsTaints:\n - key: foo\n value: bar\n effect: PreferNoSchedule\ngitClientTimeout: 30s\nmultiSelect: foo\nagentTLSMode: system-store\n',
foo: { bar: 'value' },
});
});
it('should show groups titles and hide body if group is collapsed', async() => {
const wrapper = mount(ConfigMapSettings, {
...requiredSetup(),
props: {
settings,
groups: [{
name: 'general',
children: [
'garbageCollectionInterval',
'gitClientTimeout'
],
expanded: false,
weight: 0
}],
name: 'cm-name',
namespace: 'cm-namespace',
dataKey: 'fleet'
},
computed: {
mode: () => _EDIT,
canEdit: () => true,
fetchState: () => ({ $fetchState: false }),
},
});
wrapper.vm.initValues();
await wrapper.vm.$nextTick();
const generalGroupRow = wrapper.find('[data-testid="cm-settings-row-general"]');
const generalGroupBody = wrapper.find('[data-testid="cm-settings-group-body-general"]');
const garbageCollectionInterval = wrapper.find('[data-testid="cm-settings-field-string-garbageCollectionInterval"]');
const gitClientTimeout = wrapper.find('[data-testid="cm-settings-field-string-gitClientTimeout"]');
expect(generalGroupRow.exists()).toBe(true);
expect(generalGroupBody.exists()).toBe(false);
expect(garbageCollectionInterval.exists()).toBe(false);
expect(gitClientTimeout.exists()).toBe(false);
});
});